Missing file from my previous commit.
[external/binutils.git] / binutils / od-macho.c
1 /* od-macho.c -- dump information about an Mach-O object file.
2    Copyright 2011 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
33 /* Index of the options in the options[] array.  */
34 #define OPT_HEADER 0
35 #define OPT_SECTION 1
36 #define OPT_MAP 2
37 #define OPT_LOAD 3
38 #define OPT_DYSYMTAB 4
39
40 /* List of actions.  */
41 static struct objdump_private_option options[] =
42   {
43     { "header", 0 },
44     { "section", 0 },
45     { "map", 0 },
46     { "load", 0 },
47     { "dysymtab", 0 },
48     { NULL, 0 }
49   };
50
51 /* Display help.  */
52
53 static void
54 mach_o_help (FILE *stream)
55 {
56   fprintf (stream, _("\
57 For Mach-O files:\n\
58   header      Display the file header\n\
59   section     Display the segments and sections commands\n\
60   map         Display the section map\n\
61   load        Display the load commands\n\
62   dysymtab    Display the dynamic symbol table\n\
63 "));
64 }
65
66 /* Return TRUE if ABFD is handled.  */
67
68 static int
69 mach_o_filter (bfd *abfd)
70 {
71   return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
72 }
73 \f
74 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
75 {
76   { "vax", BFD_MACH_O_CPU_TYPE_VAX },
77   { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
78   { "i386", BFD_MACH_O_CPU_TYPE_I386 },
79   { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
80   { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
81   { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
82   { "arm", BFD_MACH_O_CPU_TYPE_ARM },
83   { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
84   { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
85   { "i860", BFD_MACH_O_CPU_TYPE_I860 },
86   { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
87   { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
88   { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
89   { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
90   { NULL, 0}
91 };
92
93 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
94 {
95   { "object", BFD_MACH_O_MH_OBJECT },
96   { "execute", BFD_MACH_O_MH_EXECUTE },
97   { "fvmlib", BFD_MACH_O_MH_FVMLIB },
98   { "core", BFD_MACH_O_MH_CORE },
99   { "preload", BFD_MACH_O_MH_PRELOAD },
100   { "dylib", BFD_MACH_O_MH_DYLIB },
101   { "dylinker", BFD_MACH_O_MH_DYLINKER },
102   { "bundle", BFD_MACH_O_MH_BUNDLE },
103   { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
104   { "dym", BFD_MACH_O_MH_DSYM },
105   { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
106   { NULL, 0}
107 };
108
109 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
110 {
111   { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
112   { "incrlink", BFD_MACH_O_MH_INCRLINK },
113   { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
114   { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
115   { "prebound", BFD_MACH_O_MH_PREBOUND },
116   { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
117   { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
118   { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
119   { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
120   { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
121   { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
122   { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
123   { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
124   { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
125   { "canonical", BFD_MACH_O_MH_CANONICAL },
126   { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
127   { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
128   { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
129   { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
130   { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
131   { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
132   { "pie", BFD_MACH_O_MH_PIE },
133   { NULL, 0}
134 };
135
136 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
137 {
138   { "segment", BFD_MACH_O_LC_SEGMENT},
139   { "symtab", BFD_MACH_O_LC_SYMTAB},
140   { "symseg", BFD_MACH_O_LC_SYMSEG},
141   { "thread", BFD_MACH_O_LC_THREAD},
142   { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
143   { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
144   { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
145   { "ident", BFD_MACH_O_LC_IDENT},
146   { "fvmfile", BFD_MACH_O_LC_FVMFILE},
147   { "prepage", BFD_MACH_O_LC_PREPAGE},
148   { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
149   { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
150   { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
151   { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
152   { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
153   { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
154   { "routines", BFD_MACH_O_LC_ROUTINES},
155   { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
156   { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
157   { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
158   { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
159   { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
160   { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
161   { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
162   { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
163   { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
164   { "uuid", BFD_MACH_O_LC_UUID},
165   { "rpath", BFD_MACH_O_LC_RPATH},
166   { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
167   { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
168   { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
169   { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
170   { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
171   { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
172   { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
173   { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
174   { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
175   { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
176   { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
177   { NULL, 0}
178 };
179
180 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
181 {
182   { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32},
183   { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32},
184   { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32},
185   { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64},
186   { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64},
187   { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64},
188   { "thread_state", BFD_MACH_O_x86_THREAD_STATE},
189   { "float_state", BFD_MACH_O_x86_FLOAT_STATE},
190   { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE},
191   { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32},
192   { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64},
193   { "debug_state", BFD_MACH_O_x86_DEBUG_STATE},
194   { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
195   { NULL, 0 }
196 };
197 \f
198 static void
199 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
200                         unsigned long val)
201 {
202   int first = 1;
203
204   for (; table->name; table++)
205     {
206       if (table->val & val)
207         {
208           if (!first)
209             printf ("+");
210           printf ("%s", table->name);
211           val &= ~table->val;
212           first = 0;
213         }
214     }
215   if (val)
216     {
217       if (!first)
218         printf ("+");
219       printf ("0x%lx", val);
220       return;
221     }
222   if (first)
223     printf ("-");
224 }
225
226 static const char *
227 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
228                              unsigned long val)
229 {
230   for (; table->name; table++)
231     if (table->val == val)
232       return table->name;
233   return NULL;
234 }
235
236 static const char *
237 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
238 {
239   const char *res = bfd_mach_o_get_name_or_null (table, val);
240
241   if (res == NULL)
242     return "*UNKNOWN*";
243   else
244     return res;
245 }
246
247 static void
248 dump_header (bfd *abfd)
249 {
250   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
251   bfd_mach_o_header *h = &mdata->header;
252
253   fputs (_("Mach-O header:\n"), stdout);
254   printf (_(" magic     : %08lx\n"), h->magic);
255   printf (_(" cputype   : %08lx (%s)\n"), h->cputype,
256            bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
257   printf (_(" cpusubtype: %08lx\n"), h->cpusubtype);
258   printf (_(" filetype  : %08lx (%s)\n"),
259            h->filetype,
260            bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
261   printf (_(" ncmds     : %08lx (%lu)\n"), h->ncmds, h->ncmds);
262   printf (_(" sizeofcmds: %08lx\n"), h->sizeofcmds);
263   printf (_(" flags     : %08lx ("), h->flags);
264   bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
265   fputs (_(")\n"), stdout);
266   printf (_(" reserved  : %08x\n"), h->reserved);
267 }
268
269 static void
270 dump_section_map (bfd *abfd)
271 {
272   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
273   unsigned int i;
274   unsigned int sec_nbr = 0;
275
276   fputs (_("Segments and Sections:\n"), stdout);
277   fputs (_(" #: Segment name     Section name     Address\n"), stdout);
278
279   for (i = 0; i < mdata->header.ncmds; i++)
280     {
281       bfd_mach_o_segment_command *seg;
282       bfd_mach_o_section *sec;
283
284       if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
285           && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
286         continue;
287
288       seg = &mdata->commands[i].command.segment;
289
290       printf ("[Segment %-16s ", seg->segname);
291       printf_vma (seg->vmaddr);
292       putchar ('-');
293       printf_vma  (seg->vmaddr + seg->vmsize - 1);
294       putchar (' ');
295       putchar (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-');
296       putchar (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
297       putchar (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
298       printf ("]\n");
299
300       for (sec = seg->sect_head; sec != NULL; sec = sec->next)
301         {
302           printf ("%02u: %-16s %-16s ", ++sec_nbr,
303                   sec->segname, sec->sectname);
304           printf_vma (sec->addr);
305           putchar (' ');
306           printf_vma  (sec->size);
307           printf (" %08lx\n", sec->flags);
308         }
309     }
310 }
311
312 static void
313 dump_section (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
314 {
315   printf (" Section: %-16s %-16s (bfdname: %s)\n",
316            sec->sectname, sec->segname, sec->bfdsection->name);
317   printf ("  addr: ");
318   printf_vma (sec->addr);
319   printf (" size: ");
320   printf_vma (sec->size);
321   printf (" offset: ");
322   printf_vma (sec->offset);
323   printf ("\n");
324   printf ("  align: %ld", sec->align);
325   printf ("  nreloc: %lu  reloff: ", sec->nreloc);
326   printf_vma (sec->reloff);
327   printf ("\n");
328   printf ("  flags: %08lx (type: %s", sec->flags,
329           bfd_mach_o_get_name (bfd_mach_o_section_type_name,
330                                sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
331   printf (" attr: ");
332   bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
333                           sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
334   printf (")\n");
335   switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
336     {
337     case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
338     case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
339     case BFD_MACH_O_S_SYMBOL_STUBS:
340       printf ("  first indirect sym: %lu", sec->reserved1);
341       printf (" (%u entries)",
342                bfd_mach_o_section_get_nbr_indirect (abfd, sec));
343       break;
344     default:
345       printf ("  reserved1: 0x%lx", sec->reserved1);
346       break;
347     }
348   switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
349     {
350     case BFD_MACH_O_S_SYMBOL_STUBS:
351       printf ("  stub size: %lu", sec->reserved2);
352       break;
353     default:
354       printf ("  reserved2: 0x%lx", sec->reserved2);
355       break;
356     }
357   printf ("  reserved3: 0x%lx\n", sec->reserved3);
358 }
359
360 static void
361 dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
362 {
363   bfd_mach_o_segment_command *seg = &cmd->command.segment;
364   bfd_mach_o_section *sec;
365
366   printf (" name: %s\n", *seg->segname ? seg->segname : "*none*");
367   printf ("    vmaddr: ");
368   printf_vma (seg->vmaddr);
369   printf ("   vmsize: ");
370   printf_vma  (seg->vmsize);
371   printf ("\n");
372   printf ("   fileoff: ");
373   printf_vma (seg->fileoff);
374   printf (" filesize: ");
375   printf_vma ((bfd_vma)seg->filesize);
376   printf (" endoff: ");
377   printf_vma ((bfd_vma)(seg->fileoff + seg->filesize));
378   printf ("\n");
379   printf ("   nsects: %lu  ", seg->nsects);
380   printf (" flags: %lx\n", seg->flags);
381   for (sec = seg->sect_head; sec != NULL; sec = sec->next)
382     dump_section (abfd, sec);
383 }
384
385 static void
386 dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose)
387 {
388   bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
389   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
390   unsigned int i;
391
392   printf ("              local symbols: idx: %10lu  num: %-8lu",
393           dysymtab->ilocalsym, dysymtab->nlocalsym);
394   printf (" (nxtidx: %lu)\n",
395           dysymtab->ilocalsym + dysymtab->nlocalsym);
396   printf ("           external symbols: idx: %10lu  num: %-8lu",
397           dysymtab->iextdefsym, dysymtab->nextdefsym);
398   printf (" (nxtidx: %lu)\n",
399           dysymtab->iextdefsym + dysymtab->nextdefsym);
400   printf ("          undefined symbols: idx: %10lu  num: %-8lu",
401           dysymtab->iundefsym, dysymtab->nundefsym);
402   printf (" (nxtidx: %lu)\n",
403           dysymtab->iundefsym + dysymtab->nundefsym);
404   printf ("           table of content: off: 0x%08lx  num: %-8lu",
405           dysymtab->tocoff, dysymtab->ntoc);
406   printf (" (endoff: 0x%08lx)\n",
407           dysymtab->tocoff + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
408   printf ("               module table: off: 0x%08lx  num: %-8lu",
409           dysymtab->modtaboff, dysymtab->nmodtab);
410   printf (" (endoff: 0x%08lx)\n",
411           dysymtab->modtaboff + dysymtab->nmodtab
412           * (mdata->header.version == 2 ?
413              BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
414   printf ("   external reference table: off: 0x%08lx  num: %-8lu",
415           dysymtab->extrefsymoff, dysymtab->nextrefsyms);
416   printf (" (endoff: 0x%08lx)\n",
417           dysymtab->extrefsymoff
418           + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
419   printf ("      indirect symbol table: off: 0x%08lx  num: %-8lu",
420           dysymtab->indirectsymoff, dysymtab->nindirectsyms);
421   printf (" (endoff: 0x%08lx)\n",
422           dysymtab->indirectsymoff
423           + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
424   printf ("  external relocation table: off: 0x%08lx  num: %-8lu",
425           dysymtab->extreloff, dysymtab->nextrel);
426   printf (" (endoff: 0x%08lx)\n",
427           dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
428   printf ("     local relocation table: off: 0x%08lx  num: %-8lu",
429           dysymtab->locreloff, dysymtab->nlocrel);
430   printf (" (endoff: 0x%08lx)\n",
431           dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
432
433   if (!verbose)
434     return;
435
436   if (dysymtab->ntoc > 0
437       || dysymtab->nindirectsyms > 0
438       || dysymtab->nextrefsyms > 0)
439     {
440       /* Try to read the symbols to display the toc or indirect symbols.  */
441       bfd_mach_o_read_symtab_symbols (abfd);
442     }
443   else if (dysymtab->nmodtab > 0)
444     {
445       /* Try to read the strtab to display modules name.  */
446       bfd_mach_o_read_symtab_strtab (abfd);
447     }
448
449   for (i = 0; i < dysymtab->nmodtab; i++)
450     {
451       bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
452       printf ("  module %u:\n", i);
453       printf ("   name: %lu", module->module_name_idx);
454       if (mdata->symtab && mdata->symtab->strtab)
455         printf (": %s",
456                  mdata->symtab->strtab + module->module_name_idx);
457       printf ("\n");
458       printf ("   extdefsym: idx: %8lu  num: %lu\n",
459                module->iextdefsym, module->nextdefsym);
460       printf ("      refsym: idx: %8lu  num: %lu\n",
461                module->irefsym, module->nrefsym);
462       printf ("    localsym: idx: %8lu  num: %lu\n",
463                module->ilocalsym, module->nlocalsym);
464       printf ("      extrel: idx: %8lu  num: %lu\n",
465                module->iextrel, module->nextrel);
466       printf ("        init: idx: %8u  num: %u\n",
467                module->iinit, module->ninit);
468       printf ("        term: idx: %8u  num: %u\n",
469                module->iterm, module->nterm);
470       printf ("   objc_module_info: addr: ");
471       printf_vma (module->objc_module_info_addr);
472       printf ("  size: %lu\n", module->objc_module_info_size);
473     }
474
475   if (dysymtab->ntoc > 0)
476     {
477       bfd_mach_o_symtab_command *symtab = mdata->symtab;
478
479       printf ("  table of content: (symbol/module)\n");
480       for (i = 0; i < dysymtab->ntoc; i++)
481         {
482           bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
483
484           printf ("   %4u: ", i);
485           if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
486             {
487               const char *name = symtab->symbols[toc->symbol_index].symbol.name;
488               printf ("%s (%lu)", name ? name : "*invalid*",
489                        toc->symbol_index);
490             }
491           else
492             printf ("%lu", toc->symbol_index);
493
494           printf (" / ");
495           if (symtab && symtab->strtab
496               && toc->module_index < dysymtab->nmodtab)
497             {
498               bfd_mach_o_dylib_module *mod;
499               mod = &dysymtab->dylib_module[toc->module_index];
500               printf ("%s (%lu)",
501                        symtab->strtab + mod->module_name_idx,
502                        toc->module_index);
503             }
504           else
505             printf ("%lu", toc->module_index);
506
507           printf ("\n");
508         }
509     }
510
511   if (dysymtab->nindirectsyms != 0)
512     {
513       printf ("  indirect symbols:\n");
514
515       for (i = 0; i < mdata->nsects; i++)
516         {
517           bfd_mach_o_section *sec = mdata->sections[i];
518           unsigned int j, first, last;
519           bfd_mach_o_symtab_command *symtab = mdata->symtab;
520           bfd_vma addr;
521           bfd_vma entry_size;
522
523           switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
524             {
525             case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
526             case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
527             case BFD_MACH_O_S_SYMBOL_STUBS:
528               first = sec->reserved1;
529               last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
530               addr = sec->addr;
531               entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
532               printf ("  for section %s.%s:\n",
533                        sec->segname, sec->sectname);
534               for (j = first; j < last; j++)
535                 {
536                   unsigned int isym = dysymtab->indirect_syms[j];
537
538                   printf ("   ");
539                   printf_vma (addr);
540                   printf (" %5u: 0x%08x", j, isym);
541                   if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
542                     printf (" LOCAL");
543                   if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
544                     printf (" ABSOLUTE");
545                   if (symtab && symtab->symbols
546                       && isym < symtab->nsyms
547                       && symtab->symbols[isym].symbol.name)
548                     printf (" %s", symtab->symbols[isym].symbol.name);
549                   printf ("\n");
550                   addr += entry_size;
551                 }
552               break;
553             default:
554               break;
555             }
556         }
557     }
558   if (dysymtab->nextrefsyms > 0)
559     {
560       bfd_mach_o_symtab_command *symtab = mdata->symtab;
561
562       printf ("  external reference table: (symbol flags)\n");
563       for (i = 0; i < dysymtab->nextrefsyms; i++)
564         {
565           bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
566
567           printf ("   %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
568           if (symtab && symtab->symbols
569               && ref->isym < symtab->nsyms
570               && symtab->symbols[ref->isym].symbol.name)
571             printf (" %s", symtab->symbols[ref->isym].symbol.name);
572           printf ("\n");
573         }
574     }
575
576 }
577
578 static void
579 dump_dyld_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
580 {
581   bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
582
583   printf ("       rebase: off: 0x%08x  size: %-8u\n",
584            info->rebase_off, info->rebase_size);
585   printf ("         bind: off: 0x%08x  size: %-8u\n",
586            info->bind_off, info->bind_size);
587   printf ("    weak bind: off: 0x%08x  size: %-8u\n",
588            info->weak_bind_off, info->weak_bind_size);
589   printf ("    lazy bind: off: 0x%08x  size: %-8u\n",
590            info->lazy_bind_off, info->lazy_bind_size);
591   printf ("       export: off: 0x%08x  size: %-8u\n",
592            info->export_off, info->export_size);
593 }
594
595 static void
596 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
597 {
598   bfd_mach_o_thread_command *thread = &cmd->command.thread;
599   unsigned int j;
600   bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
601   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
602
603   printf (" nflavours: %lu\n", thread->nflavours);
604   for (j = 0; j < thread->nflavours; j++)
605     {
606       bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
607       const bfd_mach_o_xlat_name *name_table;
608
609       printf ("  %2u: flavour: 0x%08lx", j, flavour->flavour);
610       switch (mdata->header.cputype)
611         {
612         case BFD_MACH_O_CPU_TYPE_I386:
613         case BFD_MACH_O_CPU_TYPE_X86_64:
614           name_table = bfd_mach_o_thread_x86_name;
615           break;
616         default:
617           name_table = NULL;
618           break;
619         }
620       if (name_table != NULL)
621         printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
622       putchar ('\n');
623
624       printf ("       offset: 0x%08lx  size: 0x%08lx\n",
625               flavour->offset, flavour->size);
626       if (bed->_bfd_mach_o_print_thread)
627         {
628           char *buf = xmalloc (flavour->size);
629
630           if (buf
631               && bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
632               && (bfd_bread (buf, flavour->size, abfd)
633                   == flavour->size))
634             (*bed->_bfd_mach_o_print_thread)(abfd, flavour, stdout, buf);
635           free (buf);
636         }
637     }
638 }
639
640 static void
641 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
642                    bfd_boolean verbose)
643 {
644   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
645   const char *cmd_name;
646
647   cmd_name = bfd_mach_o_get_name_or_null
648     (bfd_mach_o_load_command_name, cmd->type);
649   printf ("Load command ");
650   if (cmd_name == NULL)
651     printf ("0x%02x:", cmd->type);
652   else
653     printf ("%s:", cmd_name);
654
655   switch (cmd->type)
656     {
657     case BFD_MACH_O_LC_SEGMENT:
658     case BFD_MACH_O_LC_SEGMENT_64:
659       dump_segment (abfd, cmd);
660       break;
661     case BFD_MACH_O_LC_UUID:
662       {
663         bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
664         unsigned int j;
665
666         for (j = 0; j < sizeof (uuid->uuid); j ++)
667           printf (" %02x", uuid->uuid[j]);
668         putchar ('\n');
669       }
670       break;
671     case BFD_MACH_O_LC_LOAD_DYLIB:
672     case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
673     case BFD_MACH_O_LC_REEXPORT_DYLIB:
674     case BFD_MACH_O_LC_ID_DYLIB:
675     case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
676       {
677         bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
678         printf (" %s\n", dylib->name_str);
679         printf ("            time stamp: 0x%08lx\n",
680                 dylib->timestamp);
681         printf ("       current version: 0x%08lx\n",
682                 dylib->current_version);
683         printf ("  comptibility version: 0x%08lx\n",
684                 dylib->compatibility_version);
685         break;
686       }
687     case BFD_MACH_O_LC_LOAD_DYLINKER:
688     case BFD_MACH_O_LC_ID_DYLINKER:
689       printf (" %s\n", cmd->command.dylinker.name_str);
690       break;
691     case BFD_MACH_O_LC_SYMTAB:
692       {
693         bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
694         printf ("\n"
695                 "   symoff: 0x%08x    nsyms: %8u  (endoff: 0x%08x)\n",
696                 symtab->symoff, symtab->nsyms,
697                 symtab->symoff + symtab->nsyms
698                 * (mdata->header.version == 2
699                    ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
700         printf ("   stroff: 0x%08x  strsize: %8u  (endoff: 0x%08x)\n",
701                 symtab->stroff, symtab->strsize,
702                 symtab->stroff + symtab->strsize);
703         break;
704       }
705     case BFD_MACH_O_LC_DYSYMTAB:
706       putchar ('\n');
707       dump_dysymtab (abfd, cmd, verbose);
708       break;
709     case BFD_MACH_O_LC_CODE_SIGNATURE:
710     case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
711     case BFD_MACH_O_LC_FUNCTION_STARTS:
712       {
713         bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
714         printf
715           ("\n"
716            "  dataoff: 0x%08lx  datasize: 0x%08lx  (endoff: 0x%08lx)\n",
717            linkedit->dataoff, linkedit->datasize,
718            linkedit->dataoff + linkedit->datasize);
719         break;
720       }
721     case BFD_MACH_O_LC_SUB_FRAMEWORK:
722     case BFD_MACH_O_LC_SUB_UMBRELLA:
723     case BFD_MACH_O_LC_SUB_LIBRARY:
724     case BFD_MACH_O_LC_SUB_CLIENT:
725     case BFD_MACH_O_LC_RPATH:
726       {
727         bfd_mach_o_str_command *str = &cmd->command.str;
728         printf (" %s\n", str->str);
729         break;
730       }
731     case BFD_MACH_O_LC_THREAD:
732     case BFD_MACH_O_LC_UNIXTHREAD:
733       dump_thread (abfd, cmd);
734       break;
735     case BFD_MACH_O_LC_DYLD_INFO:
736       putchar ('\n');
737       dump_dyld_info (abfd, cmd);
738       break;
739     case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
740     case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
741       {
742         bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
743
744         printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
745       }
746       break;
747     default:
748       putchar ('\n');
749       printf ("  offset: 0x%08lx\n", (unsigned long)cmd->offset);
750       printf ("    size: 0x%08lx\n", (unsigned long)cmd->len);
751       break;
752     }
753   putchar ('\n');
754 }
755
756 static void
757 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
758 {
759   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
760   unsigned int i;
761
762   for (i = 0; i < mdata->header.ncmds; i++)
763     {
764       bfd_mach_o_load_command *cmd = &mdata->commands[i];
765
766       if (cmd32 == 0)
767         dump_load_command (abfd, cmd, FALSE);
768       else if (cmd->type == cmd32 || cmd->type == cmd64)
769         dump_load_command (abfd, cmd, TRUE);
770     }
771 }
772
773 /* Dump ABFD (according to the options[] array).  */
774
775 static void
776 mach_o_dump (bfd *abfd)
777 {
778   if (options[OPT_HEADER].selected)
779     dump_header (abfd);
780   if (options[OPT_SECTION].selected)
781     dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT, BFD_MACH_O_LC_SEGMENT_64);
782   if (options[OPT_MAP].selected)
783     dump_section_map (abfd);
784   if (options[OPT_LOAD].selected)
785     dump_load_commands (abfd, 0, 0);
786   if (options[OPT_DYSYMTAB].selected)
787     dump_load_commands (abfd, BFD_MACH_O_LC_DYSYMTAB, 0);
788 }
789
790 /* Vector for Mach-O.  */
791
792 const struct objdump_private_desc objdump_private_desc_mach_o =
793   {
794     mach_o_help,
795     mach_o_filter,
796     mach_o_dump,
797     options
798   };