Adds the next bit of support for llvm-objdump’s -private-headers for executable Mach...
authorKevin Enderby <enderby@apple.com>
Thu, 4 Sep 2014 16:54:47 +0000 (16:54 +0000)
committerKevin Enderby <enderby@apple.com>
Thu, 4 Sep 2014 16:54:47 +0000 (16:54 +0000)
This adds the printing of more load commands, so that the normal load commands
in a typical X86 Mach-O executable can all be printed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217172 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/MachO.h
include/llvm/Support/MachO.h
lib/Object/MachOObjectFile.cpp
test/MC/MachO/ARM/ios-version-min-load-command.s
test/MC/MachO/osx-version-min-load-command.s
test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-x86_64 [new file with mode: 0755]
test/tools/llvm-objdump/X86/macho-private-headers.test
tools/llvm-objdump/MachODump.cpp
tools/macho-dump/macho-dump.cpp

index 4ad1555e54a049209d5a6867b7a55d2a87c174c0..dddc9c1c8c650501fdb0e423bffac37fbbf7e29b 100644 (file)
@@ -251,6 +251,16 @@ public:
   getVersionMinLoadCommand(const LoadCommandInfo &L) const;
   MachO::dylib_command
   getDylibIDLoadCommand(const LoadCommandInfo &L) const;
+  MachO::dyld_info_command
+  getDyldInfoLoadCommand(const LoadCommandInfo &L) const;
+  MachO::dylinker_command
+  getDylinkerCommand(const LoadCommandInfo &L) const;
+  MachO::uuid_command
+  getUuidCommand(const LoadCommandInfo &L) const;
+  MachO::source_version_command
+  getSourceVersionCommand(const LoadCommandInfo &L) const;
+  MachO::entry_point_command
+  getEntryPointCommand(const LoadCommandInfo &L) const;
 
   MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
   MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
index c9070b2db965bd7d406dd1492faac8bd49e882e1..c07bd88af403fc14b521047edda997dcf02be92d 100644 (file)
@@ -847,7 +847,7 @@ namespace llvm {
                           // LC_VERSION_MIN_IPHONEOS
       uint32_t cmdsize;   // sizeof(struct version_min_command)
       uint32_t version;   // X.Y.Z is encoded in nibbles xxxx.yy.zz
-      uint32_t reserved;
+      uint32_t sdk;       // X.Y.Z is encoded in nibbles xxxx.yy.zz
     };
 
     struct dyld_info_command {
@@ -1104,6 +1104,17 @@ namespace llvm {
       sys::swapByteOrder(d.name);
     }
 
+    inline void swapStruct(uuid_command &u) {
+      sys::swapByteOrder(u.cmd);
+      sys::swapByteOrder(u.cmdsize);
+    }
+
+    inline void swapStruct(source_version_command &s) {
+      sys::swapByteOrder(s.cmd);
+      sys::swapByteOrder(s.cmdsize);
+      sys::swapByteOrder(s.version);
+    }
+
     inline void swapStruct(entry_point_command &e) {
       sys::swapByteOrder(e.cmd);
       sys::swapByteOrder(e.cmdsize);
@@ -1173,7 +1184,7 @@ namespace llvm {
       sys::swapByteOrder(C.cmd);
       sys::swapByteOrder(C.cmdsize);
       sys::swapByteOrder(C.version);
-      sys::swapByteOrder(C.reserved);
+      sys::swapByteOrder(C.sdk);
     }
 
     inline void swapStruct(data_in_code_entry &C) {
index fbdc0a6c91cba63d0ce71baffbca7b5b344319e9..c6815ea27d24cfd02f8289a5a872cfc10c6cf2b5 100644 (file)
@@ -1861,6 +1861,31 @@ MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
   return getStruct<MachO::dylib_command>(this, L.Ptr);
 }
 
+MachO::dyld_info_command
+MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const {
+  return getStruct<MachO::dyld_info_command>(this, L.Ptr);
+}
+
+MachO::dylinker_command
+MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const {
+  return getStruct<MachO::dylinker_command>(this, L.Ptr);
+}
+
+MachO::uuid_command
+MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const {
+  return getStruct<MachO::uuid_command>(this, L.Ptr);
+}
+
+MachO::source_version_command
+MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const {
+  return getStruct<MachO::source_version_command>(this, L.Ptr);
+}
+
+MachO::entry_point_command
+MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const {
+  return getStruct<MachO::entry_point_command>(this, L.Ptr);
+}
+
 
 MachO::any_relocation_info
 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
index e065d147be76a4a84b3976c5d8b72457136eb8a5..9f63c9bd27c7ca869de43b2597483f42f63b1265 100644 (file)
@@ -6,5 +6,5 @@
 // CHECK:  (('command', 37)
 // CHECK:   ('size', 16)
 // CHECK:   ('version, 6490119)
-// CHECK:   ('reserved, 0)
+// CHECK:   ('sdk, 0)
 // CHECK:  ),
index 2a73609dc0126ed889bbeb5316d5adfd8ecb350d..cb62565cef9a50d72d846e2ada3464a33f82e9b5 100644 (file)
@@ -6,5 +6,5 @@
 // CHECK:  (('command', 36)
 // CHECK:   ('size', 16)
 // CHECK:   ('version, 1639169)
-// CHECK:   ('reserved, 0)
+// CHECK:   ('sdk, 0)
 // CHECK:  ),
diff --git a/test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-x86_64 b/test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-x86_64
new file mode 100755 (executable)
index 0000000..d004bed
Binary files /dev/null and b/test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-x86_64 differ
index b1881903e7c0295940ccbdd478c03d53a424f1b4..e694a526e075f7a320553a5e059fab8798172982 100644 (file)
@@ -1,4 +1,6 @@
 // RUN: llvm-objdump -p %p/Inputs/hello.obj.macho-x86_64 | FileCheck %s
+// RUN: llvm-objdump -p %p/Inputs/hello.exe.macho-x86_64 \
+// RUN:     | FileCheck %s -check-prefix=EXE
 
 CHECK: Mach header
 CHECK:       magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
@@ -95,3 +97,244 @@ CHECK:       extreloff 0
 CHECK:         nextrel 0
 CHECK:       locreloff 0
 CHECK:         nlocrel 0
+
+EXE: Mach header
+EXE:       magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
+EXE: MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    16       1296   NOUNDEFS DYLDLINK TWOLEVEL PIE
+EXE: Load command 0
+EXE:       cmd LC_SEGMENT_64
+EXE:   cmdsize 72
+EXE:   segname __PAGEZERO
+EXE:    vmaddr 0x0000000000000000
+EXE:    vmsize 0x0000000100000000
+EXE:   fileoff 0
+EXE:  filesize 0
+EXE:   maxprot ---
+EXE:  initprot ---
+EXE:    nsects 0
+EXE:     flags (none)
+EXE: Load command 1
+EXE:       cmd LC_SEGMENT_64
+EXE:   cmdsize 552
+EXE:   segname __TEXT
+EXE:    vmaddr 0x0000000100000000
+EXE:    vmsize 0x0000000000001000
+EXE:   fileoff 0
+EXE:  filesize 4096
+EXE:   maxprot rwx
+EXE:  initprot r-x
+EXE:    nsects 6
+EXE:     flags (none)
+EXE: Section
+EXE:   sectname __text
+EXE:    segname __TEXT
+EXE:       addr 0x0000000100000f30
+EXE:       size 0x000000000000003b
+EXE:     offset 3888
+EXE:      align 2^4 (16)
+EXE:     reloff 0
+EXE:     nreloc 0
+EXE:       type S_REGULAR
+EXE: attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
+EXE:  reserved1 0
+EXE:  reserved2 0
+EXE: Section
+EXE:   sectname __stubs
+EXE:    segname __TEXT
+EXE:       addr 0x0000000100000f6c
+EXE:       size 0x0000000000000006
+EXE:     offset 3948
+EXE:      align 2^1 (2)
+EXE:     reloff 0
+EXE:     nreloc 0
+EXE:       type S_SYMBOL_STUBS
+EXE: attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
+EXE:  reserved1 0 (index into indirect symbol table)
+EXE:  reserved2 6 (size of stubs)
+EXE: Section
+EXE:   sectname __stub_helper
+EXE:    segname __TEXT
+EXE:       addr 0x0000000100000f74
+EXE:       size 0x000000000000001a
+EXE:     offset 3956
+EXE:      align 2^2 (4)
+EXE:     reloff 0
+EXE:     nreloc 0
+EXE:       type S_REGULAR
+EXE: attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
+EXE:  reserved1 0
+EXE:  reserved2 0
+EXE: Section
+EXE:   sectname __cstring
+EXE:    segname __TEXT
+EXE:       addr 0x0000000100000f8e
+EXE:       size 0x000000000000000d
+EXE:     offset 3982
+EXE:      align 2^0 (1)
+EXE:     reloff 0
+EXE:     nreloc 0
+EXE:       type S_CSTRING_LITERALS
+EXE: attributes (none)
+EXE:  reserved1 0
+EXE:  reserved2 0
+EXE: Section
+EXE:   sectname __unwind_info
+EXE:    segname __TEXT
+EXE:       addr 0x0000000100000f9b
+EXE:       size 0x0000000000000048
+EXE:     offset 3995
+EXE:      align 2^0 (1)
+EXE:     reloff 0
+EXE:     nreloc 0
+EXE:       type S_REGULAR
+EXE: attributes (none)
+EXE:  reserved1 0
+EXE:  reserved2 0
+EXE: Section
+EXE:   sectname __eh_frame
+EXE:    segname __TEXT
+EXE:       addr 0x0000000100000fe8
+EXE:       size 0x0000000000000018
+EXE:     offset 4072
+EXE:      align 2^3 (8)
+EXE:     reloff 0
+EXE:     nreloc 0
+EXE:       type S_REGULAR
+EXE: attributes (none)
+EXE:  reserved1 0
+EXE:  reserved2 0
+EXE: Load command 2
+EXE:       cmd LC_SEGMENT_64
+EXE:   cmdsize 232
+EXE:   segname __DATA
+EXE:    vmaddr 0x0000000100001000
+EXE:    vmsize 0x0000000000001000
+EXE:   fileoff 4096
+EXE:  filesize 4096
+EXE:   maxprot rwx
+EXE:  initprot rw-
+EXE:    nsects 2
+EXE:     flags (none)
+EXE: Section
+EXE:   sectname __nl_symbol_ptr
+EXE:    segname __DATA
+EXE:       addr 0x0000000100001000
+EXE:       size 0x0000000000000010
+EXE:     offset 4096
+EXE:      align 2^3 (8)
+EXE:     reloff 0
+EXE:     nreloc 0
+EXE:       type S_NON_LAZY_SYMBOL_POINTERS
+EXE: attributes (none)
+EXE:  reserved1 1 (index into indirect symbol table)
+EXE:  reserved2 0
+EXE: Section
+EXE:   sectname __la_symbol_ptr
+EXE:    segname __DATA
+EXE:       addr 0x0000000100001010
+EXE:       size 0x0000000000000008
+EXE:     offset 4112
+EXE:      align 2^3 (8)
+EXE:     reloff 0
+EXE:     nreloc 0
+EXE:       type S_LAZY_SYMBOL_POINTERS
+EXE: attributes (none)
+EXE:  reserved1 3 (index into indirect symbol table)
+EXE:  reserved2 0
+EXE: Load command 3
+EXE:       cmd LC_SEGMENT_64
+EXE:   cmdsize 72
+EXE:   segname __LINKEDIT
+EXE:    vmaddr 0x0000000100002000
+EXE:    vmsize 0x0000000000001000
+EXE:   fileoff 8192
+EXE:  filesize 304
+EXE:   maxprot rwx
+EXE:  initprot r--
+EXE:    nsects 0
+EXE:     flags (none)
+EXE: Load command 4
+EXE:             cmd LC_DYLD_INFO_ONLY
+EXE:         cmdsize 48
+EXE:      rebase_off 8192
+EXE:     rebase_size 8
+EXE:        bind_off 8200
+EXE:       bind_size 24
+EXE:   weak_bind_off 0
+EXE:  weak_bind_size 0
+EXE:   lazy_bind_off 8224
+EXE:  lazy_bind_size 16
+EXE:      export_off 8240
+EXE:     export_size 48
+EXE: Load command 5
+EXE:      cmd LC_SYMTAB
+EXE:  cmdsize 24
+EXE:   symoff 8360
+EXE:    nsyms 4
+EXE:   stroff 8440
+EXE:  strsize 56
+EXE: Load command 6
+EXE:             cmd LC_DYSYMTAB
+EXE:         cmdsize 80
+EXE:       ilocalsym 0
+EXE:       nlocalsym 0
+EXE:      iextdefsym 0
+EXE:      nextdefsym 2
+EXE:       iundefsym 2
+EXE:       nundefsym 2
+EXE:          tocoff 0
+EXE:            ntoc 0
+EXE:       modtaboff 0
+EXE:         nmodtab 0
+EXE:    extrefsymoff 0
+EXE:     nextrefsyms 0
+EXE:  indirectsymoff 8424
+EXE:   nindirectsyms 4
+EXE:       extreloff 0
+EXE:         nextrel 0
+EXE:       locreloff 0
+EXE:         nlocrel 0
+EXE: Load command 7
+EXE:           cmd LC_LOAD_DYLINKER
+EXE:       cmdsize 32
+EXE:          name /usr/lib/dyld (offset 12)
+EXE: Load command 8
+EXE:      cmd LC_UUID
+EXE:  cmdsize 24
+EXE:     uuid 65C2DD41-79B0-3B34-871B-8CB3446AB762
+EXE: Load command 9
+EXE:       cmd LC_VERSION_MIN_MACOSX
+EXE:   cmdsize 16
+EXE:   version 10.9
+EXE:       sdk 10.9
+EXE: Load command 10
+EXE:       cmd LC_SOURCE_VERSION
+EXE:   cmdsize 16
+EXE:   version 0.0
+EXE: Load command 11
+EXE:        cmd LC_MAIN
+EXE:    cmdsize 24
+EXE:   entryoff 3888
+EXE:  stacksize 0
+EXE: Load command 12
+EXE:           cmd LC_LOAD_DYLIB
+EXE:       cmdsize 56
+EXE:          name /usr/lib/libSystem.B.dylib (offset 24)
+EXE:    time stamp 2 Wed Dec 31 16:00:02 1969
+EXE:       current version 1197.1.1
+EXE: compatibility version 1.0.0
+EXE: Load command 13
+EXE:       cmd LC_FUNCTION_STARTS
+EXE:   cmdsize 16
+EXE:   dataoff 8288
+EXE:  datasize 8
+EXE: Load command 14
+EXE:       cmd LC_DATA_IN_CODE
+EXE:   cmdsize 16
+EXE:   dataoff 8296
+EXE:  datasize 0
+EXE: Load command 15
+EXE:       cmd LC_DYLIB_CODE_SIGN_DRS
+EXE:   cmdsize 16
+EXE:   dataoff 8296
+EXE:  datasize 64
index 139311ade21c3848f373806debc4c63afcbf2234..18492142240ae5fb8a304c48d0c0d19005cce244 100644 (file)
@@ -1112,7 +1112,7 @@ static void PrintMachHeader(uint32_t magic, uint32_t cputype,
       break;
     }
     if ((cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64) {
-      outs() << " LIB64 ";
+      outs() << " LIB64";
     } else {
       outs() << format("  0x%02" PRIx32,
                        (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
@@ -1696,6 +1696,275 @@ static void PrintDysymtabLoadCommand(MachO::dysymtab_command dyst,
     outs() << "\n";
 }
 
+static void PrintDyldInfoLoadCommand(MachO::dyld_info_command dc,
+                                     uint32_t object_size) {
+  if (dc.cmd == MachO::LC_DYLD_INFO)
+    outs() << "            cmd LC_DYLD_INFO\n";
+  else
+    outs() << "            cmd LC_DYLD_INFO_ONLY\n";
+  outs() << "        cmdsize " << dc.cmdsize;
+  if (dc.cmdsize != sizeof(struct MachO::dyld_info_command))
+    outs() << " Incorrect size\n";
+  else
+    outs() << "\n";
+  outs() << "     rebase_off " << dc.rebase_off;
+  if (dc.rebase_off > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << "    rebase_size " << dc.rebase_size;
+  uint64_t big_size;
+  big_size = dc.rebase_off;
+  big_size += dc.rebase_size;
+  if (big_size > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << "       bind_off " << dc.bind_off;
+  if (dc.bind_off > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << "      bind_size " << dc.bind_size;
+  big_size = dc.bind_off;
+  big_size += dc.bind_size;
+  if (big_size > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << "  weak_bind_off " << dc.weak_bind_off;
+  if (dc.weak_bind_off > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << " weak_bind_size " << dc.weak_bind_size;
+  big_size = dc.weak_bind_off;
+  big_size += dc.weak_bind_size;
+  if (big_size > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << "  lazy_bind_off " << dc.lazy_bind_off;
+  if (dc.lazy_bind_off > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << " lazy_bind_size " << dc.lazy_bind_size;
+  big_size = dc.lazy_bind_off;
+  big_size += dc.lazy_bind_size;
+  if (big_size > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << "     export_off " << dc.export_off;
+  if (dc.export_off > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << "    export_size " << dc.export_size;
+  big_size = dc.export_off;
+  big_size += dc.export_size;
+  if (big_size > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+}
+
+static void PrintDyldLoadCommand(MachO::dylinker_command dyld,
+                                 const char *Ptr) {
+  if (dyld.cmd == MachO::LC_ID_DYLINKER)
+    outs() << "          cmd LC_ID_DYLINKER\n";
+  else if (dyld.cmd == MachO::LC_LOAD_DYLINKER)
+    outs() << "          cmd LC_LOAD_DYLINKER\n";
+  else if (dyld.cmd == MachO::LC_DYLD_ENVIRONMENT)
+    outs() << "          cmd LC_DYLD_ENVIRONMENT\n";
+  else
+    outs() << "          cmd ?(" << dyld.cmd << ")\n";
+  outs() << "      cmdsize " << dyld.cmdsize;
+  if (dyld.cmdsize < sizeof(struct MachO::dylinker_command))
+    outs() << " Incorrect size\n";
+  else
+    outs() << "\n";
+  if (dyld.name >= dyld.cmdsize)
+    outs() << "         name ?(bad offset " << dyld.name << ")\n";
+  else {
+    const char *P = (const char *)(Ptr)+dyld.name;
+    outs() << "         name " << P << " (offset " << dyld.name << ")\n";
+  }
+}
+
+static void PrintUuidLoadCommand(MachO::uuid_command uuid) {
+  outs() << "     cmd LC_UUID\n";
+  outs() << " cmdsize " << uuid.cmdsize;
+  if (uuid.cmdsize != sizeof(struct MachO::uuid_command))
+    outs() << " Incorrect size\n";
+  else
+    outs() << "\n";
+  outs() << "    uuid ";
+  outs() << format("%02" PRIX32, uuid.uuid[0]);
+  outs() << format("%02" PRIX32, uuid.uuid[1]);
+  outs() << format("%02" PRIX32, uuid.uuid[2]);
+  outs() << format("%02" PRIX32, uuid.uuid[3]);
+  outs() << "-";
+  outs() << format("%02" PRIX32, uuid.uuid[4]);
+  outs() << format("%02" PRIX32, uuid.uuid[5]);
+  outs() << "-";
+  outs() << format("%02" PRIX32, uuid.uuid[6]);
+  outs() << format("%02" PRIX32, uuid.uuid[7]);
+  outs() << "-";
+  outs() << format("%02" PRIX32, uuid.uuid[8]);
+  outs() << format("%02" PRIX32, uuid.uuid[9]);
+  outs() << "-";
+  outs() << format("%02" PRIX32, uuid.uuid[10]);
+  outs() << format("%02" PRIX32, uuid.uuid[11]);
+  outs() << format("%02" PRIX32, uuid.uuid[12]);
+  outs() << format("%02" PRIX32, uuid.uuid[13]);
+  outs() << format("%02" PRIX32, uuid.uuid[14]);
+  outs() << format("%02" PRIX32, uuid.uuid[15]);
+  outs() << "\n";
+}
+
+static void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
+  if (vd.cmd == MachO::LC_VERSION_MIN_MACOSX)
+    outs() << "      cmd LC_VERSION_MIN_MACOSX\n";
+  else if (vd.cmd == MachO::LC_VERSION_MIN_IPHONEOS)
+    outs() << "      cmd LC_VERSION_MIN_IPHONEOS\n";
+  else
+    outs() << "      cmd " << vd.cmd << " (?)\n";
+  outs() << "  cmdsize " << vd.cmdsize;
+  if (vd.cmdsize != sizeof(struct MachO::version_min_command))
+    outs() << " Incorrect size\n";
+  else
+    outs() << "\n";
+  outs() << "  version " << ((vd.version >> 16) & 0xffff) << "."
+         << ((vd.version >> 8) & 0xff);
+  if ((vd.version & 0xff) != 0)
+    outs() << "." << (vd.version & 0xff);
+  outs() << "\n";
+  if (vd.sdk == 0)
+    outs() << "      sdk n/a\n";
+  else {
+    outs() << "      sdk " << ((vd.sdk >> 16) & 0xffff) << "."
+           << ((vd.sdk >> 8) & 0xff);
+  }
+  if ((vd.sdk & 0xff) != 0)
+    outs() << "." << (vd.sdk & 0xff);
+  outs() << "\n";
+}
+
+static void PrintSourceVersionCommand(MachO::source_version_command sd) {
+  outs() << "      cmd LC_SOURCE_VERSION\n";
+  outs() << "  cmdsize " << sd.cmdsize;
+  if (sd.cmdsize != sizeof(struct MachO::source_version_command))
+    outs() << " Incorrect size\n";
+  else
+    outs() << "\n";
+  uint64_t a = (sd.version >> 40) & 0xffffff;
+  uint64_t b = (sd.version >> 30) & 0x3ff;
+  uint64_t c = (sd.version >> 20) & 0x3ff;
+  uint64_t d = (sd.version >> 10) & 0x3ff;
+  uint64_t e = sd.version & 0x3ff;
+  outs() << "  version " << a << "." << b;
+  if (e != 0)
+    outs() << "." << c << "." << d << "." << e;
+  else if (d != 0)
+    outs() << "." << c << "." << d;
+  else if (c != 0)
+    outs() << "." << c;
+  outs() << "\n";
+}
+
+static void PrintEntryPointCommand(MachO::entry_point_command ep) {
+  outs() << "       cmd LC_MAIN\n";
+  outs() << "   cmdsize " << ep.cmdsize;
+  if (ep.cmdsize != sizeof(struct MachO::entry_point_command))
+    outs() << " Incorrect size\n";
+  else
+    outs() << "\n";
+  outs() << "  entryoff " << ep.entryoff << "\n";
+  outs() << " stacksize " << ep.stacksize << "\n";
+}
+
+static void PrintDylibCommand(MachO::dylib_command dl, const char *Ptr) {
+  if (dl.cmd == MachO::LC_ID_DYLIB)
+    outs() << "          cmd LC_ID_DYLIB\n";
+  else if (dl.cmd == MachO::LC_LOAD_DYLIB)
+    outs() << "          cmd LC_LOAD_DYLIB\n";
+  else if (dl.cmd == MachO::LC_LOAD_WEAK_DYLIB)
+    outs() << "          cmd LC_LOAD_WEAK_DYLIB\n";
+  else if (dl.cmd == MachO::LC_REEXPORT_DYLIB)
+    outs() << "          cmd LC_REEXPORT_DYLIB\n";
+  else if (dl.cmd == MachO::LC_LAZY_LOAD_DYLIB)
+    outs() << "          cmd LC_LAZY_LOAD_DYLIB\n";
+  else if (dl.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
+    outs() << "          cmd LC_LOAD_UPWARD_DYLIB\n";
+  else
+    outs() << "          cmd " << dl.cmd << " (unknown)\n";
+  outs() << "      cmdsize " << dl.cmdsize;
+  if (dl.cmdsize < sizeof(struct MachO::dylib_command))
+    outs() << " Incorrect size\n";
+  else
+    outs() << "\n";
+  if (dl.dylib.name < dl.cmdsize) {
+    const char *P = (const char *)(Ptr)+dl.dylib.name;
+    outs() << "         name " << P << " (offset " << dl.dylib.name << ")\n";
+  } else {
+    outs() << "         name ?(bad offset " << dl.dylib.name << ")\n";
+  }
+  outs() << "   time stamp " << dl.dylib.timestamp << " ";
+  time_t t = dl.dylib.timestamp;
+  outs() << ctime(&t);
+  outs() << "      current version ";
+  if (dl.dylib.current_version == 0xffffffff)
+    outs() << "n/a\n";
+  else
+    outs() << ((dl.dylib.current_version >> 16) & 0xffff) << "."
+           << ((dl.dylib.current_version >> 8) & 0xff) << "."
+           << (dl.dylib.current_version & 0xff) << "\n";
+  outs() << "compatibility version ";
+  if (dl.dylib.compatibility_version == 0xffffffff)
+    outs() << "n/a\n";
+  else
+    outs() << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
+           << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
+           << (dl.dylib.compatibility_version & 0xff) << "\n";
+}
+
+static void PrintLinkEditDataCommand(MachO::linkedit_data_command ld,
+                                     uint32_t object_size) {
+  if (ld.cmd == MachO::LC_CODE_SIGNATURE)
+    outs() << "      cmd LC_FUNCTION_STARTS\n";
+  else if (ld.cmd == MachO::LC_SEGMENT_SPLIT_INFO)
+    outs() << "      cmd LC_SEGMENT_SPLIT_INFO\n";
+  else if (ld.cmd == MachO::LC_FUNCTION_STARTS)
+    outs() << "      cmd LC_FUNCTION_STARTS\n";
+  else if (ld.cmd == MachO::LC_DATA_IN_CODE)
+    outs() << "      cmd LC_DATA_IN_CODE\n";
+  else if (ld.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS)
+    outs() << "      cmd LC_DYLIB_CODE_SIGN_DRS\n";
+  else if (ld.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT)
+    outs() << "      cmd LC_LINKER_OPTIMIZATION_HINT\n";
+  else
+    outs() << "      cmd " << ld.cmd << " (?)\n";
+  outs() << "  cmdsize " << ld.cmdsize;
+  if (ld.cmdsize != sizeof(struct MachO::linkedit_data_command))
+    outs() << " Incorrect size\n";
+  else
+    outs() << "\n";
+  outs() << "  dataoff " << ld.dataoff;
+  if (ld.dataoff > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+  outs() << " datasize " << ld.datasize;
+  uint64_t big_size = ld.dataoff;
+  big_size += ld.datasize;
+  if (big_size > object_size)
+    outs() << " (past end of file)\n";
+  else
+    outs() << "\n";
+}
+
 static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t ncmds,
                               uint32_t filetype, uint32_t cputype,
                               bool verbose) {
@@ -1737,6 +2006,39 @@ static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t ncmds,
       MachO::dysymtab_command Dysymtab = Obj->getDysymtabLoadCommand();
       MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
       PrintDysymtabLoadCommand(Dysymtab, Symtab.nsyms, Buf.size(), cputype);
+    } else if (Command.C.cmd == MachO::LC_DYLD_INFO ||
+               Command.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
+      MachO::dyld_info_command DyldInfo = Obj->getDyldInfoLoadCommand(Command);
+      PrintDyldInfoLoadCommand(DyldInfo, Buf.size());
+    } else if (Command.C.cmd == MachO::LC_LOAD_DYLINKER ||
+               Command.C.cmd == MachO::LC_ID_DYLINKER ||
+               Command.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
+      MachO::dylinker_command Dyld = Obj->getDylinkerCommand(Command);
+      PrintDyldLoadCommand(Dyld, Command.Ptr);
+    } else if (Command.C.cmd == MachO::LC_UUID) {
+      MachO::uuid_command Uuid = Obj->getUuidCommand(Command);
+      PrintUuidLoadCommand(Uuid);
+    } else if (Command.C.cmd == MachO::LC_VERSION_MIN_MACOSX) {
+      MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
+      PrintVersionMinLoadCommand(Vd);
+    } else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
+      MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
+      PrintSourceVersionCommand(Sd);
+    } else if (Command.C.cmd == MachO::LC_MAIN) {
+      MachO::entry_point_command Ep = Obj->getEntryPointCommand(Command);
+      PrintEntryPointCommand(Ep);
+    } else if (Command.C.cmd == MachO::LC_LOAD_DYLIB) {
+      MachO::dylib_command Dl = Obj->getDylibIDLoadCommand(Command);
+      PrintDylibCommand(Dl, Command.Ptr);
+    } else if (Command.C.cmd == MachO::LC_CODE_SIGNATURE ||
+               Command.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO ||
+               Command.C.cmd == MachO::LC_FUNCTION_STARTS ||
+               Command.C.cmd == MachO::LC_DATA_IN_CODE ||
+               Command.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS ||
+               Command.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
+      MachO::linkedit_data_command Ld =
+          Obj->getLinkeditDataLoadCommand(Command);
+      PrintLinkEditDataCommand(Ld, Buf.size());
     } else {
       outs() << "      cmd ?(" << format("0x%08" PRIx32, Command.C.cmd)
              << ")\n";
index a457a4bf8f10484063316a42cda4914805a051b4..aac720ddd59c7cbb14a2e7a34d588e9e38f23d6a 100644 (file)
@@ -324,7 +324,7 @@ DumpVersionMin(const MachOObjectFile &Obj,
                const MachOObjectFile::LoadCommandInfo &LCI) {
   MachO::version_min_command VMLC = Obj.getVersionMinLoadCommand(LCI);
   outs() << "  ('version, " << VMLC.version << ")\n"
-         << "  ('reserved, " << VMLC.reserved << ")\n";
+         << "  ('sdk, " << VMLC.sdk << ")\n";
   return 0;
 }