[llvm] r229181 - [dsymutil] Add a few generic helper methods.

Frederic Riss friss at apple.com
Fri Feb 13 15:18:29 PST 2015


Author: friss
Date: Fri Feb 13 17:18:29 2015
New Revision: 229181

URL: http://llvm.org/viewvc/llvm-project?rev=229181&view=rev
Log:
[dsymutil] Add a few generic helper methods.

To be used in subsequent commits (separated to keep only core logic
in the follow-ups).

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=229181&r1=229180&r2=229181&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Fri Feb 13 17:18:29 2015
@@ -12,6 +12,7 @@
 #include "dsymutil.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/Object/MachO.h"
 #include <string>
 
@@ -112,6 +113,21 @@ private:
                             const object::MachOObjectFile &Obj,
                             const DebugMapObject &DMO);
   /// @}
+
+  /// \defgroup Helpers Various helper methods.
+  ///
+  /// @{
+  const DWARFDebugInfoEntryMinimal *
+  resolveDIEReference(DWARFFormValue &RefValue, const DWARFUnit &Unit,
+                      const DWARFDebugInfoEntryMinimal &DIE,
+                      CompileUnit *&ReferencedCU);
+
+  CompileUnit *getUnitForOffset(unsigned Offset);
+
+  void reportWarning(const Twine &Warning, const DWARFUnit *Unit = nullptr,
+                     const DWARFDebugInfoEntryMinimal *DIE = nullptr);
+  /// @}
+
 private:
   std::string OutputFilename;
   bool Verbose;
@@ -119,8 +135,57 @@ private:
 
   /// The units of the current debug map object.
   std::vector<CompileUnit> Units;
+
+  /// The debug map object curently under consideration.
+  DebugMapObject *CurrentDebugObject;
 };
 
+/// \brief Similar to DWARFUnitSection::getUnitForOffset(), but
+/// returning our CompileUnit object instead.
+CompileUnit *DwarfLinker::getUnitForOffset(unsigned Offset) {
+  auto CU =
+      std::upper_bound(Units.begin(), Units.end(), Offset,
+                       [](uint32_t LHS, const CompileUnit &RHS) {
+                         return LHS < RHS.getOrigUnit().getNextUnitOffset();
+                       });
+  return CU != Units.end() ? &*CU : nullptr;
+}
+
+/// \brief Resolve the DIE attribute reference that has been
+/// extracted in \p RefValue. The resulting DIE migh be in another
+/// CompileUnit which is stored into \p ReferencedCU.
+/// \returns null if resolving fails for any reason.
+const DWARFDebugInfoEntryMinimal *DwarfLinker::resolveDIEReference(
+    DWARFFormValue &RefValue, const DWARFUnit &Unit,
+    const DWARFDebugInfoEntryMinimal &DIE, CompileUnit *&RefCU) {
+  assert(RefValue.isFormClass(DWARFFormValue::FC_Reference));
+  uint64_t RefOffset = *RefValue.getAsReference(&Unit);
+
+  if ((RefCU = getUnitForOffset(RefOffset)))
+    if (const auto *RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset))
+      return RefDie;
+
+  reportWarning("could not find referenced DIE", &Unit, &DIE);
+  return nullptr;
+}
+
+/// \brief Report a warning to the user, optionaly including
+/// information about a specific \p DIE related to the warning.
+void DwarfLinker::reportWarning(const Twine &Warning, const DWARFUnit *Unit,
+                                const DWARFDebugInfoEntryMinimal *DIE) {
+  if (CurrentDebugObject)
+    errs() << Twine("while processing ") +
+                  CurrentDebugObject->getObjectFilename() + ":\n";
+  errs() << Twine("warning: ") + Warning + "\n";
+
+  if (!Verbose || !DIE)
+    return;
+
+  errs() << "    in DIE:\n";
+  DIE->dump(errs(), const_cast<DWARFUnit *>(Unit), 0 /* RecurseDepth */,
+            6 /* Indent */);
+}
+
 /// \brief Recursive helper to gather the child->parent relationships in the
 /// original compile unit.
 void GatherDIEParents(const DWARFDebugInfoEntryMinimal *DIE, unsigned ParentIdx,
@@ -160,7 +225,7 @@ void DwarfLinker::findValidRelocsMachO(c
     unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc);
     uint64_t Offset64;
     if ((RelocSize != 4 && RelocSize != 8) || Reloc.getOffset(Offset64)) {
-      errs() << "warning: unsupported relocation in debug_info section.\n";
+      reportWarning(" unsupported relocation in debug_info section.");
       continue;
     }
     uint32_t Offset = Offset64;
@@ -171,7 +236,7 @@ void DwarfLinker::findValidRelocsMachO(c
     if (Sym != Obj.symbol_end()) {
       StringRef SymbolName;
       if (Sym->getName(SymbolName)) {
-        errs() << "warning: error getting relocation symbol name.\n";
+        reportWarning("error getting relocation symbol name.");
         continue;
       }
       if (const auto *Mapping = DMO.lookupSymbol(SymbolName))
@@ -194,8 +259,7 @@ bool DwarfLinker::findValidRelocs(const
   if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj))
     findValidRelocsMachO(Section, *MachOObj, DMO);
   else
-    errs() << "warning: unsupported object file type: " << Obj.getFileName()
-           << '\n';
+    reportWarning(Twine("unsupported object file type: ") + Obj.getFileName());
 
   if (ValidRelocs.empty())
     return false;
@@ -235,11 +299,13 @@ bool DwarfLinker::link(const DebugMap &M
   }
 
   for (const auto &Obj : Map.objects()) {
+    CurrentDebugObject = Obj.get();
+
     if (Verbose)
       outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n";
     auto ErrOrObj = BinHolder.GetObjectFile(Obj->getObjectFilename());
     if (std::error_code EC = ErrOrObj.getError()) {
-      errs() << Obj->getObjectFilename() << ": " << EC.message() << "\n";
+      reportWarning(Twine(Obj->getObjectFilename()) + ": " + EC.message());
       continue;
     }
 





More information about the llvm-commits mailing list