tberghammer created this revision.
tberghammer added reviewers: labath, clayborg.
tberghammer added a subscriber: lldb-commits.

Add support for DW_AT_ranges_base attribute

It is a new attribute emitted by clang as a GNU extension and will
be part of Dwarf5. The purpose of the attribute is to specify a compile
unit level base value for all DW_AT_ranges to reduce the number of
relocation have to be done by the linker.
    
Fixes (at least partially): https://llvm.org/pr28826

https://reviews.llvm.org/D24514

Files:
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -3810,7 +3810,8 @@
             if (form_value.Form() == DW_FORM_sec_offset) {
               DWARFRangeList dwarf_scope_ranges;
               const DWARFDebugRanges *debug_ranges = DebugRanges();
-              debug_ranges->FindRanges(form_value.Unsigned(),
+              debug_ranges->FindRanges(die.GetCU()->GetRangesBase(),
+                                       form_value.Unsigned(),
                                        dwarf_scope_ranges);
 
               // All DW_AT_start_scope are relative to the base address of the
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -23,7 +23,8 @@
   static void Dump(lldb_private::Stream &s,
                    const lldb_private::DWARFDataExtractor &debug_ranges_data,
                    lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr);
-  bool FindRanges(dw_offset_t debug_ranges_offset,
+  bool FindRanges(dw_addr_t debug_ranges_base,
+                  dw_offset_t debug_ranges_offset,
                   DWARFRangeList &range_list) const;
 
 protected:
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -118,9 +118,11 @@
   }
 }
 
-bool DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset,
+bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base,
+                                  dw_offset_t debug_ranges_offset,
                                   DWARFRangeList &range_list) const {
-  range_map_const_iterator pos = m_range_map.find(debug_ranges_offset);
+  dw_addr_t debug_ranges_address = debug_ranges_base + debug_ranges_offset;
+  range_map_const_iterator pos = m_range_map.find(debug_ranges_address);
   if (pos != m_range_map.end()) {
     range_list = pos->second;
     return true;
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -450,7 +450,7 @@
         case DW_AT_ranges: {
           const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
           if (debug_ranges) {
-            debug_ranges->FindRanges(form_value.Unsigned(), ranges);
+            debug_ranges->FindRanges(cu->GetRangesBase(), form_value.Unsigned(), ranges);
             // All DW_AT_ranges are relative to the base address of the
             // compile unit. We add the compile unit base address to make
             // sure all the addresses are properly fixed up.
@@ -1108,7 +1108,7 @@
   if (debug_ranges_offset != DW_INVALID_OFFSET) {
     DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
 
-    debug_ranges->FindRanges(debug_ranges_offset, ranges);
+    debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges);
     ranges.Slide(cu->GetBaseAddress());
   } else if (check_hi_lo_pc) {
     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
@@ -1772,7 +1772,7 @@
         if (debug_ranges_offset != DW_INVALID_OFFSET) {
           DWARFRangeList ranges;
           DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
-          debug_ranges->FindRanges(debug_ranges_offset, ranges);
+          debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges);
           // All DW_AT_ranges are relative to the base address of the
           // compile unit. We add the compile unit base address to make
           // sure all the addresses are properly fixed up.
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -70,7 +70,8 @@
   uint8_t GetAddressByteSize() const { return m_addr_size; }
   dw_addr_t GetBaseAddress() const { return m_base_addr; }
   dw_addr_t GetAddrBase() const { return m_addr_base; }
-  void SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset);
+  dw_addr_t GetRangesBase() const { return m_ranges_base; }
+  void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base, dw_offset_t base_obj_offset);
   void ClearDIEs(bool keep_compile_unit_die);
   void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
                               DWARFDebugAranges *debug_aranges);
@@ -185,10 +186,11 @@
   lldb::LanguageType m_language_type;
   bool m_is_dwarf64;
   lldb_private::LazyBool m_is_optimized;
-  dw_addr_t m_addr_base; // Value of DW_AT_addr_base
-  dw_offset_t
-      m_base_obj_offset; // If this is a dwo compile unit this is the offset of
-                         // the base compile unit in the main object file
+  dw_addr_t m_addr_base;         // Value of DW_AT_addr_base
+  dw_addr_t m_ranges_base;       // Value of DW_AT_ranges_base
+  dw_offset_t m_base_obj_offset; // If this is a dwo compile unit this is the
+                                 // offset of the base compile unit in the main
+                                 // object file
 
   void ParseProducerInfo();
 
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -46,7 +46,7 @@
       m_producer_version_minor(0), m_producer_version_update(0),
       m_language_type(eLanguageTypeUnknown), m_is_dwarf64(false),
       m_is_optimized(eLazyBoolCalculate), m_addr_base(0),
-      m_base_obj_offset(DW_INVALID_OFFSET) {}
+      m_ranges_base(0), m_base_obj_offset(DW_INVALID_OFFSET) {}
 
 DWARFCompileUnit::~DWARFCompileUnit() {}
 
@@ -307,7 +307,9 @@
 
   dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(
       m_dwarf2Data, this, DW_AT_GNU_addr_base, 0);
-  dwo_cu->SetAddrBase(addr_base, m_offset);
+  dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
+      m_dwarf2Data, this, DW_AT_GNU_ranges_base, 0);
+  dwo_cu->SetAddrBase(addr_base, ranges_base, m_offset);
 }
 
 dw_offset_t DWARFCompileUnit::GetAbbrevOffset() const {
@@ -1114,8 +1116,10 @@
 }
 
 void DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base,
+                                   dw_addr_t ranges_base,
                                    dw_offset_t base_obj_offset) {
   m_addr_base = addr_base;
+  m_ranges_base = ranges_base;
   m_base_obj_offset = base_obj_offset;
 }
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to