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.
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"
32 #include "mach-o/external.h"
33 #include "mach-o/codesign.h"
35 /* Index of the options in the options[] array. */
40 #define OPT_DYSYMTAB 4
41 #define OPT_CODESIGN 5
42 #define OPT_SEG_SPLIT_INFO 6
44 /* List of actions. */
45 static struct objdump_private_option options[] =
53 { "seg_split_info", 0 },
60 mach_o_help (FILE *stream)
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\
74 /* Return TRUE if ABFD is handled. */
77 mach_o_filter (bfd *abfd)
79 return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
82 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
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 },
101 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
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 },
117 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
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 },
144 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
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},
188 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
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},
207 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
212 for (; table->name; table++)
214 if (table->val & val)
218 printf ("%s", table->name);
227 printf ("0x%lx", val);
235 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
238 for (; table->name; table++)
239 if (table->val == val)
245 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
247 const char *res = bfd_mach_o_get_name_or_null (table, val);
256 dump_header (bfd *abfd)
258 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
259 bfd_mach_o_header *h = &mdata->header;
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"),
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);
278 dump_section_map (bfd *abfd)
280 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
282 unsigned int sec_nbr = 0;
284 fputs (_("Segments and Sections:\n"), stdout);
285 fputs (_(" #: Segment name Section name Address\n"), stdout);
287 for (i = 0; i < mdata->header.ncmds; i++)
289 bfd_mach_o_segment_command *seg;
290 bfd_mach_o_section *sec;
292 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
293 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
296 seg = &mdata->commands[i].command.segment;
298 printf ("[Segment %-16s ", seg->segname);
299 printf_vma (seg->vmaddr);
301 printf_vma (seg->vmaddr + seg->vmsize - 1);
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' : '-');
308 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
310 printf ("%02u: %-16s %-16s ", ++sec_nbr,
311 sec->segname, sec->sectname);
312 printf_vma (sec->addr);
314 printf_vma (sec->size);
315 printf (" %08lx\n", sec->flags);
321 dump_section (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
323 printf (" Section: %-16s %-16s (bfdname: %s)\n",
324 sec->sectname, sec->segname, sec->bfdsection->name);
326 printf_vma (sec->addr);
328 printf_vma (sec->size);
329 printf (" offset: ");
330 printf_vma (sec->offset);
332 printf (" align: %ld", sec->align);
333 printf (" nreloc: %lu reloff: ", sec->nreloc);
334 printf_vma (sec->reloff);
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));
340 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
341 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
343 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
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));
353 printf (" reserved1: 0x%lx", sec->reserved1);
356 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
358 case BFD_MACH_O_S_SYMBOL_STUBS:
359 printf (" stub size: %lu", sec->reserved2);
362 printf (" reserved2: 0x%lx", sec->reserved2);
365 printf (" reserved3: 0x%lx\n", sec->reserved3);
369 dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
371 bfd_mach_o_segment_command *seg = &cmd->command.segment;
372 bfd_mach_o_section *sec;
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);
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));
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);
394 dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose)
396 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
397 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
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);
444 if (dysymtab->ntoc > 0
445 || dysymtab->nindirectsyms > 0
446 || dysymtab->nextrefsyms > 0)
448 /* Try to read the symbols to display the toc or indirect symbols. */
449 bfd_mach_o_read_symtab_symbols (abfd);
451 else if (dysymtab->nmodtab > 0)
453 /* Try to read the strtab to display modules name. */
454 bfd_mach_o_read_symtab_strtab (abfd);
457 for (i = 0; i < dysymtab->nmodtab; i++)
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)
464 mdata->symtab->strtab + module->module_name_idx);
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);
483 if (dysymtab->ntoc > 0)
485 bfd_mach_o_symtab_command *symtab = mdata->symtab;
487 printf (" table of content: (symbol/module)\n");
488 for (i = 0; i < dysymtab->ntoc; i++)
490 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
492 printf (" %4u: ", i);
493 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
495 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
496 printf ("%s (%lu)", name ? name : "*invalid*",
500 printf ("%lu", toc->symbol_index);
503 if (symtab && symtab->strtab
504 && toc->module_index < dysymtab->nmodtab)
506 bfd_mach_o_dylib_module *mod;
507 mod = &dysymtab->dylib_module[toc->module_index];
509 symtab->strtab + mod->module_name_idx,
513 printf ("%lu", toc->module_index);
519 if (dysymtab->nindirectsyms != 0)
521 printf (" indirect symbols:\n");
523 for (i = 0; i < mdata->nsects; i++)
525 bfd_mach_o_section *sec = mdata->sections[i];
526 unsigned int j, first, last;
527 bfd_mach_o_symtab_command *symtab = mdata->symtab;
531 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
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);
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++)
544 unsigned int isym = dysymtab->indirect_syms[j];
548 printf (" %5u: 0x%08x", j, isym);
549 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_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);
566 if (dysymtab->nextrefsyms > 0)
568 bfd_mach_o_symtab_command *symtab = mdata->symtab;
570 printf (" external reference table: (symbol flags)\n");
571 for (i = 0; i < dysymtab->nextrefsyms; i++)
573 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
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);
587 dump_dyld_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
589 bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
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);
604 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
606 bfd_mach_o_thread_command *thread = &cmd->command.thread;
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);
611 printf (" nflavours: %lu\n", thread->nflavours);
612 for (j = 0; j < thread->nflavours; j++)
614 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
615 const bfd_mach_o_xlat_name *name_table;
617 printf (" %2u: flavour: 0x%08lx", j, flavour->flavour);
618 switch (mdata->header.cputype)
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;
628 if (name_table != NULL)
629 printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
632 printf (" offset: 0x%08lx size: 0x%08lx\n",
633 flavour->offset, flavour->size);
634 if (bed->_bfd_mach_o_print_thread)
636 char *buf = xmalloc (flavour->size);
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);
647 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic[] =
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 },
658 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type[] =
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 },
669 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
672 dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
673 const unsigned char *buf, unsigned int len)
680 printf (_(" [bad block length]\n"));
683 count = bfd_getb32 (buf + 8);
684 printf (_(" %u index entries:\n"), count);
685 if (len < 12 + 8 * count)
687 printf (_(" [bad block length]\n"));
690 for (i = 0; i < count; i++)
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"),
700 dump_code_signature_blob (abfd, buf + off, len - off);
705 swap_code_codedirectory_v1_in
706 (const struct mach_o_codesign_codedirectory_external_v1 *src,
707 struct mach_o_codesign_codedirectory_v1 *dst)
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);
724 hexdump (unsigned int start, unsigned int len,
725 const unsigned char *buf)
729 for (i = 0; i < len; i += 16)
731 printf ("%08x:", start + i);
732 for (j = 0; j < 16; j++)
734 fputc (j == 8 ? '-' : ' ', stdout);
736 printf ("%02x", buf[i + j]);
741 for (j = 0; j < 16; j++)
744 fputc (ISPRINT (buf[i + j]) ? buf[i + j] : '.', stdout);
748 fputc ('\n', stdout);
753 dump_code_signature_codedirectory (bfd *abfd ATTRIBUTE_UNUSED,
754 const unsigned char *buf, unsigned int len)
756 struct mach_o_codesign_codedirectory_v1 cd;
759 if (len < sizeof (struct mach_o_codesign_codedirectory_external_v1))
761 printf (_(" [bad block length]\n"));
765 swap_code_codedirectory_v1_in
766 ((const struct mach_o_codesign_codedirectory_external_v1 *) (buf + 8), &cd);
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"),
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));
793 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len)
800 printf (_(" [truncated block]\n"));
803 magic = bfd_getb32 (buf);
804 length = bfd_getb32 (buf + 4);
805 if (magic == 0 || length == 0)
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);
813 printf (_(" [bad block length]\n"));
819 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE:
820 dump_code_signature_superblob (abfd, buf, length);
822 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY:
823 dump_code_signature_codedirectory (abfd, buf, length);
826 hexdump (0, length - 8, buf + 8);
833 dump_code_signature (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
835 unsigned char *buf = xmalloc (cmd->datasize);
838 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
839 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
841 non_fatal (_("cannot read code signature data"));
845 for (off = 0; off < cmd->datasize;)
849 len = dump_code_signature_blob (abfd, buf + off, cmd->datasize - off);
859 dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
861 unsigned char *buf = xmalloc (cmd->datasize);
866 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
867 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
869 non_fatal (_("cannot read segment split info"));
873 if (buf[cmd->datasize - 1] != 0)
875 non_fatal (_("segment split info is not nul terminated"));
883 printf (_(" 32 bit pointers:\n"));
886 printf (_(" 64 bit pointers:\n"));
889 printf (_(" PPC hi-16:\n"));
892 printf (_(" Unhandled location type %u\n"), buf[0]);
895 for (p = buf + 1; *p != 0; p += len)
897 addr += read_unsigned_leb128 (abfd, p, &len);
899 bfd_printf_vma (abfd, addr);
906 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
909 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
910 const char *cmd_name;
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);
918 printf ("%s:", cmd_name);
922 case BFD_MACH_O_LC_SEGMENT:
923 case BFD_MACH_O_LC_SEGMENT_64:
924 dump_segment (abfd, cmd);
926 case BFD_MACH_O_LC_UUID:
928 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
931 for (j = 0; j < sizeof (uuid->uuid); j ++)
932 printf (" %02x", uuid->uuid[j]);
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:
942 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
943 printf (" %s\n", dylib->name_str);
944 printf (" time stamp: 0x%08lx\n",
946 printf (" current version: 0x%08lx\n",
947 dylib->current_version);
948 printf (" comptibility version: 0x%08lx\n",
949 dylib->compatibility_version);
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);
956 case BFD_MACH_O_LC_SYMTAB:
958 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
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);
970 case BFD_MACH_O_LC_DYSYMTAB:
972 dump_dysymtab (abfd, cmd, verbose);
974 case BFD_MACH_O_LC_LOADFVMLIB:
975 case BFD_MACH_O_LC_IDFVMLIB:
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);
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:
987 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
990 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
991 linkedit->dataoff, linkedit->datasize,
992 linkedit->dataoff + linkedit->datasize);
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);
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:
1006 bfd_mach_o_str_command *str = &cmd->command.str;
1007 printf (" %s\n", str->str);
1010 case BFD_MACH_O_LC_THREAD:
1011 case BFD_MACH_O_LC_UNIXTHREAD:
1012 dump_thread (abfd, cmd);
1014 case BFD_MACH_O_LC_ENCRYPTION_INFO:
1016 bfd_mach_o_encryption_info_command *cryp =
1017 &cmd->command.encryption_info;
1020 " cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1022 cryp->cryptoff, cryp->cryptsize,
1023 cryp->cryptoff + cryp->cryptsize,
1027 case BFD_MACH_O_LC_DYLD_INFO:
1029 dump_dyld_info (abfd, cmd);
1031 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
1032 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
1034 bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
1036 printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
1041 printf (" offset: 0x%08lx\n", (unsigned long)cmd->offset);
1042 printf (" size: 0x%08lx\n", (unsigned long)cmd->len);
1049 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
1051 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1054 for (i = 0; i < mdata->header.ncmds; i++)
1056 bfd_mach_o_load_command *cmd = &mdata->commands[i];
1059 dump_load_command (abfd, cmd, FALSE);
1060 else if (cmd->type == cmd32 || cmd->type == cmd64)
1061 dump_load_command (abfd, cmd, TRUE);
1065 /* Dump ABFD (according to the options[] array). */
1068 mach_o_dump (bfd *abfd)
1070 if (options[OPT_HEADER].selected)
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);
1086 /* Vector for Mach-O. */
1088 const struct objdump_private_desc objdump_private_desc_mach_o =