]> granicus.if.org Git - llvm/commitdiff
llvm-dwarfdump: support dumping static archives.
authorAdrian Prantl <aprantl@apple.com>
Thu, 14 Sep 2017 17:01:53 +0000 (17:01 +0000)
committerAdrian Prantl <aprantl@apple.com>
Thu, 14 Sep 2017 17:01:53 +0000 (17:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313272 91177308-0d34-0410-b5e6-96231b3b80d8

lib/DebugInfo/DWARF/DWARFContext.cpp
test/tools/llvm-dwarfdump/X86/archive.test [new file with mode: 0644]
tools/llvm-dwarfdump/llvm-dwarfdump.cpp

index 6dac25996d2a5054aef8b5092963206ce8e3600f..d8034d08c27399fc08b16a2470cbc01b45fdccd7 100644 (file)
@@ -230,9 +230,6 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
 
   // Print UUID header.
   const auto *ObjFile = DObj->getFile();
-  if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
-    outs() << ObjFile->getFileName() << ":\tfile format "
-           << ObjFile->getFileFormatName() << "\n\n";
   if (DumpType & DIDT_UUID)
     dumpUUID(OS, *ObjFile);
 
diff --git a/test/tools/llvm-dwarfdump/X86/archive.test b/test/tools/llvm-dwarfdump/X86/archive.test
new file mode 100644 (file)
index 0000000..d5e053f
--- /dev/null
@@ -0,0 +1,5 @@
+RUN: llvm-dwarfdump --debug-info %S/../../dsymutil/Inputs/libfat-test.a | FileCheck %s
+CHECK: libfat-test.a(x86_64)(fat-test.o):        file format Mach-O 64-bit x86-64
+CHECK: .debug_info contents:
+CHECK: libfat-test.a(i386)(fat-test.o):  file format Mach-O 32-bit i386
+CHECK: .debug_info contents:
index 9bf8d0147a001d4c67df58ec351766d3f2553d71..823eb8e81334f5831319d77811d0e8b1b715a451 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Object/Archive.h"
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Object/RelocVisitor.h"
@@ -122,23 +123,52 @@ static bool verifyObjectFile(ObjectFile &Obj, Twine Filename) {
   return Result;
 }
 
+static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
+                         std::function<bool(ObjectFile &, Twine)> HandleObj);
+
+static bool handleArchive(StringRef Filename, Archive &Arch,
+                          std::function<bool(ObjectFile &, Twine)> HandleObj) {
+  bool Result = true;
+  Error Err = Error::success();
+  for (auto Child : Arch.children(Err)) {
+    auto BuffOrErr = Child.getMemoryBufferRef();
+    error(Filename, errorToErrorCode(BuffOrErr.takeError()));
+    auto NameOrErr = Child.getName();
+    error(Filename, errorToErrorCode(NameOrErr.takeError()));
+    std::string Name = (Filename + "(" + NameOrErr.get() + ")").str();
+    Result &= handleBuffer(Name, BuffOrErr.get(), HandleObj);
+  }
+  error(Filename, errorToErrorCode(std::move(Err)));
+
+  return Result;
+}
+
 static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
                          std::function<bool(ObjectFile &, Twine)> HandleObj) {
   Expected<std::unique_ptr<Binary>> BinOrErr = object::createBinary(Buffer);
-  if (!BinOrErr)
-    error(Filename, errorToErrorCode(BinOrErr.takeError()));
+  error(Filename, errorToErrorCode(BinOrErr.takeError()));
 
   bool Result = true;
   if (auto *Obj = dyn_cast<ObjectFile>(BinOrErr->get()))
     Result = HandleObj(*Obj, Filename);
   else if (auto *Fat = dyn_cast<MachOUniversalBinary>(BinOrErr->get()))
     for (auto &ObjForArch : Fat->objects()) {
-      auto MachOOrErr = ObjForArch.getAsObjectFile();
-      error(Filename, errorToErrorCode(MachOOrErr.takeError()));
-      if (!HandleObj(**MachOOrErr,
-                     Filename + " (" + ObjForArch.getArchFlagName() + ")"))
-        Result = false;
+      std::string ObjName =
+          (Filename + "(" + ObjForArch.getArchFlagName() + ")").str();
+      if (auto MachOOrErr = ObjForArch.getAsObjectFile()) {
+        Result &= HandleObj(**MachOOrErr, ObjName);
+        continue;
+      } else
+        consumeError(MachOOrErr.takeError());
+      if (auto ArchiveOrErr = ObjForArch.getAsArchive()) {
+        error(ObjName, errorToErrorCode(ArchiveOrErr.takeError()));
+        Result &= handleArchive(ObjName, *ArchiveOrErr.get(), HandleObj);
+        continue;
+      } else
+        consumeError(ArchiveOrErr.takeError());
     }
+  else if (auto *Arch = dyn_cast<Archive>(BinOrErr->get()))
+    Result = handleArchive(Filename, *Arch, HandleObj);
   return Result;
 }