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