[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:
Pavel Labath 2020-03-25 16:18:50 +01:00
parent 2ca7fe3796
commit e22f0dabcf
3 changed files with 57 additions and 11 deletions

View File

@ -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)

View File

@ -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 + ^

View File

@ -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
...