bfd/
[external/binutils.git] / binutils / od-macho.c
1 /* od-macho.c -- dump information about an Mach-O object file.
2    Copyright 2011, 2012 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 <stddef.h>
23 #include <time.h>
24 #include "sysdep.h"
25 #include "safe-ctype.h"
26 #include "bfd.h"
27 #include "objdump.h"
28 #include "bucomm.h"
29 #include "bfdlink.h"
30 #include "mach-o.h"
31 #include "mach-o/external.h"
32 #include "mach-o/codesign.h"
33
34 /* Index of the options in the options[] array.  */
35 #define OPT_HEADER 0
36 #define OPT_SECTION 1
37 #define OPT_MAP 2
38 #define OPT_LOAD 3
39 #define OPT_DYSYMTAB 4
40 #define OPT_CODESIGN 5
41
42 /* List of actions.  */
43 static struct objdump_private_option options[] =
44   {
45     { "header", 0 },
46     { "section", 0 },
47     { "map", 0 },
48     { "load", 0 },
49     { "dysymtab", 0 },
50     { "codesign", 0 },
51     { NULL, 0 }
52   };
53
54 /* Display help.  */
55
56 static void
57 mach_o_help (FILE *stream)
58 {
59   fprintf (stream, _("\
60 For Mach-O files:\n\
61   header      Display the file header\n\
62   section     Display the segments and sections commands\n\
63   map         Display the section map\n\
64   load        Display the load commands\n\
65   dysymtab    Display the dynamic symbol table\n\
66   codesign    Display code signature section\n\
67 "));
68 }
69
70 /* Return TRUE if ABFD is handled.  */
71
72 static int
73 mach_o_filter (bfd *abfd)
74 {
75   return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
76 }
77 \f
78 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
79 {
80   { "vax", BFD_MACH_O_CPU_TYPE_VAX },
81   { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
82   { "i386", BFD_MACH_O_CPU_TYPE_I386 },
83   { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
84   { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
85   { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
86   { "arm", BFD_MACH_O_CPU_TYPE_ARM },
87   { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
88   { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
89   { "i860", BFD_MACH_O_CPU_TYPE_I860 },
90   { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
91   { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
92   { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
93   { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
94   { NULL, 0}
95 };
96
97 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
98 {
99   { "object", BFD_MACH_O_MH_OBJECT },
100   { "execute", BFD_MACH_O_MH_EXECUTE },
101   { "fvmlib", BFD_MACH_O_MH_FVMLIB },
102   { "core", BFD_MACH_O_MH_CORE },
103   { "preload", BFD_MACH_O_MH_PRELOAD },
104   { "dylib", BFD_MACH_O_MH_DYLIB },
105   { "dylinker", BFD_MACH_O_MH_DYLINKER },
106   { "bundle", BFD_MACH_O_MH_BUNDLE },
107   { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
108   { "dym", BFD_MACH_O_MH_DSYM },
109   { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
110   { NULL, 0}
111 };
112
113 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
114 {
115   { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
116   { "incrlink", BFD_MACH_O_MH_INCRLINK },
117   { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
118   { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
119   { "prebound", BFD_MACH_O_MH_PREBOUND },
120   { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
121   { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
122   { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
123   { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
124   { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
125   { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
126   { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
127   { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
128   { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
129   { "canonical", BFD_MACH_O_MH_CANONICAL },
130   { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
131   { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
132   { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
133   { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
134   { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
135   { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
136   { "pie", BFD_MACH_O_MH_PIE },
137   { NULL, 0}
138 };
139
140 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
141 {
142   { "segment", BFD_MACH_O_LC_SEGMENT},
143   { "symtab", BFD_MACH_O_LC_SYMTAB},
144   { "symseg", BFD_MACH_O_LC_SYMSEG},
145   { "thread", BFD_MACH_O_LC_THREAD},
146   { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
147   { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
148   { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
149   { "ident", BFD_MACH_O_LC_IDENT},
150   { "fvmfile", BFD_MACH_O_LC_FVMFILE},
151   { "prepage", BFD_MACH_O_LC_PREPAGE},
152   { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
153   { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
154   { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
155   { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
156   { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
157   { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
158   { "routines", BFD_MACH_O_LC_ROUTINES},
159   { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
160   { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
161   { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
162   { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
163   { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
164   { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
165   { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
166   { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
167   { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
168   { "uuid", BFD_MACH_O_LC_UUID},
169   { "rpath", BFD_MACH_O_LC_RPATH},
170   { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
171   { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
172   { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
173   { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
174   { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
175   { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
176   { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
177   { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
178   { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
179   { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
180   { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
181   { NULL, 0}
182 };
183
184 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
185 {
186   { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32},
187   { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32},
188   { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32},
189   { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64},
190   { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64},
191   { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64},
192   { "thread_state", BFD_MACH_O_x86_THREAD_STATE},
193   { "float_state", BFD_MACH_O_x86_FLOAT_STATE},
194   { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE},
195   { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32},
196   { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64},
197   { "debug_state", BFD_MACH_O_x86_DEBUG_STATE},
198   { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
199   { NULL, 0 }
200 };
201 \f
202 static void
203 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
204                         unsigned long val)
205 {
206   int first = 1;
207
208   for (; table->name; table++)
209     {
210       if (table->val & val)
211         {
212           if (!first)
213             printf ("+");
214           printf ("%s", table->name);
215           val &= ~table->val;
216           first = 0;
217         }
218     }
219   if (val)
220     {
221       if (!first)
222         printf ("+");
223       printf ("0x%lx", val);
224       return;
225     }
226   if (first)
227     printf ("-");
228 }
229
230 static const char *
231 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
232                              unsigned long val)
233 {
234   for (; table->name; table++)
235     if (table->val == val)
236       return table->name;
237   return NULL;
238 }
239
240 static const char *
241 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
242 {
243   const char *res = bfd_mach_o_get_name_or_null (table, val);
244
245   if (res == NULL)
246     return "*UNKNOWN*";
247   else
248     return res;
249 }
250
251 static void
252 dump_header (bfd *abfd)
253 {
254   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
255   bfd_mach_o_header *h = &mdata->header;
256
257   fputs (_("Mach-O header:\n"), stdout);
258   printf (_(" magic     : %08lx\n"), h->magic);
259   printf (_(" cputype   : %08lx (%s)\n"), h->cputype,
260           bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
261   printf (_(" cpusubtype: %08lx\n"), h->cpusubtype);
262   printf (_(" filetype  : %08lx (%s)\n"),
263           h->filetype,
264           bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
265   printf (_(" ncmds     : %08lx (%lu)\n"), h->ncmds, h->ncmds);
266   printf (_(" sizeofcmds: %08lx\n"), h->sizeofcmds);
267   printf (_(" flags     : %08lx ("), h->flags);
268   bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
269   fputs (_(")\n"), stdout);
270   printf (_(" reserved  : %08x\n"), h->reserved);
271 }
272
273 static void
274 dump_section_map (bfd *abfd)
275 {
276   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
277   unsigned int i;
278   unsigned int sec_nbr = 0;
279
280   fputs (_("Segments and Sections:\n"), stdout);
281   fputs (_(" #: Segment name     Section name     Address\n"), stdout);
282
283   for (i = 0; i < mdata->header.ncmds; i++)
284     {
285       bfd_mach_o_segment_command *seg;
286       bfd_mach_o_section *sec;
287
288       if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
289           && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
290         continue;
291
292       seg = &mdata->commands[i].command.segment;
293
294       printf ("[Segment %-16s ", seg->segname);
295       printf_vma (seg->vmaddr);
296       putchar ('-');
297       printf_vma  (seg->vmaddr + seg->vmsize - 1);
298       putchar (' ');
299       putchar (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-');
300       putchar (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
301       putchar (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
302       printf ("]\n");
303
304       for (sec = seg->sect_head; sec != NULL; sec = sec->next)
305         {
306           printf ("%02u: %-16s %-16s ", ++sec_nbr,
307                   sec->segname, sec->sectname);
308           printf_vma (sec->addr);
309           putchar (' ');
310           printf_vma  (sec->size);
311           printf (" %08lx\n", sec->flags);
312         }
313     }
314 }
315
316 static void
317 dump_section (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
318 {
319   printf (" Section: %-16s %-16s (bfdname: %s)\n",
320            sec->sectname, sec->segname, sec->bfdsection->name);
321   printf ("  addr: ");
322   printf_vma (sec->addr);
323   printf (" size: ");
324   printf_vma (sec->size);
325   printf (" offset: ");
326   printf_vma (sec->offset);
327   printf ("\n");
328   printf ("  align: %ld", sec->align);
329   printf ("  nreloc: %lu  reloff: ", sec->nreloc);
330   printf_vma (sec->reloff);
331   printf ("\n");
332   printf ("  flags: %08lx (type: %s", sec->flags,
333           bfd_mach_o_get_name (bfd_mach_o_section_type_name,
334                                sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
335   printf (" attr: ");
336   bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
337                           sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
338   printf (")\n");
339   switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
340     {
341     case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
342     case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
343     case BFD_MACH_O_S_SYMBOL_STUBS:
344       printf ("  first indirect sym: %lu", sec->reserved1);
345       printf (" (%u entries)",
346                bfd_mach_o_section_get_nbr_indirect (abfd, sec));
347       break;
348     default:
349       printf ("  reserved1: 0x%lx", sec->reserved1);
350       break;
351     }
352   switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
353     {
354     case BFD_MACH_O_S_SYMBOL_STUBS:
355       printf ("  stub size: %lu", sec->reserved2);
356       break;
357     default:
358       printf ("  reserved2: 0x%lx", sec->reserved2);
359       break;
360     }
361   printf ("  reserved3: 0x%lx\n", sec->reserved3);
362 }
363
364 static void
365 dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
366 {
367   bfd_mach_o_segment_command *seg = &cmd->command.segment;
368   bfd_mach_o_section *sec;
369
370   printf (" name: %s\n", *seg->segname ? seg->segname : "*none*");
371   printf ("    vmaddr: ");
372   printf_vma (seg->vmaddr);
373   printf ("   vmsize: ");
374   printf_vma  (seg->vmsize);
375   printf ("\n");
376   printf ("   fileoff: ");
377   printf_vma (seg->fileoff);
378   printf (" filesize: ");
379   printf_vma ((bfd_vma)seg->filesize);
380   printf (" endoff: ");
381   printf_vma ((bfd_vma)(seg->fileoff + seg->filesize));
382   printf ("\n");
383   printf ("   nsects: %lu  ", seg->nsects);
384   printf (" flags: %lx\n", seg->flags);
385   for (sec = seg->sect_head; sec != NULL; sec = sec->next)
386     dump_section (abfd, sec);
387 }
388
389 static void
390 dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose)
391 {
392   bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
393   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
394   unsigned int i;
395
396   printf ("              local symbols: idx: %10lu  num: %-8lu",
397           dysymtab->ilocalsym, dysymtab->nlocalsym);
398   printf (" (nxtidx: %lu)\n",
399           dysymtab->ilocalsym + dysymtab->nlocalsym);
400   printf ("           external symbols: idx: %10lu  num: %-8lu",
401           dysymtab->iextdefsym, dysymtab->nextdefsym);
402   printf (" (nxtidx: %lu)\n",
403           dysymtab->iextdefsym + dysymtab->nextdefsym);
404   printf ("          undefined symbols: idx: %10lu  num: %-8lu",
405           dysymtab->iundefsym, dysymtab->nundefsym);
406   printf (" (nxtidx: %lu)\n",
407           dysymtab->iundefsym + dysymtab->nundefsym);
408   printf ("           table of content: off: 0x%08lx  num: %-8lu",
409           dysymtab->tocoff, dysymtab->ntoc);
410   printf (" (endoff: 0x%08lx)\n",
411           dysymtab->tocoff + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
412   printf ("               module table: off: 0x%08lx  num: %-8lu",
413           dysymtab->modtaboff, dysymtab->nmodtab);
414   printf (" (endoff: 0x%08lx)\n",
415           dysymtab->modtaboff + dysymtab->nmodtab
416           * (mdata->header.version == 2 ?
417              BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
418   printf ("   external reference table: off: 0x%08lx  num: %-8lu",
419           dysymtab->extrefsymoff, dysymtab->nextrefsyms);
420   printf (" (endoff: 0x%08lx)\n",
421           dysymtab->extrefsymoff
422           + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
423   printf ("      indirect symbol table: off: 0x%08lx  num: %-8lu",
424           dysymtab->indirectsymoff, dysymtab->nindirectsyms);
425   printf (" (endoff: 0x%08lx)\n",
426           dysymtab->indirectsymoff
427           + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
428   printf ("  external relocation table: off: 0x%08lx  num: %-8lu",
429           dysymtab->extreloff, dysymtab->nextrel);
430   printf (" (endoff: 0x%08lx)\n",
431           dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
432   printf ("     local relocation table: off: 0x%08lx  num: %-8lu",
433           dysymtab->locreloff, dysymtab->nlocrel);
434   printf (" (endoff: 0x%08lx)\n",
435           dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
436
437   if (!verbose)
438     return;
439
440   if (dysymtab->ntoc > 0
441       || dysymtab->nindirectsyms > 0
442       || dysymtab->nextrefsyms > 0)
443     {
444       /* Try to read the symbols to display the toc or indirect symbols.  */
445       bfd_mach_o_read_symtab_symbols (abfd);
446     }
447   else if (dysymtab->nmodtab > 0)
448     {
449       /* Try to read the strtab to display modules name.  */
450       bfd_mach_o_read_symtab_strtab (abfd);
451     }
452
453   for (i = 0; i < dysymtab->nmodtab; i++)
454     {
455       bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
456       printf ("  module %u:\n", i);
457       printf ("   name: %lu", module->module_name_idx);
458       if (mdata->symtab && mdata->symtab->strtab)
459         printf (": %s",
460                  mdata->symtab->strtab + module->module_name_idx);
461       printf ("\n");
462       printf ("   extdefsym: idx: %8lu  num: %lu\n",
463                module->iextdefsym, module->nextdefsym);
464       printf ("      refsym: idx: %8lu  num: %lu\n",
465                module->irefsym, module->nrefsym);
466       printf ("    localsym: idx: %8lu  num: %lu\n",
467                module->ilocalsym, module->nlocalsym);
468       printf ("      extrel: idx: %8lu  num: %lu\n",
469                module->iextrel, module->nextrel);
470       printf ("        init: idx: %8u  num: %u\n",
471                module->iinit, module->ninit);
472       printf ("        term: idx: %8u  num: %u\n",
473                module->iterm, module->nterm);
474       printf ("   objc_module_info: addr: ");
475       printf_vma (module->objc_module_info_addr);
476       printf ("  size: %lu\n", module->objc_module_info_size);
477     }
478
479   if (dysymtab->ntoc > 0)
480     {
481       bfd_mach_o_symtab_command *symtab = mdata->symtab;
482
483       printf ("  table of content: (symbol/module)\n");
484       for (i = 0; i < dysymtab->ntoc; i++)
485         {
486           bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
487
488           printf ("   %4u: ", i);
489           if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
490             {
491               const char *name = symtab->symbols[toc->symbol_index].symbol.name;
492               printf ("%s (%lu)", name ? name : "*invalid*",
493                        toc->symbol_index);
494             }
495           else
496             printf ("%lu", toc->symbol_index);
497
498           printf (" / ");
499           if (symtab && symtab->strtab
500               && toc->module_index < dysymtab->nmodtab)
501             {
502               bfd_mach_o_dylib_module *mod;
503               mod = &dysymtab->dylib_module[toc->module_index];
504               printf ("%s (%lu)",
505                        symtab->strtab + mod->module_name_idx,
506                        toc->module_index);
507             }
508           else
509             printf ("%lu", toc->module_index);
510
511           printf ("\n");
512         }
513     }
514
515   if (dysymtab->nindirectsyms != 0)
516     {
517       printf ("  indirect symbols:\n");
518
519       for (i = 0; i < mdata->nsects; i++)
520         {
521           bfd_mach_o_section *sec = mdata->sections[i];
522           unsigned int j, first, last;
523           bfd_mach_o_symtab_command *symtab = mdata->symtab;
524           bfd_vma addr;
525           bfd_vma entry_size;
526
527           switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
528             {
529             case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
530             case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
531             case BFD_MACH_O_S_SYMBOL_STUBS:
532               first = sec->reserved1;
533               last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
534               addr = sec->addr;
535               entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
536               printf ("  for section %s.%s:\n",
537                        sec->segname, sec->sectname);
538               for (j = first; j < last; j++)
539                 {
540                   unsigned int isym = dysymtab->indirect_syms[j];
541
542                   printf ("   ");
543                   printf_vma (addr);
544                   printf (" %5u: 0x%08x", j, isym);
545                   if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
546                     printf (" LOCAL");
547                   if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
548                     printf (" ABSOLUTE");
549                   if (symtab && symtab->symbols
550                       && isym < symtab->nsyms
551                       && symtab->symbols[isym].symbol.name)
552                     printf (" %s", symtab->symbols[isym].symbol.name);
553                   printf ("\n");
554                   addr += entry_size;
555                 }
556               break;
557             default:
558               break;
559             }
560         }
561     }
562   if (dysymtab->nextrefsyms > 0)
563     {
564       bfd_mach_o_symtab_command *symtab = mdata->symtab;
565
566       printf ("  external reference table: (symbol flags)\n");
567       for (i = 0; i < dysymtab->nextrefsyms; i++)
568         {
569           bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
570
571           printf ("   %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
572           if (symtab && symtab->symbols
573               && ref->isym < symtab->nsyms
574               && symtab->symbols[ref->isym].symbol.name)
575             printf (" %s", symtab->symbols[ref->isym].symbol.name);
576           printf ("\n");
577         }
578     }
579
580 }
581
582 static void
583 dump_dyld_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
584 {
585   bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
586
587   printf ("       rebase: off: 0x%08x  size: %-8u\n",
588            info->rebase_off, info->rebase_size);
589   printf ("         bind: off: 0x%08x  size: %-8u\n",
590            info->bind_off, info->bind_size);
591   printf ("    weak bind: off: 0x%08x  size: %-8u\n",
592            info->weak_bind_off, info->weak_bind_size);
593   printf ("    lazy bind: off: 0x%08x  size: %-8u\n",
594            info->lazy_bind_off, info->lazy_bind_size);
595   printf ("       export: off: 0x%08x  size: %-8u\n",
596            info->export_off, info->export_size);
597 }
598
599 static void
600 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
601 {
602   bfd_mach_o_thread_command *thread = &cmd->command.thread;
603   unsigned int j;
604   bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
605   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
606
607   printf (" nflavours: %lu\n", thread->nflavours);
608   for (j = 0; j < thread->nflavours; j++)
609     {
610       bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
611       const bfd_mach_o_xlat_name *name_table;
612
613       printf ("  %2u: flavour: 0x%08lx", j, flavour->flavour);
614       switch (mdata->header.cputype)
615         {
616         case BFD_MACH_O_CPU_TYPE_I386:
617         case BFD_MACH_O_CPU_TYPE_X86_64:
618           name_table = bfd_mach_o_thread_x86_name;
619           break;
620         default:
621           name_table = NULL;
622           break;
623         }
624       if (name_table != NULL)
625         printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
626       putchar ('\n');
627
628       printf ("       offset: 0x%08lx  size: 0x%08lx\n",
629               flavour->offset, flavour->size);
630       if (bed->_bfd_mach_o_print_thread)
631         {
632           char *buf = xmalloc (flavour->size);
633
634           if (bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
635               && bfd_bread (buf, flavour->size, abfd) == flavour->size)
636             (*bed->_bfd_mach_o_print_thread)(abfd, flavour, stdout, buf);
637
638           free (buf);
639         }
640     }
641 }
642
643 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic[] =
644 {
645   { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE },
646   { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT },
647   { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS },
648   { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY },
649   { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS },
650   { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER },
651   { NULL, 0 }
652 };
653
654 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type[] =
655 {
656   { "no-hash", BFD_MACH_O_CS_NO_HASH },
657   { "sha1", BFD_MACH_O_CS_HASH_SHA1 },
658   { "sha256", BFD_MACH_O_CS_HASH_SHA256 },
659   { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256 },
660   { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512 },
661   { NULL, 0 }
662 };
663
664 static unsigned int
665 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
666
667 static void
668 dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
669                                const unsigned char *buf, unsigned int len)
670 {
671   unsigned int count;
672   unsigned int i;
673
674   if (len < 12)
675     {
676       printf (_("  [bad block length]\n"));
677       return;
678     }
679   count = bfd_getb32 (buf + 8);
680   printf (_("  %u index entries:\n"), count);
681   if (len < 12 + 8 * count)
682     {
683       printf (_("  [bad block length]\n"));
684       return;
685     }
686   for (i = 0; i < count; i++)
687     {
688       unsigned int type;
689       unsigned int off;
690
691       type = bfd_getb32 (buf + 12 + 8 * i);
692       off = bfd_getb32 (buf + 12 + 8 * i + 4);
693       printf (_("  index entry %u: type: %08x, offset: %08x\n"),
694               i, type, off);
695
696       dump_code_signature_blob (abfd, buf + off, len - off);
697     }
698 }
699
700 static void
701 swap_code_codedirectory_v1_in
702   (const struct mach_o_codesign_codedirectory_external_v1 *src,
703    struct mach_o_codesign_codedirectory_v1 *dst)
704 {
705   dst->version = bfd_getb32 (src->version);
706   dst->flags = bfd_getb32 (src->flags);
707   dst->hash_offset = bfd_getb32 (src->hash_offset);
708   dst->ident_offset = bfd_getb32 (src->ident_offset);
709   dst->nbr_special_slots = bfd_getb32 (src->nbr_special_slots);
710   dst->nbr_code_slots = bfd_getb32 (src->nbr_code_slots);
711   dst->code_limit = bfd_getb32 (src->code_limit);
712   dst->hash_size = src->hash_size[0];
713   dst->hash_type = src->hash_type[0];
714   dst->spare1 = src->spare1[0];
715   dst->page_size = src->page_size[0];
716   dst->spare2 = bfd_getb32 (src->spare2);
717 }
718
719 static void
720 hexdump (unsigned int start, unsigned int len,
721          const unsigned char *buf)
722 {
723   unsigned int i, j;
724
725   for (i = 0; i < len; i += 16)
726     {
727       printf ("%08x:", start + i);
728       for (j = 0; j < 16; j++)
729         {
730           fputc (j == 8 ? '-' : ' ', stdout);
731           if (i + j < len)
732             printf ("%02x", buf[i + j]);
733           else
734             fputs ("  ", stdout);
735         }
736       fputc (' ', stdout);
737       for (j = 0; j < 16; j++)
738         {
739           if (i + j < len)
740             fputc (ISPRINT (buf[i + j]) ? buf[i + j] : '.', stdout);
741           else
742             fputc (' ', stdout);
743         }
744       fputc ('\n', stdout);
745     }
746 }
747
748 static void
749 dump_code_signature_codedirectory (bfd *abfd ATTRIBUTE_UNUSED,
750                                    const unsigned char *buf, unsigned int len)
751 {
752   struct mach_o_codesign_codedirectory_v1 cd;
753   const char *id;
754
755   if (len < sizeof (struct mach_o_codesign_codedirectory_external_v1))
756     {
757       printf (_("  [bad block length]\n"));
758       return;
759     }
760
761   swap_code_codedirectory_v1_in
762     ((const struct mach_o_codesign_codedirectory_external_v1 *) (buf + 8), &cd);
763
764   printf (_("  version:           %08x\n"), cd.version);
765   printf (_("  flags:             %08x\n"), cd.flags);
766   printf (_("  hash offset:       %08x\n"), cd.hash_offset);
767   id = (const char *) buf + cd.ident_offset;
768   printf (_("  ident offset:      %08x (- %08x)\n"),
769           cd.ident_offset, cd.ident_offset + (unsigned) strlen (id) + 1);
770   printf (_("   identity: %s\n"), id);
771   printf (_("  nbr special slots: %08x (at offset %08x)\n"),
772           cd.nbr_special_slots,
773           cd.hash_offset - cd.nbr_special_slots * cd.hash_size);
774   printf (_("  nbr code slots:    %08x\n"), cd.nbr_code_slots);
775   printf (_("  code limit:        %08x\n"), cd.code_limit);
776   printf (_("  hash size:         %02x\n"), cd.hash_size);
777   printf (_("  hash type:         %02x (%s)\n"),
778           cd.hash_type,
779           bfd_mach_o_get_name (bfd_mach_o_cs_hash_type, cd.hash_type));
780   printf (_("  spare1:            %02x\n"), cd.spare1);
781   printf (_("  page size:         %02x\n"), cd.page_size);
782   printf (_("  spare2:            %08x\n"), cd.spare2);
783   if (cd.version >= 0x20100)
784     printf (_("  scatter offset:    %08x\n"),
785             (unsigned) bfd_getb32 (buf + 44));
786 }
787
788 static unsigned int
789 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len)
790 {
791   unsigned int magic;
792   unsigned int length;
793
794   if (len < 8)
795     {
796       printf (_("  [truncated block]\n"));
797       return 0;
798     }
799   magic = bfd_getb32 (buf);
800   length = bfd_getb32 (buf + 4);
801   if (magic == 0 || length == 0)
802     return 0;
803
804   printf (_(" magic : %08x (%s)\n"), magic,
805           bfd_mach_o_get_name (bfd_mach_o_cs_magic, magic));
806   printf (_(" length: %08x\n"), length);
807   if (length > len)
808     {
809       printf (_("  [bad block length]\n"));
810       return 0;
811     }
812
813   switch (magic)
814     {
815     case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE:
816       dump_code_signature_superblob (abfd, buf, length);
817       break;
818     case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY:
819       dump_code_signature_codedirectory (abfd, buf, length);
820       break;
821     default:
822       hexdump (0, length - 8, buf + 8);
823       break;
824     }
825   return length;
826 }
827
828 static void
829 dump_code_signature (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
830 {
831   unsigned char *buf = xmalloc (cmd->datasize);
832   unsigned int off;
833
834   if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
835       || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
836     {
837       non_fatal (_("cannot read code signature data"));
838       free (buf);
839       return;
840     }
841   for (off = 0; off < cmd->datasize;)
842     {
843       unsigned int len;
844
845       len = dump_code_signature_blob (abfd, buf + off, cmd->datasize - off);
846
847       if (len == 0)
848         break;
849       off += len;
850     }
851   free (buf);
852 }
853
854 static void
855 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
856                    bfd_boolean verbose)
857 {
858   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
859   const char *cmd_name;
860
861   cmd_name = bfd_mach_o_get_name_or_null
862     (bfd_mach_o_load_command_name, cmd->type);
863   printf ("Load command ");
864   if (cmd_name == NULL)
865     printf ("0x%02x:", cmd->type);
866   else
867     printf ("%s:", cmd_name);
868
869   switch (cmd->type)
870     {
871     case BFD_MACH_O_LC_SEGMENT:
872     case BFD_MACH_O_LC_SEGMENT_64:
873       dump_segment (abfd, cmd);
874       break;
875     case BFD_MACH_O_LC_UUID:
876       {
877         bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
878         unsigned int j;
879
880         for (j = 0; j < sizeof (uuid->uuid); j ++)
881           printf (" %02x", uuid->uuid[j]);
882         putchar ('\n');
883       }
884       break;
885     case BFD_MACH_O_LC_LOAD_DYLIB:
886     case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
887     case BFD_MACH_O_LC_REEXPORT_DYLIB:
888     case BFD_MACH_O_LC_ID_DYLIB:
889     case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
890       {
891         bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
892         printf (" %s\n", dylib->name_str);
893         printf ("            time stamp: 0x%08lx\n",
894                 dylib->timestamp);
895         printf ("       current version: 0x%08lx\n",
896                 dylib->current_version);
897         printf ("  comptibility version: 0x%08lx\n",
898                 dylib->compatibility_version);
899         break;
900       }
901     case BFD_MACH_O_LC_LOAD_DYLINKER:
902     case BFD_MACH_O_LC_ID_DYLINKER:
903       printf (" %s\n", cmd->command.dylinker.name_str);
904       break;
905     case BFD_MACH_O_LC_SYMTAB:
906       {
907         bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
908         printf ("\n"
909                 "   symoff: 0x%08x    nsyms: %8u  (endoff: 0x%08x)\n",
910                 symtab->symoff, symtab->nsyms,
911                 symtab->symoff + symtab->nsyms
912                 * (mdata->header.version == 2
913                    ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
914         printf ("   stroff: 0x%08x  strsize: %8u  (endoff: 0x%08x)\n",
915                 symtab->stroff, symtab->strsize,
916                 symtab->stroff + symtab->strsize);
917         break;
918       }
919     case BFD_MACH_O_LC_DYSYMTAB:
920       putchar ('\n');
921       dump_dysymtab (abfd, cmd, verbose);
922       break;
923     case BFD_MACH_O_LC_CODE_SIGNATURE:
924     case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
925     case BFD_MACH_O_LC_FUNCTION_STARTS:
926       {
927         bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
928         printf
929           ("\n"
930            "  dataoff: 0x%08lx  datasize: 0x%08lx  (endoff: 0x%08lx)\n",
931            linkedit->dataoff, linkedit->datasize,
932            linkedit->dataoff + linkedit->datasize);
933
934         if (verbose && cmd->type == BFD_MACH_O_LC_CODE_SIGNATURE)
935           dump_code_signature (abfd, linkedit);
936         break;
937       }
938     case BFD_MACH_O_LC_SUB_FRAMEWORK:
939     case BFD_MACH_O_LC_SUB_UMBRELLA:
940     case BFD_MACH_O_LC_SUB_LIBRARY:
941     case BFD_MACH_O_LC_SUB_CLIENT:
942     case BFD_MACH_O_LC_RPATH:
943       {
944         bfd_mach_o_str_command *str = &cmd->command.str;
945         printf (" %s\n", str->str);
946         break;
947       }
948     case BFD_MACH_O_LC_THREAD:
949     case BFD_MACH_O_LC_UNIXTHREAD:
950       dump_thread (abfd, cmd);
951       break;
952     case BFD_MACH_O_LC_ENCRYPTION_INFO:
953       {
954         bfd_mach_o_encryption_info_command *cryp =
955           &cmd->command.encryption_info;
956         printf
957           ("\n"
958            "  cryptoff: 0x%08x  cryptsize: 0x%08x (endoff 0x%08x)"
959            " cryptid: %u\n",
960            cryp->cryptoff, cryp->cryptsize,
961            cryp->cryptoff + cryp->cryptsize,
962            cryp->cryptid);
963       }
964       break;
965     case BFD_MACH_O_LC_DYLD_INFO:
966       putchar ('\n');
967       dump_dyld_info (abfd, cmd);
968       break;
969     case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
970     case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
971       {
972         bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
973
974         printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
975       }
976       break;
977     default:
978       putchar ('\n');
979       printf ("  offset: 0x%08lx\n", (unsigned long)cmd->offset);
980       printf ("    size: 0x%08lx\n", (unsigned long)cmd->len);
981       break;
982     }
983   putchar ('\n');
984 }
985
986 static void
987 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
988 {
989   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
990   unsigned int i;
991
992   for (i = 0; i < mdata->header.ncmds; i++)
993     {
994       bfd_mach_o_load_command *cmd = &mdata->commands[i];
995
996       if (cmd32 == 0)
997         dump_load_command (abfd, cmd, FALSE);
998       else if (cmd->type == cmd32 || cmd->type == cmd64)
999         dump_load_command (abfd, cmd, TRUE);
1000     }
1001 }
1002
1003 /* Dump ABFD (according to the options[] array).  */
1004
1005 static void
1006 mach_o_dump (bfd *abfd)
1007 {
1008   if (options[OPT_HEADER].selected)
1009     dump_header (abfd);
1010   if (options[OPT_SECTION].selected)
1011     dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT, BFD_MACH_O_LC_SEGMENT_64);
1012   if (options[OPT_MAP].selected)
1013     dump_section_map (abfd);
1014   if (options[OPT_LOAD].selected)
1015     dump_load_commands (abfd, 0, 0);
1016   if (options[OPT_DYSYMTAB].selected)
1017     dump_load_commands (abfd, BFD_MACH_O_LC_DYSYMTAB, 0);
1018   if (options[OPT_CODESIGN].selected)
1019     dump_load_commands (abfd, BFD_MACH_O_LC_CODE_SIGNATURE, 0);
1020 }
1021
1022 /* Vector for Mach-O.  */
1023
1024 const struct objdump_private_desc objdump_private_desc_mach_o =
1025   {
1026     mach_o_help,
1027     mach_o_filter,
1028     mach_o_dump,
1029     options
1030   };