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