[Lldb-commits] [lldb] r203985 - Parse DW_AT_ranges for compile units on Darwin when .debug_aranges is not available for the current compile unit.

Greg Clayton gclayton at apple.com
Fri Mar 14 16:36:38 PDT 2014


Author: gclayton
Date: Fri Mar 14 18:36:38 2014
New Revision: 203985

URL: http://llvm.org/viewvc/llvm-project?rev=203985&view=rev
Log:
Parse DW_AT_ranges for compile units on Darwin when .debug_aranges is not available for the current compile unit.

<rdar://problem/16321434> 

Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=203985&r1=203984&r2=203985&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Fri Mar 14 18:36:38 2014
@@ -361,18 +361,43 @@ DWARFCompileUnit::SetDefaultAddressSize(
 
 void
 DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data,
-                                          DWARFDebugAranges* debug_aranges,
-                                          bool clear_dies_if_already_not_parsed)
+                                          DWARFDebugAranges* debug_aranges)
 {
     // This function is usually called if there in no .debug_aranges section
     // in order to produce a compile unit level set of address ranges that
-    // is accurate. If the DIEs weren't parsed, then we don't want all dies for
-    // all compile units to stay loaded when they weren't needed. So we can end
-    // up parsing the DWARF and then throwing them all away to keep memory usage
-    // down.
+    // is accurate.
+    
+    // First get the compile unit DIE only and check if it has a DW_AT_ranges
+    const DWARFDebugInfoEntry* die = GetCompileUnitDIEOnly();
+    
+    const dw_offset_t cu_offset = GetOffset();
+    if (die)
+    {
+        DWARFDebugRanges::RangeList ranges;
+        const size_t num_ranges = die->GetAttributeAddressRanges(dwarf2Data, this, ranges, false);
+        if (num_ranges > 0)
+        {
+            // This compile unit has DW_AT_ranges, assume this is correct if it
+            // is present since clang no longer makes .debug_aranges by default
+            // and it emits DW_AT_ranges for DW_TAG_compile_units. GCC also does
+            // this with recent GCC builds.
+            for (size_t i=0; i<num_ranges; ++i)
+            {
+                const DWARFDebugRanges::RangeList::Entry &range = ranges.GetEntryRef(i);
+                debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd());
+            }
+            
+            return; // We got all of our ranges from the DW_AT_ranges attribute
+        }
+    }
+    // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF
+    
+    // If the DIEs weren't parsed, then we don't want all dies for all compile units
+    // to stay loaded when they weren't needed. So we can end up parsing the DWARF
+    // and then throwing them all away to keep memory usage down.
     const bool clear_dies = ExtractDIEsIfNeeded (false) > 1;
     
-    const DWARFDebugInfoEntry* die = DIE();
+    die = DIE();
     if (die)
         die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges);
     
@@ -397,7 +422,7 @@ DWARFCompileUnit::BuildAddressRangeTable
                     for (uint32_t idx=0; idx<num_ranges; ++idx)
                     {
                         const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx);
-                        debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd());
+                        debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), range.GetRangeEnd());
                         printf ("0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", GetOffset(), range.GetRangeBase(), range.GetRangeEnd());
                     }
                 }

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h?rev=203985&r1=203984&r2=203985&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h Fri Mar 14 18:36:38 2014
@@ -54,8 +54,7 @@ public:
     dw_addr_t   GetBaseAddress() const { return m_base_addr; }
     void        ClearDIEs(bool keep_compile_unit_die);
     void        BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data,
-                                        DWARFDebugAranges* debug_aranges,
-                                        bool clear_dies_if_already_not_parsed);
+                                        DWARFDebugAranges* debug_aranges);
 
     void
     SetBaseAddress(dw_addr_t base_addr)

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp?rev=203985&r1=203984&r2=203985&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp Fri Mar 14 18:36:38 2014
@@ -93,14 +93,13 @@ DWARFDebugAranges::Generate(SymbolFileDW
     DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
     if (debug_info)
     {
-        const bool clear_dies_if_already_not_parsed = true;
         uint32_t cu_idx = 0;
         const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
         for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
         {
             DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
             if (cu)
-                cu->BuildAddressRangeTable(dwarf2Data, this, clear_dies_if_already_not_parsed);
+                cu->BuildAddressRangeTable(dwarf2Data, this);
         }
     }
     return !IsEmpty();

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp?rev=203985&r1=203984&r2=203985&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp Fri Mar 14 18:36:38 2014
@@ -79,7 +79,6 @@ DWARFDebugInfo::GetCompileUnitAranges ()
         // Manually build arange data for everything that wasn't in the .debug_aranges table.
         bool printed = false;
         const size_t num_compile_units = GetNumCompileUnits();
-        const bool clear_dies_if_already_not_parsed = true;
         for (size_t idx = 0; idx < num_compile_units; ++idx)
         {
             DWARFCompileUnit* cu = GetCompileUnitAtIndex(idx);
@@ -94,7 +93,7 @@ DWARFDebugInfo::GetCompileUnitAranges ()
                                      m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
                     printed = true;
                 }
-                cu->BuildAddressRangeTable (m_dwarf2Data, m_cu_aranges_ap.get(), clear_dies_if_already_not_parsed);
+                cu->BuildAddressRangeTable (m_dwarf2Data, m_cu_aranges_ap.get());
             }
         }
 

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp?rev=203985&r1=203984&r2=203985&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp Fri Mar 14 18:36:38 2014
@@ -1485,6 +1485,40 @@ DWARFDebugInfoEntry::GetAttributeAddress
     hi_pc = fail_value;
     return false;
 }
+
+size_t
+DWARFDebugInfoEntry::GetAttributeAddressRanges(SymbolFileDWARF* dwarf2Data,
+                                               const DWARFCompileUnit* cu,
+                                               DWARFDebugRanges::RangeList &ranges,
+                                               bool check_hi_lo_pc) const
+{
+    ranges.Clear();
+    
+    dw_offset_t ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
+    if (ranges_offset != DW_INVALID_OFFSET)
+    {
+        dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
+        if (debug_ranges_offset != DW_INVALID_OFFSET)
+        {
+            DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
+            
+            debug_ranges->FindRanges(debug_ranges_offset, ranges);
+            ranges.Slide (cu->GetBaseAddress());
+        }
+    }
+    else if (check_hi_lo_pc)
+    {
+        dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+        dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+        if (GetAttributeAddressRange (dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
+        {
+            if (lo_pc < hi_pc)
+                ranges.Append(DWARFDebugRanges::RangeList::Entry(lo_pc, hi_pc - lo_pc));
+        }
+    }
+    return ranges.GetSize();
+}
+
 //----------------------------------------------------------------------
 // GetAttributeValueAsLocation
 //

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h?rev=203985&r1=203984&r2=203985&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h Fri Mar 14 18:36:38 2014
@@ -209,7 +209,13 @@ public:
                     dw_addr_t& lo_pc,
                     dw_addr_t& hi_pc,
                     uint64_t fail_value) const;
-
+    
+    size_t      GetAttributeAddressRanges (
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    DWARFDebugRanges::RangeList &ranges,
+                    bool check_hi_lo_pc) const;
+    
     dw_offset_t GetAttributeValueAsLocation(
                     SymbolFileDWARF* dwarf2Data,
                     const DWARFCompileUnit* cu,





More information about the lldb-commits mailing list