[llvm] r189329 - Add support for DebugFission to DWARF parser

Alexey Samsonov samsonov at google.com
Tue Aug 27 02:20:23 PDT 2013


Author: samsonov
Date: Tue Aug 27 04:20:22 2013
New Revision: 189329

URL: http://llvm.org/viewvc/llvm-project?rev=189329&view=rev
Log:
Add support for DebugFission to DWARF parser

Summary:
1) Make llvm-symbolizer properly symbolize
files with split debug info (by using stanalone .dwo files).
2) Make DWARFCompileUnit parse and store corresponding .dwo file,
if necessary.
3) Make bits of DWARF parsing more CompileUnit-oriented.

Reviewers: echristo

Reviewed By: echristo

CC: bkramer, llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D1164

Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARFFormValue.h
    llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp
    llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h
    llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
    llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
    llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h
    llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/DWARFFormValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARFFormValue.h?rev=189329&r1=189328&r2=189329&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARFFormValue.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARFFormValue.h Tue Aug 27 04:20:22 2013
@@ -20,7 +20,7 @@ class raw_ostream;
 class DWARFFormValue {
 public:
   struct ValueType {
-    ValueType() : data(NULL) {
+    ValueType() : data(NULL), IsDWOIndex(false) {
       uval = 0;
     }
 
@@ -30,6 +30,7 @@ public:
       const char* cstr;
     };
     const uint8_t* data;
+    bool IsDWOIndex;
   };
 
   enum {
@@ -63,11 +64,8 @@ public:
   bool resolveCompileUnitReferences(const DWARFCompileUnit* cu);
   uint64_t getUnsigned() const { return Value.uval; }
   int64_t getSigned() const { return Value.sval; }
-  const char *getAsCString(const DataExtractor *debug_str_data_ptr) const;
-  const char *getIndirectCString(const DataExtractor *,
-                                 const DataExtractor *) const;
-  uint64_t getIndirectAddress(const DataExtractor *,
-                              const DWARFCompileUnit *) const;
+  const char *getAsCString(const DWARFCompileUnit *CU) const;
+  uint64_t getAsAddress(const DWARFCompileUnit *CU) const;
   bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
                  const DWARFCompileUnit *cu) const;
   static bool skipValue(uint16_t form, DataExtractor debug_info_data,

Modified: llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp?rev=189329&r1=189328&r2=189329&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFCompileUnit.cpp Tue Aug 27 04:20:22 2013
@@ -12,12 +12,31 @@
 #include "llvm/DebugInfo/DWARFFormValue.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 using namespace dwarf;
 
-DataExtractor DWARFCompileUnit::getDebugInfoExtractor() const {
-  return DataExtractor(InfoSection, isLittleEndian, AddrSize);
+bool DWARFCompileUnit::getAddrOffsetSectionItem(uint32_t Index,
+                                                uint64_t &Result) const {
+  uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize;
+  if (AddrOffsetSection.size() < Offset + AddrSize)
+    return false;
+  DataExtractor DA(AddrOffsetSection, isLittleEndian, AddrSize);
+  Result = DA.getAddress(&Offset);
+  return true;
+}
+
+bool DWARFCompileUnit::getStringOffsetSectionItem(uint32_t Index,
+                                                  uint32_t &Result) const {
+  // FIXME: string offset section entries are 8-byte for DWARF64.
+  const uint32_t ItemSize = 4;
+  uint32_t Offset = Index * ItemSize;
+  if (StringOffsetSection.size() < Offset + ItemSize)
+    return false;
+  DataExtractor DA(StringOffsetSection, isLittleEndian, 0);
+  Result = DA.getU32(&Offset);
+  return true;
 }
 
 bool DWARFCompileUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) {
@@ -78,7 +97,8 @@ bool DWARFCompileUnit::extractRangeList(
   // Require that compile unit is extracted.
   assert(DieArray.size() > 0);
   DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
-  return RangeList.extract(RangesData, &RangeListOffset);
+  uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
+  return RangeList.extract(RangesData, &ActualRangeListOffset);
 }
 
 void DWARFCompileUnit::clear() {
@@ -88,7 +108,10 @@ void DWARFCompileUnit::clear() {
   Abbrevs = 0;
   AddrSize = 0;
   BaseAddr = 0;
+  RangeSectionBase = 0;
+  AddrOffsetSectionBase = 0;
   clearDIEs(false);
+  DWO.reset();
 }
 
 void DWARFCompileUnit::dump(raw_ostream &OS) {
@@ -112,6 +135,15 @@ const char *DWARFCompileUnit::getCompila
   return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
 }
 
+uint64_t DWARFCompileUnit::getDWOId() {
+  extractDIEsIfNeeded(true);
+  const uint64_t FailValue = -1ULL;
+  if (DieArray.empty())
+    return FailValue;
+  return DieArray[0]
+      .getAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, FailValue);
+}
+
 void DWARFCompileUnit::setDIERelations() {
   if (DieArray.empty())
     return;
@@ -207,21 +239,72 @@ size_t DWARFCompileUnit::extractDIEsIfNe
       DieArray.size() > 1)
     return 0; // Already parsed.
 
-  extractDIEsToVector(DieArray.empty(), !CUDieOnly, DieArray);
+  bool HasCUDie = DieArray.size() > 0;
+  extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
+
+  if (DieArray.empty())
+    return 0;
 
-  // Set the base address of current compile unit.
-  if (!DieArray.empty()) {
+  // If CU DIE was just parsed, copy several attribute values from it.
+  if (!HasCUDie) {
     uint64_t BaseAddr =
       DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U);
     if (BaseAddr == -1U)
       BaseAddr = DieArray[0].getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0);
     setBaseAddress(BaseAddr);
+    AddrOffsetSectionBase =
+        DieArray[0].getAttributeValueAsReference(this, DW_AT_GNU_addr_base, 0);
+    RangeSectionBase =
+        DieArray[0].getAttributeValueAsReference(this, DW_AT_GNU_ranges_base, 0);
   }
 
   setDIERelations();
   return DieArray.size();
 }
 
+DWARFCompileUnit::DWOHolder::DWOHolder(object::ObjectFile *DWOFile)
+    : DWOFile(DWOFile),
+      DWOContext(cast<DWARFContext>(DIContext::getDWARFContext(DWOFile))),
+      DWOCU(0) {
+  if (DWOContext->getNumDWOCompileUnits() > 0)
+    DWOCU = DWOContext->getDWOCompileUnitAtIndex(0);
+}
+
+bool DWARFCompileUnit::parseDWO() {
+  if (DWO.get() != 0)
+    return false;
+  extractDIEsIfNeeded(true);
+  if (DieArray.empty())
+    return false;
+  const char *DWOFileName =
+      DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, 0);
+  if (DWOFileName == 0)
+    return false;
+  const char *CompilationDir =
+      DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
+  SmallString<16> AbsolutePath;
+  if (sys::path::is_relative(DWOFileName) && CompilationDir != 0) {
+    sys::path::append(AbsolutePath, CompilationDir);
+  }
+  sys::path::append(AbsolutePath, DWOFileName);
+  object::ObjectFile *DWOFile =
+      object::ObjectFile::createObjectFile(AbsolutePath);
+  if (!DWOFile)
+    return false;
+  // Reset DWOHolder.
+  DWO.reset(new DWOHolder(DWOFile));
+  DWARFCompileUnit *DWOCU = DWO->getCU();
+  // Verify that compile unit in .dwo file is valid.
+  if (DWOCU == 0 || DWOCU->getDWOId() != getDWOId()) {
+    DWO.reset();
+    return false;
+  }
+  // Share .debug_addr and .debug_ranges section with compile unit in .dwo
+  DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
+  DWOCU->setRangesSection(RangeSection, RangeSectionBase);
+  return true;
+}
+
 void DWARFCompileUnit::clearDIEs(bool KeepCUDie) {
   if (DieArray.size() > (unsigned)KeepCUDie) {
     // std::vectors never get any smaller when resized to a smaller size,
@@ -241,7 +324,8 @@ void DWARFCompileUnit::clearDIEs(bool Ke
 
 void
 DWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
-                                         bool clear_dies_if_already_not_parsed){
+                                         bool clear_dies_if_already_not_parsed,
+                                         uint32_t CUOffsetInAranges) {
   // 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
@@ -250,7 +334,17 @@ DWARFCompileUnit::buildAddressRangeTable
   // down.
   const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
                           clear_dies_if_already_not_parsed;
-  DieArray[0].buildAddressRangeTable(this, debug_aranges);
+  DieArray[0].buildAddressRangeTable(this, debug_aranges, CUOffsetInAranges);
+  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->getCU()->buildAddressRangeTable(
+        debug_aranges, clear_dies_if_already_not_parsed, CUOffsetInAranges);
+  }
+  if (DWOCreated && clear_dies_if_already_not_parsed)
+    DWO.reset();
 
   // Keep memory down by clearing DIEs if this generate function
   // caused them to be parsed.
@@ -258,21 +352,38 @@ DWARFCompileUnit::buildAddressRangeTable
     clearDIEs(true);
 }
 
+const DWARFDebugInfoEntryMinimal *
+DWARFCompileUnit::getSubprogramForAddress(uint64_t Address) {
+  extractDIEsIfNeeded(false);
+  for (size_t i = 0, n = DieArray.size(); i != n; i++)
+    if (DieArray[i].isSubprogramDIE() &&
+        DieArray[i].addressRangeContainsAddress(this, Address)) {
+      return &DieArray[i];
+    }
+  return 0;
+}
+
 DWARFDebugInfoEntryInlinedChain
 DWARFCompileUnit::getInlinedChainForAddress(uint64_t Address) {
   // First, find a subprogram that contains the given address (the root
   // of inlined chain).
-  extractDIEsIfNeeded(false);
-  const DWARFDebugInfoEntryMinimal *SubprogramDIE = 0;
-  for (size_t i = 0, n = DieArray.size(); i != n; i++) {
-    if (DieArray[i].isSubprogramDIE() &&
-        DieArray[i].addressRangeContainsAddress(this, Address)) {
-      SubprogramDIE = &DieArray[i];
-      break;
+  const DWARFCompileUnit *ChainCU = 0;
+  const DWARFDebugInfoEntryMinimal *SubprogramDIE =
+      getSubprogramForAddress(Address);
+  if (SubprogramDIE) {
+    ChainCU = this;
+  } else {
+    // Try to look for subprogram DIEs in the DWO file.
+    parseDWO();
+    if (DWO.get()) {
+      SubprogramDIE = DWO->getCU()->getSubprogramForAddress(Address);
+      if (SubprogramDIE)
+        ChainCU = DWO->getCU();
     }
   }
+
   // Get inlined chain rooted at this subprogram DIE.
   if (!SubprogramDIE)
     return DWARFDebugInfoEntryInlinedChain();
-  return SubprogramDIE->getInlinedChainForAddress(this, Address);
-}
+  return SubprogramDIE->getInlinedChainForAddress(ChainCU, Address);
+ }

Modified: llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h?rev=189329&r1=189328&r2=189329&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h Tue Aug 27 04:20:22 2013
@@ -10,6 +10,7 @@
 #ifndef LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
 #define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
 
+#include "llvm/ADT/OwningPtr.h"
 #include "DWARFDebugAbbrev.h"
 #include "DWARFDebugInfoEntry.h"
 #include "DWARFDebugRangeList.h"
@@ -18,6 +19,10 @@
 
 namespace llvm {
 
+namespace object {
+class ObjectFile;
+}
+
 class DWARFDebugAbbrev;
 class StringRef;
 class raw_ostream;
@@ -30,9 +35,11 @@ class DWARFCompileUnit {
   StringRef InfoSection;
   StringRef AbbrevSection;
   StringRef RangeSection;
+  uint32_t RangeSectionBase;
   StringRef StringSection;
   StringRef StringOffsetSection;
   StringRef AddrOffsetSection;
+  uint32_t AddrOffsetSectionBase;
   const RelocAddrMap *RelocMap;
   bool isLittleEndian;
 
@@ -44,6 +51,17 @@ class DWARFCompileUnit {
   uint64_t BaseAddr;
   // The compile unit debug information entry items.
   std::vector<DWARFDebugInfoEntryMinimal> DieArray;
+
+  class DWOHolder {
+    OwningPtr<object::ObjectFile> DWOFile;
+    OwningPtr<DWARFContext> DWOContext;
+    DWARFCompileUnit *DWOCU;
+  public:
+    DWOHolder(object::ObjectFile *DWOFile);
+    DWARFCompileUnit *getCU() const { return DWOCU; }
+  };
+  OwningPtr<DWOHolder> DWO;
+
 public:
 
   DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
@@ -57,9 +75,27 @@ public:
 
   StringRef getStringSection() const { return StringSection; }
   StringRef getStringOffsetSection() const { return StringOffsetSection; }
-  StringRef getAddrOffsetSection() const { return AddrOffsetSection; }
+  void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
+    AddrOffsetSection = AOS;
+    AddrOffsetSectionBase = Base;
+  }
+  void setRangesSection(StringRef RS, uint32_t Base) {
+    RangeSection = RS;
+    RangeSectionBase = Base;
+  }
+
+  bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
+  // FIXME: Result should be uint64_t in DWARF64.
+  bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
+
+  DataExtractor getDebugInfoExtractor() const {
+    return DataExtractor(InfoSection, isLittleEndian, AddrSize);
+  }
+  DataExtractor getStringExtractor() const {
+    return DataExtractor(StringSection, false, 0);
+  }
+
   const RelocAddrMap *getRelocMap() const { return RelocMap; }
-  DataExtractor getDebugInfoExtractor() const;
 
   bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
   uint32_t extract(uint32_t offset, DataExtractor debug_info_data,
@@ -105,6 +141,7 @@ public:
   }
 
   const char *getCompilationDir();
+  uint64_t getDWOId();
 
   /// setDIERelations - We read in all of the DIE entries into our flat list
   /// of DIE entries and now we need to go back through all of them and set the
@@ -112,7 +149,8 @@ public:
   void setDIERelations();
 
   void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
-                              bool clear_dies_if_already_not_parsed);
+                              bool clear_dies_if_already_not_parsed,
+                              uint32_t CUOffsetInAranges);
 
   /// getInlinedChainForAddress - fetches inlined chain for a given address.
   /// Returns empty chain if there is no subprogram containing address. The
@@ -125,6 +163,15 @@ private:
                            std::vector<DWARFDebugInfoEntryMinimal> &DIEs) const;
   /// clearDIEs - Clear parsed DIEs to keep memory usage low.
   void clearDIEs(bool KeepCUDie);
+
+  /// parseDWO - Parses .dwo file for current compile unit. Returns true if
+  /// it was actually constructed.
+  bool parseDWO();
+
+  /// getSubprogramForAddress - Returns subprogram DIE with address range
+  /// encompassing the provided address. The pointer is alive as long as parsed
+  /// compile unit DIEs are not cleared.
+  const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address);
 };
 
 }

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp?rev=189329&r1=189328&r2=189329&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp Tue Aug 27 04:20:22 2013
@@ -95,7 +95,7 @@ bool DWARFDebugAranges::generate(DWARFCo
       if (DWARFCompileUnit *cu = ctx->getCompileUnitAtIndex(cu_idx)) {
         uint32_t CUOffset = cu->getOffset();
         if (ParsedCUOffsets.insert(CUOffset).second)
-          cu->buildAddressRangeTable(this, true);
+          cu->buildAddressRangeTable(this, true, CUOffset);
       }
     }
   }

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp?rev=189329&r1=189328&r2=189329&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.cpp Tue Aug 27 04:20:22 2013
@@ -222,29 +222,30 @@ DWARFDebugInfoEntryMinimal::getAttribute
   return 0;
 }
 
-const char*
-DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
-                                                     const DWARFCompileUnit* cu,
-                                                     const uint16_t attr,
-                                                     const char* fail_value)
-                                                     const {
-  DWARFFormValue form_value;
-  if (getAttributeValue(cu, attr, form_value)) {
-    DataExtractor stringExtractor(cu->getStringSection(), false, 0);
-    return form_value.getAsCString(&stringExtractor);
+const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
+    const DWARFCompileUnit *CU, const uint16_t Attr,
+    const char *FailValue) const {
+  DWARFFormValue FormValue;
+  if (getAttributeValue(CU, Attr, FormValue))
+    return FormValue.getAsCString(CU);
+  return FailValue;
+}
+
+uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress(
+    const DWARFCompileUnit *CU, const uint16_t Attr, uint64_t FailValue) const {
+  DWARFFormValue FormValue;
+  if (getAttributeValue(CU, Attr, FormValue))
+    return FormValue.getAsAddress(CU);
+  return FailValue;
+}
+
+uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
+    const DWARFCompileUnit *CU, const uint16_t Attr, uint64_t FailValue) const {
+  DWARFFormValue FormValue;
+  if (getAttributeValue(CU, Attr, FormValue)) {
+    return FormValue.getUnsigned();
   }
-  return fail_value;
-}
-
-uint64_t
-DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
-                                                    const DWARFCompileUnit* cu,
-                                                    const uint16_t attr,
-                                                    uint64_t fail_value) const {
-  DWARFFormValue form_value;
-  if (getAttributeValue(cu, attr, form_value))
-      return form_value.getUnsigned();
-  return fail_value;
+  return FailValue;
 }
 
 int64_t
@@ -274,29 +275,29 @@ bool DWARFDebugInfoEntryMinimal::getLowA
                                                  uint64_t &LowPC,
                                                  uint64_t &HighPC) const {
   HighPC = -1ULL;
-  LowPC = getAttributeValueAsUnsigned(CU, DW_AT_low_pc, -1ULL);
+  LowPC = getAttributeValueAsAddress(CU, DW_AT_low_pc, -1ULL);
   if (LowPC != -1ULL)
-    HighPC = getAttributeValueAsUnsigned(CU, DW_AT_high_pc, -1ULL);
+    HighPC = getAttributeValueAsAddress(CU, DW_AT_high_pc, -1ULL);
   return (HighPC != -1ULL);
 }
 
 void
 DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *CU,
-                                               DWARFDebugAranges *DebugAranges)
+                                               DWARFDebugAranges *DebugAranges,
+                                               uint32_t CUOffsetInAranges)
                                                    const {
   if (AbbrevDecl) {
     if (isSubprogramDIE()) {
       uint64_t LowPC, HighPC;
-      if (getLowAndHighPC(CU, LowPC, HighPC)) {
-        DebugAranges->appendRange(CU->getOffset(), LowPC, HighPC);
-      }
+      if (getLowAndHighPC(CU, LowPC, HighPC))
+        DebugAranges->appendRange(CUOffsetInAranges, LowPC, HighPC);
       // FIXME: try to append ranges from .debug_ranges section.
     }
 
-    const DWARFDebugInfoEntryMinimal *child = getFirstChild();
-    while (child) {
-      child->buildAddressRangeTable(CU, DebugAranges);
-      child = child->getSibling();
+    const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
+    while (Child) {
+      Child->buildAddressRangeTable(CU, DebugAranges, CUOffsetInAranges);
+      Child = Child->getSibling();
     }
   }
 }

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h?rev=189329&r1=189328&r2=189329&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugInfoEntry.h Tue Aug 27 04:20:22 2013
@@ -128,6 +128,10 @@ public:
                                         const uint16_t attr,
                                         const char *fail_value) const;
 
+  uint64_t getAttributeValueAsAddress(const DWARFCompileUnit *CU,
+                                      const uint16_t Attr,
+                                      uint64_t FailValue) const;
+
   uint64_t getAttributeValueAsUnsigned(const DWARFCompileUnit *cu,
                                        const uint16_t attr,
                                        uint64_t fail_value) const;
@@ -146,7 +150,8 @@ public:
                        uint64_t &LowPC, uint64_t &HighPC) const;
 
   void buildAddressRangeTable(const DWARFCompileUnit *CU,
-                              DWARFDebugAranges *DebugAranges) const;
+                              DWARFDebugAranges *DebugAranges,
+                              uint32_t CUOffsetInAranges) const;
 
   bool addressRangeContainsAddress(const DWARFCompileUnit *CU,
                                    const uint64_t Address) const;

Modified: llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp?rev=189329&r1=189328&r2=189329&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp Tue Aug 27 04:20:22 2013
@@ -183,10 +183,9 @@ DWARFFormValue::extractValue(DataExtract
       Value.uval = data.getU64(offset_ptr);
       break;
     case DW_FORM_GNU_addr_index:
-      Value.uval = data.getULEB128(offset_ptr);
-      break;
     case DW_FORM_GNU_str_index:
       Value.uval = data.getULEB128(offset_ptr);
+      Value.IsDWOIndex = true;
       break;
     default:
       return false;
@@ -322,12 +321,11 @@ DWARFFormValue::dump(raw_ostream &OS, co
   switch (Form) {
   case DW_FORM_addr:      OS << format("0x%016" PRIx64, uvalue); break;
   case DW_FORM_GNU_addr_index: {
-    StringRef AddrOffsetSec = cu->getAddrOffsetSection();
     OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
-    if (AddrOffsetSec.size() != 0) {
-      DataExtractor DA(AddrOffsetSec, true, cu->getAddressByteSize());
-      OS << format("0x%016" PRIx64, getIndirectAddress(&DA, cu));
-    } else
+    uint64_t Address;
+    if (cu->getAddrOffsetSectionItem(uvalue, Address))
+      OS << format("0x%016" PRIx64, Address);
+    else
       OS << "<no .debug_addr section>";
     break;
   }
@@ -376,7 +374,7 @@ DWARFFormValue::dump(raw_ostream &OS, co
   case DW_FORM_udata:     OS << getUnsigned(); break;
   case DW_FORM_strp: {
     OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
-    const char* dbg_str = getAsCString(&debug_str_data);
+    const char* dbg_str = getAsCString(cu);
     if (dbg_str) {
       OS << '"';
       OS.write_escaped(dbg_str);
@@ -386,8 +384,7 @@ DWARFFormValue::dump(raw_ostream &OS, co
   }
   case DW_FORM_GNU_str_index: {
     OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
-    const char *dbg_str = getIndirectCString(&debug_str_data,
-                                             &debug_str_offset_data);
+    const char *dbg_str = getAsCString(cu);
     if (dbg_str) {
       OS << '"';
       OS.write_escaped(dbg_str);
@@ -440,33 +437,33 @@ DWARFFormValue::dump(raw_ostream &OS, co
 }
 
 const char*
-DWARFFormValue::getAsCString(const DataExtractor *debug_str_data_ptr) const {
-  if (isInlinedCStr()) {
+DWARFFormValue::getAsCString(const DWARFCompileUnit *CU) const {
+  if (isInlinedCStr())
     return Value.cstr;
-  } else if (debug_str_data_ptr) {
-    uint32_t offset = Value.uval;
-    return debug_str_data_ptr->getCStr(&offset);
+  if (!CU)
+    return NULL;
+  uint32_t Offset = Value.uval;
+  if (Value.IsDWOIndex) {
+    uint32_t StrOffset;
+    if (!CU->getStringOffsetSectionItem(Offset, StrOffset))
+      return NULL;
+    Offset = StrOffset;
   }
-  return NULL;
-}
-
-const char*
-DWARFFormValue::getIndirectCString(const DataExtractor *DS,
-                                   const DataExtractor *DSO) const {
-  if (!DS || !DSO) return NULL;
-
-  uint32_t offset = Value.uval * 4;
-  uint32_t soffset = DSO->getU32(&offset);
-  return DS->getCStr(&soffset);
+  return CU->getStringExtractor().getCStr(&Offset);
 }
 
 uint64_t
-DWARFFormValue::getIndirectAddress(const DataExtractor *DA,
-                                   const DWARFCompileUnit *cu) const {
-  if (!DA) return 0;
-
-  uint32_t offset = Value.uval * cu->getAddressByteSize();
-  return DA->getAddress(&offset);
+DWARFFormValue::getAsAddress(const DWARFCompileUnit *CU) const {
+  if (!CU)
+    return 0;
+  if (Value.IsDWOIndex) {
+    uint32_t Index = Value.uval;
+    uint64_t Address;
+    if (!CU->getAddrOffsetSectionItem(Index, Address))
+      return 0;
+    return Address;
+  }
+  return Value.uval;
 }
 
 uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const {





More information about the llvm-commits mailing list