forked from OSchip/llvm-project
[lldb/breakpad] Fix register resolution on arm
In breakpad, only x86 (and mips) registers have a leading '$' in their names. Arm architectures use plain register names. Previously, lldb was assuming all registers have a '$'. Fix the code to match the (unfortunately, inconsistent) reality.
This commit is contained in:
parent
2ca7fe3796
commit
e22f0dabcf
|
@ -408,20 +408,25 @@ GetRule(llvm::StringRef &unwind_rules) {
|
|||
}
|
||||
|
||||
static const RegisterInfo *
|
||||
ResolveRegister(const SymbolFile::RegisterInfoResolver &resolver,
|
||||
ResolveRegister(const llvm::Triple &triple,
|
||||
const SymbolFile::RegisterInfoResolver &resolver,
|
||||
llvm::StringRef name) {
|
||||
if (name.consume_front("$"))
|
||||
return resolver.ResolveName(name);
|
||||
|
||||
return nullptr;
|
||||
if (triple.isX86() || triple.isMIPS()) {
|
||||
// X86 and MIPS registers have '$' in front of their register names. Arm and
|
||||
// AArch64 don't.
|
||||
if (!name.consume_front("$"))
|
||||
return nullptr;
|
||||
}
|
||||
return resolver.ResolveName(name);
|
||||
}
|
||||
|
||||
static const RegisterInfo *
|
||||
ResolveRegisterOrRA(const SymbolFile::RegisterInfoResolver &resolver,
|
||||
ResolveRegisterOrRA(const llvm::Triple &triple,
|
||||
const SymbolFile::RegisterInfoResolver &resolver,
|
||||
llvm::StringRef name) {
|
||||
if (name == ".ra")
|
||||
return resolver.ResolveNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
|
||||
return ResolveRegister(resolver, name);
|
||||
return ResolveRegister(triple, resolver, name);
|
||||
}
|
||||
|
||||
llvm::ArrayRef<uint8_t> SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) {
|
||||
|
@ -440,6 +445,7 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
|
|||
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
|
||||
|
||||
llvm::BumpPtrAllocator node_alloc;
|
||||
llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple();
|
||||
while (auto rule = GetRule(unwind_rules)) {
|
||||
node_alloc.Reset();
|
||||
llvm::StringRef lhs = rule->first;
|
||||
|
@ -455,7 +461,8 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
|
|||
if (name == ".cfa" && lhs != ".cfa")
|
||||
return postfix::MakeNode<postfix::InitialValueNode>(node_alloc);
|
||||
|
||||
if (const RegisterInfo *info = ResolveRegister(resolver, name)) {
|
||||
if (const RegisterInfo *info =
|
||||
ResolveRegister(triple, resolver, name)) {
|
||||
return postfix::MakeNode<postfix::RegisterNode>(
|
||||
node_alloc, info->kinds[eRegisterKindLLDB]);
|
||||
}
|
||||
|
@ -470,7 +477,8 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
|
|||
llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*rhs);
|
||||
if (lhs == ".cfa") {
|
||||
row.GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
|
||||
} else if (const RegisterInfo *info = ResolveRegisterOrRA(resolver, lhs)) {
|
||||
} else if (const RegisterInfo *info =
|
||||
ResolveRegisterOrRA(triple, resolver, lhs)) {
|
||||
UnwindPlan::Row::RegisterLocation loc;
|
||||
loc.SetIsDWARFExpression(saved.data(), saved.size());
|
||||
row.SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
|
||||
|
@ -574,6 +582,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
|
|||
return nullptr;
|
||||
}
|
||||
auto it = program.begin();
|
||||
llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple();
|
||||
const auto &symbol_resolver =
|
||||
[&](postfix::SymbolNode &symbol) -> postfix::Node * {
|
||||
llvm::StringRef name = symbol.GetName();
|
||||
|
@ -581,7 +590,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
|
|||
if (rule.first == name)
|
||||
return rule.second;
|
||||
}
|
||||
if (const RegisterInfo *info = ResolveRegister(resolver, name))
|
||||
if (const RegisterInfo *info = ResolveRegister(triple, resolver, name))
|
||||
return postfix::MakeNode<postfix::RegisterNode>(
|
||||
node_alloc, info->kinds[eRegisterKindLLDB]);
|
||||
return nullptr;
|
||||
|
@ -611,7 +620,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
|
|||
|
||||
// Now process the rest of the assignments.
|
||||
for (++it; it != program.end(); ++it) {
|
||||
const RegisterInfo *info = ResolveRegister(resolver, it->first);
|
||||
const RegisterInfo *info = ResolveRegister(triple, resolver, it->first);
|
||||
// It is not an error if the resolution fails because the program may
|
||||
// contain temporary variables.
|
||||
if (!info)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
MODULE Linux arm E5894855C35DCCCCCCCCCCCCCCCCCCCC0 linux.out
|
||||
INFO CODE_ID E35C283BC327C28762DB788BF5A4078BE2351448
|
||||
FUNC 0 2 0 func0
|
||||
STACK CFI INIT 0 2 .cfa: sp 0 + .ra: lr
|
||||
STACK CFI 2 .cfa: sp 8 + .ra: .cfa -4 + ^ r7: .cfa -8 + ^
|
|
@ -0,0 +1,32 @@
|
|||
# REQUIRES: arm
|
||||
|
||||
# RUN: yaml2obj %s >%t
|
||||
# RUN: %lldb -c %t -o "target symbols add %S/Inputs/stack-cfi-arm.syms" \
|
||||
# RUN: -o "image show-unwind -n func0" -b | FileCheck %s
|
||||
|
||||
# CHECK: Symbol file UnwindPlan:
|
||||
# CHECK: row[0]: 0: CFA=DW_OP_breg13 +0, DW_OP_consts +0, DW_OP_plus => pc=DW_OP_breg14 +0
|
||||
# CHECK-NEXT: row[1]: 2: CFA=DW_OP_breg13 +0, DW_OP_consts +8, DW_OP_plus => r7=DW_OP_pick 0x00, DW_OP_consts -8, DW_OP_plus , DW_OP_deref pc=DW_OP_pick 0x00, DW_OP_consts -4, DW_OP_plus , DW_OP_deref
|
||||
#
|
||||
|
||||
--- !minidump
|
||||
Streams:
|
||||
- Type: ThreadList
|
||||
Threads:
|
||||
- Thread Id: 0x00003E81
|
||||
Context: DEAD
|
||||
Stack:
|
||||
Start of Memory Range: 0x00007FFCEB34A000
|
||||
Content: DEAD
|
||||
- Type: ModuleList
|
||||
Modules:
|
||||
- Base of Image: 0x0000000000400000
|
||||
Size of Image: 0x00001000
|
||||
Module Name: '/tmp/stack-cfi-arm.out'
|
||||
CodeView Record: 4C457042E35C283BC327C28762DB788BF5A4078BE2351448
|
||||
- Type: SystemInfo
|
||||
Processor Arch: ARM
|
||||
Platform ID: Linux
|
||||
CPU:
|
||||
CPUID: 0
|
||||
...
|
Loading…
Reference in New Issue