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