[llvm] r206624 - [DWARF parser] Refactor fetching DIE address ranges.

Alexey Samsonov samsonov at google.com
Fri Apr 18 10:25:47 PDT 2014


Author: samsonov
Date: Fri Apr 18 12:25:46 2014
New Revision: 206624

URL: http://llvm.org/viewvc/llvm-project?rev=206624&view=rev
Log:
[DWARF parser] Refactor fetching DIE address ranges.

Add a helper method to get address ranges specified in a DIE
(either by DW_AT_low_pc/DW_AT_high_pc, or by DW_AT_ranges). Use it
to untangle and simplify the code.

No functionality change.

Modified:
    llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
    llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
    llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h
    llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp
    llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h
    llvm/trunk/lib/DebugInfo/DWARFUnit.cpp
    llvm/trunk/lib/DebugInfo/DWARFUnit.h

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp Fri Apr 18 12:25:46 2014
@@ -58,8 +58,13 @@ void DWARFDebugAranges::generate(DWARFCo
   // manually build aranges for the rest of them.
   for (const auto &CU : CTX->compile_units()) {
     uint32_t CUOffset = CU->getOffset();
-    if (ParsedCUOffsets.insert(CUOffset).second)
-      CU->buildAddressRangeTable(this, true, CUOffset);
+    if (ParsedCUOffsets.insert(CUOffset).second) {
+      DWARFAddressRangesVector CURanges;
+      CU->collectAddressRanges(CURanges);
+      for (const auto &R : CURanges) {
+        appendRange(CUOffset, R.first, R.second);
+      }
+    }
   }
 
   sortAndMinimize();

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp Fri Apr 18 12:25:46 2014
@@ -226,39 +226,47 @@ bool DWARFDebugInfoEntryMinimal::getLowA
   return (HighPC != -1ULL);
 }
 
-void DWARFDebugInfoEntryMinimal::buildAddressRangeTable(
-    const DWARFUnit *U, DWARFDebugAranges *DebugAranges,
-    uint32_t UOffsetInAranges) const {
-  if (AbbrevDecl) {
-    if (isSubprogramDIE()) {
-      uint64_t LowPC, HighPC;
-      if (getLowAndHighPC(U, LowPC, HighPC))
-        DebugAranges->appendRange(UOffsetInAranges, LowPC, HighPC);
-      // FIXME: try to append ranges from .debug_ranges section.
-    }
-
-    const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
-    while (Child) {
-      Child->buildAddressRangeTable(U, DebugAranges, UOffsetInAranges);
-      Child = Child->getSibling();
-    }
-  }
-}
-
-bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
-    const DWARFUnit *U, const uint64_t Address) const {
+DWARFAddressRangesVector
+DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const {
   if (isNULL())
-    return false;
+    return DWARFAddressRangesVector{};
+  // Single range specified by low/high PC.
   uint64_t LowPC, HighPC;
-  if (getLowAndHighPC(U, LowPC, HighPC))
-    return (LowPC <= Address && Address <= HighPC);
-  // Try to get address ranges from .debug_ranges section.
+  if (getLowAndHighPC(U, LowPC, HighPC)) {
+    return DWARFAddressRangesVector{std::make_pair(LowPC, HighPC)};
+  }
+  // Multiple ranges from .debug_ranges section.
   uint32_t RangesOffset =
       getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U);
   if (RangesOffset != -1U) {
     DWARFDebugRangeList RangeList;
     if (U->extractRangeList(RangesOffset, RangeList))
-      return RangeList.containsAddress(U->getBaseAddress(), Address);
+      return RangeList.getAbsoluteRanges(U->getBaseAddress());
+  }
+  return DWARFAddressRangesVector{};
+}
+
+void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges(
+    const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const {
+  if (isNULL())
+    return;
+  if (isSubprogramDIE()) {
+    const auto &DIERanges = getAddressRanges(U);
+    Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
+  }
+
+  const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
+  while (Child) {
+    Child->collectChildrenAddressRanges(U, Ranges);
+    Child = Child->getSibling();
+  }
+}
+
+bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
+    const DWARFUnit *U, const uint64_t Address) const {
+  for (const auto& R : getAddressRanges(U)) {
+    if (R.first <= Address && Address < R.second)
+      return true;
   }
   return false;
 }

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h Fri Apr 18 12:25:46 2014
@@ -11,6 +11,7 @@
 #define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
 
 #include "DWARFAbbreviationDeclaration.h"
+#include "DWARFDebugRangeList.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/DataTypes.h"
 
@@ -135,9 +136,10 @@ public:
   bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC,
                        uint64_t &HighPC) const;
 
-  void buildAddressRangeTable(const DWARFUnit *U,
-                              DWARFDebugAranges *DebugAranges,
-                              uint32_t CUOffsetInAranges) const;
+  DWARFAddressRangesVector getAddressRanges(const DWARFUnit *U) const;
+
+  void collectChildrenAddressRanges(const DWARFUnit *U,
+                                    DWARFAddressRangesVector &Ranges) const;
 
   bool addressRangeContainsAddress(const DWARFUnit *U,
                                    const uint64_t Address) const;

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.cpp Fri Apr 18 12:25:46 2014
@@ -54,13 +54,16 @@ void DWARFDebugRangeList::dump(raw_ostre
   OS << format("%08x <End of list>\n", Offset);
 }
 
-bool DWARFDebugRangeList::containsAddress(uint64_t BaseAddress,
-                                          uint64_t Address) const {
+DWARFAddressRangesVector
+DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
+  DWARFAddressRangesVector Res;
   for (const RangeListEntry &RLE : Entries) {
-    if (RLE.isBaseAddressSelectionEntry(AddressSize))
+    if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
       BaseAddress = RLE.EndAddress;
-    else if (RLE.containsAddress(BaseAddress, Address))
-      return true;
+    } else {
+      Res.push_back(std::make_pair(BaseAddress + RLE.StartAddress,
+                                   BaseAddress + RLE.EndAddress));
+    }
   }
-  return false;
+  return Res;
 }

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugRangeList.h Fri Apr 18 12:25:46 2014
@@ -17,6 +17,9 @@ namespace llvm {
 
 class raw_ostream;
 
+/// DWARFAddressRangesVector - represents a set of absolute address ranges.
+typedef std::vector<std::pair<uint64_t, uint64_t>> DWARFAddressRangesVector;
+
 class DWARFDebugRangeList {
 public:
   struct RangeListEntry {
@@ -50,10 +53,6 @@ public:
       else
         return StartAddress == -1ULL;
     }
-    bool containsAddress(uint64_t BaseAddress, uint64_t Address) const {
-      return (BaseAddress + StartAddress <= Address) &&
-             (Address < BaseAddress + EndAddress);
-    }
   };
 
 private:
@@ -67,10 +66,10 @@ public:
   void clear();
   void dump(raw_ostream &OS) const;
   bool extract(DataExtractor data, uint32_t *offset_ptr);
-  /// containsAddress - Returns true if range list contains the given
-  /// address. Has to be passed base address of the compile unit that
-  /// references this range list.
-  bool containsAddress(uint64_t BaseAddress, uint64_t Address) const;
+  /// getAbsoluteRanges - Returns absolute address ranges defined by this range
+  /// list. Has to be passed base address of the compile unit referencing this
+  /// range list.
+  DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const;
 };
 
 }  // namespace llvm

Modified: llvm/trunk/lib/DebugInfo/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFUnit.cpp?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFUnit.cpp Fri Apr 18 12:25:46 2014
@@ -298,33 +298,26 @@ void DWARFUnit::clearDIEs(bool KeepCUDie
   }
 }
 
-void
-DWARFUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
-                                         bool clear_dies_if_already_not_parsed,
-                                         uint32_t CUOffsetInAranges) {
+void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
   // 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.
-  const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
-                          clear_dies_if_already_not_parsed;
-  DieArray[0].buildAddressRangeTable(this, debug_aranges, CUOffsetInAranges);
+  const bool ClearDIEs = extractDIEsIfNeeded(false) > 1;
+  DieArray[0].collectChildrenAddressRanges(this, CURanges);
+
+  // Collect address ranges from DIEs in .dwo if necessary.
   bool DWOCreated = parseDWO();
-  if (DWO.get()) {
-    // If there is a .dwo file for this compile unit, then skeleton CU DIE
-    // doesn't have children, and we should instead build address range table
-    // from DIEs in the .debug_info.dwo section of .dwo file.
-    DWO->getUnit()->buildAddressRangeTable(
-        debug_aranges, clear_dies_if_already_not_parsed, CUOffsetInAranges);
-  }
-  if (DWOCreated && clear_dies_if_already_not_parsed)
+  if (DWO.get())
+    DWO->getUnit()->collectAddressRanges(CURanges);
+  if (DWOCreated)
     DWO.reset();
 
   // Keep memory down by clearing DIEs if this generate function
   // caused them to be parsed.
-  if (clear_dies)
+  if (ClearDIEs)
     clearDIEs(true);
 }
 

Modified: llvm/trunk/lib/DebugInfo/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFUnit.h?rev=206624&r1=206623&r2=206624&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFUnit.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFUnit.h Fri Apr 18 12:25:46 2014
@@ -129,9 +129,7 @@ public:
   const char *getCompilationDir();
   uint64_t getDWOId();
 
-  void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
-                              bool clear_dies_if_already_not_parsed,
-                              uint32_t CUOffsetInAranges);
+  void collectAddressRanges(DWARFAddressRangesVector &CURanges);
 
   /// getInlinedChainForAddress - fetches inlined chain for a given address.
   /// Returns empty chain if there is no subprogram containing address. The





More information about the llvm-commits mailing list