From 3ddec31300922a807b1fa92189991dcbae3794f6 Mon Sep 17 00:00:00 2001 From: Frederic Riss Date: Wed, 28 Jan 2015 22:15:14 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227382 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/dsymutil/DwarfLinker.cpp | 62 ++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tools/dsymutil/DwarfLinker.cpp b/tools/dsymutil/DwarfLinker.cpp index 4af8efb03af..7f6d69cc7de 100644 --- a/tools/dsymutil/DwarfLinker.cpp +++ b/tools/dsymutil/DwarfLinker.cpp @@ -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 Info; ///< DIE info indexed by DIE index. +}; + /// \brief The core of the Dwarf linking logic. class DwarfLinker { public: @@ -29,12 +53,41 @@ public: /// \brief Link the contents of the DebugMap. 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 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 &Map) { 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; -- 2.34.1