OSDN Git Service

[llvm-objdump] Add --archive-headers (-a) option
authorPaul Semel <semelpaul@gmail.com>
Thu, 5 Jul 2018 14:43:29 +0000 (14:43 +0000)
committerPaul Semel <semelpaul@gmail.com>
Thu, 5 Jul 2018 14:43:29 +0000 (14:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336357 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/llvm-objdump/Inputs/liblong_filenames.a [new file with mode: 0644]
test/tools/llvm-objdump/archive-headers-disas.test [new file with mode: 0644]
test/tools/llvm-objdump/archive-headers.test [new file with mode: 0644]
tools/llvm-objdump/MachODump.cpp
tools/llvm-objdump/llvm-objdump.cpp

diff --git a/test/tools/llvm-objdump/Inputs/liblong_filenames.a b/test/tools/llvm-objdump/Inputs/liblong_filenames.a
new file mode 100644 (file)
index 0000000..368d665
Binary files /dev/null and b/test/tools/llvm-objdump/Inputs/liblong_filenames.a differ
diff --git a/test/tools/llvm-objdump/archive-headers-disas.test b/test/tools/llvm-objdump/archive-headers-disas.test
new file mode 100644 (file)
index 0000000..3b2a5cb
--- /dev/null
@@ -0,0 +1,29 @@
+# RUN: llvm-objdump -a -d %p/Inputs/liblong_filenames.a | FileCheck %s
+
+# CHECK: {{.*}}liblong_filenames.a(1.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200   1416 Tue Oct 30 15:33:29 2012 1.o
+# CHECK: Disassembly of section .text:
+
+# CHECK: {{.*}}liblong_filenames.a(2.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200   1224 Tue Oct 30 15:33:29 2012 2.o
+# CHECK: Disassembly of section .text:
+
+# CHECK: {{.*}}liblong_filenames.a(3.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200   1312 Tue Oct 30 15:33:29 2012 3.o
+# CHECK: Disassembly of section .text:
+
+# CHECK: {{.*}}liblong_filenames.a(4.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200    957 Tue Oct 30 15:33:29 2012 4.o
+# CHECK: {{.*}}liblong_filenames.a(5.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200    951 Tue Oct 30 15:33:29 2012 5.o
+# CHECK: {{.*}}liblong_filenames.a(6.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200    951 Tue Oct 30 15:33:29 2012 6.o
+# CHECK: {{.*}}liblong_filenames.a(abcdefghijklmnopqrstuvwxyz1.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200    977 Tue Oct 30 15:33:29 2012 abcdefghijklmnopqrstuvwxyz1.o
+
+# CHECK: {{.*}}liblong_filenames.a(abcdefghijklmnopqrstuvwxyz2.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200   1272 Tue Oct 30 15:33:29 2012 abcdefghijklmnopqrstuvwxyz2.o
+# CHECK: Disassembly of section .text:
+
+# CHECK: {{.*}}liblong_filenames.a(abcdefghijklmnopq.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200    977 Tue Oct 30 15:29:33 2012 abcdefghijklmnopq.o
diff --git a/test/tools/llvm-objdump/archive-headers.test b/test/tools/llvm-objdump/archive-headers.test
new file mode 100644 (file)
index 0000000..9724f46
--- /dev/null
@@ -0,0 +1,21 @@
+# RUN: llvm-objdump -a %p/Inputs/liblong_filenames.a | FileCheck %s
+# RUN: llvm-objdump -archive-headers %p/Inputs/liblong_filenames.a | FileCheck %s
+
+# CHECK: {{.*}}liblong_filenames.a(1.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200  1416 Tue Oct 30 15:33:29 2012 1.o
+# CHECK: {{.*}}liblong_filenames.a(2.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200  1224 Tue Oct 30 15:33:29 2012 2.o
+# CHECK: {{.*}}liblong_filenames.a(3.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200  1312 Tue Oct 30 15:33:29 2012 3.o
+# CHECK: {{.*}}liblong_filenames.a(4.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200   957 Tue Oct 30 15:33:29 2012 4.o
+# CHECK: {{.*}}liblong_filenames.a(5.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200   951 Tue Oct 30 15:33:29 2012 5.o
+# CHECK: {{.*}}liblong_filenames.a(6.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200   951 Tue Oct 30 15:33:29 2012 6.o
+# CHECK: {{.*}}liblong_filenames.a(abcdefghijklmnopqrstuvwxyz1.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200   977 Tue Oct 30 15:33:29 2012 abcdefghijklmnopqrstuvwxyz1.o
+# CHECK: {{.*}}liblong_filenames.a(abcdefghijklmnopqrstuvwxyz2.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200  1272 Tue Oct 30 15:33:29 2012 abcdefghijklmnopqrstuvwxyz2.o
+# CHECK: {{.*}}liblong_filenames.a(abcdefghijklmnopq.o): file format ELF64-x86-64
+# CHECK: rw-r--r-- 204299/200   977 Tue Oct 30 15:29:33 2012 abcdefghijklmnopq.o
index 7e4f996..e7a1f47 100644 (file)
@@ -76,11 +76,6 @@ cl::opt<bool> llvm::UniversalHeaders("universal-headers",
                                               "(requires -macho)"));
 
 cl::opt<bool>
-    llvm::ArchiveHeaders("archive-headers",
-                         cl::desc("Print archive headers for Mach-O archives "
-                                  "(requires -macho)"));
-
-cl::opt<bool>
     ArchiveMemberOffsets("archive-member-offsets",
                          cl::desc("Print the offset to each archive member for "
                                   "Mach-O archives (requires -macho and "
index e639fd9..d1a765b 100644 (file)
@@ -208,6 +208,14 @@ static cl::alias FileHeadersShort("f", cl::desc("Alias for --file-headers"),
                                   cl::aliasopt(FileHeaders));
 
 cl::opt<bool>
+    llvm::ArchiveHeaders("archive-headers",
+                         cl::desc("Display archive header information"));
+
+cl::alias
+ArchiveHeadersShort("a", cl::desc("Alias for --archive-headers"),
+                    cl::aliasopt(ArchiveHeaders));
+
+cl::opt<bool>
     llvm::PrintImmHex("print-imm-hex",
                       cl::desc("Use hex format for immediate values"));
 
@@ -2144,7 +2152,72 @@ static void printFileHeaders(const ObjectFile *o) {
          << "\n";
 }
 
-static void DumpObject(ObjectFile *o, const Archive *a = nullptr) {
+static void printArchiveChild(StringRef Filename, const Archive::Child &C) {
+  Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
+  if (!ModeOrErr) {
+    errs() << "ill-formed archive entry.\n";
+    consumeError(ModeOrErr.takeError());
+    return;
+  }
+  sys::fs::perms Mode = ModeOrErr.get();
+  outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
+  outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
+  outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
+  outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
+  outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
+  outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
+  outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
+  outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
+  outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
+
+  outs() << " ";
+
+  Expected<unsigned> UIDOrErr = C.getUID();
+  if (!UIDOrErr)
+    report_error(Filename, UIDOrErr.takeError());
+  unsigned UID = UIDOrErr.get();
+  outs() << format("%d/", UID);
+
+  Expected<unsigned> GIDOrErr = C.getGID();
+  if (!GIDOrErr)
+    report_error(Filename, GIDOrErr.takeError());
+  unsigned GID = GIDOrErr.get();
+  outs() << format("%-d ", GID);
+
+  Expected<uint64_t> Size = C.getRawSize();
+  if (!Size)
+    report_error(Filename, Size.takeError());
+  outs() << format("%6" PRId64, Size.get()) << " ";
+
+  StringRef RawLastModified = C.getRawLastModified();
+  unsigned Seconds;
+  if (RawLastModified.getAsInteger(10, Seconds))
+    outs() << "(date: \"" << RawLastModified
+           << "\" contains non-decimal chars) ";
+  else {
+    // Since ctime(3) returns a 26 character string of the form:
+    // "Sun Sep 16 01:03:52 1973\n\0"
+    // just print 24 characters.
+    time_t t = Seconds;
+    outs() << format("%.24s ", ctime(&t));
+  }
+
+  StringRef Name = "";
+  Expected<StringRef> NameOrErr = C.getName();
+  if (!NameOrErr) {
+    consumeError(NameOrErr.takeError());
+    Expected<StringRef> RawNameOrErr = C.getRawName();
+    if (!RawNameOrErr)
+      report_error(Filename, NameOrErr.takeError());
+    Name = RawNameOrErr.get();
+  } else {
+    Name = NameOrErr.get();
+  }
+  outs() << Name << "\n";
+}
+
+static void DumpObject(ObjectFile *o, const Archive *a = nullptr,
+                       const Archive::Child *c = nullptr) {
   StringRef ArchiveName = a != nullptr ? a->getFileName() : "";
   // Avoid other output when using a raw option.
   if (!RawClangAST) {
@@ -2156,6 +2229,8 @@ static void DumpObject(ObjectFile *o, const Archive *a = nullptr) {
     outs() << ":\tfile format " << o->getFileFormatName() << "\n\n";
   }
 
+  if (ArchiveHeaders && !MachOOpt)
+    printArchiveChild(a->getFileName(), *c);
   if (Disassemble)
     DisassembleObject(o, Relocations);
   if (Relocations && !Disassemble)
@@ -2197,7 +2272,8 @@ static void DumpObject(ObjectFile *o, const Archive *a = nullptr) {
   }
 }
 
-static void DumpObject(const COFFImportFile *I, const Archive *A) {
+static void DumpObject(const COFFImportFile *I, const Archive *A,
+                       const Archive::Child *C = nullptr) {
   StringRef ArchiveName = A ? A->getFileName() : "";
 
   // Avoid other output when using a raw option.
@@ -2207,6 +2283,8 @@ static void DumpObject(const COFFImportFile *I, const Archive *A) {
            << ":\tfile format COFF-import-file"
            << "\n\n";
 
+  if (ArchiveHeaders && !MachOOpt)
+    printArchiveChild(A->getFileName(), *C);
   if (SymbolTable)
     printCOFFSymbolTable(I);
 }
@@ -2222,9 +2300,9 @@ static void DumpArchive(const Archive *a) {
       continue;
     }
     if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
-      DumpObject(o, a);
+      DumpObject(o, a, &C);
     else if (COFFImportFile *I = dyn_cast<COFFImportFile>(&*ChildOrErr.get()))
-      DumpObject(I, a);
+      DumpObject(I, a, &C);
     else
       report_error(a->getFileName(), object_error::invalid_file_type);
   }
@@ -2299,7 +2377,7 @@ int main(int argc, char **argv) {
       && !WeakBind
       && !RawClangAST
       && !(UniversalHeaders && MachOOpt)
-      && !(ArchiveHeaders && MachOOpt)
+      && !ArchiveHeaders
       && !(IndirectSymbols && MachOOpt)
       && !(DataInCode && MachOOpt)
       && !(LinkOptHints && MachOOpt)