summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Riss <friss@apple.com>2015-01-28 22:15:14 +0000
committerFrederic Riss <friss@apple.com>2015-01-28 22:15:14 +0000
commit563cba6d2b29510ac23db46173f1b86abe7102cc (patch)
tree92d8d6aef57fcda60bfbb960245a27743c37c0c4
parentdc7b2869ab601e074b89650fe3ffc16d3da5823a (diff)
downloadbcm5719-llvm-563cba6d2b29510ac23db46173f1b86abe7102cc.tar.gz
bcm5719-llvm-563cba6d2b29510ac23db46173f1b86abe7102cc.zip
[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. llvm-svn: 227382
-rw-r--r--llvm/tools/dsymutil/DwarfLinker.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp
index 4af8efb03af..7f6d69cc7de 100644
--- a/llvm/tools/dsymutil/DwarfLinker.cpp
+++ b/llvm/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<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 &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;
OpenPOWER on IntegriCloud