1/* od-macho.c -- dump information about an Mach-O object file.
2   Copyright (C) 2011-2022 Free Software Foundation, Inc.
3   Written by Tristan Gingold, Adacore.
4
5   This file is part of GNU Binutils.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3, or (at your option)
10   any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, 51 Franklin Street - Fifth Floor, Boston,
20   MA 02110-1301, USA.  */
21
22#include "sysdep.h"
23#include <stddef.h>
24#include <time.h>
25#include "safe-ctype.h"
26#include "bfd.h"
27#include "objdump.h"
28#include "bucomm.h"
29#include "elfcomm.h"
30#include "dwarf.h"
31#include "bfdlink.h"
32#include "mach-o.h"
33#include "mach-o/external.h"
34#include "mach-o/codesign.h"
35#include "mach-o/unwind.h"
36
37/* Index of the options in the options[] array.  */
38#define OPT_HEADER 0
39#define OPT_SECTION 1
40#define OPT_MAP 2
41#define OPT_LOAD 3
42#define OPT_DYSYMTAB 4
43#define OPT_CODESIGN 5
44#define OPT_SEG_SPLIT_INFO 6
45#define OPT_COMPACT_UNWIND 7
46#define OPT_FUNCTION_STARTS 8
47#define OPT_DATA_IN_CODE 9
48#define OPT_TWOLEVEL_HINTS 10
49#define OPT_DYLD_INFO 11
50
51/* List of actions.  */
52static struct objdump_private_option options[] =
53  {
54    { "header", 0 },
55    { "section", 0 },
56    { "map", 0 },
57    { "load", 0 },
58    { "dysymtab", 0 },
59    { "codesign", 0 },
60    { "seg_split_info", 0 },
61    { "compact_unwind", 0 },
62    { "function_starts", 0 },
63    { "data_in_code", 0 },
64    { "twolevel_hints", 0 },
65    { "dyld_info", 0 },
66    { NULL, 0 }
67  };
68
69/* Display help.  */
70
71static void
72mach_o_help (FILE *stream)
73{
74  fprintf (stream, _("\
75For Mach-O files:\n\
76  header           Display the file header\n\
77  section          Display the segments and sections commands\n\
78  map              Display the section map\n\
79  load             Display the load commands\n\
80  dysymtab         Display the dynamic symbol table\n\
81  codesign         Display code signature\n\
82  seg_split_info   Display segment split info\n\
83  compact_unwind   Display compact unwinding info\n\
84  function_starts  Display start address of functions\n\
85  data_in_code     Display data in code entries\n\
86  twolevel_hints   Display the two-level namespace lookup hints table\n\
87  dyld_info        Display dyld information\n\
88"));
89}
90
91/* Return TRUE if ABFD is handled.  */
92
93static int
94mach_o_filter (bfd *abfd)
95{
96  return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
97}
98
99static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
100{
101  { "vax", BFD_MACH_O_CPU_TYPE_VAX },
102  { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
103  { "i386", BFD_MACH_O_CPU_TYPE_I386 },
104  { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
105  { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
106  { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
107  { "arm", BFD_MACH_O_CPU_TYPE_ARM },
108  { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
109  { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
110  { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
111  { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
112  { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
113  { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
114  { "arm64", BFD_MACH_O_CPU_TYPE_ARM64 },
115  { NULL, 0}
116};
117
118static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
119{
120  { "object", BFD_MACH_O_MH_OBJECT },
121  { "execute", BFD_MACH_O_MH_EXECUTE },
122  { "fvmlib", BFD_MACH_O_MH_FVMLIB },
123  { "core", BFD_MACH_O_MH_CORE },
124  { "preload", BFD_MACH_O_MH_PRELOAD },
125  { "dylib", BFD_MACH_O_MH_DYLIB },
126  { "dylinker", BFD_MACH_O_MH_DYLINKER },
127  { "bundle", BFD_MACH_O_MH_BUNDLE },
128  { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
129  { "dym", BFD_MACH_O_MH_DSYM },
130  { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
131  { NULL, 0}
132};
133
134static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
135{
136  { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
137  { "incrlink", BFD_MACH_O_MH_INCRLINK },
138  { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
139  { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
140  { "prebound", BFD_MACH_O_MH_PREBOUND },
141  { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
142  { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
143  { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
144  { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
145  { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
146  { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
147  { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
148  { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
149  { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
150  { "canonical", BFD_MACH_O_MH_CANONICAL },
151  { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
152  { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
153  { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
154  { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
155  { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
156  { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
157  { "pie", BFD_MACH_O_MH_PIE },
158  { "dead_strippable_dylib", BFD_MACH_O_MH_DEAD_STRIPPABLE_DYLIB },
159  { "has_tlv", BFD_MACH_O_MH_HAS_TLV_DESCRIPTORS },
160  { "no_heap_execution", BFD_MACH_O_MH_NO_HEAP_EXECUTION },
161  { "app_extension_safe", BFD_MACH_O_MH_APP_EXTENSION_SAFE },
162  { NULL, 0}
163};
164
165static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
166{
167  { "segment", BFD_MACH_O_LC_SEGMENT},
168  { "symtab", BFD_MACH_O_LC_SYMTAB},
169  { "symseg", BFD_MACH_O_LC_SYMSEG},
170  { "thread", BFD_MACH_O_LC_THREAD},
171  { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
172  { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
173  { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
174  { "ident", BFD_MACH_O_LC_IDENT},
175  { "fvmfile", BFD_MACH_O_LC_FVMFILE},
176  { "prepage", BFD_MACH_O_LC_PREPAGE},
177  { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
178  { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
179  { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
180  { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
181  { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
182  { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
183  { "routines", BFD_MACH_O_LC_ROUTINES},
184  { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
185  { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
186  { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
187  { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
188  { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
189  { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
190  { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
191  { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
192  { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
193  { "uuid", BFD_MACH_O_LC_UUID},
194  { "rpath", BFD_MACH_O_LC_RPATH},
195  { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
196  { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
197  { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
198  { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
199  { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
200  { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
201  { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
202  { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
203  { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
204  { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
205  { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
206  { "main", BFD_MACH_O_LC_MAIN},
207  { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE},
208  { "source_version", BFD_MACH_O_LC_SOURCE_VERSION},
209  { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS},
210  { "encryption_info_64", BFD_MACH_O_LC_ENCRYPTION_INFO_64},
211  { "linker_options", BFD_MACH_O_LC_LINKER_OPTIONS},
212  { "linker_optimization_hint", BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT},
213  { "version_min_tvos", BFD_MACH_O_LC_VERSION_MIN_TVOS},
214  { "version_min_watchos", BFD_MACH_O_LC_VERSION_MIN_WATCHOS},
215  { "note", BFD_MACH_O_LC_NOTE},
216  { "build_version", BFD_MACH_O_LC_BUILD_VERSION},
217  { "exports_trie", BFD_MACH_O_LC_DYLD_EXPORTS_TRIE},
218  { "chained_fixups", BFD_MACH_O_LC_DYLD_CHAINED_FIXUPS},
219  { NULL, 0}
220};
221
222static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
223{
224  { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32},
225  { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32},
226  { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32},
227  { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64},
228  { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64},
229  { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64},
230  { "thread_state", BFD_MACH_O_x86_THREAD_STATE},
231  { "float_state", BFD_MACH_O_x86_FLOAT_STATE},
232  { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE},
233  { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32},
234  { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64},
235  { "debug_state", BFD_MACH_O_x86_DEBUG_STATE},
236  { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
237  { NULL, 0 }
238};
239
240static const bfd_mach_o_xlat_name bfd_mach_o_platform_name[] =
241{
242  { "macos", BFD_MACH_O_PLATFORM_MACOS},
243  { "ios", BFD_MACH_O_PLATFORM_IOS},
244  { "tvos", BFD_MACH_O_PLATFORM_TVOS},
245  { "watchos", BFD_MACH_O_PLATFORM_WATCHOS},
246  { "bridgeos", BFD_MACH_O_PLATFORM_BRIDGEOS},
247  { NULL, 0 }
248};
249
250static const bfd_mach_o_xlat_name bfd_mach_o_tool_name[] =
251{
252  { "clang", BFD_MACH_O_TOOL_CLANG},
253  { "swift", BFD_MACH_O_TOOL_SWIFT},
254  { "ld", BFD_MACH_O_TOOL_LD},
255  { NULL, 0 }
256};
257
258static void
259bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
260                        unsigned long val)
261{
262  int first = 1;
263
264  for (; table->name; table++)
265    {
266      if (table->val & val)
267        {
268          if (!first)
269            printf ("+");
270          printf ("%s", table->name);
271          val &= ~table->val;
272          first = 0;
273        }
274    }
275  if (val)
276    {
277      if (!first)
278        printf ("+");
279      printf ("0x%lx", val);
280      return;
281    }
282  if (first)
283    printf ("-");
284}
285
286static const char *
287bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
288                             unsigned long val)
289{
290  for (; table->name; table++)
291    if (table->val == val)
292      return table->name;
293  return NULL;
294}
295
296static const char *
297bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
298{
299  const char *res = bfd_mach_o_get_name_or_null (table, val);
300
301  if (res == NULL)
302    return "*UNKNOWN*";
303  else
304    return res;
305}
306
307static void
308dump_header (bfd *abfd)
309{
310  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
311  bfd_mach_o_header *h = &mdata->header;
312
313  fputs (_("Mach-O header:\n"), stdout);
314  printf (_(" magic     : %08lx\n"), h->magic);
315  printf (_(" cputype   : %08lx (%s)\n"), h->cputype,
316          bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
317  printf (_(" cpusubtype: %08lx\n"), h->cpusubtype);
318  printf (_(" filetype  : %08lx (%s)\n"),
319          h->filetype,
320          bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
321  printf (_(" ncmds     : %08lx (%lu)\n"), h->ncmds, h->ncmds);
322  printf (_(" sizeofcmds: %08lx (%lu)\n"), h->sizeofcmds, h->sizeofcmds);
323  printf (_(" flags     : %08lx ("), h->flags);
324  bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
325  fputs (_(")\n"), stdout);
326  printf (_(" reserved  : %08x\n"), h->reserved);
327  putchar ('\n');
328}
329
330static void
331disp_segment_prot (unsigned int prot)
332{
333  putchar (prot & BFD_MACH_O_PROT_READ ? 'r' : '-');
334  putchar (prot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
335  putchar (prot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
336}
337
338static void
339dump_section_map (bfd *abfd)
340{
341  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
342  bfd_mach_o_load_command *cmd;
343  unsigned int sec_nbr = 0;
344
345  fputs (_("Segments and Sections:\n"), stdout);
346  fputs (_(" #: Segment name     Section name     Address\n"), stdout);
347
348  for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
349    {
350      bfd_mach_o_segment_command *seg;
351      bfd_mach_o_section *sec;
352
353      if (cmd->type != BFD_MACH_O_LC_SEGMENT
354	  && cmd->type != BFD_MACH_O_LC_SEGMENT_64)
355	continue;
356
357      seg = &cmd->command.segment;
358
359      printf ("[Segment %-16s ", seg->segname);
360      printf_vma (seg->vmaddr);
361      putchar ('-');
362      printf_vma  (seg->vmaddr + seg->vmsize - 1);
363      putchar (' ');
364      disp_segment_prot (seg->initprot);
365      printf ("]\n");
366
367      for (sec = seg->sect_head; sec != NULL; sec = sec->next)
368	{
369	  printf ("%02u: %-16s %-16s ", ++sec_nbr,
370                  sec->segname, sec->sectname);
371	  printf_vma (sec->addr);
372	  putchar (' ');
373	  printf_vma  (sec->size);
374	  printf (" %08lx\n", sec->flags);
375	}
376    }
377}
378
379static void
380dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
381{
382  printf (" Section: %-16s %-16s (bfdname: %s)\n",
383           sec->sectname, sec->segname, sec->bfdsection->name);
384  printf ("  addr: ");
385  printf_vma (sec->addr);
386  printf (" size: ");
387  printf_vma (sec->size);
388  printf (" offset: ");
389  printf_vma (sec->offset);
390  printf ("\n");
391  printf ("  align: %ld", sec->align);
392  printf ("  nreloc: %lu  reloff: ", sec->nreloc);
393  printf_vma (sec->reloff);
394  printf ("\n");
395  printf ("  flags: %08lx (type: %s", sec->flags,
396          bfd_mach_o_get_name (bfd_mach_o_section_type_name,
397                               sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
398  printf (" attr: ");
399  bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
400                          sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
401  printf (")\n");
402  switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
403    {
404    case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
405    case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
406    case BFD_MACH_O_S_SYMBOL_STUBS:
407      printf ("  first indirect sym: %lu", sec->reserved1);
408      printf (" (%u entries)",
409               bfd_mach_o_section_get_nbr_indirect (abfd, sec));
410      break;
411    default:
412      printf ("  reserved1: 0x%lx", sec->reserved1);
413      break;
414    }
415  switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
416    {
417    case BFD_MACH_O_S_SYMBOL_STUBS:
418      printf ("  stub size: %lu", sec->reserved2);
419      break;
420    default:
421      printf ("  reserved2: 0x%lx", sec->reserved2);
422      break;
423    }
424  printf ("  reserved3: 0x%lx\n", sec->reserved3);
425}
426
427static void
428dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
429{
430  bfd_mach_o_segment_command *seg = &cmd->command.segment;
431  bfd_mach_o_section *sec;
432
433  printf ("     name: %16s", *seg->segname ? seg->segname : "*none*");
434  printf ("  nsects: %lu", seg->nsects);
435  printf ("  flags: %lx", seg->flags);
436  printf ("  initprot: ");
437  disp_segment_prot (seg->initprot);
438  printf ("  maxprot: ");
439  disp_segment_prot (seg->maxprot);
440  printf ("\n");
441  printf ("   vmaddr: ");
442  printf_vma (seg->vmaddr);
443  printf ("   vmsize: ");
444  printf_vma  (seg->vmsize);
445  printf ("\n");
446  printf ("  fileoff: ");
447  printf_vma (seg->fileoff);
448  printf (" filesize: ");
449  printf_vma ((bfd_vma)seg->filesize);
450  printf (" endoff: ");
451  printf_vma ((bfd_vma)(seg->fileoff + seg->filesize));
452  printf ("\n");
453  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
454    dump_section_header (abfd, sec);
455}
456
457static void
458dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bool verbose)
459{
460  bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
461  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
462  unsigned int i;
463
464  printf ("              local symbols: idx: %10lu  num: %-8lu",
465          dysymtab->ilocalsym, dysymtab->nlocalsym);
466  printf (" (nxtidx: %lu)\n",
467          dysymtab->ilocalsym + dysymtab->nlocalsym);
468  printf ("           external symbols: idx: %10lu  num: %-8lu",
469          dysymtab->iextdefsym, dysymtab->nextdefsym);
470  printf (" (nxtidx: %lu)\n",
471          dysymtab->iextdefsym + dysymtab->nextdefsym);
472  printf ("          undefined symbols: idx: %10lu  num: %-8lu",
473          dysymtab->iundefsym, dysymtab->nundefsym);
474  printf (" (nxtidx: %lu)\n",
475          dysymtab->iundefsym + dysymtab->nundefsym);
476  printf ("           table of content: off: 0x%08lx  num: %-8lu",
477          dysymtab->tocoff, dysymtab->ntoc);
478  printf (" (endoff: 0x%08lx)\n",
479          dysymtab->tocoff + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
480  printf ("               module table: off: 0x%08lx  num: %-8lu",
481          dysymtab->modtaboff, dysymtab->nmodtab);
482  printf (" (endoff: 0x%08lx)\n",
483          dysymtab->modtaboff + dysymtab->nmodtab
484          * (mdata->header.version == 2 ?
485             BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
486  printf ("   external reference table: off: 0x%08lx  num: %-8lu",
487          dysymtab->extrefsymoff, dysymtab->nextrefsyms);
488  printf (" (endoff: 0x%08lx)\n",
489          dysymtab->extrefsymoff
490          + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
491  printf ("      indirect symbol table: off: 0x%08lx  num: %-8lu",
492          dysymtab->indirectsymoff, dysymtab->nindirectsyms);
493  printf (" (endoff: 0x%08lx)\n",
494          dysymtab->indirectsymoff
495          + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
496  printf ("  external relocation table: off: 0x%08lx  num: %-8lu",
497          dysymtab->extreloff, dysymtab->nextrel);
498  printf (" (endoff: 0x%08lx)\n",
499          dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
500  printf ("     local relocation table: off: 0x%08lx  num: %-8lu",
501          dysymtab->locreloff, dysymtab->nlocrel);
502  printf (" (endoff: 0x%08lx)\n",
503          dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
504
505  if (!verbose)
506    return;
507
508  if (dysymtab->ntoc > 0
509      || dysymtab->nindirectsyms > 0
510      || dysymtab->nextrefsyms > 0)
511    {
512      /* Try to read the symbols to display the toc or indirect symbols.  */
513      bfd_mach_o_read_symtab_symbols (abfd);
514    }
515  else if (dysymtab->nmodtab > 0)
516    {
517      /* Try to read the strtab to display modules name.  */
518      bfd_mach_o_read_symtab_strtab (abfd);
519    }
520
521  for (i = 0; i < dysymtab->nmodtab; i++)
522    {
523      bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
524      printf ("  module %u:\n", i);
525      printf ("   name: %lu", module->module_name_idx);
526      if (mdata->symtab && mdata->symtab->strtab)
527        printf (": %s",
528                 mdata->symtab->strtab + module->module_name_idx);
529      printf ("\n");
530      printf ("   extdefsym: idx: %8lu  num: %lu\n",
531               module->iextdefsym, module->nextdefsym);
532      printf ("      refsym: idx: %8lu  num: %lu\n",
533               module->irefsym, module->nrefsym);
534      printf ("    localsym: idx: %8lu  num: %lu\n",
535               module->ilocalsym, module->nlocalsym);
536      printf ("      extrel: idx: %8lu  num: %lu\n",
537               module->iextrel, module->nextrel);
538      printf ("        init: idx: %8u  num: %u\n",
539               module->iinit, module->ninit);
540      printf ("        term: idx: %8u  num: %u\n",
541               module->iterm, module->nterm);
542      printf ("   objc_module_info: addr: ");
543      printf_vma (module->objc_module_info_addr);
544      printf ("  size: %lu\n", module->objc_module_info_size);
545    }
546
547  if (dysymtab->ntoc > 0)
548    {
549      bfd_mach_o_symtab_command *symtab = mdata->symtab;
550
551      printf ("  table of content: (symbol/module)\n");
552      for (i = 0; i < dysymtab->ntoc; i++)
553        {
554          bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
555
556          printf ("   %4u: ", i);
557          if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
558            {
559              const char *name = symtab->symbols[toc->symbol_index].symbol.name;
560              printf ("%s (%lu)", name ? name : "*invalid*",
561                       toc->symbol_index);
562            }
563          else
564            printf ("%lu", toc->symbol_index);
565
566          printf (" / ");
567          if (symtab && symtab->strtab
568              && toc->module_index < dysymtab->nmodtab)
569            {
570              bfd_mach_o_dylib_module *mod;
571              mod = &dysymtab->dylib_module[toc->module_index];
572              printf ("%s (%lu)",
573                       symtab->strtab + mod->module_name_idx,
574                       toc->module_index);
575            }
576          else
577            printf ("%lu", toc->module_index);
578
579          printf ("\n");
580        }
581    }
582
583  if (dysymtab->nindirectsyms != 0)
584    {
585      printf ("  indirect symbols:\n");
586
587      for (i = 0; i < mdata->nsects; i++)
588        {
589          bfd_mach_o_section *sec = mdata->sections[i];
590          unsigned int j, first, last;
591          bfd_mach_o_symtab_command *symtab = mdata->symtab;
592          bfd_vma addr;
593          bfd_vma entry_size;
594
595          switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
596            {
597            case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
598            case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
599            case BFD_MACH_O_S_SYMBOL_STUBS:
600              first = sec->reserved1;
601              last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
602              addr = sec->addr;
603              entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
604              printf ("  for section %s.%s:\n",
605                       sec->segname, sec->sectname);
606              for (j = first; j < last; j++)
607                {
608                  unsigned int isym = dysymtab->indirect_syms[j];
609
610                  printf ("   ");
611                  printf_vma (addr);
612                  printf (" %5u: 0x%08x", j, isym);
613                  if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
614                    printf (" LOCAL");
615                  if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
616                    printf (" ABSOLUTE");
617                  if (symtab && symtab->symbols
618                      && isym < symtab->nsyms
619                      && symtab->symbols[isym].symbol.name)
620                    printf (" %s", symtab->symbols[isym].symbol.name);
621                  printf ("\n");
622                  addr += entry_size;
623                }
624              break;
625            default:
626              break;
627            }
628        }
629    }
630  if (dysymtab->nextrefsyms > 0)
631    {
632      bfd_mach_o_symtab_command *symtab = mdata->symtab;
633
634      printf ("  external reference table: (symbol flags)\n");
635      for (i = 0; i < dysymtab->nextrefsyms; i++)
636        {
637          bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
638
639          printf ("   %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
640          if (symtab && symtab->symbols
641              && ref->isym < symtab->nsyms
642              && symtab->symbols[ref->isym].symbol.name)
643            printf (" %s", symtab->symbols[ref->isym].symbol.name);
644          printf ("\n");
645        }
646    }
647
648}
649
650static bool
651load_and_dump (bfd *abfd, ufile_ptr off, unsigned int len,
652	       void (*dump)(bfd *abfd, unsigned char *buf, unsigned int len,
653			    ufile_ptr off))
654{
655  unsigned char *buf;
656
657  if (len == 0)
658    return true;
659
660  buf = xmalloc (len);
661
662  if (bfd_seek (abfd, off, SEEK_SET) == 0
663      && bfd_bread (buf, len, abfd) == len)
664    dump (abfd, buf, len, off);
665  else
666    return false;
667
668  free (buf);
669  return true;
670}
671
672static const bfd_mach_o_xlat_name bfd_mach_o_dyld_rebase_type_name[] =
673{
674  { "pointer",      BFD_MACH_O_REBASE_TYPE_POINTER },
675  { "text_abs32",   BFD_MACH_O_REBASE_TYPE_TEXT_ABSOLUTE32 },
676  { "text_pcrel32", BFD_MACH_O_REBASE_TYPE_TEXT_PCREL32 },
677  { NULL, 0 }
678};
679
680static void
681dump_dyld_info_rebase (bfd *abfd, unsigned char *buf, unsigned int len,
682		       ufile_ptr off ATTRIBUTE_UNUSED)
683{
684  unsigned int i;
685  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
686  unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
687
688  for (i = 0; i < len; )
689    {
690      unsigned char b = buf[i++];
691      unsigned char imm = b & BFD_MACH_O_REBASE_IMMEDIATE_MASK;
692      bfd_vma leb;
693      unsigned int leblen;
694
695      printf ("   [0x%04x] 0x%02x: ", i, b);
696      switch (b & BFD_MACH_O_REBASE_OPCODE_MASK)
697	{
698	case BFD_MACH_O_REBASE_OPCODE_DONE:
699	  printf ("done\n");
700	  return;
701	case BFD_MACH_O_REBASE_OPCODE_SET_TYPE_IMM:
702	  printf ("set_type %s\n",
703		  bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
704	  break;
705	case BFD_MACH_O_REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
706	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
707	  printf ("set segment: %u and offset: 0x%08x\n",
708		  imm, (unsigned) leb);
709	  i += leblen;
710	  break;
711	case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_ULEB:
712	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
713	  printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
714	  i += leblen;
715	  break;
716	case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
717	  printf ("add addr imm scaled: %u\n", imm * ptrsize);
718	  break;
719	case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_IMM_TIMES:
720	  printf ("rebase imm times: %u\n", imm);
721	  break;
722	case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
723	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
724	  printf ("rebase uleb times: %u\n", (unsigned) leb);
725	  i += leblen;
726	  break;
727	case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
728	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
729	  printf ("rebase add addr uleb: %u\n", (unsigned) leb);
730	  i += leblen;
731	  break;
732	case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
733	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
734	  printf ("rebase uleb times (%u)", (unsigned) leb);
735	  i += leblen;
736	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
737	  printf (" skipping uleb (%u)\n", (unsigned) leb);
738	  i += leblen;
739	  break;
740	default:
741	  printf ("unknown\n");
742	  return;
743	}
744    }
745  printf ("   rebase commands without end!\n");
746}
747
748static void
749dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len,
750		     ufile_ptr off ATTRIBUTE_UNUSED)
751{
752  unsigned int i;
753  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
754  unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
755
756  for (i = 0; i < len; )
757    {
758      unsigned char b = buf[i++];
759      unsigned char imm = b & BFD_MACH_O_BIND_IMMEDIATE_MASK;
760      bfd_vma leb;
761      unsigned int leblen;
762
763      printf ("   [0x%04x] 0x%02x: ", i, b);
764      switch (b & BFD_MACH_O_BIND_OPCODE_MASK)
765	{
766	case BFD_MACH_O_BIND_OPCODE_DONE:
767	  printf ("done\n");
768	  return;
769	case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
770	  printf ("set dylib ordinal imm: %u\n", imm);
771	  break;
772	case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
773	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
774	  printf ("set dylib ordinal uleb: %u\n", imm);
775	  i += leblen;
776	  break;
777	case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
778	  imm = (imm != 0) ? imm | BFD_MACH_O_BIND_OPCODE_MASK : imm;
779	  printf ("set dylib special imm: %d\n", imm);
780	  break;
781	case BFD_MACH_O_BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
782	  printf ("set symbol trailing flags imm: 0x%02x, ", imm);
783	  for (; i < len && buf[i] != 0; i++)
784	    putchar (buf[i] >= ' ' && buf[i] < 0x7f ? buf[i] : '?');
785	  putchar ('\n');
786	  i++;
787	  break;
788	case BFD_MACH_O_BIND_OPCODE_SET_TYPE_IMM:
789	  /* Kludge: use the same table as rebase type.  */
790	  printf ("set_type %s\n",
791		  bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
792	  break;
793	case BFD_MACH_O_BIND_OPCODE_SET_ADDEND_SLEB:
794	  {
795	    bfd_signed_vma svma;
796	    svma = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
797	    printf ("set addend sleb: 0x%08x\n", (unsigned) svma);
798	    i += leblen;
799	  }
800	  break;
801	case BFD_MACH_O_BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
802	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
803	  printf ("set segment: %u and offset: 0x%08x\n",
804		  imm, (unsigned) leb);
805	  i += leblen;
806	  break;
807	case BFD_MACH_O_BIND_OPCODE_ADD_ADDR_ULEB:
808	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
809	  printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
810	  i += leblen;
811	  break;
812	case BFD_MACH_O_BIND_OPCODE_DO_BIND:
813	  printf ("do bind\n");
814	  break;
815	case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
816	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
817	  printf ("do bind add addr uleb: 0x%08x\n", (unsigned) leb);
818	  i += leblen;
819	  break;
820	case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
821	  printf ("do bind add addr imm scaled: %u\n", imm * ptrsize);
822	  break;
823	case BFD_MACH_O_BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
824	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
825	  printf ("do bind uleb times (%u)", (unsigned) leb);
826	  i += leblen;
827	  leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
828	  printf (" skipping uleb (%u)\n", (unsigned) leb);
829	  i += leblen;
830	  break;
831	default:
832	  printf ("unknown\n");
833	  return;
834	}
835    }
836  printf ("   bind commands without end!\n");
837}
838
839struct export_info_data
840{
841  const unsigned char *name;
842  struct export_info_data *next;
843};
844
845static void
846dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
847			 unsigned int off, struct export_info_data *parent,
848			 struct export_info_data *base)
849{
850  bfd_vma size;
851  unsigned int leblen;
852  unsigned int child_count;
853  unsigned int i;
854
855  size = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
856  off += leblen;
857
858  if (size != 0)
859    {
860      bfd_vma flags;
861      struct export_info_data *d;
862
863      flags = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
864      off += leblen;
865
866      fputs ("   ", stdout);
867      switch (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_MASK)
868	{
869	case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_REGULAR:
870	  putchar ('-');
871	  break;
872	case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL:
873	  putchar ('T');
874	  break;
875	default:
876	  putchar ('?');
877	  break;
878	}
879      putchar ((flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION) ?
880	       'W' : '-');
881
882      if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_REEXPORT)
883	{
884	  bfd_vma lib;
885
886	  lib = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
887	  off += leblen;
888
889	  fputs (" [reexport] ", stdout);
890	  for (d = base; d != NULL; d = d->next)
891	    printf ("%s", d->name);
892
893	  fputs (" (", stdout);
894	  if (buf[off] != 0)
895	    {
896	      fputs ((const char *)buf + off, stdout);
897	      putchar (' ');
898	      off += strlen ((const char *)buf + off);
899	    }
900	  printf ("from dylib %u)\n", (unsigned) lib);
901	  off++;
902	}
903      else
904	{
905	  bfd_vma offset;
906	  bfd_vma resolv = 0;
907
908	  offset = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
909	  off += leblen;
910
911	  if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
912	    {
913	      resolv = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
914	      off += leblen;
915	    }
916
917	  printf (" 0x%08x ", (unsigned) offset);
918	  for (d = base; d != NULL; d = d->next)
919	    printf ("%s", d->name);
920	  if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
921	    printf (" [resolv: 0x%08x]", (unsigned) resolv);
922	  printf ("\n");
923	}
924    }
925
926  child_count = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
927  off += leblen;
928
929  for (i = 0; i < child_count; i++)
930    {
931      struct export_info_data sub_data;
932      bfd_vma sub_off;
933
934      sub_data.name = buf + off;
935      sub_data.next = NULL;
936      parent->next = &sub_data;
937
938      off += strlen ((const char *)buf + off) + 1;
939
940      sub_off = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
941      off += leblen;
942
943      dump_dyld_info_export_1 (abfd, buf, len, sub_off, &sub_data, base);
944    }
945}
946
947static void
948dump_dyld_info_export (bfd *abfd, unsigned char *buf, unsigned int len,
949		       ufile_ptr off ATTRIBUTE_UNUSED)
950{
951  struct export_info_data data;
952
953  data.name = (const unsigned char *) "";
954  data.next = NULL;
955
956  printf ("   fl offset     sym        (Flags: Tls Weak)\n");
957  dump_dyld_info_export_1 (abfd, buf, len, 0, &data, &data);
958}
959
960static void
961dump_dyld_info (bfd *abfd, bfd_mach_o_load_command *cmd,
962		bool verbose)
963{
964  bfd_mach_o_dyld_info_command *dinfo = &cmd->command.dyld_info;
965
966  printf ("       rebase: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
967	  dinfo->rebase_off, dinfo->rebase_size,
968	  dinfo->rebase_off + dinfo->rebase_size);
969  printf ("         bind: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
970	  dinfo->bind_off, dinfo->bind_size,
971	  dinfo->bind_off + dinfo->bind_size);
972  printf ("    weak bind: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
973	  dinfo->weak_bind_off, dinfo->weak_bind_size,
974	  dinfo->weak_bind_off + dinfo->weak_bind_size);
975  printf ("    lazy bind: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
976	  dinfo->lazy_bind_off, dinfo->lazy_bind_size,
977	  dinfo->lazy_bind_off + dinfo->lazy_bind_size);
978  printf ("       export: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
979	  dinfo->export_off, dinfo->export_size,
980	  dinfo->export_off + dinfo->export_size);
981
982  if (!verbose)
983    return;
984
985  printf ("   rebase:\n");
986  if (!load_and_dump (abfd, dinfo->rebase_off, dinfo->rebase_size,
987		      dump_dyld_info_rebase))
988    non_fatal (_("cannot read rebase dyld info"));
989
990  printf ("   bind:\n");
991  if (!load_and_dump (abfd, dinfo->bind_off, dinfo->bind_size,
992		      dump_dyld_info_bind))
993    non_fatal (_("cannot read bind dyld info"));
994
995  printf ("   weak bind:\n");
996  if (!load_and_dump (abfd, dinfo->weak_bind_off, dinfo->weak_bind_size,
997		      dump_dyld_info_bind))
998    non_fatal (_("cannot read weak bind dyld info"));
999
1000  printf ("   lazy bind:\n");
1001  if (!load_and_dump (abfd, dinfo->lazy_bind_off, dinfo->lazy_bind_size,
1002		      dump_dyld_info_bind))
1003    non_fatal (_("cannot read lazy bind dyld info"));
1004
1005  printf ("   exported symbols:\n");
1006  if (!load_and_dump (abfd, dinfo->export_off, dinfo->export_size,
1007		      dump_dyld_info_export))
1008    non_fatal (_("cannot read export symbols dyld info"));
1009}
1010
1011static void
1012dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
1013{
1014  bfd_mach_o_thread_command *thread = &cmd->command.thread;
1015  unsigned int j;
1016  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1017  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1018
1019  printf (" nflavours: %lu\n", thread->nflavours);
1020  for (j = 0; j < thread->nflavours; j++)
1021    {
1022      bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
1023      const bfd_mach_o_xlat_name *name_table;
1024
1025      printf ("  %2u: flavour: 0x%08lx", j, flavour->flavour);
1026      switch (mdata->header.cputype)
1027        {
1028        case BFD_MACH_O_CPU_TYPE_I386:
1029        case BFD_MACH_O_CPU_TYPE_X86_64:
1030          name_table = bfd_mach_o_thread_x86_name;
1031          break;
1032        default:
1033          name_table = NULL;
1034          break;
1035        }
1036      if (name_table != NULL)
1037        printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
1038      putchar ('\n');
1039
1040      printf ("       offset: 0x%08lx  size: 0x%08lx\n",
1041              flavour->offset, flavour->size);
1042      if (bed->_bfd_mach_o_print_thread)
1043        {
1044          char *buf = xmalloc (flavour->size);
1045
1046          if (bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
1047              && bfd_bread (buf, flavour->size, abfd) == flavour->size)
1048            (*bed->_bfd_mach_o_print_thread)(abfd, flavour, stdout, buf);
1049
1050          free (buf);
1051        }
1052    }
1053}
1054
1055static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic[] =
1056{
1057  { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE },
1058  { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT },
1059  { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS },
1060  { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY },
1061  { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS },
1062  { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER },
1063  { NULL, 0 }
1064};
1065
1066static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type[] =
1067{
1068  { "no-hash", BFD_MACH_O_CS_NO_HASH },
1069  { "sha1", BFD_MACH_O_CS_HASH_SHA1 },
1070  { "sha256", BFD_MACH_O_CS_HASH_SHA256 },
1071  { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256 },
1072  { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512 },
1073  { NULL, 0 }
1074};
1075
1076static unsigned int
1077dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
1078
1079static void
1080dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
1081                               const unsigned char *buf, unsigned int len)
1082{
1083  unsigned int count;
1084  unsigned int i;
1085
1086  if (len < 12)
1087    {
1088      printf (_("  [bad block length]\n"));
1089      return;
1090    }
1091  count = bfd_getb32 (buf + 8);
1092  printf (ngettext ("  %u index entry:\n",
1093		    "  %u index entries:\n",
1094		    count),
1095	  count);
1096  if (len < 12 + 8 * count)
1097    {
1098      printf (_("  [bad block length]\n"));
1099      return;
1100    }
1101  for (i = 0; i < count; i++)
1102    {
1103      unsigned int type;
1104      unsigned int off;
1105
1106      type = bfd_getb32 (buf + 12 + 8 * i);
1107      off = bfd_getb32 (buf + 12 + 8 * i + 4);
1108      printf (_("  index entry %u: type: %08x, offset: %08x\n"),
1109              i, type, off);
1110
1111      dump_code_signature_blob (abfd, buf + off, len - off);
1112    }
1113}
1114
1115static void
1116swap_code_codedirectory_v1_in
1117  (const struct mach_o_codesign_codedirectory_external_v1 *src,
1118   struct mach_o_codesign_codedirectory_v1 *dst)
1119{
1120  dst->version = bfd_getb32 (src->version);
1121  dst->flags = bfd_getb32 (src->flags);
1122  dst->hash_offset = bfd_getb32 (src->hash_offset);
1123  dst->ident_offset = bfd_getb32 (src->ident_offset);
1124  dst->nbr_special_slots = bfd_getb32 (src->nbr_special_slots);
1125  dst->nbr_code_slots = bfd_getb32 (src->nbr_code_slots);
1126  dst->code_limit = bfd_getb32 (src->code_limit);
1127  dst->hash_size = src->hash_size[0];
1128  dst->hash_type = src->hash_type[0];
1129  dst->spare1 = src->spare1[0];
1130  dst->page_size = src->page_size[0];
1131  dst->spare2 = bfd_getb32 (src->spare2);
1132}
1133
1134static void
1135hexdump (unsigned int start, unsigned int len,
1136         const unsigned char *buf)
1137{
1138  unsigned int i, j;
1139
1140  for (i = 0; i < len; i += 16)
1141    {
1142      printf ("%08x:", start + i);
1143      for (j = 0; j < 16; j++)
1144        {
1145          fputc (j == 8 ? '-' : ' ', stdout);
1146          if (i + j < len)
1147            printf ("%02x", buf[i + j]);
1148          else
1149            fputs ("  ", stdout);
1150        }
1151      fputc (' ', stdout);
1152      for (j = 0; j < 16; j++)
1153        {
1154          if (i + j < len)
1155            fputc (ISPRINT (buf[i + j]) ? buf[i + j] : '.', stdout);
1156          else
1157            fputc (' ', stdout);
1158        }
1159      fputc ('\n', stdout);
1160    }
1161}
1162
1163static void
1164dump_code_signature_codedirectory (bfd *abfd ATTRIBUTE_UNUSED,
1165                                   const unsigned char *buf, unsigned int len)
1166{
1167  struct mach_o_codesign_codedirectory_v1 cd;
1168  const char *id;
1169
1170  if (len < sizeof (struct mach_o_codesign_codedirectory_external_v1))
1171    {
1172      printf (_("  [bad block length]\n"));
1173      return;
1174    }
1175
1176  swap_code_codedirectory_v1_in
1177    ((const struct mach_o_codesign_codedirectory_external_v1 *) (buf + 8), &cd);
1178
1179  printf (_("  version:           %08x\n"), cd.version);
1180  printf (_("  flags:             %08x\n"), cd.flags);
1181  printf (_("  hash offset:       %08x\n"), cd.hash_offset);
1182  id = (const char *) buf + cd.ident_offset;
1183  printf (_("  ident offset:      %08x (- %08x)\n"),
1184          cd.ident_offset, cd.ident_offset + (unsigned) strlen (id) + 1);
1185  printf (_("   identity: %s\n"), id);
1186  printf (_("  nbr special slots: %08x (at offset %08x)\n"),
1187          cd.nbr_special_slots,
1188          cd.hash_offset - cd.nbr_special_slots * cd.hash_size);
1189  printf (_("  nbr code slots:    %08x\n"), cd.nbr_code_slots);
1190  printf (_("  code limit:        %08x\n"), cd.code_limit);
1191  printf (_("  hash size:         %02x\n"), cd.hash_size);
1192  printf (_("  hash type:         %02x (%s)\n"),
1193          cd.hash_type,
1194          bfd_mach_o_get_name (bfd_mach_o_cs_hash_type, cd.hash_type));
1195  printf (_("  spare1:            %02x\n"), cd.spare1);
1196  printf (_("  page size:         %02x\n"), cd.page_size);
1197  printf (_("  spare2:            %08x\n"), cd.spare2);
1198  if (cd.version >= 0x20100)
1199    printf (_("  scatter offset:    %08x\n"),
1200            (unsigned) bfd_getb32 (buf + 44));
1201}
1202
1203static unsigned int
1204dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len)
1205{
1206  unsigned int magic;
1207  unsigned int length;
1208
1209  if (len < 8)
1210    {
1211      printf (_("  [truncated block]\n"));
1212      return 0;
1213    }
1214  magic = bfd_getb32 (buf);
1215  length = bfd_getb32 (buf + 4);
1216  if (magic == 0 || length == 0)
1217    return 0;
1218
1219  printf (_(" magic : %08x (%s)\n"), magic,
1220          bfd_mach_o_get_name (bfd_mach_o_cs_magic, magic));
1221  printf (_(" length: %08x\n"), length);
1222  if (length > len)
1223    {
1224      printf (_("  [bad block length]\n"));
1225      return 0;
1226    }
1227
1228  switch (magic)
1229    {
1230    case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE:
1231      dump_code_signature_superblob (abfd, buf, length);
1232      break;
1233    case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY:
1234      dump_code_signature_codedirectory (abfd, buf, length);
1235      break;
1236    default:
1237      hexdump (0, length - 8, buf + 8);
1238      break;
1239    }
1240  return length;
1241}
1242
1243static void
1244dump_code_signature (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1245{
1246  unsigned char *buf = xmalloc (cmd->datasize);
1247  unsigned int off;
1248
1249  if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1250      || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1251    {
1252      non_fatal (_("cannot read code signature data"));
1253      free (buf);
1254      return;
1255    }
1256  for (off = 0; off < cmd->datasize;)
1257    {
1258      unsigned int len;
1259
1260      len = dump_code_signature_blob (abfd, buf + off, cmd->datasize - off);
1261
1262      if (len == 0)
1263        break;
1264      off += len;
1265    }
1266  free (buf);
1267}
1268
1269static void
1270dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1271{
1272  unsigned char *buf = xmalloc (cmd->datasize);
1273  unsigned char *p;
1274  unsigned int len;
1275  bfd_vma addr = 0;
1276
1277  if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1278      || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1279    {
1280      non_fatal (_("cannot read segment split info"));
1281      free (buf);
1282      return;
1283    }
1284  if (buf[cmd->datasize - 1] != 0)
1285    {
1286      non_fatal (_("segment split info is not nul terminated"));
1287      free (buf);
1288      return;
1289    }
1290
1291  switch (buf[0])
1292    {
1293    case 0:
1294      printf (_("  32 bit pointers:\n"));
1295      break;
1296    case 1:
1297      printf (_("  64 bit pointers:\n"));
1298      break;
1299    case 2:
1300      printf (_("  PPC hi-16:\n"));
1301      break;
1302    default:
1303      printf (_("  Unhandled location type %u\n"), buf[0]);
1304      break;
1305    }
1306  for (p = buf + 1; *p != 0; p += len)
1307    {
1308      addr += read_leb128 (p, buf + cmd->datasize, 0, &len, NULL);
1309      fputs ("    ", stdout);
1310      bfd_printf_vma (abfd, addr);
1311      putchar ('\n');
1312    }
1313  free (buf);
1314}
1315
1316static void
1317dump_function_starts (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1318{
1319  unsigned char *buf = xmalloc (cmd->datasize);
1320  unsigned char *end_buf = buf + cmd->datasize;
1321  unsigned char *p;
1322  bfd_vma addr;
1323
1324  if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1325      || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1326    {
1327      non_fatal (_("cannot read function starts"));
1328      free (buf);
1329      return;
1330    }
1331
1332  /* Function starts are delta encoded, starting from the base address.  */
1333  addr = bfd_mach_o_get_base_address (abfd);
1334
1335  for (p = buf; ;)
1336    {
1337      bfd_vma delta = 0;
1338      unsigned int shift = 0;
1339
1340      if (*p == 0 || p == end_buf)
1341	break;
1342      while (1)
1343	{
1344	  unsigned char b = *p++;
1345
1346	  delta |= (b & 0x7f) << shift;
1347	  if ((b & 0x80) == 0)
1348	    break;
1349	  if (p == end_buf)
1350	    {
1351	      fputs ("   [truncated]\n", stdout);
1352	      break;
1353	    }
1354	  shift += 7;
1355	}
1356
1357      addr += delta;
1358      fputs ("    ", stdout);
1359      bfd_printf_vma (abfd, addr);
1360      putchar ('\n');
1361    }
1362  free (buf);
1363}
1364
1365static const bfd_mach_o_xlat_name data_in_code_kind_name[] =
1366{
1367  { "data", BFD_MACH_O_DICE_KIND_DATA },
1368  { "1 byte jump table", BFD_MACH_O_DICE_JUMP_TABLES8 },
1369  { "2 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES16 },
1370  { "4 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES32 },
1371  { "4 bytes abs jump table", BFD_MACH_O_DICE_ABS_JUMP_TABLES32 },
1372  { NULL, 0 }
1373};
1374
1375static void
1376dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1377{
1378  unsigned char *buf;
1379  unsigned char *p;
1380
1381  if (cmd->datasize == 0)
1382    {
1383      printf ("   no data_in_code entries\n");
1384      return;
1385    }
1386
1387  buf = xmalloc (cmd->datasize);
1388  if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1389      || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1390    {
1391      non_fatal (_("cannot read data_in_code"));
1392      free (buf);
1393      return;
1394    }
1395
1396  printf ("   offset     length kind\n");
1397  for (p = buf; p < buf + cmd->datasize; )
1398    {
1399      struct mach_o_data_in_code_entry_external *dice;
1400      unsigned int offset;
1401      unsigned int length;
1402      unsigned int kind;
1403
1404      dice = (struct mach_o_data_in_code_entry_external *) p;
1405
1406      offset = bfd_get_32 (abfd, dice->offset);
1407      length = bfd_get_16 (abfd, dice->length);
1408      kind = bfd_get_16 (abfd, dice->kind);
1409
1410      printf ("   0x%08x 0x%04x 0x%04x %s\n", offset, length, kind,
1411	      bfd_mach_o_get_name (data_in_code_kind_name, kind));
1412
1413      p += sizeof (*dice);
1414    }
1415  free (buf);
1416}
1417
1418static void
1419dump_twolevel_hints (bfd *abfd, bfd_mach_o_twolevel_hints_command *cmd)
1420{
1421  size_t sz = 4 * cmd->nhints;
1422  unsigned char *buf;
1423  unsigned char *p;
1424
1425  buf = xmalloc (sz);
1426  if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
1427      || bfd_bread (buf, sz, abfd) != sz)
1428    {
1429      non_fatal (_("cannot read twolevel hints"));
1430      free (buf);
1431      return;
1432    }
1433
1434  for (p = buf; p < buf + sz; p += 4)
1435    {
1436      unsigned int v;
1437      unsigned int isub_image;
1438      unsigned int itoc;
1439
1440      v = bfd_get_32 (abfd, p);
1441      if (bfd_big_endian (abfd))
1442	{
1443	  isub_image = (v >> 24) & 0xff;
1444	  itoc = v & 0xffffff;
1445	}
1446      else
1447	{
1448	  isub_image = v & 0xff;
1449	  itoc = (v >> 8) & 0xffffff;
1450	}
1451
1452      printf ("  %3u %8u\n", isub_image, itoc);
1453    }
1454  free (buf);
1455}
1456
1457static void
1458printf_version (uint32_t version)
1459{
1460  uint32_t maj, min, upd;
1461
1462  maj = (version >> 16) & 0xffff;
1463  min = (version >> 8) & 0xff;
1464  upd = version & 0xff;
1465
1466  printf ("%u.%u.%u", maj, min, upd);
1467}
1468
1469static void
1470dump_build_version (bfd *abfd, bfd_mach_o_load_command *cmd)
1471{
1472  const char *platform_name;
1473  size_t tools_len, tools_offset;
1474  bfd_mach_o_build_version_tool *tools, *tool;
1475  bfd_mach_o_build_version_command *ver = &cmd->command.build_version;
1476  uint32_t i;
1477
1478  platform_name = bfd_mach_o_get_name_or_null
1479    (bfd_mach_o_platform_name, ver->platform);
1480  if (platform_name == NULL)
1481    printf ("   platform: 0x%08x\n", ver->platform);
1482  else
1483    printf ("   platform: %s\n", platform_name);
1484  printf ("   os:       ");
1485  printf_version (ver->minos);
1486  printf ("\n   sdk:      ");
1487  printf_version (ver->sdk);
1488  printf ("\n   ntools:   %u\n", ver->ntools);
1489
1490  tools_len = sizeof (bfd_mach_o_build_version_tool) * ver->ntools;
1491  tools_offset = cmd->offset + cmd->len - tools_len;
1492
1493  tools = xmalloc (tools_len);
1494  if (bfd_seek (abfd, tools_offset, SEEK_SET) != 0
1495      || bfd_bread (tools, tools_len, abfd) != tools_len)
1496    {
1497      non_fatal (_("cannot read build tools"));
1498      free (tools);
1499      return;
1500    }
1501
1502  for (i = 0, tool = tools; i < ver->ntools; i++, tool++)
1503    {
1504      const char * tool_name;
1505
1506      tool_name = bfd_mach_o_get_name_or_null
1507	(bfd_mach_o_tool_name, tool->tool);
1508      if (tool_name == NULL)
1509	printf ("   tool:     0x%08x\n", tool->tool);
1510      else
1511	printf ("   tool:     %s\n", tool_name);
1512      printf ("   version:  ");
1513      printf_version (tool->version);
1514      printf ("\n");
1515    }
1516  free (tools);
1517}
1518
1519static void
1520dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
1521                   unsigned int idx, bool verbose)
1522{
1523  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1524  const char *cmd_name;
1525
1526  cmd_name = bfd_mach_o_get_name_or_null
1527    (bfd_mach_o_load_command_name, cmd->type);
1528  printf ("Load command #%-2u (size: %3u, offset: %4u): ",
1529	  idx, cmd->len, cmd->offset);
1530  if (cmd_name == NULL)
1531    printf ("0x%02x\n", cmd->type);
1532  else
1533    printf ("%s\n", cmd_name);
1534
1535  switch (cmd->type)
1536    {
1537    case BFD_MACH_O_LC_SEGMENT:
1538    case BFD_MACH_O_LC_SEGMENT_64:
1539      dump_segment (abfd, cmd);
1540      break;
1541    case BFD_MACH_O_LC_UUID:
1542      {
1543        bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
1544        unsigned int j;
1545
1546	printf ("   ");
1547        for (j = 0; j < sizeof (uuid->uuid); j ++)
1548          printf (" %02x", uuid->uuid[j]);
1549        putchar ('\n');
1550      }
1551      break;
1552    case BFD_MACH_O_LC_LOAD_DYLIB:
1553    case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
1554    case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1555    case BFD_MACH_O_LC_REEXPORT_DYLIB:
1556    case BFD_MACH_O_LC_ID_DYLIB:
1557    case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
1558      {
1559        bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
1560        printf ("  name: %s\n", dylib->name_str);
1561        printf ("            time stamp: 0x%08lx\n",
1562                dylib->timestamp);
1563        printf ("       current version: 0x%08lx\n",
1564                dylib->current_version);
1565        printf ("  comptibility version: 0x%08lx\n",
1566                dylib->compatibility_version);
1567      }
1568      break;
1569    case BFD_MACH_O_LC_LOAD_DYLINKER:
1570    case BFD_MACH_O_LC_ID_DYLINKER:
1571      printf ("    %s\n", cmd->command.dylinker.name_str);
1572      break;
1573    case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
1574      printf ("    %s\n", cmd->command.dylinker.name_str);
1575      break;
1576    case BFD_MACH_O_LC_SYMTAB:
1577      {
1578        bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
1579        printf ("   symoff: 0x%08x    nsyms: %8u  (endoff: 0x%08x)\n",
1580                symtab->symoff, symtab->nsyms,
1581                symtab->symoff + symtab->nsyms
1582                * (mdata->header.version == 2
1583                   ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
1584        printf ("   stroff: 0x%08x  strsize: %8u  (endoff: 0x%08x)\n",
1585                symtab->stroff, symtab->strsize,
1586                symtab->stroff + symtab->strsize);
1587        break;
1588      }
1589    case BFD_MACH_O_LC_DYSYMTAB:
1590      dump_dysymtab (abfd, cmd, verbose);
1591      break;
1592    case BFD_MACH_O_LC_LOADFVMLIB:
1593    case BFD_MACH_O_LC_IDFVMLIB:
1594      {
1595        bfd_mach_o_fvmlib_command *fvmlib = &cmd->command.fvmlib;
1596        printf ("                fvmlib: %s\n", fvmlib->name_str);
1597        printf ("         minor version: 0x%08x\n", fvmlib->minor_version);
1598        printf ("        header address: 0x%08x\n", fvmlib->header_addr);
1599      }
1600      break;
1601    case BFD_MACH_O_LC_CODE_SIGNATURE:
1602    case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1603    case BFD_MACH_O_LC_FUNCTION_STARTS:
1604    case BFD_MACH_O_LC_DATA_IN_CODE:
1605    case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
1606    case BFD_MACH_O_LC_DYLD_EXPORTS_TRIE:
1607    case BFD_MACH_O_LC_DYLD_CHAINED_FIXUPS:
1608      {
1609        bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
1610        printf
1611          ("  dataoff: 0x%08lx  datasize: 0x%08lx  (endoff: 0x%08lx)\n",
1612           linkedit->dataoff, linkedit->datasize,
1613           linkedit->dataoff + linkedit->datasize);
1614
1615	if (verbose)
1616	  switch (cmd->type)
1617	    {
1618	    case BFD_MACH_O_LC_CODE_SIGNATURE:
1619	      dump_code_signature (abfd, linkedit);
1620	      break;
1621	    case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1622	      dump_segment_split_info (abfd, linkedit);
1623	      break;
1624	    case BFD_MACH_O_LC_FUNCTION_STARTS:
1625	      dump_function_starts (abfd, linkedit);
1626	      break;
1627	    case BFD_MACH_O_LC_DATA_IN_CODE:
1628	      dump_data_in_code (abfd, linkedit);
1629	      break;
1630	    default:
1631	      break;
1632	    }
1633      }
1634      break;
1635    case BFD_MACH_O_LC_SUB_FRAMEWORK:
1636    case BFD_MACH_O_LC_SUB_UMBRELLA:
1637    case BFD_MACH_O_LC_SUB_LIBRARY:
1638    case BFD_MACH_O_LC_SUB_CLIENT:
1639    case BFD_MACH_O_LC_RPATH:
1640      {
1641        bfd_mach_o_str_command *strc = &cmd->command.str;
1642        printf ("    %s\n", strc->str);
1643        break;
1644      }
1645    case BFD_MACH_O_LC_THREAD:
1646    case BFD_MACH_O_LC_UNIXTHREAD:
1647      dump_thread (abfd, cmd);
1648      break;
1649    case BFD_MACH_O_LC_ENCRYPTION_INFO:
1650      {
1651        bfd_mach_o_encryption_info_command *cryp =
1652          &cmd->command.encryption_info;
1653        printf ("  cryptoff: 0x%08x  cryptsize: 0x%08x (endoff 0x%08x)"
1654		" cryptid: %u\n",
1655		cryp->cryptoff, cryp->cryptsize,
1656		cryp->cryptoff + cryp->cryptsize,
1657		cryp->cryptid);
1658      }
1659      break;
1660    case BFD_MACH_O_LC_DYLD_INFO:
1661      dump_dyld_info (abfd, cmd, verbose);
1662      break;
1663    case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
1664    case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
1665    case BFD_MACH_O_LC_VERSION_MIN_WATCHOS:
1666    case BFD_MACH_O_LC_VERSION_MIN_TVOS:
1667      {
1668        bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
1669
1670        printf ("   os: ");
1671        printf_version (ver->version);
1672        printf ("\n   sdk: ");
1673        printf_version (ver->sdk);
1674        printf ("\n");
1675      }
1676      break;
1677    case BFD_MACH_O_LC_SOURCE_VERSION:
1678      {
1679        bfd_mach_o_source_version_command *version =
1680	  &cmd->command.source_version;
1681        printf ("   version a.b.c.d.e: %u.%u.%u.%u.%u\n",
1682		version->a, version->b, version->c, version->d, version->e);
1683        break;
1684      }
1685    case BFD_MACH_O_LC_PREBOUND_DYLIB:
1686      {
1687        bfd_mach_o_prebound_dylib_command *pbdy = &cmd->command.prebound_dylib;
1688	unsigned char *lm = pbdy->linked_modules;
1689	unsigned int j;
1690	unsigned int last;
1691
1692        printf ("      dylib: %s\n", pbdy->name_str);
1693        printf ("   nmodules: %u\n", pbdy->nmodules);
1694	printf ("   linked modules (at %u): ",
1695		pbdy->linked_modules_offset - cmd->offset);
1696	last = pbdy->nmodules > 32 ? 32 : pbdy->nmodules;
1697	for (j = 0; j < last; j++)
1698	  printf ("%u", (lm[j >> 3] >> (j & 7)) & 1);
1699	if (last < pbdy->nmodules)
1700	  printf ("...");
1701	putchar ('\n');
1702        break;
1703      }
1704    case BFD_MACH_O_LC_PREBIND_CKSUM:
1705      {
1706        bfd_mach_o_prebind_cksum_command *cksum = &cmd->command.prebind_cksum;
1707        printf ("   0x%08x\n", cksum->cksum);
1708        break;
1709      }
1710    case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1711      {
1712        bfd_mach_o_twolevel_hints_command *hints =
1713	  &cmd->command.twolevel_hints;
1714
1715        printf ("   table offset: 0x%08x  nbr hints: %u\n",
1716		hints->offset, hints->nhints);
1717	if (verbose)
1718	  dump_twolevel_hints (abfd, hints);
1719        break;
1720      }
1721    case BFD_MACH_O_LC_MAIN:
1722      {
1723	bfd_mach_o_main_command *entry = &cmd->command.main;
1724	printf ("   entry offset: %#016" PRIx64 "\n"
1725		"   stack size:   %#016" PRIx64 "\n",
1726		entry->entryoff, entry->stacksize);
1727	break;
1728      }
1729    case BFD_MACH_O_LC_NOTE:
1730      {
1731	bfd_mach_o_note_command *note = &cmd->command.note;
1732	printf ("   data owner: %.16s\n"
1733		"   offset:     %#016" PRIx64 "\n"
1734		"   size:       %#016" PRIx64 "\n",
1735		note->data_owner, note->offset, note->size);
1736	break;
1737      }
1738    case BFD_MACH_O_LC_BUILD_VERSION:
1739      dump_build_version (abfd, cmd);
1740      break;
1741    default:
1742      break;
1743    }
1744  putchar ('\n');
1745}
1746
1747static void
1748dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
1749{
1750  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1751  bfd_mach_o_load_command *cmd;
1752  unsigned int i;
1753
1754  for (cmd = mdata->first_command, i = 0; cmd != NULL; cmd = cmd->next, i++)
1755    {
1756      if (cmd32 == 0)
1757        dump_load_command (abfd, cmd, i, false);
1758      else if (cmd->type == cmd32 || cmd->type == cmd64)
1759        dump_load_command (abfd, cmd, i, true);
1760    }
1761}
1762
1763static const char * const unwind_x86_64_regs[] =
1764  {"", "rbx", "r12", "r13", "r14", "r15", "rbp", "???" };
1765
1766static const char * const unwind_x86_regs[] =
1767  {"", "ebx", "ecx", "edx", "edi", "edi", "ebp", "???" };
1768
1769/* Dump x86 or x86-64 compact unwind encoding.  Works for both architecture,
1770   as the encoding is the same (but not register names).  */
1771
1772static void
1773dump_unwind_encoding_x86 (unsigned int encoding, unsigned int sz,
1774			  const char * const regs_name[])
1775{
1776  unsigned int mode;
1777
1778  mode = encoding & MACH_O_UNWIND_X86_64_MODE_MASK;
1779  switch (mode)
1780    {
1781    case MACH_O_UNWIND_X86_64_MODE_RBP_FRAME:
1782      {
1783	unsigned int regs;
1784	char pfx = sz == 8 ? 'R' : 'E';
1785
1786	regs = encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_REGISTERS;
1787	printf (" %cSP frame", pfx);
1788	if (regs != 0)
1789	  {
1790	    unsigned int offset;
1791	    int i;
1792
1793	    offset = (encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET) >> 16;
1794	    printf (" at %cBP-%u:", pfx, offset * sz);
1795	    for (i = 0; i < 5; i++)
1796	      {
1797		unsigned int reg = (regs >> (i * 3)) & 0x7;
1798		if (reg != MACH_O_UNWIND_X86_64_REG_NONE)
1799		  printf (" %s", regs_name[reg]);
1800	      }
1801	  }
1802      }
1803      break;
1804    case MACH_O_UNWIND_X86_64_MODE_STACK_IMMD:
1805    case MACH_O_UNWIND_X86_64_MODE_STACK_IND:
1806      {
1807	unsigned int stack_size;
1808	unsigned int reg_count;
1809	unsigned int reg_perm;
1810	unsigned int regs[6];
1811	int i, j;
1812
1813	printf (" frameless");
1814	stack_size =
1815	  (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE) >> 16;
1816	reg_count =
1817	  (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT) >> 10;
1818	reg_perm = encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION;
1819
1820	if (mode == MACH_O_UNWIND_X86_64_MODE_STACK_IMMD)
1821	  printf (" size: 0x%03x", stack_size * sz);
1822	else
1823	  {
1824	    unsigned int stack_adj;
1825
1826	    stack_adj =
1827	      (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST) >> 13;
1828	    printf (" size at 0x%03x + 0x%02x", stack_size, stack_adj * sz);
1829	  }
1830	/* Registers are coded using arithmetic compression: the register
1831	   is indexed in range 0-6, the second in range 0-5, the third in
1832	   range 0-4, etc.  Already used registers are removed in next
1833	   ranges.  */
1834#define DO_PERM(R, NUM) R = reg_perm / NUM; reg_perm -= R * NUM
1835	switch (reg_count)
1836	  {
1837	  case 6:
1838	  case 5:
1839	    DO_PERM (regs[0], 120);
1840	    DO_PERM (regs[1], 24);
1841	    DO_PERM (regs[2], 6);
1842	    DO_PERM (regs[3], 2);
1843	    DO_PERM (regs[4], 1);
1844	    regs[5] = 0; /* Not used if reg_count = 5.  */
1845	    break;
1846	  case 4:
1847	    DO_PERM (regs[0], 60);
1848	    DO_PERM (regs[1], 12);
1849	    DO_PERM (regs[2], 3);
1850	    DO_PERM (regs[3], 1);
1851	    break;
1852	  case 3:
1853	    DO_PERM (regs[0], 20);
1854	    DO_PERM (regs[1], 4);
1855	    DO_PERM (regs[2], 1);
1856	    break;
1857	  case 2:
1858	    DO_PERM (regs[0], 5);
1859	    DO_PERM (regs[1], 1);
1860	    break;
1861	  case 1:
1862	    DO_PERM (regs[0], 1);
1863	    break;
1864	  case 0:
1865	    break;
1866	  default:
1867	    printf (" [bad reg count]");
1868	    return;
1869	  }
1870#undef DO_PERM
1871	/* Renumber.  */
1872	for (i = reg_count - 1; i >= 0; i--)
1873	  {
1874	    unsigned int inc = 1;
1875	    for (j = 0; j < i; j++)
1876	      if (regs[i] >= regs[j])
1877		inc++;
1878	    regs[i] += inc;
1879	  }
1880	/* Display.  */
1881	for (i = 0; i < (int) reg_count; i++)
1882	  printf (" %s", regs_name[regs[i]]);
1883      }
1884      break;
1885    case MACH_O_UNWIND_X86_64_MODE_DWARF:
1886      printf (" Dwarf offset: 0x%06x",
1887	      encoding & MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET);
1888      break;
1889    default:
1890      printf (" [unhandled mode]");
1891      break;
1892    }
1893}
1894
1895/* Dump arm64 compact unwind entries.  */
1896
1897static void
1898dump_unwind_encoding_arm64 (unsigned int encoding)
1899{
1900  switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1901    {
1902    case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1903      printf (" frameless");
1904      break;
1905    case MACH_O_UNWIND_ARM64_MODE_DWARF:
1906      printf (" Dwarf offset: 0x%06x",
1907	      encoding & MACH_O_UNWIND_ARM64_DWARF_SECTION_OFFSET);
1908      return;
1909    case MACH_O_UNWIND_ARM64_MODE_FRAME:
1910      printf (" frame");
1911      break;
1912    default:
1913      printf (" [unhandled mode]");
1914      return;
1915    }
1916  switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1917    {
1918    case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1919    case MACH_O_UNWIND_ARM64_MODE_FRAME:
1920      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X19_X20_PAIR)
1921	printf (" x19-x20");
1922      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X21_X22_PAIR)
1923	printf (" x21-x22");
1924      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X23_X24_PAIR)
1925	printf (" x23-x24");
1926      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X25_X26_PAIR)
1927	printf (" x25-x26");
1928      if (encoding & MACH_O_UNWIND_ARM64_FRAME_X27_X28_PAIR)
1929	printf (" x27-x28");
1930      break;
1931    }
1932  switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1933    {
1934    case MACH_O_UNWIND_ARM64_MODE_FRAME:
1935      if (encoding & MACH_O_UNWIND_ARM64_FRAME_D8_D9_PAIR)
1936	printf (" d8-d9");
1937      if (encoding & MACH_O_UNWIND_ARM64_FRAME_D10_D11_PAIR)
1938	printf (" d10-d11");
1939      if (encoding & MACH_O_UNWIND_ARM64_FRAME_D12_D13_PAIR)
1940	printf (" d12-d13");
1941      if (encoding & MACH_O_UNWIND_ARM64_FRAME_D14_D15_PAIR)
1942	printf (" d14-d15");
1943      break;
1944    case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1945      printf (" size: %u",
1946	      (encoding & MACH_O_UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK) >> 8);
1947      break;
1948    }
1949}
1950
1951static void
1952dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding)
1953{
1954  printf ("0x%08x", encoding);
1955  if (encoding == 0)
1956    return;
1957
1958  switch (mdata->header.cputype)
1959    {
1960    case BFD_MACH_O_CPU_TYPE_X86_64:
1961      dump_unwind_encoding_x86 (encoding, 8, unwind_x86_64_regs);
1962      break;
1963    case BFD_MACH_O_CPU_TYPE_I386:
1964      dump_unwind_encoding_x86 (encoding, 4, unwind_x86_regs);
1965      break;
1966    case BFD_MACH_O_CPU_TYPE_ARM64:
1967      dump_unwind_encoding_arm64 (encoding);
1968      break;
1969    default:
1970      printf (" [unhandled cpu]");
1971      break;
1972    }
1973  if (encoding & MACH_O_UNWIND_HAS_LSDA)
1974    printf (" LSDA");
1975  if (encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1976    printf (" PERS(%u)",
1977	    ((encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1978	     >> MACH_O_UNWIND_PERSONALITY_SHIFT));
1979}
1980
1981static void
1982dump_obj_compact_unwind (bfd *abfd,
1983			 const unsigned char *content, bfd_size_type size)
1984{
1985  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1986  int is_64 = mdata->header.version == 2;
1987  const unsigned char *p;
1988
1989  printf ("Compact unwind info:\n");
1990  printf (" start            length   personality      lsda\n");
1991
1992  if (is_64)
1993    {
1994      struct mach_o_compact_unwind_64 *e =
1995	(struct mach_o_compact_unwind_64 *) content;
1996
1997      for (p = content; p < content + size; p += sizeof (*e))
1998	{
1999	  e = (struct mach_o_compact_unwind_64 *) p;
2000
2001	  printf (" %#016" PRIx64 " %#08x %#016" PRIx64 " %#016" PRIx64 "\n",
2002		  (uint64_t) bfd_get_64 (abfd, e->start),
2003		  (unsigned int) bfd_get_32 (abfd, e->length),
2004		  (uint64_t) bfd_get_64 (abfd, e->personality),
2005		  (uint64_t) bfd_get_64 (abfd, e->lsda));
2006
2007	  printf ("  encoding: ");
2008	  dump_unwind_encoding (mdata, bfd_get_32 (abfd, e->encoding));
2009	  putchar ('\n');
2010	}
2011    }
2012  else
2013    {
2014      printf ("unhandled\n");
2015    }
2016}
2017
2018static void
2019dump_exe_compact_unwind (bfd *abfd,
2020			 const unsigned char *content, bfd_size_type size)
2021{
2022  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2023  struct mach_o_unwind_info_header *hdr;
2024  unsigned int version;
2025  unsigned int encodings_offset;
2026  unsigned int encodings_count;
2027  unsigned int personality_offset;
2028  unsigned int personality_count;
2029  unsigned int index_offset;
2030  unsigned int index_count;
2031  struct mach_o_unwind_index_entry *index_entry;
2032  unsigned int i;
2033
2034  /* The header.  */
2035  printf ("Compact unwind info:\n");
2036
2037  hdr = (struct mach_o_unwind_info_header *) content;
2038  if (size < sizeof (*hdr))
2039    {
2040      printf ("  truncated!\n");
2041      return;
2042    }
2043
2044  version = bfd_get_32 (abfd, hdr->version);
2045  if (version != MACH_O_UNWIND_SECTION_VERSION)
2046    {
2047      printf ("  unknown version: %u\n", version);
2048      return;
2049    }
2050  encodings_offset = bfd_get_32 (abfd, hdr->encodings_array_offset);
2051  encodings_count = bfd_get_32 (abfd, hdr->encodings_array_count);
2052  personality_offset = bfd_get_32 (abfd, hdr->personality_array_offset);
2053  personality_count = bfd_get_32 (abfd, hdr->personality_array_count);
2054  index_offset = bfd_get_32 (abfd, hdr->index_offset);
2055  index_count = bfd_get_32 (abfd, hdr->index_count);
2056  printf ("   %u encodings, %u personalities, %u level-1 indexes:\n",
2057	  encodings_count, personality_count, index_count);
2058
2059  /* Personality.  */
2060  if (personality_count > 0)
2061    {
2062      const unsigned char *pers = content + personality_offset;
2063
2064      printf ("   personalities\n");
2065      for (i = 0; i < personality_count; i++)
2066	printf ("     %u: 0x%08x\n", i,
2067		(unsigned) bfd_get_32 (abfd, pers + 4 * i));
2068    }
2069
2070  /* Level-1 index.  */
2071  printf ("   idx function   level2 off lsda off\n");
2072
2073  index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
2074  for (i = 0; i < index_count; i++)
2075    {
2076      unsigned int func_offset;
2077      unsigned int level2_offset;
2078      unsigned int lsda_offset;
2079
2080      func_offset = bfd_get_32 (abfd, index_entry->function_offset);
2081      level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
2082      lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
2083      printf ("   %3u 0x%08x 0x%08x 0x%08x\n",
2084	      i, func_offset, level2_offset, lsda_offset);
2085      index_entry++;
2086    }
2087
2088  /* Level-1 index.  */
2089  index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
2090  for (i = 0; i < index_count; i++)
2091    {
2092      unsigned int func_offset;
2093      unsigned int level2_offset;
2094      const unsigned char *level2;
2095      unsigned int kind;
2096
2097      func_offset = bfd_get_32 (abfd, index_entry->function_offset);
2098      level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
2099
2100      /* No level-2 for this index (should be the last index).  */
2101      if (level2_offset == 0)
2102	continue;
2103
2104      level2 = content + level2_offset;
2105      kind = bfd_get_32 (abfd, level2);
2106      switch (kind)
2107	{
2108	case MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED:
2109	  {
2110	    struct mach_o_unwind_compressed_second_level_page_header *l2;
2111	    unsigned int entry_offset;
2112	    unsigned int entry_count;
2113	    unsigned int l2_encodings_offset;
2114	    unsigned int l2_encodings_count;
2115	    const unsigned char *en;
2116	    unsigned int j;
2117
2118	    l2 = (struct mach_o_unwind_compressed_second_level_page_header *)
2119	      level2;
2120	    entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
2121	    entry_count = bfd_get_16 (abfd, l2->entry_count);
2122	    l2_encodings_offset = bfd_get_16 (abfd, l2->encodings_offset);
2123	    l2_encodings_count = bfd_get_16 (abfd, l2->encodings_count);
2124
2125	    printf ("   index %2u: compressed second level: "
2126		    "%u entries, %u encodings (at 0x%08x)\n",
2127		    i, entry_count, l2_encodings_count, l2_encodings_offset);
2128	    printf ("   #    function   eidx  encoding\n");
2129
2130	    en = level2 + entry_offset;
2131	    for (j = 0; j < entry_count; j++)
2132	      {
2133		unsigned int entry;
2134		unsigned int en_func;
2135		unsigned int enc_idx;
2136		unsigned int encoding;
2137		const unsigned char *enc_addr;
2138
2139		entry = bfd_get_32 (abfd, en);
2140		en_func =
2141		  MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry);
2142		enc_idx =
2143		  MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry);
2144		if (enc_idx < encodings_count)
2145		  enc_addr = content + encodings_offset
2146		    + 4 * enc_idx;
2147		else
2148		  enc_addr = level2 + l2_encodings_offset
2149		    + 4 * (enc_idx - encodings_count);
2150		encoding = bfd_get_32 (abfd, enc_addr);
2151
2152		printf ("   %4u 0x%08x [%3u] ", j,
2153			func_offset + en_func, enc_idx);
2154		dump_unwind_encoding (mdata, encoding);
2155		putchar ('\n');
2156
2157		en += 4;
2158	      }
2159	  }
2160	  break;
2161
2162	case MACH_O_UNWIND_SECOND_LEVEL_REGULAR:
2163	  {
2164	    struct mach_o_unwind_regular_second_level_page_header *l2;
2165	    struct mach_o_unwind_regular_second_level_entry *en;
2166	    unsigned int entry_offset;
2167	    unsigned int entry_count;
2168	    unsigned int j;
2169
2170	    l2 = (struct mach_o_unwind_regular_second_level_page_header *)
2171	      level2;
2172
2173	    entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
2174	    entry_count = bfd_get_16 (abfd, l2->entry_count);
2175	    printf ("   index %2u: regular level 2 at 0x%04x, %u entries\n",
2176		    i, entry_offset, entry_count);
2177	    printf ("   #    function   encoding\n");
2178
2179	    en = (struct mach_o_unwind_regular_second_level_entry *)
2180	      (level2 + entry_offset);
2181	    for (j = 0; j < entry_count; j++)
2182	      {
2183		unsigned int en_func;
2184		unsigned int encoding;
2185
2186		en_func = bfd_get_32 (abfd, en->function_offset);
2187		encoding = bfd_get_32 (abfd, en->encoding);
2188		printf ("   %-4u 0x%08x ", j, en_func);
2189		dump_unwind_encoding (mdata, encoding);
2190		putchar ('\n');
2191		en++;
2192	      }
2193	  }
2194	  break;
2195
2196	default:
2197	  printf ("   index %2u: unhandled second level format (%u)\n",
2198		  i, kind);
2199	  break;
2200	}
2201
2202      {
2203	struct mach_o_unwind_lsda_index_entry *lsda;
2204	unsigned int lsda_offset;
2205	unsigned int next_lsda_offset;
2206	unsigned int nbr_lsda;
2207	unsigned int j;
2208
2209	lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
2210	next_lsda_offset = bfd_get_32 (abfd, index_entry[1].lsda_index_offset);
2211	lsda = (struct mach_o_unwind_lsda_index_entry *)
2212	  (content + lsda_offset);
2213	nbr_lsda = (next_lsda_offset - lsda_offset) / sizeof (*lsda);
2214	for (j = 0; j < nbr_lsda; j++)
2215	  {
2216	    printf ("   lsda %3u: function 0x%08x lsda 0x%08x\n",
2217		    j, (unsigned int) bfd_get_32 (abfd, lsda->function_offset),
2218		    (unsigned int) bfd_get_32 (abfd, lsda->lsda_offset));
2219	    lsda++;
2220	  }
2221      }
2222      index_entry++;
2223    }
2224}
2225
2226static void
2227dump_section_content (bfd *abfd,
2228		      const char *segname, const char *sectname,
2229		      void (*dump)(bfd*, const unsigned char*, bfd_size_type))
2230{
2231  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2232  bfd_mach_o_load_command *cmd;
2233
2234  for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
2235    {
2236      if (cmd->type == BFD_MACH_O_LC_SEGMENT
2237	  || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
2238	{
2239	  bfd_mach_o_segment_command *seg = &cmd->command.segment;
2240	  bfd_mach_o_section *sec;
2241	  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
2242	    if (strcmp (sec->segname, segname) == 0
2243		&& strcmp (sec->sectname, sectname) == 0)
2244	      {
2245		bfd_size_type size;
2246		asection *bfdsec = sec->bfdsection;
2247		unsigned char *content;
2248
2249		size = bfd_section_size (bfdsec);
2250		content = (unsigned char *) xmalloc (size);
2251		bfd_get_section_contents (abfd, bfdsec, content, 0, size);
2252
2253		(*dump)(abfd, content, size);
2254
2255		free (content);
2256	      }
2257	}
2258    }
2259}
2260
2261/* Dump ABFD (according to the options[] array).  */
2262
2263static void
2264mach_o_dump (bfd *abfd)
2265{
2266  if (options[OPT_HEADER].selected)
2267    dump_header (abfd);
2268  if (options[OPT_SECTION].selected)
2269    dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT, BFD_MACH_O_LC_SEGMENT_64);
2270  if (options[OPT_MAP].selected)
2271    dump_section_map (abfd);
2272  if (options[OPT_LOAD].selected)
2273    dump_load_commands (abfd, 0, 0);
2274  if (options[OPT_DYSYMTAB].selected)
2275    dump_load_commands (abfd, BFD_MACH_O_LC_DYSYMTAB, 0);
2276  if (options[OPT_CODESIGN].selected)
2277    dump_load_commands (abfd, BFD_MACH_O_LC_CODE_SIGNATURE, 0);
2278  if (options[OPT_SEG_SPLIT_INFO].selected)
2279    dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO, 0);
2280  if (options[OPT_FUNCTION_STARTS].selected)
2281    dump_load_commands (abfd, BFD_MACH_O_LC_FUNCTION_STARTS, 0);
2282  if (options[OPT_DATA_IN_CODE].selected)
2283    dump_load_commands (abfd, BFD_MACH_O_LC_DATA_IN_CODE, 0);
2284  if (options[OPT_TWOLEVEL_HINTS].selected)
2285    dump_load_commands (abfd, BFD_MACH_O_LC_TWOLEVEL_HINTS, 0);
2286  if (options[OPT_COMPACT_UNWIND].selected)
2287    {
2288      dump_section_content (abfd, "__LD", "__compact_unwind",
2289			    dump_obj_compact_unwind);
2290      dump_section_content (abfd, "__TEXT", "__unwind_info",
2291			    dump_exe_compact_unwind);
2292    }
2293  if (options[OPT_DYLD_INFO].selected)
2294    dump_load_commands (abfd, BFD_MACH_O_LC_DYLD_INFO, 0);
2295}
2296
2297/* Vector for Mach-O.  */
2298
2299const struct objdump_private_desc objdump_private_desc_mach_o =
2300{
2301 mach_o_help,
2302 mach_o_filter,
2303 mach_o_dump,
2304 options
2305};
2306