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.
5 This file is part of GNU Binutils.
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)
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.
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. */
25 #include "safe-ctype.h"
31 #include "mach-o/external.h"
33 /* Index of the options in the options[] array. */
38 #define OPT_DYSYMTAB 4
40 /* List of actions. */
41 static struct objdump_private_option options[] =
54 mach_o_help (FILE *stream)
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\
66 /* Return TRUE if ABFD is handled. */
69 mach_o_filter (bfd *abfd)
71 return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
74 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
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 },
93 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
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 },
109 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
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 },
136 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
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},
180 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
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},
199 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
204 for (; table->name; table++)
206 if (table->val & val)
210 printf ("%s", table->name);
219 printf ("0x%lx", val);
227 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
230 for (; table->name; table++)
231 if (table->val == val)
237 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
239 const char *res = bfd_mach_o_get_name_or_null (table, val);
248 dump_header (bfd *abfd)
250 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
251 bfd_mach_o_header *h = &mdata->header;
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"),
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);
270 dump_section_map (bfd *abfd)
272 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
274 unsigned int sec_nbr = 0;
276 fputs (_("Segments and Sections:\n"), stdout);
277 fputs (_(" #: Segment name Section name Address\n"), stdout);
279 for (i = 0; i < mdata->header.ncmds; i++)
281 bfd_mach_o_segment_command *seg;
282 bfd_mach_o_section *sec;
284 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
285 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
288 seg = &mdata->commands[i].command.segment;
290 printf ("[Segment %-16s ", seg->segname);
291 printf_vma (seg->vmaddr);
293 printf_vma (seg->vmaddr + seg->vmsize - 1);
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' : '-');
300 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
302 printf ("%02u: %-16s %-16s ", ++sec_nbr,
303 sec->segname, sec->sectname);
304 printf_vma (sec->addr);
306 printf_vma (sec->size);
307 printf (" %08lx\n", sec->flags);
313 dump_section (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
315 printf (" Section: %-16s %-16s (bfdname: %s)\n",
316 sec->sectname, sec->segname, sec->bfdsection->name);
318 printf_vma (sec->addr);
320 printf_vma (sec->size);
321 printf (" offset: ");
322 printf_vma (sec->offset);
324 printf (" align: %ld", sec->align);
325 printf (" nreloc: %lu reloff: ", sec->nreloc);
326 printf_vma (sec->reloff);
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));
332 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
333 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
335 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
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));
345 printf (" reserved1: 0x%lx", sec->reserved1);
348 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
350 case BFD_MACH_O_S_SYMBOL_STUBS:
351 printf (" stub size: %lu", sec->reserved2);
354 printf (" reserved2: 0x%lx", sec->reserved2);
357 printf (" reserved3: 0x%lx\n", sec->reserved3);
361 dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
363 bfd_mach_o_segment_command *seg = &cmd->command.segment;
364 bfd_mach_o_section *sec;
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);
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));
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);
386 dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose)
388 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
389 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
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);
436 if (dysymtab->ntoc > 0
437 || dysymtab->nindirectsyms > 0
438 || dysymtab->nextrefsyms > 0)
440 /* Try to read the symbols to display the toc or indirect symbols. */
441 bfd_mach_o_read_symtab_symbols (abfd);
443 else if (dysymtab->nmodtab > 0)
445 /* Try to read the strtab to display modules name. */
446 bfd_mach_o_read_symtab_strtab (abfd);
449 for (i = 0; i < dysymtab->nmodtab; i++)
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)
456 mdata->symtab->strtab + module->module_name_idx);
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);
475 if (dysymtab->ntoc > 0)
477 bfd_mach_o_symtab_command *symtab = mdata->symtab;
479 printf (" table of content: (symbol/module)\n");
480 for (i = 0; i < dysymtab->ntoc; i++)
482 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
484 printf (" %4u: ", i);
485 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
487 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
488 printf ("%s (%lu)", name ? name : "*invalid*",
492 printf ("%lu", toc->symbol_index);
495 if (symtab && symtab->strtab
496 && toc->module_index < dysymtab->nmodtab)
498 bfd_mach_o_dylib_module *mod;
499 mod = &dysymtab->dylib_module[toc->module_index];
501 symtab->strtab + mod->module_name_idx,
505 printf ("%lu", toc->module_index);
511 if (dysymtab->nindirectsyms != 0)
513 printf (" indirect symbols:\n");
515 for (i = 0; i < mdata->nsects; i++)
517 bfd_mach_o_section *sec = mdata->sections[i];
518 unsigned int j, first, last;
519 bfd_mach_o_symtab_command *symtab = mdata->symtab;
523 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
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);
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++)
536 unsigned int isym = dysymtab->indirect_syms[j];
540 printf (" %5u: 0x%08x", j, isym);
541 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_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);
558 if (dysymtab->nextrefsyms > 0)
560 bfd_mach_o_symtab_command *symtab = mdata->symtab;
562 printf (" external reference table: (symbol flags)\n");
563 for (i = 0; i < dysymtab->nextrefsyms; i++)
565 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
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);
579 dump_dyld_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
581 bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
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);
596 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
598 bfd_mach_o_thread_command *thread = &cmd->command.thread;
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);
603 printf (" nflavours: %lu\n", thread->nflavours);
604 for (j = 0; j < thread->nflavours; j++)
606 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
607 const bfd_mach_o_xlat_name *name_table;
609 printf (" %2u: flavour: 0x%08lx", j, flavour->flavour);
610 switch (mdata->header.cputype)
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;
620 if (name_table != NULL)
621 printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
624 printf (" offset: 0x%08lx size: 0x%08lx\n",
625 flavour->offset, flavour->size);
626 if (bed->_bfd_mach_o_print_thread)
628 char *buf = xmalloc (flavour->size);
631 && bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
632 && (bfd_bread (buf, flavour->size, abfd)
634 (*bed->_bfd_mach_o_print_thread)(abfd, flavour, stdout, buf);
641 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
644 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
645 const char *cmd_name;
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);
653 printf ("%s:", cmd_name);
657 case BFD_MACH_O_LC_SEGMENT:
658 case BFD_MACH_O_LC_SEGMENT_64:
659 dump_segment (abfd, cmd);
661 case BFD_MACH_O_LC_UUID:
663 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
666 for (j = 0; j < sizeof (uuid->uuid); j ++)
667 printf (" %02x", uuid->uuid[j]);
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:
677 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
678 printf (" %s\n", dylib->name_str);
679 printf (" time stamp: 0x%08lx\n",
681 printf (" current version: 0x%08lx\n",
682 dylib->current_version);
683 printf (" comptibility version: 0x%08lx\n",
684 dylib->compatibility_version);
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);
691 case BFD_MACH_O_LC_SYMTAB:
693 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
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);
705 case BFD_MACH_O_LC_DYSYMTAB:
707 dump_dysymtab (abfd, cmd, verbose);
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:
713 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
716 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
717 linkedit->dataoff, linkedit->datasize,
718 linkedit->dataoff + linkedit->datasize);
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:
727 bfd_mach_o_str_command *str = &cmd->command.str;
728 printf (" %s\n", str->str);
731 case BFD_MACH_O_LC_THREAD:
732 case BFD_MACH_O_LC_UNIXTHREAD:
733 dump_thread (abfd, cmd);
735 case BFD_MACH_O_LC_DYLD_INFO:
737 dump_dyld_info (abfd, cmd);
739 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
740 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
742 bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
744 printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
749 printf (" offset: 0x%08lx\n", (unsigned long)cmd->offset);
750 printf (" size: 0x%08lx\n", (unsigned long)cmd->len);
757 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
759 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
762 for (i = 0; i < mdata->header.ncmds; i++)
764 bfd_mach_o_load_command *cmd = &mdata->commands[i];
767 dump_load_command (abfd, cmd, FALSE);
768 else if (cmd->type == cmd32 || cmd->type == cmd64)
769 dump_load_command (abfd, cmd, TRUE);
773 /* Dump ABFD (according to the options[] array). */
776 mach_o_dump (bfd *abfd)
778 if (options[OPT_HEADER].selected)
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);
790 /* Vector for Mach-O. */
792 const struct objdump_private_desc objdump_private_desc_mach_o =