2019-05-13 04:42:32 +00:00
|
|
|
//===-- PdbFPOProgramToDWARFExpression.cpp ----------------------*- C++ -*-===//
|
2019-02-01 10:01:18 +00:00
|
|
|
//
|
2019-02-08 08:48:15 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2019-02-01 10:01:18 +00:00
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
#include "PdbFPOProgramToDWARFExpression.h"
|
|
|
|
|
#include "CodeViewRegisterMapping.h"
|
|
|
|
|
|
|
|
|
|
#include "lldb/Core/StreamBuffer.h"
|
Move postfix expression code out of the NativePDB plugin
Summary:
The NativePDB plugin contains code to convert "programs" describing the
layout of function frames into dwarf (for easier interaction with the
rest of lldb). This functionality is useful for the Breakpad plugin too,
as it contains the same kind of expressions (because breakpad info is
generated from pdb files).
In this patch, I move the core classes of this code into a common place,
where it can be used from both files. Previously, these were the details
of the implementation, but here I am exposing them (instead of just a
single "string->string" conversion function), as breakpad will need to
use these in a slightly different way. The reason for that is that
breakpad files generated from dwarf expressions use a slightly different
syntax, although most of the core code can be reused with a bit of
thought.
This is also the reason why I am not moving the parsing or dwarf
generation bits, as they will need to be generalized a bit before
they're usable for both scenarios.
This patch should be NFC, modulo renaming the moved entities to more
neutral names.
The reason I am moving this to the "Symbol" library, is because both
customers will be "Symbol"Files, and also the unwinding code lives in
the Symbol library. From a purely dependency standpoint this code will
probably be standalone, and so it could be moved all the way to Utility,
but that seems too low for this kind of functionality.
Reviewers: jasonmolenda, amccarth, clayborg, JDevlieghere, aleksandr.urakov
Subscribers: aprantl, markmentovai, lldb-commits
Differential Revision: https://reviews.llvm.org/D60599
llvm-svn: 358976
2019-04-23 11:50:07 +00:00
|
|
|
#include "lldb/Symbol/PostfixExpression.h"
|
2019-02-01 10:01:18 +00:00
|
|
|
#include "lldb/Utility/LLDBAssert.h"
|
|
|
|
|
#include "lldb/Utility/Stream.h"
|
|
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
|
|
|
|
|
|
|
|
#include "llvm/ADT/StringExtras.h"
|
|
|
|
|
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
|
|
|
|
#include "llvm/DebugInfo/CodeView/EnumTables.h"
|
|
|
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
|
using namespace lldb_private;
|
Move postfix expression code out of the NativePDB plugin
Summary:
The NativePDB plugin contains code to convert "programs" describing the
layout of function frames into dwarf (for easier interaction with the
rest of lldb). This functionality is useful for the Breakpad plugin too,
as it contains the same kind of expressions (because breakpad info is
generated from pdb files).
In this patch, I move the core classes of this code into a common place,
where it can be used from both files. Previously, these were the details
of the implementation, but here I am exposing them (instead of just a
single "string->string" conversion function), as breakpad will need to
use these in a slightly different way. The reason for that is that
breakpad files generated from dwarf expressions use a slightly different
syntax, although most of the core code can be reused with a bit of
thought.
This is also the reason why I am not moving the parsing or dwarf
generation bits, as they will need to be generalized a bit before
they're usable for both scenarios.
This patch should be NFC, modulo renaming the moved entities to more
neutral names.
The reason I am moving this to the "Symbol" library, is because both
customers will be "Symbol"Files, and also the unwinding code lives in
the Symbol library. From a purely dependency standpoint this code will
probably be standalone, and so it could be moved all the way to Utility,
but that seems too low for this kind of functionality.
Reviewers: jasonmolenda, amccarth, clayborg, JDevlieghere, aleksandr.urakov
Subscribers: aprantl, markmentovai, lldb-commits
Differential Revision: https://reviews.llvm.org/D60599
llvm-svn: 358976
2019-04-23 11:50:07 +00:00
|
|
|
using namespace lldb_private::postfix;
|
2019-02-01 10:01:18 +00:00
|
|
|
|
PDBFPO: Refactor register reference resolution
Summary:
This refactors moves the register name->number resolution out of the
FPOProgramNodeRegisterRef class. Instead I create a special
FPOProgramNodeSymbol class, which holds unresolved symbols, and move the
resolution into the ResolveRegisterRefs visitor.
The background here is that I'd like to use this code for Breakpad
unwind info, which uses similar syntax to describe unwind info. For
example, a simple breakpad unwind program might look like:
.cfa: $esp 8 + $ebp: .cfa 8 - ^
To be able to do this, I need to be able to customize register
resolving, as that is presently hardcoded to use codeview register
names, but breakpad supports a lot more architectures with different
register names. Moving the resolution into a separate class will allow
each user to use a different resolution logic.
Reviewers: aleksandr.urakov, zturner, amccarth
Subscribers: jdoerfert, lldb-commits
Differential Revision: https://reviews.llvm.org/D60068
llvm-svn: 357455
2019-04-02 08:44:24 +00:00
|
|
|
static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::ArchType arch_type) {
|
|
|
|
|
// lookup register name to get lldb register number
|
2019-06-03 00:48:16 +00:00
|
|
|
llvm::codeview::CPUType cpu_type;
|
|
|
|
|
switch (arch_type) {
|
|
|
|
|
case llvm::Triple::ArchType::aarch64:
|
|
|
|
|
cpu_type = llvm::codeview::CPUType::ARM64;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
cpu_type = llvm::codeview::CPUType::X64;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
PDBFPO: Refactor register reference resolution
Summary:
This refactors moves the register name->number resolution out of the
FPOProgramNodeRegisterRef class. Instead I create a special
FPOProgramNodeSymbol class, which holds unresolved symbols, and move the
resolution into the ResolveRegisterRefs visitor.
The background here is that I'd like to use this code for Breakpad
unwind info, which uses similar syntax to describe unwind info. For
example, a simple breakpad unwind program might look like:
.cfa: $esp 8 + $ebp: .cfa 8 - ^
To be able to do this, I need to be able to customize register
resolving, as that is presently hardcoded to use codeview register
names, but breakpad supports a lot more architectures with different
register names. Moving the resolution into a separate class will allow
each user to use a different resolution logic.
Reviewers: aleksandr.urakov, zturner, amccarth
Subscribers: jdoerfert, lldb-commits
Differential Revision: https://reviews.llvm.org/D60068
llvm-svn: 357455
2019-04-02 08:44:24 +00:00
|
|
|
llvm::ArrayRef<llvm::EnumEntry<uint16_t>> register_names =
|
2019-06-03 00:48:16 +00:00
|
|
|
llvm::codeview::getRegisterNames(cpu_type);
|
PDBFPO: Refactor register reference resolution
Summary:
This refactors moves the register name->number resolution out of the
FPOProgramNodeRegisterRef class. Instead I create a special
FPOProgramNodeSymbol class, which holds unresolved symbols, and move the
resolution into the ResolveRegisterRefs visitor.
The background here is that I'd like to use this code for Breakpad
unwind info, which uses similar syntax to describe unwind info. For
example, a simple breakpad unwind program might look like:
.cfa: $esp 8 + $ebp: .cfa 8 - ^
To be able to do this, I need to be able to customize register
resolving, as that is presently hardcoded to use codeview register
names, but breakpad supports a lot more architectures with different
register names. Moving the resolution into a separate class will allow
each user to use a different resolution logic.
Reviewers: aleksandr.urakov, zturner, amccarth
Subscribers: jdoerfert, lldb-commits
Differential Revision: https://reviews.llvm.org/D60068
llvm-svn: 357455
2019-04-02 08:44:24 +00:00
|
|
|
auto it = llvm::find_if(
|
|
|
|
|
register_names,
|
|
|
|
|
[®_name](const llvm::EnumEntry<uint16_t> ®ister_entry) {
|
|
|
|
|
return reg_name.compare_lower(register_entry.Name) == 0;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (it == register_names.end())
|
|
|
|
|
return LLDB_INVALID_REGNUM;
|
|
|
|
|
|
|
|
|
|
auto reg_id = static_cast<llvm::codeview::RegisterId>(it->Value);
|
|
|
|
|
return npdb::GetLLDBRegisterNumber(arch_type, reg_id);
|
|
|
|
|
}
|
2019-02-01 10:01:18 +00:00
|
|
|
|
|
|
|
|
static bool ParseFPOSingleAssignmentProgram(llvm::StringRef program,
|
2019-04-24 07:27:05 +00:00
|
|
|
llvm::BumpPtrAllocator &alloc,
|
2019-02-01 10:01:18 +00:00
|
|
|
llvm::StringRef ®ister_name,
|
Move postfix expression code out of the NativePDB plugin
Summary:
The NativePDB plugin contains code to convert "programs" describing the
layout of function frames into dwarf (for easier interaction with the
rest of lldb). This functionality is useful for the Breakpad plugin too,
as it contains the same kind of expressions (because breakpad info is
generated from pdb files).
In this patch, I move the core classes of this code into a common place,
where it can be used from both files. Previously, these were the details
of the implementation, but here I am exposing them (instead of just a
single "string->string" conversion function), as breakpad will need to
use these in a slightly different way. The reason for that is that
breakpad files generated from dwarf expressions use a slightly different
syntax, although most of the core code can be reused with a bit of
thought.
This is also the reason why I am not moving the parsing or dwarf
generation bits, as they will need to be generalized a bit before
they're usable for both scenarios.
This patch should be NFC, modulo renaming the moved entities to more
neutral names.
The reason I am moving this to the "Symbol" library, is because both
customers will be "Symbol"Files, and also the unwinding code lives in
the Symbol library. From a purely dependency standpoint this code will
probably be standalone, and so it could be moved all the way to Utility,
but that seems too low for this kind of functionality.
Reviewers: jasonmolenda, amccarth, clayborg, JDevlieghere, aleksandr.urakov
Subscribers: aprantl, markmentovai, lldb-commits
Differential Revision: https://reviews.llvm.org/D60599
llvm-svn: 358976
2019-04-23 11:50:07 +00:00
|
|
|
Node *&ast) {
|
2019-02-01 10:01:18 +00:00
|
|
|
// lvalue of assignment is always first token
|
|
|
|
|
// rvalue program goes next
|
2019-04-24 07:27:05 +00:00
|
|
|
std::tie(register_name, program) = getToken(program);
|
|
|
|
|
if (register_name.empty())
|
2019-02-01 10:01:18 +00:00
|
|
|
return false;
|
|
|
|
|
|
2019-04-24 07:27:05 +00:00
|
|
|
ast = Parse(program, alloc);
|
|
|
|
|
return ast != nullptr;
|
2019-02-01 10:01:18 +00:00
|
|
|
}
|
|
|
|
|
|
Move postfix expression code out of the NativePDB plugin
Summary:
The NativePDB plugin contains code to convert "programs" describing the
layout of function frames into dwarf (for easier interaction with the
rest of lldb). This functionality is useful for the Breakpad plugin too,
as it contains the same kind of expressions (because breakpad info is
generated from pdb files).
In this patch, I move the core classes of this code into a common place,
where it can be used from both files. Previously, these were the details
of the implementation, but here I am exposing them (instead of just a
single "string->string" conversion function), as breakpad will need to
use these in a slightly different way. The reason for that is that
breakpad files generated from dwarf expressions use a slightly different
syntax, although most of the core code can be reused with a bit of
thought.
This is also the reason why I am not moving the parsing or dwarf
generation bits, as they will need to be generalized a bit before
they're usable for both scenarios.
This patch should be NFC, modulo renaming the moved entities to more
neutral names.
The reason I am moving this to the "Symbol" library, is because both
customers will be "Symbol"Files, and also the unwinding code lives in
the Symbol library. From a purely dependency standpoint this code will
probably be standalone, and so it could be moved all the way to Utility,
but that seems too low for this kind of functionality.
Reviewers: jasonmolenda, amccarth, clayborg, JDevlieghere, aleksandr.urakov
Subscribers: aprantl, markmentovai, lldb-commits
Differential Revision: https://reviews.llvm.org/D60599
llvm-svn: 358976
2019-04-23 11:50:07 +00:00
|
|
|
static Node *ParseFPOProgram(llvm::StringRef program,
|
|
|
|
|
llvm::StringRef register_name,
|
|
|
|
|
llvm::Triple::ArchType arch_type,
|
2019-04-24 07:27:05 +00:00
|
|
|
llvm::BumpPtrAllocator &alloc) {
|
Move postfix expression code out of the NativePDB plugin
Summary:
The NativePDB plugin contains code to convert "programs" describing the
layout of function frames into dwarf (for easier interaction with the
rest of lldb). This functionality is useful for the Breakpad plugin too,
as it contains the same kind of expressions (because breakpad info is
generated from pdb files).
In this patch, I move the core classes of this code into a common place,
where it can be used from both files. Previously, these were the details
of the implementation, but here I am exposing them (instead of just a
single "string->string" conversion function), as breakpad will need to
use these in a slightly different way. The reason for that is that
breakpad files generated from dwarf expressions use a slightly different
syntax, although most of the core code can be reused with a bit of
thought.
This is also the reason why I am not moving the parsing or dwarf
generation bits, as they will need to be generalized a bit before
they're usable for both scenarios.
This patch should be NFC, modulo renaming the moved entities to more
neutral names.
The reason I am moving this to the "Symbol" library, is because both
customers will be "Symbol"Files, and also the unwinding code lives in
the Symbol library. From a purely dependency standpoint this code will
probably be standalone, and so it could be moved all the way to Utility,
but that seems too low for this kind of functionality.
Reviewers: jasonmolenda, amccarth, clayborg, JDevlieghere, aleksandr.urakov
Subscribers: aprantl, markmentovai, lldb-commits
Differential Revision: https://reviews.llvm.org/D60599
llvm-svn: 358976
2019-04-23 11:50:07 +00:00
|
|
|
llvm::DenseMap<llvm::StringRef, Node *> dependent_programs;
|
2019-02-01 10:01:18 +00:00
|
|
|
|
|
|
|
|
size_t cur = 0;
|
|
|
|
|
while (true) {
|
|
|
|
|
size_t assign_index = program.find('=', cur);
|
|
|
|
|
if (assign_index == llvm::StringRef::npos) {
|
|
|
|
|
llvm::StringRef tail = program.slice(cur, llvm::StringRef::npos);
|
|
|
|
|
if (!tail.trim().empty()) {
|
|
|
|
|
// missing assign operator
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
llvm::StringRef assignment_program = program.slice(cur, assign_index);
|
|
|
|
|
|
|
|
|
|
llvm::StringRef lvalue_name;
|
Move postfix expression code out of the NativePDB plugin
Summary:
The NativePDB plugin contains code to convert "programs" describing the
layout of function frames into dwarf (for easier interaction with the
rest of lldb). This functionality is useful for the Breakpad plugin too,
as it contains the same kind of expressions (because breakpad info is
generated from pdb files).
In this patch, I move the core classes of this code into a common place,
where it can be used from both files. Previously, these were the details
of the implementation, but here I am exposing them (instead of just a
single "string->string" conversion function), as breakpad will need to
use these in a slightly different way. The reason for that is that
breakpad files generated from dwarf expressions use a slightly different
syntax, although most of the core code can be reused with a bit of
thought.
This is also the reason why I am not moving the parsing or dwarf
generation bits, as they will need to be generalized a bit before
they're usable for both scenarios.
This patch should be NFC, modulo renaming the moved entities to more
neutral names.
The reason I am moving this to the "Symbol" library, is because both
customers will be "Symbol"Files, and also the unwinding code lives in
the Symbol library. From a purely dependency standpoint this code will
probably be standalone, and so it could be moved all the way to Utility,
but that seems too low for this kind of functionality.
Reviewers: jasonmolenda, amccarth, clayborg, JDevlieghere, aleksandr.urakov
Subscribers: aprantl, markmentovai, lldb-commits
Differential Revision: https://reviews.llvm.org/D60599
llvm-svn: 358976
2019-04-23 11:50:07 +00:00
|
|
|
Node *rvalue_ast = nullptr;
|
2019-02-01 10:01:18 +00:00
|
|
|
if (!ParseFPOSingleAssignmentProgram(assignment_program, alloc, lvalue_name,
|
|
|
|
|
rvalue_ast)) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lldbassert(rvalue_ast);
|
|
|
|
|
|
2019-04-26 08:52:04 +00:00
|
|
|
// Emplace valid dependent subtrees to make target assignment independent
|
|
|
|
|
// from predecessors. Resolve all other SymbolNodes as registers.
|
|
|
|
|
bool success =
|
|
|
|
|
ResolveSymbols(rvalue_ast, [&](SymbolNode &symbol) -> Node * {
|
|
|
|
|
if (Node *node = dependent_programs.lookup(symbol.GetName()))
|
|
|
|
|
return node;
|
|
|
|
|
uint32_t reg_num =
|
|
|
|
|
ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), arch_type);
|
|
|
|
|
|
|
|
|
|
if (reg_num == LLDB_INVALID_REGNUM)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
return MakeNode<RegisterNode>(alloc, reg_num);
|
|
|
|
|
});
|
|
|
|
|
if (!success)
|
2019-02-01 10:01:18 +00:00
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
if (lvalue_name == register_name) {
|
|
|
|
|
// found target assignment program - no need to parse further
|
|
|
|
|
return rvalue_ast;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dependent_programs[lvalue_name] = rvalue_ast;
|
|
|
|
|
cur = assign_index + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool lldb_private::npdb::TranslateFPOProgramToDWARFExpression(
|
|
|
|
|
llvm::StringRef program, llvm::StringRef register_name,
|
|
|
|
|
llvm::Triple::ArchType arch_type, Stream &stream) {
|
2019-04-24 07:27:05 +00:00
|
|
|
llvm::BumpPtrAllocator node_alloc;
|
Move postfix expression code out of the NativePDB plugin
Summary:
The NativePDB plugin contains code to convert "programs" describing the
layout of function frames into dwarf (for easier interaction with the
rest of lldb). This functionality is useful for the Breakpad plugin too,
as it contains the same kind of expressions (because breakpad info is
generated from pdb files).
In this patch, I move the core classes of this code into a common place,
where it can be used from both files. Previously, these were the details
of the implementation, but here I am exposing them (instead of just a
single "string->string" conversion function), as breakpad will need to
use these in a slightly different way. The reason for that is that
breakpad files generated from dwarf expressions use a slightly different
syntax, although most of the core code can be reused with a bit of
thought.
This is also the reason why I am not moving the parsing or dwarf
generation bits, as they will need to be generalized a bit before
they're usable for both scenarios.
This patch should be NFC, modulo renaming the moved entities to more
neutral names.
The reason I am moving this to the "Symbol" library, is because both
customers will be "Symbol"Files, and also the unwinding code lives in
the Symbol library. From a purely dependency standpoint this code will
probably be standalone, and so it could be moved all the way to Utility,
but that seems too low for this kind of functionality.
Reviewers: jasonmolenda, amccarth, clayborg, JDevlieghere, aleksandr.urakov
Subscribers: aprantl, markmentovai, lldb-commits
Differential Revision: https://reviews.llvm.org/D60599
llvm-svn: 358976
2019-04-23 11:50:07 +00:00
|
|
|
Node *target_program =
|
2019-02-01 10:01:18 +00:00
|
|
|
ParseFPOProgram(program, register_name, arch_type, node_alloc);
|
|
|
|
|
if (target_program == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-26 08:52:04 +00:00
|
|
|
ToDWARF(*target_program, stream);
|
2019-02-01 10:01:18 +00:00
|
|
|
return true;
|
|
|
|
|
}
|