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


_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to