diff options
author | Ashok Thirumurthi <ashok.thirumurthi@intel.com> | 2013-09-16 22:00:17 +0000 |
---|---|---|
committer | Ashok Thirumurthi <ashok.thirumurthi@intel.com> | 2013-09-16 22:00:17 +0000 |
commit | 388071417256d6be830504de3727fa14ed2c810d (patch) | |
tree | bef684ad62a606376cbc704954de4b86ec6820e4 /lldb/source/Core/Module.cpp | |
parent | 52694e3bb8613942658bfb55753c1ab3033d6746 (diff) | |
download | bcm5719-llvm-388071417256d6be830504de3727fa14ed2c810d.tar.gz bcm5719-llvm-388071417256d6be830504de3727fa14ed2c810d.zip |
Fixes symbol resolution for a function with a tail call because the PC
for the frame is one past the address range of the calling function.
- Lowers the fix from RegisterContextLLDB for use with disassembly
- Fixes one of three issues in the disassembly test in TestInferiorAssert.py
Also adds documentation that explains the resolution depths and interface.
Note: This change affects the resolution scope for eSymbolContextFunction
without impacting the performance of eSymbolContextSymbol.
Thanks to Matt Kopec for his review.
llvm-svn: 190812
Diffstat (limited to 'lldb/source/Core/Module.cpp')
-rw-r--r-- | lldb/source/Core/Module.cpp | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 859ec866ac0..f010f39f8d4 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -468,6 +468,10 @@ Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve sc.module_sp = shared_from_this(); resolved_flags |= eSymbolContextModule; + SymbolVendor* sym_vendor = GetSymbolVendor(); + if (!sym_vendor) + return resolved_flags; + // Resolve the compile unit, function, block, line table or line // entry if requested. if (resolve_scope & eSymbolContextCompUnit || @@ -475,25 +479,51 @@ Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve resolve_scope & eSymbolContextBlock || resolve_scope & eSymbolContextLineEntry ) { - SymbolVendor *symbols = GetSymbolVendor (); - if (symbols) - resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc); + resolved_flags |= sym_vendor->ResolveSymbolContext (so_addr, resolve_scope, sc); } // Resolve the symbol if requested, but don't re-look it up if we've already found it. if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol)) { - SymbolVendor* sym_vendor = GetSymbolVendor(); - if (sym_vendor) + Symtab *symtab = sym_vendor->GetSymtab(); + if (symtab && so_addr.IsSectionOffset()) { - Symtab *symtab = sym_vendor->GetSymtab(); - if (symtab) + sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); + if (sc.symbol) + resolved_flags |= eSymbolContextSymbol; + } + } + + // For function symbols, so_addr may be off by one. This is a convention consistent + // with FDE row indices in eh_frame sections, but requires extra logic here to permit + // symbol lookup for disassembly and unwind. + if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol) && + resolve_scope & eSymbolContextFunction && !(resolved_flags & eSymbolContextFunction) && + so_addr.GetOffset() > 0) + { + Address previous_addr = so_addr; + previous_addr.SetOffset(so_addr.GetOffset() - 1); + + const uint32_t flags = sym_vendor->ResolveSymbolContext (previous_addr, resolve_scope, sc); + if (flags & eSymbolContextSymbol) + { + AddressRange addr_range; + if (sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range)) { - if (so_addr.IsSectionOffset()) + if (addr_range.GetBaseAddress().GetSection() == so_addr.GetSection()) + { + // If the requested address is one past the address range of a function (i.e. a tail call), + // or the decremented address is the start of a function (i.e. some forms of trampoline), + // indicate that the symbol has been resolved. + if (so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() || + so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() + addr_range.GetByteSize()) + { + resolved_flags |= flags; + } + } + else { - sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); - if (sc.symbol) - resolved_flags |= eSymbolContextSymbol; + sc.symbol = nullptr; // Don't trust the symbol if the sections didn't match. } } } |