summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ObjectFile
diff options
context:
space:
mode:
authorAntonio Afonso <antonio.afonso@gmail.com>2019-10-04 00:11:22 +0000
committerAntonio Afonso <antonio.afonso@gmail.com>2019-10-04 00:11:22 +0000
commitac146958041ce41aff96a2ad2a3f984fb631eb43 (patch)
tree6572c6801ce0917d9815b79d7bcc332bdfd00b6a /lldb/source/Plugins/ObjectFile
parentebaa3eb127632851e3b7dbcceb98c0a2155c6324 (diff)
downloadbcm5719-llvm-ac146958041ce41aff96a2ad2a3f984fb631eb43.tar.gz
bcm5719-llvm-ac146958041ce41aff96a2ad2a3f984fb631eb43.zip
Explicitly set entry point arch when it's thumb
Summary: I found a case where the main android binary (app_process32) had thumb code at its entry point but no entry in the symbol table indicating this. This made lldb set a 4 byte breakpoint at that address (we default to arm code) instead of a 2 byte one (like we should for thumb). The big deal with this is that the expression evaluator uses the entry point as a way to know when a JITed expression has finished executing by putting a breakpoint there. Because of this, evaluating expressions on certain android devices (Google Pixel something) made the process crash. This was fixed by checking this specific situation when we parse the symbol table and add an artificial symbol for this 2 byte range and indicating that it's arm thumb. I created 2 unit tests for this, one to check that now we know that the entry point is arm thumb, and the other to make sure we didn't change the behaviour for arm code. I also run the following on the command line with the `app_process32` where I found the issue: **Before:** ``` (lldb) dis -s 0x1640 -e 0x1644 app_process32[0x1640]: .long 0xf0004668 ; unknown opcode ``` **After:** ``` (lldb) dis -s 0x1640 -e 0x1644 app_process32`: app_process32[0x1640] <+0>: mov r0, sp app_process32[0x1642]: andeq r0, r0, r0 ``` Reviewers: clayborg, labath, wallace, espindola Subscribers: srhines, emaste, arichardson, kristof.beyls, MaskRay, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D68069 llvm-svn: 373680
Diffstat (limited to 'lldb/source/Plugins/ObjectFile')
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index e507f0e4d74..76abe32ff51 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2703,6 +2703,46 @@ Symtab *ObjectFileELF::GetSymtab() {
if (m_symtab_up == nullptr)
m_symtab_up.reset(new Symtab(this));
+ // In the event that there's no symbol entry for the entry point we'll
+ // artifically create one. We delegate to the symtab object the figuring
+ // out of the proper size, this will usually make it span til the next
+ // symbol it finds in the section. This means that if there are missing
+ // symbols the entry point might span beyond its function definition.
+ // We're fine with this as it doesn't make it worse than not having a
+ // symbol entry at all.
+ ArchSpec arch = GetArchitecture();
+ auto entry_point_addr = GetEntryPointAddress().GetFileAddress();
+ if (entry_point_addr != LLDB_INVALID_ADDRESS) {
+ if (!m_symtab_up->FindSymbolContainingFileAddress(entry_point_addr)) {
+ uint64_t symbol_id = m_symtab_up->GetNumSymbols();
+ SectionSP section_sp =
+ GetSectionList()->FindSectionContainingFileAddress(entry_point_addr);
+ Symbol symbol(
+ symbol_id,
+ GetNextSyntheticSymbolName().GetCString(), // Symbol name.
+ false, // Is the symbol name mangled?
+ eSymbolTypeCode, // Type of this symbol.
+ true, // Is this globally visible?
+ false, // Is this symbol debug info?
+ false, // Is this symbol a trampoline?
+ true, // Is this symbol artificial?
+ section_sp, // Section in which this symbol is defined or null.
+ 0, // Offset in section or symbol value.
+ 0, // Size.
+ false, // Size is valid.
+ false, // Contains linker annotations?
+ 0); // Symbol flags.
+ m_symtab_up->AddSymbol(symbol);
+ // When the entry point is arm thumb we need to explicitly set its
+ // class address to reflect that. This is important because expression
+ // evaluation relies on correctly setting a breakpoint at this address.
+ if (arch.GetMachine() == llvm::Triple::arm && (entry_point_addr & 1))
+ m_address_class_map[entry_point_addr ^ 1] = AddressClass::eCodeAlternateISA;
+ else
+ m_address_class_map[entry_point_addr] = AddressClass::eCode;
+ }
+ }
+
m_symtab_up->CalculateSymbolSizes();
}
OpenPOWER on IntegriCloud