1 /* od-macho.c -- dump information about an Mach-O object file.
2    Copyright (C) 2011-2016 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 "bfdlink.h"
30 #include "libbfd.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.  */
51 static 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 
70 static void
mach_o_help(FILE * stream)71 mach_o_help (FILE *stream)
72 {
73   fprintf (stream, _("\
74 For 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 
92 static int
mach_o_filter(bfd * abfd)93 mach_o_filter (bfd *abfd)
94 {
95   return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
96 }
97 
98 static 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 
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   { NULL, 0}
214 };
215 
216 static 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 
234 static void
bfd_mach_o_print_flags(const bfd_mach_o_xlat_name * table,unsigned long val)235 bfd_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 independant style.  */
263 
264 static void
printf_uint64(bfd_uint64_t v)265 printf_uint64 (bfd_uint64_t v)
266 {
267   printf ("0x%08lx%08lx",
268 	  (unsigned long)((v >> 16) >> 16), (unsigned long)(v & 0xffffffffUL));
269 }
270 
271 static const char *
bfd_mach_o_get_name_or_null(const bfd_mach_o_xlat_name * table,unsigned long val)272 bfd_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 
281 static const char *
bfd_mach_o_get_name(const bfd_mach_o_xlat_name * table,unsigned long val)282 bfd_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 
292 static void
dump_header(bfd * abfd)293 dump_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 
315 static void
disp_segment_prot(unsigned int prot)316 disp_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 
323 static void
dump_section_map(bfd * abfd)324 dump_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 
364 static void
dump_section_header(bfd * abfd ATTRIBUTE_UNUSED,bfd_mach_o_section * sec)365 dump_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 
412 static void
dump_segment(bfd * abfd ATTRIBUTE_UNUSED,bfd_mach_o_load_command * cmd)413 dump_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 
442 static void
dump_dysymtab(bfd * abfd,bfd_mach_o_load_command * cmd,bfd_boolean verbose)443 dump_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 
635 static bfd_boolean
load_and_dump(bfd * abfd,ufile_ptr off,unsigned int len,void (* dump)(bfd * abfd,unsigned char * buf,unsigned int len,ufile_ptr off))636 load_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 
657 static 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 
665 static void
dump_dyld_info_rebase(bfd * abfd,unsigned char * buf,unsigned int len,ufile_ptr off ATTRIBUTE_UNUSED)666 dump_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_unsigned_leb128 (abfd, buf + i, &leblen);
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_unsigned_leb128 (abfd, buf + i, &leblen);
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_unsigned_leb128 (abfd, buf + i, &leblen);
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_unsigned_leb128 (abfd, buf + i, &leblen);
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_unsigned_leb128 (abfd, buf + i, &leblen);
719 	  printf ("rebase uleb times (%u)", (unsigned) leb);
720 	  i += leblen;
721 	  leb = read_unsigned_leb128 (abfd, buf + i, &leblen);
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 
733 static void
dump_dyld_info_bind(bfd * abfd,unsigned char * buf,unsigned int len,ufile_ptr off ATTRIBUTE_UNUSED)734 dump_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_unsigned_leb128 (abfd, buf + i, &leblen);
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_unsigned_leb128 (abfd, buf + i, &leblen);
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_unsigned_leb128 (abfd, buf + i, &leblen);
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_unsigned_leb128 (abfd, buf + i, &leblen);
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_unsigned_leb128 (abfd, buf + i, &leblen);
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_unsigned_leb128 (abfd, buf + i, &leblen);
810 	  printf ("do bind uleb times (%u)", (unsigned) leb);
811 	  i += leblen;
812 	  leb = read_unsigned_leb128 (abfd, buf + i, &leblen);
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 
824 struct export_info_data
825 {
826   const unsigned char *name;
827   struct export_info_data *next;
828 };
829 
830 static void
dump_dyld_info_export_1(bfd * abfd,unsigned char * buf,unsigned int len,unsigned int off,struct export_info_data * parent,struct export_info_data * base)831 dump_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_unsigned_leb128 (abfd, buf + off, &leblen);
841   off += leblen;
842 
843   if (size != 0)
844     {
845       bfd_vma flags;
846       struct export_info_data *d;
847 
848       flags = read_unsigned_leb128 (abfd, buf + off, &leblen);
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_unsigned_leb128 (abfd, buf + off, &leblen);
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_unsigned_leb128 (abfd, buf + off, &leblen);
894 	  off += leblen;
895 
896 	  if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
897 	    {
898 	      resolv = read_unsigned_leb128 (abfd, buf + off, &leblen);
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_unsigned_leb128 (abfd, buf + off, &leblen);
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_unsigned_leb128 (abfd, buf + off, &leblen);
926       off += leblen;
927 
928       dump_dyld_info_export_1 (abfd, buf, len, sub_off, &sub_data, base);
929     }
930 }
931 
932 static void
dump_dyld_info_export(bfd * abfd,unsigned char * buf,unsigned int len,ufile_ptr off ATTRIBUTE_UNUSED)933 dump_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 
945 static void
dump_dyld_info(bfd * abfd,bfd_mach_o_load_command * cmd,bfd_boolean verbose)946 dump_dyld_info (bfd *abfd, bfd_mach_o_load_command *cmd,
947 		bfd_boolean verbose)
948 {
949   bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
950 
951   printf ("       rebase: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
952 	  info->rebase_off, info->rebase_size,
953 	  info->rebase_off + info->rebase_size);
954   printf ("         bind: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
955 	  info->bind_off, info->bind_size,
956 	  info->bind_off + info->bind_size);
957   printf ("    weak bind: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
958 	  info->weak_bind_off, info->weak_bind_size,
959 	  info->weak_bind_off + info->weak_bind_size);
960   printf ("    lazy bind: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
961 	  info->lazy_bind_off, info->lazy_bind_size,
962 	  info->lazy_bind_off + info->lazy_bind_size);
963   printf ("       export: off: 0x%08x  size: %-8u   (endoff: 0x%08x)\n",
964 	  info->export_off, info->export_size,
965 	  info->export_off + info->export_size);
966 
967   if (!verbose)
968     return;
969 
970   printf ("   rebase:\n");
971   if (!load_and_dump (abfd, info->rebase_off, info->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, info->bind_off, info->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, info->weak_bind_off, info->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, info->lazy_bind_off, info->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, info->export_off, info->export_size,
992 		      dump_dyld_info_export))
993     non_fatal (_("cannot read export symbols dyld info"));
994 }
995 
996 static void
dump_thread(bfd * abfd,bfd_mach_o_load_command * cmd)997 dump_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 
1040 static 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 
1051 static 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 
1061 static unsigned int
1062 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
1063 
1064 static void
dump_code_signature_superblob(bfd * abfd ATTRIBUTE_UNUSED,const unsigned char * buf,unsigned int len)1065 dump_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 
1097 static void
swap_code_codedirectory_v1_in(const struct mach_o_codesign_codedirectory_external_v1 * src,struct mach_o_codesign_codedirectory_v1 * dst)1098 swap_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 
1116 static void
hexdump(unsigned int start,unsigned int len,const unsigned char * buf)1117 hexdump (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 
1145 static void
dump_code_signature_codedirectory(bfd * abfd ATTRIBUTE_UNUSED,const unsigned char * buf,unsigned int len)1146 dump_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 
1185 static unsigned int
dump_code_signature_blob(bfd * abfd,const unsigned char * buf,unsigned int len)1186 dump_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 
1225 static void
dump_code_signature(bfd * abfd,bfd_mach_o_linkedit_command * cmd)1226 dump_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 
1251 static void
dump_segment_split_info(bfd * abfd,bfd_mach_o_linkedit_command * cmd)1252 dump_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_unsigned_leb128 (abfd, p, &len);
1291       fputs ("    ", stdout);
1292       bfd_printf_vma (abfd, addr);
1293       putchar ('\n');
1294     }
1295   free (buf);
1296 }
1297 
1298 static void
dump_function_starts(bfd * abfd,bfd_mach_o_linkedit_command * cmd)1299 dump_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 
1347 static 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 
1357 static void
dump_data_in_code(bfd * abfd,bfd_mach_o_linkedit_command * cmd)1358 dump_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 
1400 static void
dump_twolevel_hints(bfd * abfd,bfd_mach_o_twolevel_hints_command * cmd)1401 dump_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 
1439 static void
dump_load_command(bfd * abfd,bfd_mach_o_load_command * cmd,unsigned int idx,bfd_boolean verbose)1440 dump_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 *str = &cmd->command.str;
1560         printf ("    %s\n", str->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 
1650 static void
dump_load_commands(bfd * abfd,unsigned int cmd32,unsigned int cmd64)1651 dump_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 
1666 static const char * const unwind_x86_64_regs[] =
1667   {"", "rbx", "r12", "r13", "r14", "r15", "rbp", "???" };
1668 
1669 static 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 
1675 static void
dump_unwind_encoding_x86(unsigned int encoding,unsigned int sz,const char * const regs_name[])1676 dump_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 
1800 static void
dump_unwind_encoding_arm64(unsigned int encoding)1801 dump_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 
1854 static void
dump_unwind_encoding(bfd_mach_o_data_struct * mdata,unsigned int encoding)1855 dump_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 
1884 static void
dump_obj_compact_unwind(bfd * abfd,const unsigned char * content,bfd_size_type size)1885 dump_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 
1924 static void
dump_exe_compact_unwind(bfd * abfd,const unsigned char * content,bfd_size_type size)1925 dump_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 
2132 static void
dump_section_content(bfd * abfd,const char * segname,const char * sectname,void (* dump)(bfd *,const unsigned char *,bfd_size_type))2133 dump_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 
2169 static void
mach_o_dump(bfd * abfd)2170 mach_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 
2205 const 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