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