[llvm] r176882 - Debug Info: use DW_FORM_ref_addr instead of DW_FORM_ref4 if the referenced DIE

Manman Ren mren at apple.com
Tue Mar 12 11:27:15 PDT 2013


Author: mren
Date: Tue Mar 12 13:27:15 2013
New Revision: 176882

URL: http://llvm.org/viewvc/llvm-project?rev=176882&view=rev
Log:
Debug Info: use DW_FORM_ref_addr instead of DW_FORM_ref4 if the referenced DIE
belongs to a different compile unit.

DW_FORM_ref_addr should be used for cross compile-unit reference.

When compiling a large application, we got a dwarfdump verification error where
abstract_origin points to nowhere.

This error can't be reproduced on any testing case in MultiSource.
We may have other cases where we use DW_FORM_ref4 unconditionally.

rdar://problem/13370501

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp?rev=176882&r1=176881&r2=176882&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp Tue Mar 12 13:27:15 2013
@@ -112,6 +112,17 @@ DIE::~DIE() {
     delete Children[i];
 }
 
+/// Climb up the parent chain to get the compile unit DIE this DIE belongs to.
+DIE *DIE::getCompileUnit() const{
+  DIE *p = getParent();
+  while (p) {
+    if (p->getTag() == dwarf::DW_TAG_compile_unit)
+      return p;
+    p = p->getParent();
+  }
+  return NULL;
+}
+
 #ifndef NDEBUG
 void DIE::print(raw_ostream &O, unsigned IncIndent) {
   IndentCount += IncIndent;

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h?rev=176882&r1=176881&r2=176882&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h Tue Mar 12 13:27:15 2013
@@ -152,6 +152,9 @@ namespace llvm {
     const std::vector<DIE *> &getChildren() const { return Children; }
     const SmallVector<DIEValue*, 32> &getValues() const { return Values; }
     DIE *getParent() const { return Parent; }
+    /// Climb up the parent chain to get the compile unit DIE this DIE belongs
+    /// to.
+    DIE *getCompileUnit() const;
     void setTag(unsigned Tag) { Abbrev.setTag(Tag); }
     void setOffset(unsigned O) { Offset = O; }
     void setSize(unsigned S) { Size = S; }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=176882&r1=176881&r2=176882&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Tue Mar 12 13:27:15 2013
@@ -35,7 +35,7 @@ using namespace llvm;
 CompileUnit::CompileUnit(unsigned UID, unsigned L, DIE *D, AsmPrinter *A,
                          DwarfDebug *DW, DwarfUnits *DWU)
   : UniqueID(UID), Language(L), CUDie(D), Asm(A), DD(DW), DU(DWU),
-    IndexTyDie(0) {
+    IndexTyDie(0), DebugInfoOffset(0) {
   DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
 }
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h?rev=176882&r1=176881&r2=176882&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h Tue Mar 12 13:27:15 2013
@@ -87,6 +87,9 @@ class CompileUnit {
   /// corresponds to the MDNode mapped with the subprogram DIE.
   DenseMap<DIE *, const MDNode *> ContainingTypeMap;
 
+  /// Offset of the CUDie from beginning of debug info section.
+  unsigned DebugInfoOffset;
+
   /// getLowerBoundDefault - Return the default lower bound for an array. If the
   /// DWARF version doesn't handle the language, return -1.
   int64_t getDefaultLowerBound() const;
@@ -103,6 +106,7 @@ public:
   unsigned getUniqueID()            const { return UniqueID; }
   unsigned getLanguage()            const { return Language; }
   DIE* getCUDie()                   const { return CUDie.get(); }
+  unsigned getDebugInfoOffset()     const { return DebugInfoOffset; }
   const StringMap<DIE*> &getGlobalNames() const { return GlobalNames; }
   const StringMap<DIE*> &getGlobalTypes() const { return GlobalTypes; }
 
@@ -120,6 +124,7 @@ public:
     return AccelTypes;
   }
 
+  void setDebugInfoOffset(unsigned DbgInfoOff) { DebugInfoOffset = DbgInfoOff; }
   /// hasContent - Return true if this compile unit has something to write out.
   ///
   bool hasContent() const { return !CUDie->getChildren().empty(); }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=176882&r1=176881&r2=176882&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Mar 12 13:27:15 2013
@@ -352,11 +352,16 @@ DIE *DwarfDebug::updateSubprogramScopeDI
   // If we're updating an abstract DIE, then we will be adding the children and
   // object pointer later on. But what we don't want to do is process the
   // concrete DIE twice.
-  if (DIE *AbsSPDIE = AbstractSPDies.lookup(SPNode)) {
+  DIE *AbsSPDIE = AbstractSPDies.lookup(SPNode);
+  if (AbsSPDIE) {
+    bool InSameCU = (AbsSPDIE->getCompileUnit() == SPCU->getCUDie());
     // Pick up abstract subprogram DIE.
     SPDie = new DIE(dwarf::DW_TAG_subprogram);
+    // If AbsSPDIE belongs to a different CU, use DW_FORM_ref_addr instead of
+    // DW_FORM_ref4.
     SPCU->addDIEEntry(SPDie, dwarf::DW_AT_abstract_origin,
-                      dwarf::DW_FORM_ref4, AbsSPDIE);
+                      InSameCU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,
+                      AbsSPDIE);
     SPCU->addDie(SPDie);
   } else {
     DISubprogram SPDecl = SP.getFunctionDeclaration();
@@ -1692,15 +1697,19 @@ DwarfUnits::computeSizeAndOffset(DIE *Di
 
 // Compute the size and offset of all the DIEs.
 void DwarfUnits::computeSizeAndOffsets() {
+  // Offset from the beginning of debug info section.
+  unsigned AccuOffset = 0;
   for (SmallVector<CompileUnit *, 1>::iterator I = CUs.begin(),
          E = CUs.end(); I != E; ++I) {
+    (*I)->setDebugInfoOffset(AccuOffset);
     unsigned Offset =
       sizeof(int32_t) + // Length of Compilation Unit Info
       sizeof(int16_t) + // DWARF version number
       sizeof(int32_t) + // Offset Into Abbrev. Section
       sizeof(int8_t);   // Pointer Size (in bytes)
 
-    computeSizeAndOffset((*I)->getCUDie(), Offset);
+    unsigned EndOffset = computeSizeAndOffset((*I)->getCUDie(), Offset);
+    AccuOffset += EndOffset;
   }
 }
 
@@ -1774,6 +1783,13 @@ void DwarfDebug::emitDIE(DIE *Die, std::
       DIEEntry *E = cast<DIEEntry>(Values[i]);
       DIE *Origin = E->getEntry();
       unsigned Addr = Origin->getOffset();
+      if (Form == dwarf::DW_FORM_ref_addr) {
+        // For DW_FORM_ref_addr, output the offset from beginning of debug info
+        // section. Origin->getOffset() returns the offset from start of the
+        // compile unit.
+        DwarfUnits &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
+        Addr += Holder.getCUOffset(Origin->getCompileUnit());
+      }
       Asm->EmitInt32(Addr);
       break;
     }
@@ -1871,6 +1887,17 @@ void DwarfUnits::emitUnits(DwarfDebug *D
   }
 }
 
+/// For a given compile unit DIE, returns offset from beginning of debug info.
+unsigned DwarfUnits::getCUOffset(DIE *Die) {
+  for (SmallVector<CompileUnit *, 1>::iterator I = CUs.begin(),
+       E = CUs.end(); I != E; ++I) {
+    CompileUnit *TheCU = *I;
+    if (TheCU->getCUDie() == Die)
+      return TheCU->getDebugInfoOffset();
+  }
+  return 0;
+}
+
 // Emit the debug info section.
 void DwarfDebug::emitDebugInfo() {
   DwarfUnits &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=176882&r1=176881&r2=176882&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Mar 12 13:27:15 2013
@@ -274,6 +274,10 @@ public:
 
   /// \brief Returns the address pool.
   AddrPool *getAddrPool() { return &AddressPool; }
+
+  /// \brief for a given compile unit DIE, returns offset from beginning of
+  /// debug info.
+  unsigned getCUOffset(DIE *Die);
 };
 
 /// \brief Collects and handles dwarf debug information.





More information about the llvm-commits mailing list