[Lldb-commits] [lldb] r191307 - Adds an option to resolve a symbol from an address that can be used

Ashok Thirumurthi ashok.thirumurthi at intel.com
Tue Sep 24 08:34:14 PDT 2013


Author: athirumu
Date: Tue Sep 24 10:34:13 2013
New Revision: 191307

URL: http://llvm.org/viewvc/llvm-project?rev=191307&view=rev
Log:
Adds an option to resolve a symbol from an address that can be used
to build out the symbol table as addresses are used, and implements
the mechanism for ELF to add stripped symbols from eh_frame.

Uses this mechanism to allow disassembly for addresses corresponding
to stripped symbols for ELF, and provide hooks to implement this for
PE COFF.

Also removes eSymbolContextTailCall in favor of an option for
ResolveSymbolContextForAddress for consistency with the documentation
for eSymbolContextEverything.  Essentially, this is just an option for
interpreting the so_addr.
                  

Modified:
    lldb/trunk/include/lldb/Core/Module.h
    lldb/trunk/include/lldb/Symbol/ObjectFile.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
    lldb/trunk/source/Core/Module.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/test/functionalities/inferior-assert/TestInferiorAssert.py

Modified: lldb/trunk/include/lldb/Core/Module.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Module.h?rev=191307&r1=191306&r2=191307&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Module.h (original)
+++ lldb/trunk/include/lldb/Core/Module.h Tue Sep 24 10:34:13 2013
@@ -776,13 +776,22 @@ public:
     ///     eSymbolContextModule, and eSymbolContextFunction requires
     ///     eSymbolContextSymbol.
     ///
+    /// @param[out] sc
+    ///     The SymbolContext that is modified based on symbol resolution.
+    ///
+    /// @param[in] resolve_tail_call_address
+    ///     Determines if so_addr should resolve to a symbol in the case
+    ///     of a function whose last instruction is a call.  In this case,
+    ///     the PC can be one past the address range of the function.
+    ///
     /// @return
     ///     The scope that has been resolved (see SymbolContext::Scope).
     ///
     /// @see SymbolContext::Scope
     //------------------------------------------------------------------
     uint32_t
-    ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc);
+    ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope,
+                                    SymbolContext& sc, bool resolve_tail_call_address = false);
 
     //------------------------------------------------------------------
     /// Resolve items in the symbol context for a given file and line.

Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=191307&r1=191306&r2=191307&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Tue Sep 24 10:34:13 2013
@@ -368,6 +368,34 @@ public:
     GetSymtab () = 0;
 
     //------------------------------------------------------------------
+    /// Appends a Symbol for the specified so_addr to the symbol table.
+    ///
+    /// If verify_unique is false, the symbol table is not searched
+    /// to determine if a Symbol found at this address has already been
+    /// added to the symbol table.  When verify_unique is true, this
+    /// method resolves the Symbol as the first match in the SymbolTable
+    /// and appends a Symbol only if required/found.
+    ///
+    /// @return
+    ///     The resolved symbol or nullptr.  Returns nullptr if a
+    ///     a Symbol could not be found for the specified so_addr.
+    //------------------------------------------------------------------
+    virtual Symbol *
+    ResolveSymbolForAddress(const Address &so_addr, bool verify_unique)
+    {
+        // Typically overridden to lazily add stripped symbols recoverable from
+        // the exception handling unwind information (i.e. without parsing
+        // the entire eh_frame section.
+        //
+        // The availability of LC_FUNCTION_STARTS allows ObjectFileMachO
+        // to efficiently add stripped symbols when the symbol table is
+        // first constructed.  Poorer cousins are PECoff and ELF.
+        return nullptr;
+    }
+
+    //------------------------------------------------------------------
+    /// Detect if this object file has been stripped of local symbols.
+    //------------------------------------------------------------------
     /// Detect if this object file has been stripped of local symbols.
     ///
     /// @return

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=191307&r1=191306&r2=191307&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Tue Sep 24 10:34:13 2013
@@ -263,7 +263,6 @@ namespace lldb {
         eSymbolContextBlock      = (1u << 4), ///< Set when the deepest \a block is requested from a query, or was located in query results
         eSymbolContextLineEntry  = (1u << 5), ///< Set when \a line_entry is requested from a query, or was located in query results
         eSymbolContextSymbol     = (1u << 6), ///< Set when \a symbol is requested from a query, or was located in query results
-        eSymbolContextTailCall   = (1u << 7), ///< Set when a function symbol with a tail call is requested from a query, or was located in query results
         eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u)  ///< Indicates to try and lookup everything up during a query.
     } SymbolContextItem;
 

Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=191307&r1=191306&r2=191307&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Tue Sep 24 10:34:13 2013
@@ -453,7 +453,9 @@ CommandObjectDisassemble::DoExecute (Arg
                         {
                             ModuleSP module_sp (symbol_containing_address.GetModule());
                             SymbolContext sc;
-                            module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc);
+                            bool resolve_tail_call_address = true; // PC can be one past the address range of the function.
+                            module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc,
+                                                                       resolve_tail_call_address);
                             if (sc.function || sc.symbol)
                             {
                                 sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range);

Modified: lldb/trunk/source/Core/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=191307&r1=191306&r2=191307&view=diff
==============================================================================
--- lldb/trunk/source/Core/Module.cpp (original)
+++ lldb/trunk/source/Core/Module.cpp Tue Sep 24 10:34:13 2013
@@ -449,7 +449,8 @@ Module::ResolveFileAddress (lldb::addr_t
 }
 
 uint32_t
-Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
+Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc,
+                                        bool resolve_tail_call_address)
 {
     Mutex::Locker locker (m_mutex);
     uint32_t resolved_flags = 0;
@@ -489,6 +490,14 @@ Module::ResolveSymbolContextForAddress (
             if (symtab && so_addr.IsSectionOffset())
             {
                 sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
+                if (!sc.symbol &&
+                    resolve_scope & eSymbolContextFunction && !(resolved_flags & eSymbolContextFunction))
+                {
+                    bool verify_unique = false; // No need to check again since ResolveSymbolContext failed to find a symbol at this address.
+                    if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())
+                        sc.symbol = obj_file->ResolveSymbolForAddress(so_addr, verify_unique);
+                }
+
                 if (sc.symbol)
                     resolved_flags |= eSymbolContextSymbol;
             }
@@ -498,13 +507,14 @@ Module::ResolveSymbolContextForAddress (
         // 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 & eSymbolContextTailCall &&
-            so_addr.IsSectionOffset())
+            resolve_tail_call_address && so_addr.IsSectionOffset())
         {
             Address previous_addr = so_addr;
             previous_addr.Slide(-1);
 
-            const uint32_t flags = ResolveSymbolContextForAddress(previous_addr, resolve_scope & ~eSymbolContextTailCall, sc);
+            bool do_resolve_tail_call_address = false; // prevent recursion
+            const uint32_t flags = ResolveSymbolContextForAddress(previous_addr, resolve_scope, sc,
+                                                                  do_resolve_tail_call_address);
             if (flags & eSymbolContextSymbol)
             {
                 AddressRange addr_range;

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=191307&r1=191306&r2=191307&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Tue Sep 24 10:34:13 2013
@@ -21,6 +21,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Symbol/DWARFCallFrameInfo.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Host/Host.h"
 
@@ -1513,6 +1514,57 @@ ObjectFileELF::GetSymtab()
     return m_symtab_ap.get();
 }
 
+Symbol *
+ObjectFileELF::ResolveSymbolForAddress(const Address& so_addr, bool verify_unique)
+{
+    if (!m_symtab_ap.get())
+        return nullptr; // GetSymtab() should be called first.
+
+    const SectionList *section_list = GetSectionList();
+    if (!section_list)
+        return nullptr;
+
+    if (DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo())
+    {
+        AddressRange range;
+        if (eh_frame->GetAddressRange (so_addr, range))
+        {
+            const addr_t file_addr = range.GetBaseAddress().GetFileAddress();
+            Symbol * symbol = verify_unique ? m_symtab_ap->FindSymbolContainingFileAddress(file_addr) : nullptr;
+            if (symbol)
+                return symbol;
+
+            // Note that a (stripped) symbol won't be found by GetSymtab()...
+            lldb::SectionSP eh_sym_section_sp = section_list->FindSectionContainingFileAddress(file_addr);
+            if (eh_sym_section_sp.get())
+            {
+                addr_t section_base = eh_sym_section_sp->GetFileAddress();
+                addr_t offset = file_addr - section_base;
+                uint64_t symbol_id = m_symtab_ap->GetNumSymbols();
+
+                Symbol eh_symbol(
+                        symbol_id,            // Symbol table index.
+                        "???",                // 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?
+                        eh_sym_section_sp,    // Section in which this symbol is defined or null.
+                        offset,               // Offset in section or symbol value.
+                        range.GetByteSize(),  // Size in bytes of this symbol.
+                        true,                 // Size is valid.
+                        0);                   // Symbol flags.
+                if (symbol_id == m_symtab_ap->AddSymbol(eh_symbol))
+                    return m_symtab_ap->SymbolAtIndex(symbol_id);
+            }
+        }
+    }
+    return nullptr;
+}
+
+
 bool
 ObjectFileELF::IsStripped ()
 {

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=191307&r1=191306&r2=191307&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Tue Sep 24 10:34:13 2013
@@ -102,6 +102,9 @@ public:
     virtual lldb_private::Symtab *
     GetSymtab();
 
+    virtual lldb_private::Symbol *
+    ResolveSymbolForAddress(const lldb_private::Address& so_addr, bool verify_unique);
+
     virtual bool
     IsStripped ();
 

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=191307&r1=191306&r2=191307&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Tue Sep 24 10:34:13 2013
@@ -369,9 +369,13 @@ RegisterContextLLDB::InitializeNonZeroth
         return;
     }
 
+    bool resolve_tail_call_address = true; // m_current_pc can be one past the address range of the function...
+    uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc,
+                                                                            eSymbolContextFunction | eSymbolContextSymbol,
+                                                                            m_sym_ctx, resolve_tail_call_address);
+
     // We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us.
-    uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol | eSymbolContextTailCall;
-    if ((pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, resolve_scope, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol)
+    if ((resolved_scope & eSymbolContextSymbol) == eSymbolContextSymbol)
     {
         m_sym_ctx_valid = true;
     }

Modified: lldb/trunk/test/functionalities/inferior-assert/TestInferiorAssert.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/inferior-assert/TestInferiorAssert.py?rev=191307&r1=191306&r2=191307&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/inferior-assert/TestInferiorAssert.py (original)
+++ lldb/trunk/test/functionalities/inferior-assert/TestInferiorAssert.py Tue Sep 24 10:34:13 2013
@@ -32,9 +32,7 @@ class AssertingInferiorTestCase(TestBase
         self.buildDwarf()
         self.inferior_asserting_registers()
 
-    @skipIfGcc # Avoid xpasses as the verion of libc used on the gcc buildbot has the required function symbols.
-    @expectedFailureFreeBSD # ResolveSymbolContextForAddress can fail using ELF with stripped function symbols.
-    @expectedFailureLinux # ResolveSymbolContextForAddress can fail using ELF with stripped function symbols.
+    @expectedFailureLinux # Disassembly does not specify '->' for the PC for a non-terminal frame for a function with a tail call.
     def test_inferior_asserting_disassemble(self):
         """Test that lldb reliably disassembles frames after asserting (command)."""
         self.buildDefault()





More information about the lldb-commits mailing list