1 /* od-macho.c -- dump information about an Mach-O object file.
2 Copyright (C) 2011-2014 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"
34 #include "mach-o/unwind.h"
36 /* Index of the options in the options[] array. */
41 #define OPT_DYSYMTAB 4
42 #define OPT_CODESIGN 5
43 #define OPT_SEG_SPLIT_INFO 6
44 #define OPT_COMPACT_UNWIND 7
45 #define OPT_FUNCTION_STARTS 8
46 #define OPT_DATA_IN_CODE 9
47 #define OPT_TWOLEVEL_HINTS 10
49 /* List of actions. */
50 static struct objdump_private_option options[] =
58 { "seg_split_info", 0 },
59 { "compact_unwind", 0 },
60 { "function_starts", 0 },
61 { "data_in_code", 0 },
62 { "twolevel_hints", 0 },
69 mach_o_help (FILE *stream)
73 header Display the file header\n\
74 section Display the segments and sections commands\n\
75 map Display the section map\n\
76 load Display the load commands\n\
77 dysymtab Display the dynamic symbol table\n\
78 codesign Display code signature\n\
79 seg_split_info Display segment split info\n\
80 compact_unwind Display compact unwinding info\n\
81 function_starts Display start address of functions\n\
82 data_in_code Display data in code entries\n\
83 twolevel_hints Display the two-level namespace lookup hints table\n\
87 /* Return TRUE if ABFD is handled. */
90 mach_o_filter (bfd *abfd)
92 return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
95 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
97 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
98 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
99 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
100 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
101 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
102 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
103 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
104 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
105 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
106 { "i860", BFD_MACH_O_CPU_TYPE_I860 },
107 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
108 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
109 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
110 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
111 { "arm64", BFD_MACH_O_CPU_TYPE_ARM64 },
115 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
117 { "object", BFD_MACH_O_MH_OBJECT },
118 { "execute", BFD_MACH_O_MH_EXECUTE },
119 { "fvmlib", BFD_MACH_O_MH_FVMLIB },
120 { "core", BFD_MACH_O_MH_CORE },
121 { "preload", BFD_MACH_O_MH_PRELOAD },
122 { "dylib", BFD_MACH_O_MH_DYLIB },
123 { "dylinker", BFD_MACH_O_MH_DYLINKER },
124 { "bundle", BFD_MACH_O_MH_BUNDLE },
125 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
126 { "dym", BFD_MACH_O_MH_DSYM },
127 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
131 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
133 { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
134 { "incrlink", BFD_MACH_O_MH_INCRLINK },
135 { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
136 { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
137 { "prebound", BFD_MACH_O_MH_PREBOUND },
138 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
139 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
140 { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
141 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
142 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
143 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
144 { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
145 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
146 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
147 { "canonical", BFD_MACH_O_MH_CANONICAL },
148 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
149 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
150 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
151 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
152 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
153 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
154 { "pie", BFD_MACH_O_MH_PIE },
158 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
160 { "segment", BFD_MACH_O_LC_SEGMENT},
161 { "symtab", BFD_MACH_O_LC_SYMTAB},
162 { "symseg", BFD_MACH_O_LC_SYMSEG},
163 { "thread", BFD_MACH_O_LC_THREAD},
164 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
165 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
166 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
167 { "ident", BFD_MACH_O_LC_IDENT},
168 { "fvmfile", BFD_MACH_O_LC_FVMFILE},
169 { "prepage", BFD_MACH_O_LC_PREPAGE},
170 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
171 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
172 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
173 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
174 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
175 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
176 { "routines", BFD_MACH_O_LC_ROUTINES},
177 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
178 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
179 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
180 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
181 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
182 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
183 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
184 { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
185 { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
186 { "uuid", BFD_MACH_O_LC_UUID},
187 { "rpath", BFD_MACH_O_LC_RPATH},
188 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
189 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
190 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
191 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
192 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
193 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
194 { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
195 { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
196 { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
197 { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
198 { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
199 { "main", BFD_MACH_O_LC_MAIN},
200 { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE},
201 { "source_version", BFD_MACH_O_LC_SOURCE_VERSION},
202 { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS},
206 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
208 { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32},
209 { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32},
210 { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32},
211 { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64},
212 { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64},
213 { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64},
214 { "thread_state", BFD_MACH_O_x86_THREAD_STATE},
215 { "float_state", BFD_MACH_O_x86_FLOAT_STATE},
216 { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE},
217 { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32},
218 { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64},
219 { "debug_state", BFD_MACH_O_x86_DEBUG_STATE},
220 { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
225 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
230 for (; table->name; table++)
232 if (table->val & val)
236 printf ("%s", table->name);
245 printf ("0x%lx", val);
252 /* Print a bfd_uint64_t, using a platform independant style. */
255 printf_uint64 (bfd_uint64_t v)
257 printf ("0x%08lx%08lx",
258 (unsigned long)((v >> 16) >> 16), (unsigned long)(v & 0xffffffffUL));
262 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
265 for (; table->name; table++)
266 if (table->val == val)
272 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
274 const char *res = bfd_mach_o_get_name_or_null (table, val);
283 dump_header (bfd *abfd)
285 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
286 bfd_mach_o_header *h = &mdata->header;
288 fputs (_("Mach-O header:\n"), stdout);
289 printf (_(" magic : %08lx\n"), h->magic);
290 printf (_(" cputype : %08lx (%s)\n"), h->cputype,
291 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
292 printf (_(" cpusubtype: %08lx\n"), h->cpusubtype);
293 printf (_(" filetype : %08lx (%s)\n"),
295 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
296 printf (_(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
297 printf (_(" sizeofcmds: %08lx (%lu)\n"), h->sizeofcmds, h->sizeofcmds);
298 printf (_(" flags : %08lx ("), h->flags);
299 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
300 fputs (_(")\n"), stdout);
301 printf (_(" reserved : %08x\n"), h->reserved);
306 disp_segment_prot (unsigned int prot)
308 putchar (prot & BFD_MACH_O_PROT_READ ? 'r' : '-');
309 putchar (prot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
310 putchar (prot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
314 dump_section_map (bfd *abfd)
316 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
318 unsigned int sec_nbr = 0;
320 fputs (_("Segments and Sections:\n"), stdout);
321 fputs (_(" #: Segment name Section name Address\n"), stdout);
323 for (i = 0; i < mdata->header.ncmds; i++)
325 bfd_mach_o_segment_command *seg;
326 bfd_mach_o_section *sec;
328 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
329 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
332 seg = &mdata->commands[i].command.segment;
334 printf ("[Segment %-16s ", seg->segname);
335 printf_vma (seg->vmaddr);
337 printf_vma (seg->vmaddr + seg->vmsize - 1);
339 disp_segment_prot (seg->initprot);
342 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
344 printf ("%02u: %-16s %-16s ", ++sec_nbr,
345 sec->segname, sec->sectname);
346 printf_vma (sec->addr);
348 printf_vma (sec->size);
349 printf (" %08lx\n", sec->flags);
355 dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
357 printf (" Section: %-16s %-16s (bfdname: %s)\n",
358 sec->sectname, sec->segname, sec->bfdsection->name);
360 printf_vma (sec->addr);
362 printf_vma (sec->size);
363 printf (" offset: ");
364 printf_vma (sec->offset);
366 printf (" align: %ld", sec->align);
367 printf (" nreloc: %lu reloff: ", sec->nreloc);
368 printf_vma (sec->reloff);
370 printf (" flags: %08lx (type: %s", sec->flags,
371 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
372 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
374 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
375 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
377 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
379 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
380 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
381 case BFD_MACH_O_S_SYMBOL_STUBS:
382 printf (" first indirect sym: %lu", sec->reserved1);
383 printf (" (%u entries)",
384 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
387 printf (" reserved1: 0x%lx", sec->reserved1);
390 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
392 case BFD_MACH_O_S_SYMBOL_STUBS:
393 printf (" stub size: %lu", sec->reserved2);
396 printf (" reserved2: 0x%lx", sec->reserved2);
399 printf (" reserved3: 0x%lx\n", sec->reserved3);
403 dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
405 bfd_mach_o_segment_command *seg = &cmd->command.segment;
406 bfd_mach_o_section *sec;
408 printf (" name: %16s", *seg->segname ? seg->segname : "*none*");
409 printf (" nsects: %lu", seg->nsects);
410 printf (" flags: %lx", seg->flags);
411 printf (" initprot: ");
412 disp_segment_prot (seg->initprot);
413 printf (" maxprot: ");
414 disp_segment_prot (seg->maxprot);
416 printf (" vmaddr: ");
417 printf_vma (seg->vmaddr);
418 printf (" vmsize: ");
419 printf_vma (seg->vmsize);
421 printf (" fileoff: ");
422 printf_vma (seg->fileoff);
423 printf (" filesize: ");
424 printf_vma ((bfd_vma)seg->filesize);
425 printf (" endoff: ");
426 printf_vma ((bfd_vma)(seg->fileoff + seg->filesize));
428 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
429 dump_section_header (abfd, sec);
433 dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose)
435 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
436 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
439 printf (" local symbols: idx: %10lu num: %-8lu",
440 dysymtab->ilocalsym, dysymtab->nlocalsym);
441 printf (" (nxtidx: %lu)\n",
442 dysymtab->ilocalsym + dysymtab->nlocalsym);
443 printf (" external symbols: idx: %10lu num: %-8lu",
444 dysymtab->iextdefsym, dysymtab->nextdefsym);
445 printf (" (nxtidx: %lu)\n",
446 dysymtab->iextdefsym + dysymtab->nextdefsym);
447 printf (" undefined symbols: idx: %10lu num: %-8lu",
448 dysymtab->iundefsym, dysymtab->nundefsym);
449 printf (" (nxtidx: %lu)\n",
450 dysymtab->iundefsym + dysymtab->nundefsym);
451 printf (" table of content: off: 0x%08lx num: %-8lu",
452 dysymtab->tocoff, dysymtab->ntoc);
453 printf (" (endoff: 0x%08lx)\n",
454 dysymtab->tocoff + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
455 printf (" module table: off: 0x%08lx num: %-8lu",
456 dysymtab->modtaboff, dysymtab->nmodtab);
457 printf (" (endoff: 0x%08lx)\n",
458 dysymtab->modtaboff + dysymtab->nmodtab
459 * (mdata->header.version == 2 ?
460 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
461 printf (" external reference table: off: 0x%08lx num: %-8lu",
462 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
463 printf (" (endoff: 0x%08lx)\n",
464 dysymtab->extrefsymoff
465 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
466 printf (" indirect symbol table: off: 0x%08lx num: %-8lu",
467 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
468 printf (" (endoff: 0x%08lx)\n",
469 dysymtab->indirectsymoff
470 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
471 printf (" external relocation table: off: 0x%08lx num: %-8lu",
472 dysymtab->extreloff, dysymtab->nextrel);
473 printf (" (endoff: 0x%08lx)\n",
474 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
475 printf (" local relocation table: off: 0x%08lx num: %-8lu",
476 dysymtab->locreloff, dysymtab->nlocrel);
477 printf (" (endoff: 0x%08lx)\n",
478 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
483 if (dysymtab->ntoc > 0
484 || dysymtab->nindirectsyms > 0
485 || dysymtab->nextrefsyms > 0)
487 /* Try to read the symbols to display the toc or indirect symbols. */
488 bfd_mach_o_read_symtab_symbols (abfd);
490 else if (dysymtab->nmodtab > 0)
492 /* Try to read the strtab to display modules name. */
493 bfd_mach_o_read_symtab_strtab (abfd);
496 for (i = 0; i < dysymtab->nmodtab; i++)
498 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
499 printf (" module %u:\n", i);
500 printf (" name: %lu", module->module_name_idx);
501 if (mdata->symtab && mdata->symtab->strtab)
503 mdata->symtab->strtab + module->module_name_idx);
505 printf (" extdefsym: idx: %8lu num: %lu\n",
506 module->iextdefsym, module->nextdefsym);
507 printf (" refsym: idx: %8lu num: %lu\n",
508 module->irefsym, module->nrefsym);
509 printf (" localsym: idx: %8lu num: %lu\n",
510 module->ilocalsym, module->nlocalsym);
511 printf (" extrel: idx: %8lu num: %lu\n",
512 module->iextrel, module->nextrel);
513 printf (" init: idx: %8u num: %u\n",
514 module->iinit, module->ninit);
515 printf (" term: idx: %8u num: %u\n",
516 module->iterm, module->nterm);
517 printf (" objc_module_info: addr: ");
518 printf_vma (module->objc_module_info_addr);
519 printf (" size: %lu\n", module->objc_module_info_size);
522 if (dysymtab->ntoc > 0)
524 bfd_mach_o_symtab_command *symtab = mdata->symtab;
526 printf (" table of content: (symbol/module)\n");
527 for (i = 0; i < dysymtab->ntoc; i++)
529 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
531 printf (" %4u: ", i);
532 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
534 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
535 printf ("%s (%lu)", name ? name : "*invalid*",
539 printf ("%lu", toc->symbol_index);
542 if (symtab && symtab->strtab
543 && toc->module_index < dysymtab->nmodtab)
545 bfd_mach_o_dylib_module *mod;
546 mod = &dysymtab->dylib_module[toc->module_index];
548 symtab->strtab + mod->module_name_idx,
552 printf ("%lu", toc->module_index);
558 if (dysymtab->nindirectsyms != 0)
560 printf (" indirect symbols:\n");
562 for (i = 0; i < mdata->nsects; i++)
564 bfd_mach_o_section *sec = mdata->sections[i];
565 unsigned int j, first, last;
566 bfd_mach_o_symtab_command *symtab = mdata->symtab;
570 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
572 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
573 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
574 case BFD_MACH_O_S_SYMBOL_STUBS:
575 first = sec->reserved1;
576 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
578 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
579 printf (" for section %s.%s:\n",
580 sec->segname, sec->sectname);
581 for (j = first; j < last; j++)
583 unsigned int isym = dysymtab->indirect_syms[j];
587 printf (" %5u: 0x%08x", j, isym);
588 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
590 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
591 printf (" ABSOLUTE");
592 if (symtab && symtab->symbols
593 && isym < symtab->nsyms
594 && symtab->symbols[isym].symbol.name)
595 printf (" %s", symtab->symbols[isym].symbol.name);
605 if (dysymtab->nextrefsyms > 0)
607 bfd_mach_o_symtab_command *symtab = mdata->symtab;
609 printf (" external reference table: (symbol flags)\n");
610 for (i = 0; i < dysymtab->nextrefsyms; i++)
612 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
614 printf (" %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
615 if (symtab && symtab->symbols
616 && ref->isym < symtab->nsyms
617 && symtab->symbols[ref->isym].symbol.name)
618 printf (" %s", symtab->symbols[ref->isym].symbol.name);
626 dump_dyld_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
628 bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
630 printf (" rebase: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
631 info->rebase_off, info->rebase_size,
632 info->rebase_off + info->rebase_size);
633 printf (" bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
634 info->bind_off, info->bind_size,
635 info->bind_off + info->bind_size);
636 printf (" weak bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
637 info->weak_bind_off, info->weak_bind_size,
638 info->weak_bind_off + info->weak_bind_size);
639 printf (" lazy bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
640 info->lazy_bind_off, info->lazy_bind_size,
641 info->lazy_bind_off + info->lazy_bind_size);
642 printf (" export: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
643 info->export_off, info->export_size,
644 info->export_off + info->export_size);
648 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
650 bfd_mach_o_thread_command *thread = &cmd->command.thread;
652 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
653 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
655 printf (" nflavours: %lu\n", thread->nflavours);
656 for (j = 0; j < thread->nflavours; j++)
658 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
659 const bfd_mach_o_xlat_name *name_table;
661 printf (" %2u: flavour: 0x%08lx", j, flavour->flavour);
662 switch (mdata->header.cputype)
664 case BFD_MACH_O_CPU_TYPE_I386:
665 case BFD_MACH_O_CPU_TYPE_X86_64:
666 name_table = bfd_mach_o_thread_x86_name;
672 if (name_table != NULL)
673 printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
676 printf (" offset: 0x%08lx size: 0x%08lx\n",
677 flavour->offset, flavour->size);
678 if (bed->_bfd_mach_o_print_thread)
680 char *buf = xmalloc (flavour->size);
682 if (bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
683 && bfd_bread (buf, flavour->size, abfd) == flavour->size)
684 (*bed->_bfd_mach_o_print_thread)(abfd, flavour, stdout, buf);
691 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic[] =
693 { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE },
694 { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT },
695 { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS },
696 { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY },
697 { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS },
698 { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER },
702 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type[] =
704 { "no-hash", BFD_MACH_O_CS_NO_HASH },
705 { "sha1", BFD_MACH_O_CS_HASH_SHA1 },
706 { "sha256", BFD_MACH_O_CS_HASH_SHA256 },
707 { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256 },
708 { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512 },
713 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
716 dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
717 const unsigned char *buf, unsigned int len)
724 printf (_(" [bad block length]\n"));
727 count = bfd_getb32 (buf + 8);
728 printf (_(" %u index entries:\n"), count);
729 if (len < 12 + 8 * count)
731 printf (_(" [bad block length]\n"));
734 for (i = 0; i < count; i++)
739 type = bfd_getb32 (buf + 12 + 8 * i);
740 off = bfd_getb32 (buf + 12 + 8 * i + 4);
741 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
744 dump_code_signature_blob (abfd, buf + off, len - off);
749 swap_code_codedirectory_v1_in
750 (const struct mach_o_codesign_codedirectory_external_v1 *src,
751 struct mach_o_codesign_codedirectory_v1 *dst)
753 dst->version = bfd_getb32 (src->version);
754 dst->flags = bfd_getb32 (src->flags);
755 dst->hash_offset = bfd_getb32 (src->hash_offset);
756 dst->ident_offset = bfd_getb32 (src->ident_offset);
757 dst->nbr_special_slots = bfd_getb32 (src->nbr_special_slots);
758 dst->nbr_code_slots = bfd_getb32 (src->nbr_code_slots);
759 dst->code_limit = bfd_getb32 (src->code_limit);
760 dst->hash_size = src->hash_size[0];
761 dst->hash_type = src->hash_type[0];
762 dst->spare1 = src->spare1[0];
763 dst->page_size = src->page_size[0];
764 dst->spare2 = bfd_getb32 (src->spare2);
768 hexdump (unsigned int start, unsigned int len,
769 const unsigned char *buf)
773 for (i = 0; i < len; i += 16)
775 printf ("%08x:", start + i);
776 for (j = 0; j < 16; j++)
778 fputc (j == 8 ? '-' : ' ', stdout);
780 printf ("%02x", buf[i + j]);
785 for (j = 0; j < 16; j++)
788 fputc (ISPRINT (buf[i + j]) ? buf[i + j] : '.', stdout);
792 fputc ('\n', stdout);
797 dump_code_signature_codedirectory (bfd *abfd ATTRIBUTE_UNUSED,
798 const unsigned char *buf, unsigned int len)
800 struct mach_o_codesign_codedirectory_v1 cd;
803 if (len < sizeof (struct mach_o_codesign_codedirectory_external_v1))
805 printf (_(" [bad block length]\n"));
809 swap_code_codedirectory_v1_in
810 ((const struct mach_o_codesign_codedirectory_external_v1 *) (buf + 8), &cd);
812 printf (_(" version: %08x\n"), cd.version);
813 printf (_(" flags: %08x\n"), cd.flags);
814 printf (_(" hash offset: %08x\n"), cd.hash_offset);
815 id = (const char *) buf + cd.ident_offset;
816 printf (_(" ident offset: %08x (- %08x)\n"),
817 cd.ident_offset, cd.ident_offset + (unsigned) strlen (id) + 1);
818 printf (_(" identity: %s\n"), id);
819 printf (_(" nbr special slots: %08x (at offset %08x)\n"),
820 cd.nbr_special_slots,
821 cd.hash_offset - cd.nbr_special_slots * cd.hash_size);
822 printf (_(" nbr code slots: %08x\n"), cd.nbr_code_slots);
823 printf (_(" code limit: %08x\n"), cd.code_limit);
824 printf (_(" hash size: %02x\n"), cd.hash_size);
825 printf (_(" hash type: %02x (%s)\n"),
827 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type, cd.hash_type));
828 printf (_(" spare1: %02x\n"), cd.spare1);
829 printf (_(" page size: %02x\n"), cd.page_size);
830 printf (_(" spare2: %08x\n"), cd.spare2);
831 if (cd.version >= 0x20100)
832 printf (_(" scatter offset: %08x\n"),
833 (unsigned) bfd_getb32 (buf + 44));
837 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len)
844 printf (_(" [truncated block]\n"));
847 magic = bfd_getb32 (buf);
848 length = bfd_getb32 (buf + 4);
849 if (magic == 0 || length == 0)
852 printf (_(" magic : %08x (%s)\n"), magic,
853 bfd_mach_o_get_name (bfd_mach_o_cs_magic, magic));
854 printf (_(" length: %08x\n"), length);
857 printf (_(" [bad block length]\n"));
863 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE:
864 dump_code_signature_superblob (abfd, buf, length);
866 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY:
867 dump_code_signature_codedirectory (abfd, buf, length);
870 hexdump (0, length - 8, buf + 8);
877 dump_code_signature (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
879 unsigned char *buf = xmalloc (cmd->datasize);
882 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
883 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
885 non_fatal (_("cannot read code signature data"));
889 for (off = 0; off < cmd->datasize;)
893 len = dump_code_signature_blob (abfd, buf + off, cmd->datasize - off);
903 dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
905 unsigned char *buf = xmalloc (cmd->datasize);
910 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
911 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
913 non_fatal (_("cannot read segment split info"));
917 if (buf[cmd->datasize - 1] != 0)
919 non_fatal (_("segment split info is not nul terminated"));
927 printf (_(" 32 bit pointers:\n"));
930 printf (_(" 64 bit pointers:\n"));
933 printf (_(" PPC hi-16:\n"));
936 printf (_(" Unhandled location type %u\n"), buf[0]);
939 for (p = buf + 1; *p != 0; p += len)
941 addr += read_unsigned_leb128 (abfd, p, &len);
943 bfd_printf_vma (abfd, addr);
950 dump_function_starts (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
952 unsigned char *buf = xmalloc (cmd->datasize);
953 unsigned char *end_buf = buf + cmd->datasize;
957 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
958 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
960 non_fatal (_("cannot read function starts"));
965 /* Function starts are delta encoded, starting from the base address. */
966 addr = bfd_mach_o_get_base_address (abfd);
971 unsigned int shift = 0;
973 if (*p == 0 || p == end_buf)
977 unsigned char b = *p++;
979 delta |= (b & 0x7f) << shift;
984 fputs (" [truncated]\n", stdout);
992 bfd_printf_vma (abfd, addr);
998 static const bfd_mach_o_xlat_name data_in_code_kind_name[] =
1000 { "data", BFD_MACH_O_DICE_KIND_DATA },
1001 { "1 byte jump table", BFD_MACH_O_DICE_JUMP_TABLES8 },
1002 { "2 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES16 },
1003 { "4 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES32 },
1004 { "4 bytes abs jump table", BFD_MACH_O_DICE_ABS_JUMP_TABLES32 },
1009 dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1014 if (cmd->datasize == 0)
1016 printf (" no data_in_code entries\n");
1020 buf = xmalloc (cmd->datasize);
1021 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1022 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1024 non_fatal (_("cannot read data_in_code"));
1029 printf (" offset length kind\n");
1030 for (p = buf; p < buf + cmd->datasize; )
1032 struct mach_o_data_in_code_entry_external *dice;
1033 unsigned int offset;
1034 unsigned int length;
1037 dice = (struct mach_o_data_in_code_entry_external *) p;
1039 offset = bfd_get_32 (abfd, dice->offset);
1040 length = bfd_get_16 (abfd, dice->length);
1041 kind = bfd_get_16 (abfd, dice->kind);
1043 printf (" 0x%08x 0x%04x 0x%04x %s\n", offset, length, kind,
1044 bfd_mach_o_get_name (data_in_code_kind_name, kind));
1046 p += sizeof (*dice);
1052 dump_twolevel_hints (bfd *abfd, bfd_mach_o_twolevel_hints_command *cmd)
1054 size_t sz = 4 * cmd->nhints;
1059 if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
1060 || bfd_bread (buf, sz, abfd) != sz)
1062 non_fatal (_("cannot read twolevel hints"));
1067 for (p = buf; p < buf + sz; p += 4)
1070 unsigned int isub_image;
1073 v = bfd_get_32 (abfd, p);
1074 if (bfd_big_endian (abfd))
1076 isub_image = (v >> 24) & 0xff;
1077 itoc = v & 0xffffff;
1081 isub_image = v & 0xff;
1082 itoc = (v >> 8) & 0xffffff;
1085 printf (" %3u %8u\n", isub_image, itoc);
1091 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
1092 unsigned int idx, bfd_boolean verbose)
1094 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1095 const char *cmd_name;
1097 cmd_name = bfd_mach_o_get_name_or_null
1098 (bfd_mach_o_load_command_name, cmd->type);
1099 printf ("Load command #%-2u (size: %3u, offset: %4u): ",
1100 idx, cmd->len, cmd->offset);
1101 if (cmd_name == NULL)
1102 printf ("0x%02x\n", cmd->type);
1104 printf ("%s\n", cmd_name);
1108 case BFD_MACH_O_LC_SEGMENT:
1109 case BFD_MACH_O_LC_SEGMENT_64:
1110 dump_segment (abfd, cmd);
1112 case BFD_MACH_O_LC_UUID:
1114 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
1118 for (j = 0; j < sizeof (uuid->uuid); j ++)
1119 printf (" %02x", uuid->uuid[j]);
1123 case BFD_MACH_O_LC_LOAD_DYLIB:
1124 case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
1125 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1126 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1127 case BFD_MACH_O_LC_ID_DYLIB:
1128 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
1130 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
1131 printf (" name: %s\n", dylib->name_str);
1132 printf (" time stamp: 0x%08lx\n",
1134 printf (" current version: 0x%08lx\n",
1135 dylib->current_version);
1136 printf (" comptibility version: 0x%08lx\n",
1137 dylib->compatibility_version);
1140 case BFD_MACH_O_LC_LOAD_DYLINKER:
1141 case BFD_MACH_O_LC_ID_DYLINKER:
1142 printf (" %s\n", cmd->command.dylinker.name_str);
1144 case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
1145 printf (" %s\n", cmd->command.dylinker.name_str);
1147 case BFD_MACH_O_LC_SYMTAB:
1149 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
1150 printf (" symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
1151 symtab->symoff, symtab->nsyms,
1152 symtab->symoff + symtab->nsyms
1153 * (mdata->header.version == 2
1154 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
1155 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
1156 symtab->stroff, symtab->strsize,
1157 symtab->stroff + symtab->strsize);
1160 case BFD_MACH_O_LC_DYSYMTAB:
1161 dump_dysymtab (abfd, cmd, verbose);
1163 case BFD_MACH_O_LC_LOADFVMLIB:
1164 case BFD_MACH_O_LC_IDFVMLIB:
1166 bfd_mach_o_fvmlib_command *fvmlib = &cmd->command.fvmlib;
1167 printf (" fvmlib: %s\n", fvmlib->name_str);
1168 printf (" minor version: 0x%08x\n", fvmlib->minor_version);
1169 printf (" header address: 0x%08x\n", fvmlib->header_addr);
1172 case BFD_MACH_O_LC_CODE_SIGNATURE:
1173 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1174 case BFD_MACH_O_LC_FUNCTION_STARTS:
1175 case BFD_MACH_O_LC_DATA_IN_CODE:
1176 case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
1178 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
1180 (" dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
1181 linkedit->dataoff, linkedit->datasize,
1182 linkedit->dataoff + linkedit->datasize);
1187 case BFD_MACH_O_LC_CODE_SIGNATURE:
1188 dump_code_signature (abfd, linkedit);
1190 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1191 dump_segment_split_info (abfd, linkedit);
1193 case BFD_MACH_O_LC_FUNCTION_STARTS:
1194 dump_function_starts (abfd, linkedit);
1196 case BFD_MACH_O_LC_DATA_IN_CODE:
1197 dump_data_in_code (abfd, linkedit);
1204 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1205 case BFD_MACH_O_LC_SUB_UMBRELLA:
1206 case BFD_MACH_O_LC_SUB_LIBRARY:
1207 case BFD_MACH_O_LC_SUB_CLIENT:
1208 case BFD_MACH_O_LC_RPATH:
1210 bfd_mach_o_str_command *str = &cmd->command.str;
1211 printf (" %s\n", str->str);
1214 case BFD_MACH_O_LC_THREAD:
1215 case BFD_MACH_O_LC_UNIXTHREAD:
1216 dump_thread (abfd, cmd);
1218 case BFD_MACH_O_LC_ENCRYPTION_INFO:
1220 bfd_mach_o_encryption_info_command *cryp =
1221 &cmd->command.encryption_info;
1223 (" cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1225 cryp->cryptoff, cryp->cryptsize,
1226 cryp->cryptoff + cryp->cryptsize,
1230 case BFD_MACH_O_LC_DYLD_INFO:
1231 dump_dyld_info (abfd, cmd);
1233 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
1234 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
1236 bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
1238 printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
1241 case BFD_MACH_O_LC_SOURCE_VERSION:
1243 bfd_mach_o_source_version_command *version =
1244 &cmd->command.source_version;
1245 printf (" version a.b.c.d.e: %u.%u.%u.%u.%u\n",
1246 version->a, version->b, version->c, version->d, version->e);
1249 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1251 bfd_mach_o_prebound_dylib_command *pbdy = &cmd->command.prebound_dylib;
1252 unsigned char *lm = pbdy->linked_modules;
1256 printf (" dylib: %s\n", pbdy->name_str);
1257 printf (" nmodules: %u\n", pbdy->nmodules);
1258 printf (" linked modules (at %u): ",
1259 pbdy->linked_modules_offset - cmd->offset);
1260 last = pbdy->nmodules > 32 ? 32 : pbdy->nmodules;
1261 for (j = 0; j < last; j++)
1262 printf ("%u", (lm[j >> 3] >> (j & 7)) & 1);
1263 if (last < pbdy->nmodules)
1268 case BFD_MACH_O_LC_PREBIND_CKSUM:
1270 bfd_mach_o_prebind_cksum_command *cksum = &cmd->command.prebind_cksum;
1271 printf (" 0x%08x\n", cksum->cksum);
1274 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1276 bfd_mach_o_twolevel_hints_command *hints =
1277 &cmd->command.twolevel_hints;
1279 printf (" table offset: 0x%08x nbr hints: %u\n",
1280 hints->offset, hints->nhints);
1282 dump_twolevel_hints (abfd, hints);
1285 case BFD_MACH_O_LC_MAIN:
1287 bfd_mach_o_main_command *entry = &cmd->command.main;
1288 printf (" entry offset: ");
1289 printf_uint64 (entry->entryoff);
1292 printf_uint64 (entry->stacksize);
1303 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
1305 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1308 for (i = 0; i < mdata->header.ncmds; i++)
1310 bfd_mach_o_load_command *cmd = &mdata->commands[i];
1313 dump_load_command (abfd, cmd, i, FALSE);
1314 else if (cmd->type == cmd32 || cmd->type == cmd64)
1315 dump_load_command (abfd, cmd, i, TRUE);
1319 static const char * const unwind_x86_64_regs[] =
1320 {"", "rbx", "r12", "r13", "r14", "r15", "rbp", "???" };
1322 static const char * const unwind_x86_regs[] =
1323 {"", "ebx", "ecx", "edx", "edi", "edi", "ebp", "???" };
1325 /* Dump x86 or x86-64 compact unwind encoding. Works for both architecture,
1326 as the encoding is the same (but not register names). */
1329 dump_unwind_encoding_x86 (unsigned int encoding, unsigned int sz,
1330 const char * const regs_name[])
1334 mode = encoding & MACH_O_UNWIND_X86_64_MODE_MASK;
1337 case MACH_O_UNWIND_X86_64_MODE_RBP_FRAME:
1340 char pfx = sz == 8 ? 'R' : 'E';
1342 regs = encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_REGSITERS;
1343 printf (" %cSP frame", pfx);
1346 unsigned int offset;
1349 offset = (encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET) >> 16;
1350 printf (" at %cBP-%u:", pfx, offset * sz);
1351 for (i = 0; i < 5; i++)
1353 unsigned int reg = (regs >> (i * 3)) & 0x7;
1354 if (reg != MACH_O_UNWIND_X86_64_REG_NONE)
1355 printf (" %s", regs_name[reg]);
1360 case MACH_O_UNWIND_X86_64_MODE_STACK_IMMD:
1361 case MACH_O_UNWIND_X86_64_MODE_STACK_IND:
1363 unsigned int stack_size;
1364 unsigned int reg_count;
1365 unsigned int reg_perm;
1366 unsigned int regs[6];
1369 printf (" frameless");
1371 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE) >> 16;
1373 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT) >> 10;
1374 reg_perm = encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION;
1376 if (mode == MACH_O_UNWIND_X86_64_MODE_STACK_IMMD)
1377 printf (" size: 0x%03x", stack_size * sz);
1380 unsigned int stack_adj;
1383 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST) >> 13;
1384 printf (" size at 0x%03x + 0x%02x", stack_size, stack_adj * sz);
1386 /* Registers are coded using arithmetic compression: the register
1387 is indexed in range 0-6, the second in range 0-5, the third in
1388 range 0-4, etc. Already used registers are removed in next
1390 #define DO_PERM(R, NUM) R = reg_perm / NUM; reg_perm -= R * NUM
1395 DO_PERM (regs[0], 120);
1396 DO_PERM (regs[1], 24);
1397 DO_PERM (regs[2], 6);
1398 DO_PERM (regs[3], 2);
1399 DO_PERM (regs[4], 1);
1400 regs[5] = 0; /* Not used if reg_count = 5. */
1403 DO_PERM (regs[0], 60);
1404 DO_PERM (regs[1], 12);
1405 DO_PERM (regs[2], 3);
1406 DO_PERM (regs[3], 1);
1409 DO_PERM (regs[0], 20);
1410 DO_PERM (regs[1], 4);
1411 DO_PERM (regs[2], 1);
1414 DO_PERM (regs[0], 5);
1415 DO_PERM (regs[1], 1);
1418 DO_PERM (regs[0], 1);
1423 printf (" [bad reg count]");
1428 for (i = reg_count - 1; i >= 0; i--)
1430 unsigned int inc = 1;
1431 for (j = 0; j < i; j++)
1432 if (regs[i] >= regs[j])
1437 for (i = 0; i < (int) reg_count; i++)
1438 printf (" %s", regs_name[regs[i]]);
1441 case MACH_O_UNWIND_X86_64_MODE_DWARF:
1442 printf (" Dwarf offset: 0x%06x",
1443 encoding & MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET);
1446 printf (" [unhandled mode]");
1452 dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding)
1454 printf ("0x%08x", encoding);
1458 switch (mdata->header.cputype)
1460 case BFD_MACH_O_CPU_TYPE_X86_64:
1461 dump_unwind_encoding_x86 (encoding, 8, unwind_x86_64_regs);
1463 case BFD_MACH_O_CPU_TYPE_I386:
1464 dump_unwind_encoding_x86 (encoding, 4, unwind_x86_regs);
1467 printf (" [unhandled cpu]");
1470 if (encoding & MACH_O_UNWIND_HAS_LSDA)
1472 if (encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1473 printf (" PERS(%u)",
1474 ((encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1475 >> MACH_O_UNWIND_PERSONALITY_SHIFT));
1479 dump_obj_compact_unwind (bfd *abfd,
1480 const unsigned char *content, bfd_size_type size)
1482 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1483 int is_64 = mdata->header.version == 2;
1484 const unsigned char *p;
1486 printf ("Compact unwind info:\n");
1487 printf (" start length personality lsda\n");
1491 struct mach_o_compact_unwind_64 *e =
1492 (struct mach_o_compact_unwind_64 *) content;
1494 for (p = content; p < content + size; p += sizeof (*e))
1496 e = (struct mach_o_compact_unwind_64 *) p;
1499 printf_uint64 (bfd_get_64 (abfd, e->start));
1500 printf (" %08lx", bfd_get_32 (abfd, e->length));
1502 printf_uint64 (bfd_get_64 (abfd, e->personality));
1504 printf_uint64 (bfd_get_64 (abfd, e->lsda));
1507 printf (" encoding: ");
1508 dump_unwind_encoding (mdata, bfd_get_32 (abfd, e->encoding));
1514 printf ("unhandled\n");
1519 dump_exe_compact_unwind (bfd *abfd,
1520 const unsigned char *content, bfd_size_type size)
1522 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1523 struct mach_o_unwind_info_header *hdr;
1524 unsigned int version;
1525 unsigned int encodings_offset;
1526 unsigned int encodings_count;
1527 unsigned int personality_offset;
1528 unsigned int personality_count;
1529 unsigned int index_offset;
1530 unsigned int index_count;
1531 struct mach_o_unwind_index_entry *index_entry;
1535 printf ("Compact unwind info:\n");
1537 hdr = (struct mach_o_unwind_info_header *) content;
1538 if (size < sizeof (*hdr))
1540 printf (" truncated!\n");
1544 version = bfd_get_32 (abfd, hdr->version);
1545 if (version != MACH_O_UNWIND_SECTION_VERSION)
1547 printf (" unknown version: %u\n", version);
1550 encodings_offset = bfd_get_32 (abfd, hdr->encodings_array_offset);
1551 encodings_count = bfd_get_32 (abfd, hdr->encodings_array_count);
1552 personality_offset = bfd_get_32 (abfd, hdr->personality_array_offset);
1553 personality_count = bfd_get_32 (abfd, hdr->personality_array_count);
1554 index_offset = bfd_get_32 (abfd, hdr->index_offset);
1555 index_count = bfd_get_32 (abfd, hdr->index_count);
1556 printf (" %u encodings, %u personalities, %u level-1 indexes:\n",
1557 encodings_count, personality_count, index_count);
1560 if (personality_count > 0)
1562 const unsigned char *pers = content + personality_offset;
1564 printf (" personalities\n");
1565 for (i = 0; i < personality_count; i++)
1566 printf (" %u: 0x%08x\n", i,
1567 (unsigned) bfd_get_32 (abfd, pers + 4 * i));
1570 /* Level-1 index. */
1571 printf (" idx function level2 off lsda off\n");
1573 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
1574 for (i = 0; i < index_count; i++)
1576 unsigned int func_offset;
1577 unsigned int level2_offset;
1578 unsigned int lsda_offset;
1580 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
1581 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
1582 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
1583 printf (" %3u 0x%08x 0x%08x 0x%08x\n",
1584 i, func_offset, level2_offset, lsda_offset);
1588 /* Level-1 index. */
1589 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
1590 for (i = 0; i < index_count; i++)
1592 unsigned int func_offset;
1593 unsigned int level2_offset;
1594 const unsigned char *level2;
1597 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
1598 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
1600 /* No level-2 for this index (should be the last index). */
1601 if (level2_offset == 0)
1604 level2 = content + level2_offset;
1605 kind = bfd_get_32 (abfd, level2);
1608 case MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED:
1610 struct mach_o_unwind_compressed_second_level_page_header *l2;
1611 unsigned int entry_offset;
1612 unsigned int entry_count;
1613 unsigned int l2_encodings_offset;
1614 unsigned int l2_encodings_count;
1615 const unsigned char *en;
1618 l2 = (struct mach_o_unwind_compressed_second_level_page_header *)
1620 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
1621 entry_count = bfd_get_16 (abfd, l2->entry_count);
1622 l2_encodings_offset = bfd_get_16 (abfd, l2->encodings_offset);
1623 l2_encodings_count = bfd_get_16 (abfd, l2->encodings_count);
1625 printf (" index %2u: compressed second level: "
1626 "%u entries, %u encodings (at 0x%08x)\n",
1627 i, entry_count, l2_encodings_count, l2_encodings_offset);
1628 printf (" # function eidx encoding\n");
1630 en = level2 + entry_offset;
1631 for (j = 0; j < entry_count; j++)
1634 unsigned int en_func;
1635 unsigned int enc_idx;
1636 unsigned int encoding;
1637 const unsigned char *enc_addr;
1639 entry = bfd_get_32 (abfd, en);
1641 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry);
1643 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry);
1644 if (enc_idx < encodings_count)
1645 enc_addr = content + encodings_offset
1648 enc_addr = level2 + l2_encodings_offset
1649 + 4 * (enc_idx - encodings_count);
1650 encoding = bfd_get_32 (abfd, enc_addr);
1652 printf (" %4u 0x%08x [%3u] ", j,
1653 func_offset + en_func, enc_idx);
1654 dump_unwind_encoding (mdata, encoding);
1662 case MACH_O_UNWIND_SECOND_LEVEL_REGULAR:
1664 struct mach_o_unwind_regular_second_level_page_header *l2;
1665 struct mach_o_unwind_regular_second_level_entry *en;
1666 unsigned int entry_offset;
1667 unsigned int entry_count;
1670 l2 = (struct mach_o_unwind_regular_second_level_page_header *)
1673 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
1674 entry_count = bfd_get_16 (abfd, l2->entry_count);
1675 printf (" index %2u: regular level 2 at 0x%04x, %u entries\n",
1676 i, entry_offset, entry_count);
1677 printf (" # function encoding\n");
1679 en = (struct mach_o_unwind_regular_second_level_entry *)
1680 (level2 + entry_offset);
1681 for (j = 0; j < entry_count; j++)
1683 unsigned int en_func;
1684 unsigned int encoding;
1686 en_func = bfd_get_32 (abfd, en->function_offset);
1687 encoding = bfd_get_32 (abfd, en->encoding);
1688 printf (" %-4u 0x%08x ", j, en_func);
1689 dump_unwind_encoding (mdata, encoding);
1697 printf (" index %2u: unhandled second level format (%u)\n",
1703 struct mach_o_unwind_lsda_index_entry *lsda;
1704 unsigned int lsda_offset;
1705 unsigned int next_lsda_offset;
1706 unsigned int nbr_lsda;
1709 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
1710 next_lsda_offset = bfd_get_32 (abfd, index_entry[1].lsda_index_offset);
1711 lsda = (struct mach_o_unwind_lsda_index_entry *)
1712 (content + lsda_offset);
1713 nbr_lsda = (next_lsda_offset - lsda_offset) / sizeof (*lsda);
1714 for (j = 0; j < nbr_lsda; j++)
1716 printf (" lsda %3u: function 0x%08x lsda 0x%08x\n",
1717 j, (unsigned int) bfd_get_32 (abfd, lsda->function_offset),
1718 (unsigned int) bfd_get_32 (abfd, lsda->lsda_offset));
1727 dump_section_content (bfd *abfd,
1728 const char *segname, const char *sectname,
1729 void (*dump)(bfd*, const unsigned char*, bfd_size_type))
1731 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1734 for (i = 0; i < mdata->header.ncmds; i++)
1736 bfd_mach_o_load_command *cmd = &mdata->commands[i];
1737 if (cmd->type == BFD_MACH_O_LC_SEGMENT
1738 || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
1740 bfd_mach_o_segment_command *seg = &cmd->command.segment;
1741 bfd_mach_o_section *sec;
1742 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1743 if (strcmp (sec->segname, segname) == 0
1744 && strcmp (sec->sectname, sectname) == 0)
1747 asection *bfdsec = sec->bfdsection;
1748 unsigned char *content;
1750 size = bfd_get_section_size (bfdsec);
1751 content = (unsigned char *) xmalloc (size);
1752 bfd_get_section_contents (abfd, bfdsec, content, 0, size);
1754 (*dump)(abfd, content, size);
1762 /* Dump ABFD (according to the options[] array). */
1765 mach_o_dump (bfd *abfd)
1767 if (options[OPT_HEADER].selected)
1769 if (options[OPT_SECTION].selected)
1770 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT, BFD_MACH_O_LC_SEGMENT_64);
1771 if (options[OPT_MAP].selected)
1772 dump_section_map (abfd);
1773 if (options[OPT_LOAD].selected)
1774 dump_load_commands (abfd, 0, 0);
1775 if (options[OPT_DYSYMTAB].selected)
1776 dump_load_commands (abfd, BFD_MACH_O_LC_DYSYMTAB, 0);
1777 if (options[OPT_CODESIGN].selected)
1778 dump_load_commands (abfd, BFD_MACH_O_LC_CODE_SIGNATURE, 0);
1779 if (options[OPT_SEG_SPLIT_INFO].selected)
1780 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO, 0);
1781 if (options[OPT_FUNCTION_STARTS].selected)
1782 dump_load_commands (abfd, BFD_MACH_O_LC_FUNCTION_STARTS, 0);
1783 if (options[OPT_DATA_IN_CODE].selected)
1784 dump_load_commands (abfd, BFD_MACH_O_LC_DATA_IN_CODE, 0);
1785 if (options[OPT_TWOLEVEL_HINTS].selected)
1786 dump_load_commands (abfd, BFD_MACH_O_LC_TWOLEVEL_HINTS, 0);
1787 if (options[OPT_COMPACT_UNWIND].selected)
1789 dump_section_content (abfd, "__LD", "__compact_unwind",
1790 dump_obj_compact_unwind);
1791 dump_section_content (abfd, "__TEXT", "__unwind_info",
1792 dump_exe_compact_unwind);
1796 /* Vector for Mach-O. */
1798 const struct objdump_private_desc objdump_private_desc_mach_o =