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