[llvm] r227382 - [dsymutil] Gather the DIE tree child->parent relationships.

Frederic Riss friss at apple.com
Wed Jan 28 14:15:14 PST 2015


Author: friss
Date: Wed Jan 28 16:15:14 2015
New Revision: 227382

URL: http://llvm.org/viewvc/llvm-project?rev=227382&view=rev
Log:
[dsymutil] Gather the DIE tree child->parent relationships.

The libDebugInfo DIE parsing doesn't store these relationships, we have to
recompute them. This commit introduces the CompileUnit bookkeeping class to
store this data. It will be expanded with more fields in the future.

No tests as this produces no visible output.

Modified:
    llvm/trunk/tools/dsymutil/DwarfLinker.cpp

Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=227382&r1=227381&r2=227382&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Wed Jan 28 16:15:14 2015
@@ -20,6 +20,30 @@ namespace dsymutil {
 
 namespace {
 
+/// \brief Stores all information relating to a compile unit, be it in
+/// its original instance in the object file to its brand new cloned
+/// and linked DIE tree.
+class CompileUnit {
+public:
+  /// \brief Information gathered about a DIE in the object file.
+  struct DIEInfo {
+    uint32_t ParentIdx;
+  };
+
+  CompileUnit(DWARFUnit &OrigUnit) : OrigUnit(OrigUnit) {
+    Info.resize(OrigUnit.getNumDIEs());
+  }
+
+  DWARFUnit &getOrigUnit() { return OrigUnit; }
+
+  DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
+  const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }
+
+private:
+  DWARFUnit &OrigUnit;
+  std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index.
+};
+
 /// \brief The core of the Dwarf linking logic.
 class DwarfLinker {
 public:
@@ -30,11 +54,40 @@ public:
   bool link(const DebugMap &);
 
 private:
+  /// \brief Called at the start of a debug object link.
+  void startDebugObject(DWARFContext &);
+
+  /// \brief Called at the end of a debug object link.
+  void endDebugObject();
+
+private:
   std::string OutputFilename;
   bool Verbose;
   BinaryHolder BinHolder;
+
+  /// The units of the current debug map object.
+  std::vector<CompileUnit> Units;
 };
 
+/// \brief Recursive helper to gather the child->parent relationships in the
+/// original compile unit.
+void GatherDIEParents(const DWARFDebugInfoEntryMinimal *DIE, unsigned ParentIdx,
+                      CompileUnit &CU) {
+  unsigned MyIdx = CU.getOrigUnit().getDIEIndex(DIE);
+  CU.getInfo(MyIdx).ParentIdx = ParentIdx;
+
+  if (DIE->hasChildren())
+    for (auto *Child = DIE->getFirstChild(); Child && !Child->isNULL();
+         Child = Child->getSibling())
+      GatherDIEParents(Child, MyIdx, CU);
+}
+
+void DwarfLinker::startDebugObject(DWARFContext &Dwarf) {
+  Units.reserve(Dwarf.getNumCompileUnits());
+}
+
+void DwarfLinker::endDebugObject() { Units.clear(); }
+
 bool DwarfLinker::link(const DebugMap &Map) {
 
   if (Map.begin() == Map.end()) {
@@ -51,15 +104,24 @@ bool DwarfLinker::link(const DebugMap &M
       continue;
     }
 
+    // Setup access to the debug info.
     DWARFContextInMemory DwarfContext(*ErrOrObj);
+    startDebugObject(DwarfContext);
 
+    // In a first phase, just read in the debug info and store the DIE
+    // parent links that we will use during the next phase.
     for (const auto &CU : DwarfContext.compile_units()) {
       auto *CUDie = CU->getCompileUnitDIE(false);
       if (Verbose) {
         outs() << "Input compilation unit:";
         CUDie->dump(outs(), CU.get(), 0);
       }
+      Units.emplace_back(*CU);
+      GatherDIEParents(CUDie, 0, Units.back());
     }
+
+    // Clean-up before starting working on the next object.
+    endDebugObject();
   }
 
   return true;





More information about the llvm-commits mailing list