daily update
[binutils.git] / binutils / od-macho.c
blobca1dba73b4a51a907297fd4a79100ecf2b72f471
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)
10 any later version.
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. */
22 #include "sysdep.h"
23 #include <stddef.h>
24 #include <time.h>
25 #include "safe-ctype.h"
26 #include "bfd.h"
27 #include "objdump.h"
28 #include "bucomm.h"
29 #include "bfdlink.h"
30 #include "libbfd.h"
31 #include "mach-o.h"
32 #include "mach-o/external.h"
33 #include "mach-o/codesign.h"
35 /* Index of the options in the options[] array. */
36 #define OPT_HEADER 0
37 #define OPT_SECTION 1
38 #define OPT_MAP 2
39 #define OPT_LOAD 3
40 #define OPT_DYSYMTAB 4
41 #define OPT_CODESIGN 5
42 #define OPT_SEG_SPLIT_INFO 6
44 /* List of actions. */
45 static struct objdump_private_option options[] =
47 { "header", 0 },
48 { "section", 0 },
49 { "map", 0 },
50 { "load", 0 },
51 { "dysymtab", 0 },
52 { "codesign", 0 },
53 { "seg_split_info", 0 },
54 { NULL, 0 }
57 /* Display help. */
59 static void
60 mach_o_help (FILE *stream)
62 fprintf (stream, _("\
63 For Mach-O files:\n\
64 header Display the file header\n\
65 section Display the segments and sections commands\n\
66 map Display the section map\n\
67 load Display the load commands\n\
68 dysymtab Display the dynamic symbol table\n\
69 codesign Display code signature\n\
70 seg_split_info Display segment split info\n\
71 "));
74 /* Return TRUE if ABFD is handled. */
76 static int
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 },
98 { NULL, 0}
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 },
114 { NULL, 0}
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 },
141 { NULL, 0}
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},
185 { NULL, 0}
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},
203 { NULL, 0 }
206 static void
207 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
208 unsigned long val)
210 int first = 1;
212 for (; table->name; table++)
214 if (table->val & val)
216 if (!first)
217 printf ("+");
218 printf ("%s", table->name);
219 val &= ~table->val;
220 first = 0;
223 if (val)
225 if (!first)
226 printf ("+");
227 printf ("0x%lx", val);
228 return;
230 if (first)
231 printf ("-");
234 static const char *
235 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
236 unsigned long val)
238 for (; table->name; table++)
239 if (table->val == val)
240 return table->name;
241 return NULL;
244 static const char *
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);
249 if (res == NULL)
250 return "*UNKNOWN*";
251 else
252 return res;
255 static void
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"),
267 h->filetype,
268 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
269 printf (_(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
270 printf (_(" sizeofcmds: %08lx\n"), h->sizeofcmds);
271 printf (_(" flags : %08lx ("), h->flags);
272 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
273 fputs (_(")\n"), stdout);
274 printf (_(" reserved : %08x\n"), h->reserved);
277 static void
278 dump_section_map (bfd *abfd)
280 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
281 unsigned int i;
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)
294 continue;
296 seg = &mdata->commands[i].command.segment;
298 printf ("[Segment %-16s ", seg->segname);
299 printf_vma (seg->vmaddr);
300 putchar ('-');
301 printf_vma (seg->vmaddr + seg->vmsize - 1);
302 putchar (' ');
303 putchar (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-');
304 putchar (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
305 putchar (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
306 printf ("]\n");
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);
313 putchar (' ');
314 printf_vma (sec->size);
315 printf (" %08lx\n", sec->flags);
320 static void
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);
325 printf (" addr: ");
326 printf_vma (sec->addr);
327 printf (" size: ");
328 printf_vma (sec->size);
329 printf (" offset: ");
330 printf_vma (sec->offset);
331 printf ("\n");
332 printf (" align: %ld", sec->align);
333 printf (" nreloc: %lu reloff: ", sec->nreloc);
334 printf_vma (sec->reloff);
335 printf ("\n");
336 printf (" flags: %08lx (type: %s", sec->flags,
337 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
338 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
339 printf (" attr: ");
340 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
341 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
342 printf (")\n");
343 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
345 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
346 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
347 case BFD_MACH_O_S_SYMBOL_STUBS:
348 printf (" first indirect sym: %lu", sec->reserved1);
349 printf (" (%u entries)",
350 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
351 break;
352 default:
353 printf (" reserved1: 0x%lx", sec->reserved1);
354 break;
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);
360 break;
361 default:
362 printf (" reserved2: 0x%lx", sec->reserved2);
363 break;
365 printf (" reserved3: 0x%lx\n", sec->reserved3);
368 static void
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);
379 printf ("\n");
380 printf (" fileoff: ");
381 printf_vma (seg->fileoff);
382 printf (" filesize: ");
383 printf_vma ((bfd_vma)seg->filesize);
384 printf (" endoff: ");
385 printf_vma ((bfd_vma)(seg->fileoff + seg->filesize));
386 printf ("\n");
387 printf (" nsects: %lu ", seg->nsects);
388 printf (" flags: %lx\n", seg->flags);
389 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
390 dump_section (abfd, sec);
393 static void
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);
398 unsigned int i;
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);
441 if (!verbose)
442 return;
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)
463 printf (": %s",
464 mdata->symtab->strtab + module->module_name_idx);
465 printf ("\n");
466 printf (" extdefsym: idx: %8lu num: %lu\n",
467 module->iextdefsym, module->nextdefsym);
468 printf (" refsym: idx: %8lu num: %lu\n",
469 module->irefsym, module->nrefsym);
470 printf (" localsym: idx: %8lu num: %lu\n",
471 module->ilocalsym, module->nlocalsym);
472 printf (" extrel: idx: %8lu num: %lu\n",
473 module->iextrel, module->nextrel);
474 printf (" init: idx: %8u num: %u\n",
475 module->iinit, module->ninit);
476 printf (" term: idx: %8u num: %u\n",
477 module->iterm, module->nterm);
478 printf (" objc_module_info: addr: ");
479 printf_vma (module->objc_module_info_addr);
480 printf (" size: %lu\n", module->objc_module_info_size);
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*",
497 toc->symbol_index);
499 else
500 printf ("%lu", toc->symbol_index);
502 printf (" / ");
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];
508 printf ("%s (%lu)",
509 symtab->strtab + mod->module_name_idx,
510 toc->module_index);
512 else
513 printf ("%lu", toc->module_index);
515 printf ("\n");
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;
528 bfd_vma addr;
529 bfd_vma entry_size;
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);
538 addr = sec->addr;
539 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
540 printf (" for section %s.%s:\n",
541 sec->segname, sec->sectname);
542 for (j = first; j < last; j++)
544 unsigned int isym = dysymtab->indirect_syms[j];
546 printf (" ");
547 printf_vma (addr);
548 printf (" %5u: 0x%08x", j, isym);
549 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
550 printf (" LOCAL");
551 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
552 printf (" ABSOLUTE");
553 if (symtab && symtab->symbols
554 && isym < symtab->nsyms
555 && symtab->symbols[isym].symbol.name)
556 printf (" %s", symtab->symbols[isym].symbol.name);
557 printf ("\n");
558 addr += entry_size;
560 break;
561 default:
562 break;
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);
580 printf ("\n");
586 static void
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);
603 static void
604 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
606 bfd_mach_o_thread_command *thread = &cmd->command.thread;
607 unsigned int j;
608 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
609 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
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;
623 break;
624 default:
625 name_table = NULL;
626 break;
628 if (name_table != NULL)
629 printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
630 putchar ('\n');
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);
642 free (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 },
655 { NULL, 0 }
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 },
665 { NULL, 0 }
668 static unsigned int
669 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
671 static void
672 dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
673 const unsigned char *buf, unsigned int len)
675 unsigned int count;
676 unsigned int i;
678 if (len < 12)
680 printf (_(" [bad block length]\n"));
681 return;
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"));
688 return;
690 for (i = 0; i < count; i++)
692 unsigned int type;
693 unsigned int off;
695 type = bfd_getb32 (buf + 12 + 8 * i);
696 off = bfd_getb32 (buf + 12 + 8 * i + 4);
697 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
698 i, type, off);
700 dump_code_signature_blob (abfd, buf + off, len - off);
704 static void
705 swap_code_codedirectory_v1_in
706 (const struct mach_o_codesign_codedirectory_external_v1 *src,
707 struct mach_o_codesign_codedirectory_v1 *dst)
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);
723 static void
724 hexdump (unsigned int start, unsigned int len,
725 const unsigned char *buf)
727 unsigned int i, j;
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);
735 if (i + j < len)
736 printf ("%02x", buf[i + j]);
737 else
738 fputs (" ", stdout);
740 fputc (' ', stdout);
741 for (j = 0; j < 16; j++)
743 if (i + j < len)
744 fputc (ISPRINT (buf[i + j]) ? buf[i + j] : '.', stdout);
745 else
746 fputc (' ', stdout);
748 fputc ('\n', stdout);
752 static void
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;
757 const char *id;
759 if (len < sizeof (struct mach_o_codesign_codedirectory_external_v1))
761 printf (_(" [bad block length]\n"));
762 return;
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"),
782 cd.hash_type,
783 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type, cd.hash_type));
784 printf (_(" spare1: %02x\n"), cd.spare1);
785 printf (_(" page size: %02x\n"), cd.page_size);
786 printf (_(" spare2: %08x\n"), cd.spare2);
787 if (cd.version >= 0x20100)
788 printf (_(" scatter offset: %08x\n"),
789 (unsigned) bfd_getb32 (buf + 44));
792 static unsigned int
793 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len)
795 unsigned int magic;
796 unsigned int length;
798 if (len < 8)
800 printf (_(" [truncated block]\n"));
801 return 0;
803 magic = bfd_getb32 (buf);
804 length = bfd_getb32 (buf + 4);
805 if (magic == 0 || length == 0)
806 return 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);
811 if (length > len)
813 printf (_(" [bad block length]\n"));
814 return 0;
817 switch (magic)
819 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE:
820 dump_code_signature_superblob (abfd, buf, length);
821 break;
822 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY:
823 dump_code_signature_codedirectory (abfd, buf, length);
824 break;
825 default:
826 hexdump (0, length - 8, buf + 8);
827 break;
829 return length;
832 static void
833 dump_code_signature (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
835 unsigned char *buf = xmalloc (cmd->datasize);
836 unsigned int off;
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"));
842 free (buf);
843 return;
845 for (off = 0; off < cmd->datasize;)
847 unsigned int len;
849 len = dump_code_signature_blob (abfd, buf + off, cmd->datasize - off);
851 if (len == 0)
852 break;
853 off += len;
855 free (buf);
858 static void
859 dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
861 unsigned char *buf = xmalloc (cmd->datasize);
862 unsigned char *p;
863 unsigned int len;
864 bfd_vma addr = 0;
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"));
870 free (buf);
871 return;
873 if (buf[cmd->datasize - 1] != 0)
875 non_fatal (_("segment split info is not nul terminated"));
876 free (buf);
877 return;
880 switch (buf[0])
882 case 0:
883 printf (_(" 32 bit pointers:\n"));
884 break;
885 case 1:
886 printf (_(" 64 bit pointers:\n"));
887 break;
888 case 2:
889 printf (_(" PPC hi-16:\n"));
890 break;
891 default:
892 printf (_(" Unhandled location type %u\n"), buf[0]);
893 break;
895 for (p = buf + 1; *p != 0; p += len)
897 addr += read_unsigned_leb128 (abfd, p, &len);
898 fputs (" ", stdout);
899 bfd_printf_vma (abfd, addr);
900 putchar ('\n');
902 free (buf);
905 static void
906 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
907 bfd_boolean verbose)
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);
917 else
918 printf ("%s:", cmd_name);
920 switch (cmd->type)
922 case BFD_MACH_O_LC_SEGMENT:
923 case BFD_MACH_O_LC_SEGMENT_64:
924 dump_segment (abfd, cmd);
925 break;
926 case BFD_MACH_O_LC_UUID:
928 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
929 unsigned int j;
931 for (j = 0; j < sizeof (uuid->uuid); j ++)
932 printf (" %02x", uuid->uuid[j]);
933 putchar ('\n');
935 break;
936 case BFD_MACH_O_LC_LOAD_DYLIB:
937 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
938 case BFD_MACH_O_LC_REEXPORT_DYLIB:
939 case BFD_MACH_O_LC_ID_DYLIB:
940 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
942 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
943 printf (" %s\n", dylib->name_str);
944 printf (" time stamp: 0x%08lx\n",
945 dylib->timestamp);
946 printf (" current version: 0x%08lx\n",
947 dylib->current_version);
948 printf (" comptibility version: 0x%08lx\n",
949 dylib->compatibility_version);
951 break;
952 case BFD_MACH_O_LC_LOAD_DYLINKER:
953 case BFD_MACH_O_LC_ID_DYLINKER:
954 printf (" %s\n", cmd->command.dylinker.name_str);
955 break;
956 case BFD_MACH_O_LC_SYMTAB:
958 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
959 printf ("\n"
960 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
961 symtab->symoff, symtab->nsyms,
962 symtab->symoff + symtab->nsyms
963 * (mdata->header.version == 2
964 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
965 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
966 symtab->stroff, symtab->strsize,
967 symtab->stroff + symtab->strsize);
968 break;
970 case BFD_MACH_O_LC_DYSYMTAB:
971 putchar ('\n');
972 dump_dysymtab (abfd, cmd, verbose);
973 break;
974 case BFD_MACH_O_LC_LOADFVMLIB:
975 case BFD_MACH_O_LC_IDFVMLIB:
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);
982 break;
983 case BFD_MACH_O_LC_CODE_SIGNATURE:
984 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
985 case BFD_MACH_O_LC_FUNCTION_STARTS:
987 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
988 printf
989 ("\n"
990 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
991 linkedit->dataoff, linkedit->datasize,
992 linkedit->dataoff + linkedit->datasize);
994 if (verbose && cmd->type == BFD_MACH_O_LC_CODE_SIGNATURE)
995 dump_code_signature (abfd, linkedit);
996 else if (verbose && cmd->type == BFD_MACH_O_LC_SEGMENT_SPLIT_INFO)
997 dump_segment_split_info (abfd, linkedit);
998 break;
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);
1008 break;
1010 case BFD_MACH_O_LC_THREAD:
1011 case BFD_MACH_O_LC_UNIXTHREAD:
1012 dump_thread (abfd, cmd);
1013 break;
1014 case BFD_MACH_O_LC_ENCRYPTION_INFO:
1016 bfd_mach_o_encryption_info_command *cryp =
1017 &cmd->command.encryption_info;
1018 printf
1019 ("\n"
1020 " cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1021 " cryptid: %u\n",
1022 cryp->cryptoff, cryp->cryptsize,
1023 cryp->cryptoff + cryp->cryptsize,
1024 cryp->cryptid);
1026 break;
1027 case BFD_MACH_O_LC_DYLD_INFO:
1028 putchar ('\n');
1029 dump_dyld_info (abfd, cmd);
1030 break;
1031 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
1032 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
1034 bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
1036 printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
1038 break;
1039 default:
1040 putchar ('\n');
1041 printf (" offset: 0x%08lx\n", (unsigned long)cmd->offset);
1042 printf (" size: 0x%08lx\n", (unsigned long)cmd->len);
1043 break;
1045 putchar ('\n');
1048 static void
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);
1052 unsigned int i;
1054 for (i = 0; i < mdata->header.ncmds; i++)
1056 bfd_mach_o_load_command *cmd = &mdata->commands[i];
1058 if (cmd32 == 0)
1059 dump_load_command (abfd, cmd, FALSE);
1060 else if (cmd->type == cmd32 || cmd->type == cmd64)
1061 dump_load_command (abfd, cmd, TRUE);
1065 /* Dump ABFD (according to the options[] array). */
1067 static void
1068 mach_o_dump (bfd *abfd)
1070 if (options[OPT_HEADER].selected)
1071 dump_header (abfd);
1072 if (options[OPT_SECTION].selected)
1073 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT, BFD_MACH_O_LC_SEGMENT_64);
1074 if (options[OPT_MAP].selected)
1075 dump_section_map (abfd);
1076 if (options[OPT_LOAD].selected)
1077 dump_load_commands (abfd, 0, 0);
1078 if (options[OPT_DYSYMTAB].selected)
1079 dump_load_commands (abfd, BFD_MACH_O_LC_DYSYMTAB, 0);
1080 if (options[OPT_CODESIGN].selected)
1081 dump_load_commands (abfd, BFD_MACH_O_LC_CODE_SIGNATURE, 0);
1082 if (options[OPT_SEG_SPLIT_INFO].selected)
1083 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO, 0);
1086 /* Vector for Mach-O. */
1088 const struct objdump_private_desc objdump_private_desc_mach_o =
1090 mach_o_help,
1091 mach_o_filter,
1092 mach_o_dump,
1093 options