]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/od-macho.c
Two fixes in dwarf-mode.el
[thirdparty/binutils-gdb.git] / binutils / od-macho.c
index 31cce9dab3f77f264a0acb11401e20871972272e..938426806c530c9cf01093d54229e581dca17761 100644 (file)
@@ -1,5 +1,5 @@
 /* od-macho.c -- dump information about an Mach-O object file.
-   Copyright (C) 2011-2014 Free Software Foundation, Inc.
+   Copyright (C) 2011-2020 Free Software Foundation, Inc.
    Written by Tristan Gingold, Adacore.
 
    This file is part of GNU Binutils.
@@ -26,8 +26,9 @@
 #include "bfd.h"
 #include "objdump.h"
 #include "bucomm.h"
+#include "elfcomm.h"
+#include "dwarf.h"
 #include "bfdlink.h"
-#include "libbfd.h"
 #include "mach-o.h"
 #include "mach-o/external.h"
 #include "mach-o/codesign.h"
@@ -44,6 +45,8 @@
 #define OPT_COMPACT_UNWIND 7
 #define OPT_FUNCTION_STARTS 8
 #define OPT_DATA_IN_CODE 9
+#define OPT_TWOLEVEL_HINTS 10
+#define OPT_DYLD_INFO 11
 
 /* List of actions.  */
 static struct objdump_private_option options[] =
@@ -58,6 +61,8 @@ static struct objdump_private_option options[] =
     { "compact_unwind", 0 },
     { "function_starts", 0 },
     { "data_in_code", 0 },
+    { "twolevel_hints", 0 },
+    { "dyld_info", 0 },
     { NULL, 0 }
   };
 
@@ -78,6 +83,8 @@ For Mach-O files:\n\
   compact_unwind   Display compact unwinding info\n\
   function_starts  Display start address of functions\n\
   data_in_code     Display data in code entries\n\
+  twolevel_hints   Display the two-level namespace lookup hints table\n\
+  dyld_info        Display dyld information\n\
 "));
 }
 
@@ -100,7 +107,6 @@ static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
   { "arm", BFD_MACH_O_CPU_TYPE_ARM },
   { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
   { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
-  { "i860", BFD_MACH_O_CPU_TYPE_I860 },
   { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
   { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
   { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
@@ -149,6 +155,10 @@ static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
   { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
   { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
   { "pie", BFD_MACH_O_MH_PIE },
+  { "dead_strippable_dylib", BFD_MACH_O_MH_DEAD_STRIPPABLE_DYLIB },
+  { "has_tlv", BFD_MACH_O_MH_HAS_TLV_DESCRIPTORS },
+  { "no_heap_execution", BFD_MACH_O_MH_NO_HEAP_EXECUTION },
+  { "app_extension_safe", BFD_MACH_O_MH_APP_EXTENSION_SAFE },
   { NULL, 0}
 };
 
@@ -197,6 +207,15 @@ static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
   { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE},
   { "source_version", BFD_MACH_O_LC_SOURCE_VERSION},
   { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS},
+  { "encryption_info_64", BFD_MACH_O_LC_ENCRYPTION_INFO_64},
+  { "linker_options", BFD_MACH_O_LC_LINKER_OPTIONS},
+  { "linker_optimization_hint", BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT},
+  { "version_min_tvos", BFD_MACH_O_LC_VERSION_MIN_TVOS},
+  { "version_min_watchos", BFD_MACH_O_LC_VERSION_MIN_WATCHOS},
+  { "note", BFD_MACH_O_LC_NOTE},
+  { "build_version", BFD_MACH_O_LC_BUILD_VERSION},
+  { "exports_trie", BFD_MACH_O_LC_DYLD_EXPORTS_TRIE},
+  { "chained_fixups", BFD_MACH_O_LC_DYLD_CHAINED_FIXUPS},
   { NULL, 0}
 };
 
@@ -217,7 +236,25 @@ static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
   { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
   { NULL, 0 }
 };
-\f
+
+static const bfd_mach_o_xlat_name bfd_mach_o_platform_name[] =
+{
+  { "macos", BFD_MACH_O_PLATFORM_MACOS},
+  { "ios", BFD_MACH_O_PLATFORM_IOS},
+  { "tvos", BFD_MACH_O_PLATFORM_TVOS},
+  { "watchos", BFD_MACH_O_PLATFORM_WATCHOS},
+  { "bridgeos", BFD_MACH_O_PLATFORM_BRIDGEOS},
+  { NULL, 0 }
+};
+
+static const bfd_mach_o_xlat_name bfd_mach_o_tool_name[] =
+{
+  { "clang", BFD_MACH_O_TOOL_CLANG},
+  { "swift", BFD_MACH_O_TOOL_SWIFT},
+  { "ld", BFD_MACH_O_TOOL_LD},
+  { NULL, 0 }
+};
+
 static void
 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
                         unsigned long val)
@@ -246,6 +283,15 @@ bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
     printf ("-");
 }
 
+/* Print a bfd_uint64_t, using a platform independent style.  */
+
+static void
+printf_uint64 (bfd_uint64_t v)
+{
+  printf ("0x%08lx%08lx",
+         (unsigned long)((v >> 16) >> 16), (unsigned long)(v & 0xffffffffUL));
+}
+
 static const char *
 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
                              unsigned long val)
@@ -282,7 +328,7 @@ dump_header (bfd *abfd)
           h->filetype,
           bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
   printf (_(" ncmds     : %08lx (%lu)\n"), h->ncmds, h->ncmds);
-  printf (_(" sizeofcmds: %08lx\n"), h->sizeofcmds);
+  printf (_(" sizeofcmds: %08lx (%lu)\n"), h->sizeofcmds, h->sizeofcmds);
   printf (_(" flags     : %08lx ("), h->flags);
   bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
   fputs (_(")\n"), stdout);
@@ -302,22 +348,22 @@ static void
 dump_section_map (bfd *abfd)
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
-  unsigned int i;
+  bfd_mach_o_load_command *cmd;
   unsigned int sec_nbr = 0;
 
   fputs (_("Segments and Sections:\n"), stdout);
   fputs (_(" #: Segment name     Section name     Address\n"), stdout);
 
-  for (i = 0; i < mdata->header.ncmds; i++)
+  for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
     {
       bfd_mach_o_segment_command *seg;
       bfd_mach_o_section *sec;
 
-      if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
-         && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
+      if (cmd->type != BFD_MACH_O_LC_SEGMENT
+         && cmd->type != BFD_MACH_O_LC_SEGMENT_64)
        continue;
 
-      seg = &mdata->commands[i].command.segment;
+      seg = &cmd->command.segment;
 
       printf ("[Segment %-16s ", seg->segname);
       printf_vma (seg->vmaddr);
@@ -393,26 +439,26 @@ dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
   bfd_mach_o_segment_command *seg = &cmd->command.segment;
   bfd_mach_o_section *sec;
 
-  printf (" name: %s\n", *seg->segname ? seg->segname : "*none*");
-  printf ("    vmaddr: ");
+  printf ("     name: %16s", *seg->segname ? seg->segname : "*none*");
+  printf ("  nsects: %lu", seg->nsects);
+  printf ("  flags: %lx", seg->flags);
+  printf ("  initprot: ");
+  disp_segment_prot (seg->initprot);
+  printf ("  maxprot: ");
+  disp_segment_prot (seg->maxprot);
+  printf ("\n");
+  printf ("   vmaddr: ");
   printf_vma (seg->vmaddr);
   printf ("   vmsize: ");
   printf_vma  (seg->vmsize);
   printf ("\n");
-  printf ("   fileoff: ");
+  printf ("  fileoff: ");
   printf_vma (seg->fileoff);
   printf (" filesize: ");
   printf_vma ((bfd_vma)seg->filesize);
   printf (" endoff: ");
   printf_vma ((bfd_vma)(seg->fileoff + seg->filesize));
   printf ("\n");
-  printf ("   nsects: %lu", seg->nsects);
-  printf ("   flags: %lx", seg->flags);
-  printf ("   initprot: ");
-  disp_segment_prot (seg->initprot);
-  printf ("   maxprot: ");
-  disp_segment_prot (seg->maxprot);
-  printf ("\n");
   for (sec = seg->sect_head; sec != NULL; sec = sec->next)
     dump_section_header (abfd, sec);
 }
@@ -610,21 +656,365 @@ dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose)
 
 }
 
+static bfd_boolean
+load_and_dump (bfd *abfd, ufile_ptr off, unsigned int len,
+              void (*dump)(bfd *abfd, unsigned char *buf, unsigned int len,
+                           ufile_ptr off))
+{
+  unsigned char *buf;
+
+  if (len == 0)
+    return TRUE;
+
+  buf = xmalloc (len);
+
+  if (bfd_seek (abfd, off, SEEK_SET) == 0
+      && bfd_bread (buf, len, abfd) == len)
+    dump (abfd, buf, len, off);
+  else
+    return FALSE;
+
+  free (buf);
+  return TRUE;
+}
+
+static const bfd_mach_o_xlat_name bfd_mach_o_dyld_rebase_type_name[] =
+{
+  { "pointer",      BFD_MACH_O_REBASE_TYPE_POINTER },
+  { "text_abs32",   BFD_MACH_O_REBASE_TYPE_TEXT_ABSOLUTE32 },
+  { "text_pcrel32", BFD_MACH_O_REBASE_TYPE_TEXT_PCREL32 },
+  { NULL, 0 }
+};
+
+static void
+dump_dyld_info_rebase (bfd *abfd, unsigned char *buf, unsigned int len,
+                      ufile_ptr off ATTRIBUTE_UNUSED)
+{
+  unsigned int i;
+  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+  unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
+
+  for (i = 0; i < len; )
+    {
+      unsigned char b = buf[i++];
+      unsigned char imm = b & BFD_MACH_O_REBASE_IMMEDIATE_MASK;
+      bfd_vma leb;
+      unsigned int leblen;
+
+      printf ("   [0x%04x] 0x%02x: ", i, b);
+      switch (b & BFD_MACH_O_REBASE_OPCODE_MASK)
+       {
+       case BFD_MACH_O_REBASE_OPCODE_DONE:
+         printf ("done\n");
+         return;
+       case BFD_MACH_O_REBASE_OPCODE_SET_TYPE_IMM:
+         printf ("set_type %s\n",
+                 bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
+         break;
+       case BFD_MACH_O_REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("set segment: %u and offset: 0x%08x\n",
+                 imm, (unsigned) leb);
+         i += leblen;
+         break;
+       case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_ULEB:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
+         i += leblen;
+         break;
+       case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
+         printf ("add addr imm scaled: %u\n", imm * ptrsize);
+         break;
+       case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_IMM_TIMES:
+         printf ("rebase imm times: %u\n", imm);
+         break;
+       case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("rebase uleb times: %u\n", (unsigned) leb);
+         i += leblen;
+         break;
+       case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("rebase add addr uleb: %u\n", (unsigned) leb);
+         i += leblen;
+         break;
+       case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("rebase uleb times (%u)", (unsigned) leb);
+         i += leblen;
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf (" skipping uleb (%u)\n", (unsigned) leb);
+         i += leblen;
+         break;
+       default:
+         printf ("unknown\n");
+         return;
+       }
+    }
+  printf ("   rebase commands without end!\n");
+}
+
+static void
+dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len,
+                    ufile_ptr off ATTRIBUTE_UNUSED)
+{
+  unsigned int i;
+  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+  unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
+
+  for (i = 0; i < len; )
+    {
+      unsigned char b = buf[i++];
+      unsigned char imm = b & BFD_MACH_O_BIND_IMMEDIATE_MASK;
+      bfd_vma leb;
+      unsigned int leblen;
+
+      printf ("   [0x%04x] 0x%02x: ", i, b);
+      switch (b & BFD_MACH_O_BIND_OPCODE_MASK)
+       {
+       case BFD_MACH_O_BIND_OPCODE_DONE:
+         printf ("done\n");
+         return;
+       case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
+         printf ("set dylib ordinal imm: %u\n", imm);
+         break;
+       case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("set dylib ordinal uleb: %u\n", imm);
+         i += leblen;
+         break;
+       case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
+         imm = (imm != 0) ? imm | BFD_MACH_O_BIND_OPCODE_MASK : imm;
+         printf ("set dylib special imm: %d\n", imm);
+         break;
+       case BFD_MACH_O_BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
+         printf ("set symbol trailing flags imm: 0x%02x, ", imm);
+         for (; i < len && buf[i] != 0; i++)
+           putchar (buf[i] >= ' ' && buf[i] < 0x7f ? buf[i] : '?');
+         putchar ('\n');
+         i++;
+         break;
+       case BFD_MACH_O_BIND_OPCODE_SET_TYPE_IMM:
+         /* Kludge: use the same table as rebase type.  */
+         printf ("set_type %s\n",
+                 bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
+         break;
+       case BFD_MACH_O_BIND_OPCODE_SET_ADDEND_SLEB:
+         {
+           bfd_signed_vma svma;
+           svma = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+           printf ("set addend sleb: 0x%08x\n", (unsigned) svma);
+           i += leblen;
+         }
+         break;
+       case BFD_MACH_O_BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("set segment: %u and offset: 0x%08x\n",
+                 imm, (unsigned) leb);
+         i += leblen;
+         break;
+       case BFD_MACH_O_BIND_OPCODE_ADD_ADDR_ULEB:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
+         i += leblen;
+         break;
+       case BFD_MACH_O_BIND_OPCODE_DO_BIND:
+         printf ("do bind\n");
+         break;
+       case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("do bind add addr uleb: 0x%08x\n", (unsigned) leb);
+         i += leblen;
+         break;
+       case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
+         printf ("do bind add addr imm scaled: %u\n", imm * ptrsize);
+         break;
+       case BFD_MACH_O_BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf ("do bind uleb times (%u)", (unsigned) leb);
+         i += leblen;
+         leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
+         printf (" skipping uleb (%u)\n", (unsigned) leb);
+         i += leblen;
+         break;
+       default:
+         printf ("unknown\n");
+         return;
+       }
+    }
+  printf ("   bind commands without end!\n");
+}
+
+struct export_info_data
+{
+  const unsigned char *name;
+  struct export_info_data *next;
+};
+
+static void
+dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
+                        unsigned int off, struct export_info_data *parent,
+                        struct export_info_data *base)
+{
+  bfd_vma size;
+  unsigned int leblen;
+  unsigned int child_count;
+  unsigned int i;
+
+  size = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
+  off += leblen;
+
+  if (size != 0)
+    {
+      bfd_vma flags;
+      struct export_info_data *d;
+
+      flags = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
+      off += leblen;
+
+      fputs ("   ", stdout);
+      switch (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_MASK)
+       {
+       case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_REGULAR:
+         putchar ('-');
+         break;
+       case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL:
+         putchar ('T');
+         break;
+       default:
+         putchar ('?');
+         break;
+       }
+      putchar ((flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION) ?
+              'W' : '-');
+
+      if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_REEXPORT)
+       {
+         bfd_vma lib;
+
+         lib = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
+         off += leblen;
+
+         fputs (" [reexport] ", stdout);
+         for (d = base; d != NULL; d = d->next)
+           printf ("%s", d->name);
+
+         fputs (" (", stdout);
+         if (buf[off] != 0)
+           {
+             fputs ((const char *)buf + off, stdout);
+             putchar (' ');
+             off += strlen ((const char *)buf + off);
+           }
+         printf ("from dylib %u)\n", (unsigned) lib);
+         off++;
+       }
+      else
+       {
+         bfd_vma offset;
+         bfd_vma resolv = 0;
+
+         offset = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
+         off += leblen;
+
+         if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
+           {
+             resolv = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
+             off += leblen;
+           }
+
+         printf (" 0x%08x ", (unsigned) offset);
+         for (d = base; d != NULL; d = d->next)
+           printf ("%s", d->name);
+         if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
+           printf (" [resolv: 0x%08x]", (unsigned) resolv);
+         printf ("\n");
+       }
+    }
+
+  child_count = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
+  off += leblen;
+
+  for (i = 0; i < child_count; i++)
+    {
+      struct export_info_data sub_data;
+      bfd_vma sub_off;
+
+      sub_data.name = buf + off;
+      sub_data.next = NULL;
+      parent->next = &sub_data;
+
+      off += strlen ((const char *)buf + off) + 1;
+
+      sub_off = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
+      off += leblen;
+
+      dump_dyld_info_export_1 (abfd, buf, len, sub_off, &sub_data, base);
+    }
+}
+
+static void
+dump_dyld_info_export (bfd *abfd, unsigned char *buf, unsigned int len,
+                      ufile_ptr off ATTRIBUTE_UNUSED)
+{
+  struct export_info_data data;
+
+  data.name = (const unsigned char *) "";
+  data.next = NULL;
+
+  printf ("   fl offset     sym        (Flags: Tls Weak)\n");
+  dump_dyld_info_export_1 (abfd, buf, len, 0, &data, &data);
+}
+
 static void
-dump_dyld_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
+dump_dyld_info (bfd *abfd, bfd_mach_o_load_command *cmd,
+               bfd_boolean verbose)
 {
-  bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
-
-  printf ("       rebase: off: 0x%08x  size: %-8u\n",
-           info->rebase_off, info->rebase_size);
-  printf ("         bind: off: 0x%08x  size: %-8u\n",
-           info->bind_off, info->bind_size);
-  printf ("    weak bind: off: 0x%08x  size: %-8u\n",
-           info->weak_bind_off, info->weak_bind_size);
-  printf ("    lazy bind: off: 0x%08x  size: %-8u\n",
-           info->lazy_bind_off, info->lazy_bind_size);
-  printf ("       export: off: 0x%08x  size: %-8u\n",
-           info->export_off, info->export_size);
+  bfd_mach_o_dyld_info_command *dinfo = &cmd->command.dyld_info;
+
+  printf ("       rebase: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
+         dinfo->rebase_off, dinfo->rebase_size,
+         dinfo->rebase_off + dinfo->rebase_size);
+  printf ("         bind: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
+         dinfo->bind_off, dinfo->bind_size,
+         dinfo->bind_off + dinfo->bind_size);
+  printf ("    weak bind: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
+         dinfo->weak_bind_off, dinfo->weak_bind_size,
+         dinfo->weak_bind_off + dinfo->weak_bind_size);
+  printf ("    lazy bind: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
+         dinfo->lazy_bind_off, dinfo->lazy_bind_size,
+         dinfo->lazy_bind_off + dinfo->lazy_bind_size);
+  printf ("       export: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
+         dinfo->export_off, dinfo->export_size,
+         dinfo->export_off + dinfo->export_size);
+
+  if (!verbose)
+    return;
+
+  printf ("   rebase:\n");
+  if (!load_and_dump (abfd, dinfo->rebase_off, dinfo->rebase_size,
+                     dump_dyld_info_rebase))
+    non_fatal (_("cannot read rebase dyld info"));
+
+  printf ("   bind:\n");
+  if (!load_and_dump (abfd, dinfo->bind_off, dinfo->bind_size,
+                     dump_dyld_info_bind))
+    non_fatal (_("cannot read bind dyld info"));
+
+  printf ("   weak bind:\n");
+  if (!load_and_dump (abfd, dinfo->weak_bind_off, dinfo->weak_bind_size,
+                     dump_dyld_info_bind))
+    non_fatal (_("cannot read weak bind dyld info"));
+
+  printf ("   lazy bind:\n");
+  if (!load_and_dump (abfd, dinfo->lazy_bind_off, dinfo->lazy_bind_size,
+                     dump_dyld_info_bind))
+    non_fatal (_("cannot read lazy bind dyld info"));
+
+  printf ("   exported symbols:\n");
+  if (!load_and_dump (abfd, dinfo->export_off, dinfo->export_size,
+                     dump_dyld_info_export))
+    non_fatal (_("cannot read export symbols dyld info"));
 }
 
 static void
@@ -708,7 +1098,10 @@ dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
       return;
     }
   count = bfd_getb32 (buf + 8);
-  printf (_("  %u index entries:\n"), count);
+  printf (ngettext ("  %u index entry:\n",
+                   "  %u index entries:\n",
+                   count),
+         count);
   if (len < 12 + 8 * count)
     {
       printf (_("  [bad block length]\n"));
@@ -921,7 +1314,7 @@ dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
     }
   for (p = buf + 1; *p != 0; p += len)
     {
-      addr += read_unsigned_leb128 (abfd, p, &len);
+      addr += read_leb128 (p, buf + cmd->datasize, 0, &len, NULL);
       fputs ("    ", stdout);
       bfd_printf_vma (abfd, addr);
       putchar ('\n');
@@ -1004,7 +1397,7 @@ dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
   if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
       || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
     {
-      non_fatal (_("cannot read function starts"));
+      non_fatal (_("cannot read data_in_code"));
       free (buf);
       return;
     }
@@ -1031,20 +1424,122 @@ dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
   free (buf);
 }
 
+static void
+dump_twolevel_hints (bfd *abfd, bfd_mach_o_twolevel_hints_command *cmd)
+{
+  size_t sz = 4 * cmd->nhints;
+  unsigned char *buf;
+  unsigned char *p;
+
+  buf = xmalloc (sz);
+  if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
+      || bfd_bread (buf, sz, abfd) != sz)
+    {
+      non_fatal (_("cannot read twolevel hints"));
+      free (buf);
+      return;
+    }
+
+  for (p = buf; p < buf + sz; p += 4)
+    {
+      unsigned int v;
+      unsigned int isub_image;
+      unsigned int itoc;
+
+      v = bfd_get_32 (abfd, p);
+      if (bfd_big_endian (abfd))
+       {
+         isub_image = (v >> 24) & 0xff;
+         itoc = v & 0xffffff;
+       }
+      else
+       {
+         isub_image = v & 0xff;
+         itoc = (v >> 8) & 0xffffff;
+       }
+
+      printf ("  %3u %8u\n", isub_image, itoc);
+    }
+  free (buf);
+}
+
+static void
+printf_version (uint32_t version)
+{
+  uint32_t maj, min, upd;
+
+  maj = (version >> 16) & 0xffff;
+  min = (version >> 8) & 0xff;
+  upd = version & 0xff;
+
+  printf ("%u.%u.%u", maj, min, upd);
+}
+
+static void
+dump_build_version (bfd *abfd, bfd_mach_o_load_command *cmd)
+{
+  const char *platform_name;
+  size_t tools_len, tools_offset;
+  bfd_mach_o_build_version_tool *tools, *tool;
+  bfd_mach_o_build_version_command *ver = &cmd->command.build_version;
+  uint32_t i;
+
+  platform_name = bfd_mach_o_get_name_or_null
+    (bfd_mach_o_platform_name, ver->platform);
+  if (platform_name == NULL)
+    printf ("   platform: 0x%08x\n", ver->platform);
+  else
+    printf ("   platform: %s\n", platform_name);
+  printf ("   os:       ");
+  printf_version (ver->minos);
+  printf ("\n   sdk:      ");
+  printf_version (ver->sdk);
+  printf ("\n   ntools:   %u\n", ver->ntools);
+
+  tools_len = sizeof (bfd_mach_o_build_version_tool) * ver->ntools;
+  tools_offset = cmd->offset + cmd->len - tools_len;
+
+  tools = xmalloc (tools_len);
+  if (bfd_seek (abfd, tools_offset, SEEK_SET) != 0
+      || bfd_bread (tools, tools_len, abfd) != tools_len)
+    {
+      non_fatal (_("cannot read build tools"));
+      free (tools);
+      return;
+    }
+
+  for (i = 0, tool = tools; i < ver->ntools; i++, tool++)
+    {
+      const char * tool_name;
+
+      tool_name = bfd_mach_o_get_name_or_null
+       (bfd_mach_o_tool_name, tool->tool);
+      if (tool_name == NULL)
+       printf ("   tool:     0x%08x\n", tool->tool);
+      else
+       printf ("   tool:     %s\n", tool_name);
+      printf ("   version:  ");
+      printf_version (tool->version);
+      printf ("\n");
+    }
+  free (tools);
+}
+
 static void
 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
-                   bfd_boolean verbose)
+                   unsigned int idx, bfd_boolean verbose)
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
   const char *cmd_name;
 
   cmd_name = bfd_mach_o_get_name_or_null
     (bfd_mach_o_load_command_name, cmd->type);
-  printf ("Load command ");
+  printf ("Load command #%-2u (size: %3u, offset: %4u): ",
+         idx, cmd->len, cmd->offset);
   if (cmd_name == NULL)
-    printf ("0x%02x:", cmd->type);
+    printf ("0x%02x\n", cmd->type);
   else
-    printf ("%s:", cmd_name);
+    printf ("%s\n", cmd_name);
 
   switch (cmd->type)
     {
@@ -1057,6 +1552,7 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
         bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
         unsigned int j;
 
+       printf ("   ");
         for (j = 0; j < sizeof (uuid->uuid); j ++)
           printf (" %02x", uuid->uuid[j]);
         putchar ('\n');
@@ -1070,7 +1566,7 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
     case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
       {
         bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
-        printf (" %s\n", dylib->name_str);
+        printf ("  name: %s\n", dylib->name_str);
         printf ("            time stamp: 0x%08lx\n",
                 dylib->timestamp);
         printf ("       current version: 0x%08lx\n",
@@ -1081,17 +1577,15 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
       break;
     case BFD_MACH_O_LC_LOAD_DYLINKER:
     case BFD_MACH_O_LC_ID_DYLINKER:
-      printf (" %s\n", cmd->command.dylinker.name_str);
+      printf ("    %s\n", cmd->command.dylinker.name_str);
       break;
     case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
-      putchar ('\n');
-      printf ("  %s\n", cmd->command.dylinker.name_str);
+      printf ("    %s\n", cmd->command.dylinker.name_str);
       break;
     case BFD_MACH_O_LC_SYMTAB:
       {
         bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
-        printf ("\n"
-                "   symoff: 0x%08x    nsyms: %8u  (endoff: 0x%08x)\n",
+        printf ("   symoff: 0x%08x    nsyms: %8u  (endoff: 0x%08x)\n",
                 symtab->symoff, symtab->nsyms,
                 symtab->symoff + symtab->nsyms
                 * (mdata->header.version == 2
@@ -1102,14 +1596,13 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
         break;
       }
     case BFD_MACH_O_LC_DYSYMTAB:
-      putchar ('\n');
       dump_dysymtab (abfd, cmd, verbose);
       break;
     case BFD_MACH_O_LC_LOADFVMLIB:
     case BFD_MACH_O_LC_IDFVMLIB:
       {
         bfd_mach_o_fvmlib_command *fvmlib = &cmd->command.fvmlib;
-        printf (" %s\n", fvmlib->name_str);
+        printf ("                fvmlib: %s\n", fvmlib->name_str);
         printf ("         minor version: 0x%08x\n", fvmlib->minor_version);
         printf ("        header address: 0x%08x\n", fvmlib->header_addr);
       }
@@ -1119,11 +1612,12 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
     case BFD_MACH_O_LC_FUNCTION_STARTS:
     case BFD_MACH_O_LC_DATA_IN_CODE:
     case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
+    case BFD_MACH_O_LC_DYLD_EXPORTS_TRIE:
+    case BFD_MACH_O_LC_DYLD_CHAINED_FIXUPS:
       {
         bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
         printf
-          ("\n"
-           "  dataoff: 0x%08lx  datasize: 0x%08lx  (endoff: 0x%08lx)\n",
+          ("  dataoff: 0x%08lx  datasize: 0x%08lx  (endoff: 0x%08lx)\n",
            linkedit->dataoff, linkedit->datasize,
            linkedit->dataoff + linkedit->datasize);
 
@@ -1153,8 +1647,8 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
     case BFD_MACH_O_LC_SUB_CLIENT:
     case BFD_MACH_O_LC_RPATH:
       {
-        bfd_mach_o_str_command *str = &cmd->command.str;
-        printf (" %s\n", str->str);
+        bfd_mach_o_str_command *strc = &cmd->command.str;
+        printf ("    %s\n", strc->str);
         break;
       }
     case BFD_MACH_O_LC_THREAD:
@@ -1165,52 +1659,101 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
       {
         bfd_mach_o_encryption_info_command *cryp =
           &cmd->command.encryption_info;
-        printf
-          ("\n"
-           "  cryptoff: 0x%08x  cryptsize: 0x%08x (endoff 0x%08x)"
-           " cryptid: %u\n",
-           cryp->cryptoff, cryp->cryptsize,
-           cryp->cryptoff + cryp->cryptsize,
-           cryp->cryptid);
+        printf ("  cryptoff: 0x%08x  cryptsize: 0x%08x (endoff 0x%08x)"
+               " cryptid: %u\n",
+               cryp->cryptoff, cryp->cryptsize,
+               cryp->cryptoff + cryp->cryptsize,
+               cryp->cryptid);
       }
       break;
     case BFD_MACH_O_LC_DYLD_INFO:
-      putchar ('\n');
-      dump_dyld_info (abfd, cmd);
+      dump_dyld_info (abfd, cmd, verbose);
       break;
     case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
     case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
+    case BFD_MACH_O_LC_VERSION_MIN_WATCHOS:
+    case BFD_MACH_O_LC_VERSION_MIN_TVOS:
       {
         bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
 
-        printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
+        printf ("   os: ");
+        printf_version (ver->version);
+        printf ("\n   sdk: ");
+        printf_version (ver->sdk);
+        printf ("\n");
       }
       break;
     case BFD_MACH_O_LC_SOURCE_VERSION:
       {
         bfd_mach_o_source_version_command *version =
          &cmd->command.source_version;
-        printf ("\n"
-                "   version a.b.c.d.e: %u.%u.%u.%u.%u\n",
+        printf ("   version a.b.c.d.e: %u.%u.%u.%u.%u\n",
                version->a, version->b, version->c, version->d, version->e);
         break;
       }
+    case BFD_MACH_O_LC_PREBOUND_DYLIB:
+      {
+        bfd_mach_o_prebound_dylib_command *pbdy = &cmd->command.prebound_dylib;
+       unsigned char *lm = pbdy->linked_modules;
+       unsigned int j;
+       unsigned int last;
+
+        printf ("      dylib: %s\n", pbdy->name_str);
+        printf ("   nmodules: %u\n", pbdy->nmodules);
+       printf ("   linked modules (at %u): ",
+               pbdy->linked_modules_offset - cmd->offset);
+       last = pbdy->nmodules > 32 ? 32 : pbdy->nmodules;
+       for (j = 0; j < last; j++)
+         printf ("%u", (lm[j >> 3] >> (j & 7)) & 1);
+       if (last < pbdy->nmodules)
+         printf ("...");
+       putchar ('\n');
+        break;
+      }
+    case BFD_MACH_O_LC_PREBIND_CKSUM:
+      {
+        bfd_mach_o_prebind_cksum_command *cksum = &cmd->command.prebind_cksum;
+        printf ("   0x%08x\n", cksum->cksum);
+        break;
+      }
+    case BFD_MACH_O_LC_TWOLEVEL_HINTS:
+      {
+        bfd_mach_o_twolevel_hints_command *hints =
+         &cmd->command.twolevel_hints;
+
+        printf ("   table offset: 0x%08x  nbr hints: %u\n",
+               hints->offset, hints->nhints);
+       if (verbose)
+         dump_twolevel_hints (abfd, hints);
+        break;
+      }
     case BFD_MACH_O_LC_MAIN:
       {
         bfd_mach_o_main_command *entry = &cmd->command.main;
-        printf ("\n"
-                "   entry offset: ");
-       printf_vma (entry->entryoff);
+        printf ("   entry offset: ");
+       printf_uint64 (entry->entryoff);
         printf ("\n"
                 "   stack size:   ");
-       printf_vma (entry->stacksize);
+       printf_uint64 (entry->stacksize);
        printf ("\n");
         break;
       }
+    case BFD_MACH_O_LC_NOTE:
+      {
+        bfd_mach_o_note_command *note = &cmd->command.note;
+        printf ("   data owner: %.16s\n", note->data_owner);
+        printf ("   offset:     ");
+       printf_uint64 (note->offset);
+        printf ("\n"
+                "   size:       ");
+       printf_uint64 (note->size);
+       printf ("\n");
+        break;
+      }
+    case BFD_MACH_O_LC_BUILD_VERSION:
+      dump_build_version (abfd, cmd);
+      break;
     default:
-      putchar ('\n');
-      printf ("  offset: 0x%08lx\n", (unsigned long)cmd->offset);
-      printf ("    size: 0x%08lx\n", (unsigned long)cmd->len);
       break;
     }
   putchar ('\n');
@@ -1220,16 +1763,15 @@ static void
 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+  bfd_mach_o_load_command *cmd;
   unsigned int i;
 
-  for (i = 0; i < mdata->header.ncmds; i++)
+  for (cmd = mdata->first_command, i = 0; cmd != NULL; cmd = cmd->next, i++)
     {
-      bfd_mach_o_load_command *cmd = &mdata->commands[i];
-
       if (cmd32 == 0)
-        dump_load_command (abfd, cmd, FALSE);
+        dump_load_command (abfd, cmd, i, FALSE);
       else if (cmd->type == cmd32 || cmd->type == cmd64)
-        dump_load_command (abfd, cmd, TRUE);
+        dump_load_command (abfd, cmd, i, TRUE);
     }
 }
 
@@ -1256,7 +1798,7 @@ dump_unwind_encoding_x86 (unsigned int encoding, unsigned int sz,
        unsigned int regs;
        char pfx = sz == 8 ? 'R' : 'E';
 
-       regs = encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_REGSITERS;
+       regs = encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_REGISTERS;
        printf (" %cSP frame", pfx);
        if (regs != 0)
          {
@@ -1365,6 +1907,62 @@ dump_unwind_encoding_x86 (unsigned int encoding, unsigned int sz,
     }
 }
 
+/* Dump arm64 compact unwind entries.  */
+
+static void
+dump_unwind_encoding_arm64 (unsigned int encoding)
+{
+  switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
+    {
+    case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
+      printf (" frameless");
+      break;
+    case MACH_O_UNWIND_ARM64_MODE_DWARF:
+      printf (" Dwarf offset: 0x%06x",
+             encoding & MACH_O_UNWIND_ARM64_DWARF_SECTION_OFFSET);
+      return;
+    case MACH_O_UNWIND_ARM64_MODE_FRAME:
+      printf (" frame");
+      break;
+    default:
+      printf (" [unhandled mode]");
+      return;
+    }
+  switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
+    {
+    case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
+    case MACH_O_UNWIND_ARM64_MODE_FRAME:
+      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X19_X20_PAIR)
+       printf (" x19-x20");
+      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X21_X22_PAIR)
+       printf (" x21-x22");
+      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X23_X24_PAIR)
+       printf (" x23-x24");
+      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X25_X26_PAIR)
+       printf (" x25-x26");
+      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X27_X28_PAIR)
+       printf (" x27-x28");
+      break;
+    }
+  switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
+    {
+    case MACH_O_UNWIND_ARM64_MODE_FRAME:
+      if (encoding & MACH_O_UNWIND_ARM64_FRAME_D8_D9_PAIR)
+       printf (" d8-d9");
+      if (encoding & MACH_O_UNWIND_ARM64_FRAME_D10_D11_PAIR)
+       printf (" d10-d11");
+      if (encoding & MACH_O_UNWIND_ARM64_FRAME_D12_D13_PAIR)
+       printf (" d12-d13");
+      if (encoding & MACH_O_UNWIND_ARM64_FRAME_D14_D15_PAIR)
+       printf (" d14-d15");
+      break;
+    case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
+      printf (" size: %u",
+             (encoding & MACH_O_UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK) >> 8);
+      break;
+    }
+}
+
 static void
 dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding)
 {
@@ -1380,6 +1978,9 @@ dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding)
     case BFD_MACH_O_CPU_TYPE_I386:
       dump_unwind_encoding_x86 (encoding, 4, unwind_x86_regs);
       break;
+    case BFD_MACH_O_CPU_TYPE_ARM64:
+      dump_unwind_encoding_arm64 (encoding);
+      break;
     default:
       printf (" [unhandled cpu]");
       break;
@@ -1413,12 +2014,12 @@ dump_obj_compact_unwind (bfd *abfd,
          e = (struct mach_o_compact_unwind_64 *) p;
 
          putchar (' ');
-         fprintf_vma (stdout, bfd_get_64 (abfd, e->start));
-         printf (" %08lx", bfd_get_32 (abfd, e->length));
+         printf_uint64 (bfd_get_64 (abfd, e->start));
+         printf (" %08lx", (unsigned long)bfd_get_32 (abfd, e->length));
          putchar (' ');
-         fprintf_vma (stdout, bfd_get_64 (abfd, e->personnality));
+         printf_uint64 (bfd_get_64 (abfd, e->personality));
          putchar (' ');
-         fprintf_vma (stdout, bfd_get_64 (abfd, e->lsda));
+         printf_uint64 (bfd_get_64 (abfd, e->lsda));
          putchar ('\n');
 
          printf ("  encoding: ");
@@ -1473,6 +2074,17 @@ dump_exe_compact_unwind (bfd *abfd,
   printf ("   %u encodings, %u personalities, %u level-1 indexes:\n",
          encodings_count, personality_count, index_count);
 
+  /* Personality.  */
+  if (personality_count > 0)
+    {
+      const unsigned char *pers = content + personality_offset;
+
+      printf ("   personalities\n");
+      for (i = 0; i < personality_count; i++)
+       printf ("     %u: 0x%08x\n", i,
+               (unsigned) bfd_get_32 (abfd, pers + 4 * i));
+    }
+
   /* Level-1 index.  */
   printf ("   idx function   level2 off lsda off\n");
 
@@ -1555,7 +2167,7 @@ dump_exe_compact_unwind (bfd *abfd,
                    + 4 * (enc_idx - encodings_count);
                encoding = bfd_get_32 (abfd, enc_addr);
 
-               printf ("   %-4u 0x%08x [%3u] ", j,
+               printf ("   %4u 0x%08x [%3u] ", j,
                        func_offset + en_func, enc_idx);
                dump_unwind_encoding (mdata, encoding);
                putchar ('\n');
@@ -1635,11 +2247,10 @@ dump_section_content (bfd *abfd,
                      void (*dump)(bfd*, const unsigned char*, bfd_size_type))
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
-  unsigned int i;
+  bfd_mach_o_load_command *cmd;
 
-  for (i = 0; i < mdata->header.ncmds; i++)
+  for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
     {
-      bfd_mach_o_load_command *cmd = &mdata->commands[i];
       if (cmd->type == BFD_MACH_O_LC_SEGMENT
          || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
        {
@@ -1653,7 +2264,7 @@ dump_section_content (bfd *abfd,
                asection *bfdsec = sec->bfdsection;
                unsigned char *content;
 
-               size = bfd_get_section_size (bfdsec);
+               size = bfd_section_size (bfdsec);
                content = (unsigned char *) xmalloc (size);
                bfd_get_section_contents (abfd, bfdsec, content, 0, size);
 
@@ -1688,6 +2299,8 @@ mach_o_dump (bfd *abfd)
     dump_load_commands (abfd, BFD_MACH_O_LC_FUNCTION_STARTS, 0);
   if (options[OPT_DATA_IN_CODE].selected)
     dump_load_commands (abfd, BFD_MACH_O_LC_DATA_IN_CODE, 0);
+  if (options[OPT_TWOLEVEL_HINTS].selected)
+    dump_load_commands (abfd, BFD_MACH_O_LC_TWOLEVEL_HINTS, 0);
   if (options[OPT_COMPACT_UNWIND].selected)
     {
       dump_section_content (abfd, "__LD", "__compact_unwind",
@@ -1695,14 +2308,16 @@ mach_o_dump (bfd *abfd)
       dump_section_content (abfd, "__TEXT", "__unwind_info",
                            dump_exe_compact_unwind);
     }
+  if (options[OPT_DYLD_INFO].selected)
+    dump_load_commands (abfd, BFD_MACH_O_LC_DYLD_INFO, 0);
 }
 
 /* Vector for Mach-O.  */
 
 const struct objdump_private_desc objdump_private_desc_mach_o =
-  {
   mach_o_help,
   mach_o_filter,
   mach_o_dump,
   options
-  };
+{
+ mach_o_help,
+ mach_o_filter,
+ mach_o_dump,
+ options
+};