[Lldb-commits] [lldb] r177624 - Add a new method GetFunctionAddressAndSizeVector to DWARFCallFrameInfo.

Jason Molenda jmolenda at apple.com
Wed Mar 20 20:36:02 PDT 2013


Author: jmolenda
Date: Wed Mar 20 22:36:01 2013
New Revision: 177624

URL: http://llvm.org/viewvc/llvm-project?rev=177624&view=rev
Log:
Add a new method GetFunctionAddressAndSizeVector to DWARFCallFrameInfo.
This returns a vector of <file address, size> entries for all of
the functions in the module that have an eh_frame FDE.

Update ObjectFileMachO to use the eh_frame FDE function addresses if
the LC_FUNCTION_STARTS section is missing, to fill in the start 
addresses of any symbols that have been stripped from the binary.

Generally speaking, lldb works best if it knows the actual start
address of every function in a module - it's especially important
for unwinding, where lldb inspects the instructions in the prologue
of the function.  In a stripped binary, it is deprived of this
information and it reduces the quality of our unwinds and saved
register retrieval.  

Other ObjectFile users may want to use the function addresses from 
DWARFCallFrameInfo to fill in any stripped symbols like ObjectFileMachO
does already.
<rdar://problem/13365659> 

Modified:
    lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp

Modified: lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h?rev=177624&r1=177623&r2=177624&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h (original)
+++ lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h Wed Mar 20 22:36:01 2013
@@ -54,6 +54,25 @@ public:
     bool
     GetUnwindPlan (Address addr, UnwindPlan& unwind_plan);
 
+    typedef RangeVector<lldb::addr_t, uint32_t> FunctionAddressAndSizeVector;
+
+    //------------------------------------------------------------------
+    // Build a vector of file address and size for all functions in this Module
+    // based on the eh_frame FDE entries.
+    //
+    // The eh_frame information can be a useful source of file address and size of
+    // the functions in a Module.  Often a binary's non-exported symbols are stripped
+    // before shipping so lldb won't know the start addr / size of many functions
+    // in the Module.  But the eh_frame can help to give the addresses of these 
+    // stripped symbols, at least.
+    //
+    // @param[out] function_info
+    //      A vector provided by the caller is filled out.  May be empty if no FDEs/no eh_frame
+    //      is present in this Module.
+
+    void
+    GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info);
+
 private:
     enum
     {
@@ -81,13 +100,13 @@ private:
 
     typedef STD_SHARED_PTR(CIE) CIESP;
 
-    // Start address, size, offset of FDE location
+    typedef std::map<off_t, CIESP> cie_map_t;
+
+    // Start address (file address), size, offset of FDE location
     // used for finding an FDE for a given File address; the start address field is
     // an offset into an individual Module.
     typedef RangeDataVector<lldb::addr_t, uint32_t, dw_offset_t> FDEEntryMap;
 
-    typedef std::map<off_t, CIESP> cie_map_t;
-
     bool
     IsEHFrame() const;
 

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=177624&r1=177623&r2=177624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Wed Mar 20 22:36:01 2013
@@ -28,6 +28,7 @@
 #include "lldb/Host/Host.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Symbol/ClangNamespaceDecl.h"
+#include "lldb/Symbol/DWARFCallFrameInfo.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
@@ -1449,6 +1450,17 @@ ObjectFileMachO::ParseSymtab (bool minim
             eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
 
         const bool is_arm = (m_header.cputype == llvm::MachO::CPUTypeARM);
+
+        // lldb works best if it knows the start addresss of all functions in a module.
+        // Linker symbols or debug info are normally the best source of information for start addr / size but
+        // they may be stripped in a released binary.
+        // Two additional sources of information exist in Mach-O binaries:  
+        //    LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
+        //                         binary, relative to the text section.
+        //    eh_frame           - the eh_frame FDEs have the start addr & size of each function
+        //  LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
+        //  Binaries built to run on older releases may need to use eh_frame information.
+
         if (text_section_sp && function_starts_data.GetByteSize())
         {
             FunctionStarts::Entry function_start_entry;
@@ -1462,6 +1474,27 @@ ObjectFileMachO::ParseSymtab (bool minim
                 function_start_entry.addr += delta;
                 function_starts.Append(function_start_entry);
             }
+        } 
+        else
+        {
+            if (text_section_sp.get() && eh_frame_section_sp.get())
+            {
+                DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindGCC, true);
+                DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
+                eh_frame.GetFunctionAddressAndSizeVector (functions);
+                addr_t text_base_addr = text_section_sp->GetFileAddress();
+                size_t count = functions.GetSize();
+                for (size_t i = 0; i < count; ++i)
+                {
+                    const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
+                    if (func)
+                    {
+                        FunctionStarts::Entry function_start_entry;
+                        function_start_entry.addr = func->base - text_base_addr;
+                        function_starts.Append(function_start_entry);
+                    }
+                }
+            }
         }
 
         const size_t function_starts_count = function_starts.GetSize();

Modified: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp?rev=177624&r1=177623&r2=177624&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp Wed Mar 20 22:36:01 2013
@@ -104,6 +104,22 @@ DWARFCallFrameInfo::GetFDEEntryByFileAdd
     return true;
 }
 
+void
+DWARFCallFrameInfo::GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info)
+{
+    GetFDEIndex();
+    const size_t count = m_fde_index.GetSize();
+    for (size_t i = 0; i < count; ++i)
+    {
+        const FDEEntryMap::Entry *func_offset_data_entry = m_fde_index.GetEntryAtIndex (i);
+        if (func_offset_data_entry)
+        {
+            FunctionAddressAndSizeVector::Entry function_offset_entry (func_offset_data_entry->base, func_offset_data_entry->size);
+            function_info.Append (function_offset_entry);
+        }
+    }
+}
+
 const DWARFCallFrameInfo::CIE*
 DWARFCallFrameInfo::GetCIE(dw_offset_t cie_offset)
 {





More information about the lldb-commits mailing list