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"
31 #include "mach-o/external.h"
32 #include "mach-o/codesign.h"
34 /* Index of the options in the options[] array. */
39 #define OPT_DYSYMTAB 4
40 #define OPT_CODESIGN 5
42 /* List of actions. */
43 static struct objdump_private_option options
[] =
57 mach_o_help (FILE *stream
)
61 header Display the file header\n\
62 section Display the segments and sections commands\n\
63 map Display the section map\n\
64 load Display the load commands\n\
65 dysymtab Display the dynamic symbol table\n\
66 codesign Display code signature section\n\
70 /* Return TRUE if ABFD is handled. */
73 mach_o_filter (bfd
*abfd
)
75 return bfd_get_flavour (abfd
) == bfd_target_mach_o_flavour
;
78 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name
[] =
80 { "vax", BFD_MACH_O_CPU_TYPE_VAX
},
81 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0
},
82 { "i386", BFD_MACH_O_CPU_TYPE_I386
},
83 { "mips", BFD_MACH_O_CPU_TYPE_MIPS
},
84 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000
},
85 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA
},
86 { "arm", BFD_MACH_O_CPU_TYPE_ARM
},
87 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000
},
88 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC
},
89 { "i860", BFD_MACH_O_CPU_TYPE_I860
},
90 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA
},
91 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC
},
92 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64
},
93 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64
},
97 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name
[] =
99 { "object", BFD_MACH_O_MH_OBJECT
},
100 { "execute", BFD_MACH_O_MH_EXECUTE
},
101 { "fvmlib", BFD_MACH_O_MH_FVMLIB
},
102 { "core", BFD_MACH_O_MH_CORE
},
103 { "preload", BFD_MACH_O_MH_PRELOAD
},
104 { "dylib", BFD_MACH_O_MH_DYLIB
},
105 { "dylinker", BFD_MACH_O_MH_DYLINKER
},
106 { "bundle", BFD_MACH_O_MH_BUNDLE
},
107 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB
},
108 { "dym", BFD_MACH_O_MH_DSYM
},
109 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE
},
113 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name
[] =
115 { "noundefs", BFD_MACH_O_MH_NOUNDEFS
},
116 { "incrlink", BFD_MACH_O_MH_INCRLINK
},
117 { "dyldlink", BFD_MACH_O_MH_DYLDLINK
},
118 { "bindatload", BFD_MACH_O_MH_BINDATLOAD
},
119 { "prebound", BFD_MACH_O_MH_PREBOUND
},
120 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS
},
121 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT
},
122 { "twolevel", BFD_MACH_O_MH_TWOLEVEL
},
123 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT
},
124 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS
},
125 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING
},
126 { "prebindable", BFD_MACH_O_MH_PREBINDABLE
},
127 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND
},
128 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS
},
129 { "canonical", BFD_MACH_O_MH_CANONICAL
},
130 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES
},
131 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK
},
132 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION
},
133 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE
},
134 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE
},
135 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS
},
136 { "pie", BFD_MACH_O_MH_PIE
},
140 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name
[] =
142 { "segment", BFD_MACH_O_LC_SEGMENT
},
143 { "symtab", BFD_MACH_O_LC_SYMTAB
},
144 { "symseg", BFD_MACH_O_LC_SYMSEG
},
145 { "thread", BFD_MACH_O_LC_THREAD
},
146 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD
},
147 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB
},
148 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB
},
149 { "ident", BFD_MACH_O_LC_IDENT
},
150 { "fvmfile", BFD_MACH_O_LC_FVMFILE
},
151 { "prepage", BFD_MACH_O_LC_PREPAGE
},
152 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB
},
153 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB
},
154 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB
},
155 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER
},
156 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER
},
157 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB
},
158 { "routines", BFD_MACH_O_LC_ROUTINES
},
159 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK
},
160 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA
},
161 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT
},
162 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY
},
163 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS
},
164 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM
},
165 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB
},
166 { "segment_64", BFD_MACH_O_LC_SEGMENT_64
},
167 { "routines_64", BFD_MACH_O_LC_ROUTINES_64
},
168 { "uuid", BFD_MACH_O_LC_UUID
},
169 { "rpath", BFD_MACH_O_LC_RPATH
},
170 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE
},
171 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
},
172 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB
},
173 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB
},
174 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO
},
175 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO
},
176 { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB
},
177 { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX
},
178 { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS
},
179 { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS
},
180 { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT
},
184 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name
[] =
186 { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32
},
187 { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32
},
188 { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32
},
189 { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64
},
190 { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64
},
191 { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64
},
192 { "thread_state", BFD_MACH_O_x86_THREAD_STATE
},
193 { "float_state", BFD_MACH_O_x86_FLOAT_STATE
},
194 { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE
},
195 { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32
},
196 { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64
},
197 { "debug_state", BFD_MACH_O_x86_DEBUG_STATE
},
198 { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE
},
203 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name
*table
,
208 for (; table
->name
; table
++)
210 if (table
->val
& val
)
214 printf ("%s", table
->name
);
223 printf ("0x%lx", val
);
231 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name
*table
,
234 for (; table
->name
; table
++)
235 if (table
->val
== val
)
241 bfd_mach_o_get_name (const bfd_mach_o_xlat_name
*table
, unsigned long val
)
243 const char *res
= bfd_mach_o_get_name_or_null (table
, val
);
252 dump_header (bfd
*abfd
)
254 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
255 bfd_mach_o_header
*h
= &mdata
->header
;
257 fputs (_("Mach-O header:\n"), stdout
);
258 printf (_(" magic : %08lx\n"), h
->magic
);
259 printf (_(" cputype : %08lx (%s)\n"), h
->cputype
,
260 bfd_mach_o_get_name (bfd_mach_o_cpu_name
, h
->cputype
));
261 printf (_(" cpusubtype: %08lx\n"), h
->cpusubtype
);
262 printf (_(" filetype : %08lx (%s)\n"),
264 bfd_mach_o_get_name (bfd_mach_o_filetype_name
, h
->filetype
));
265 printf (_(" ncmds : %08lx (%lu)\n"), h
->ncmds
, h
->ncmds
);
266 printf (_(" sizeofcmds: %08lx\n"), h
->sizeofcmds
);
267 printf (_(" flags : %08lx ("), h
->flags
);
268 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name
, h
->flags
);
269 fputs (_(")\n"), stdout
);
270 printf (_(" reserved : %08x\n"), h
->reserved
);
274 dump_section_map (bfd
*abfd
)
276 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
278 unsigned int sec_nbr
= 0;
280 fputs (_("Segments and Sections:\n"), stdout
);
281 fputs (_(" #: Segment name Section name Address\n"), stdout
);
283 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
285 bfd_mach_o_segment_command
*seg
;
286 bfd_mach_o_section
*sec
;
288 if (mdata
->commands
[i
].type
!= BFD_MACH_O_LC_SEGMENT
289 && mdata
->commands
[i
].type
!= BFD_MACH_O_LC_SEGMENT_64
)
292 seg
= &mdata
->commands
[i
].command
.segment
;
294 printf ("[Segment %-16s ", seg
->segname
);
295 printf_vma (seg
->vmaddr
);
297 printf_vma (seg
->vmaddr
+ seg
->vmsize
- 1);
299 putchar (seg
->initprot
& BFD_MACH_O_PROT_READ
? 'r' : '-');
300 putchar (seg
->initprot
& BFD_MACH_O_PROT_WRITE
? 'w' : '-');
301 putchar (seg
->initprot
& BFD_MACH_O_PROT_EXECUTE
? 'x' : '-');
304 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
306 printf ("%02u: %-16s %-16s ", ++sec_nbr
,
307 sec
->segname
, sec
->sectname
);
308 printf_vma (sec
->addr
);
310 printf_vma (sec
->size
);
311 printf (" %08lx\n", sec
->flags
);
317 dump_section (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_section
*sec
)
319 printf (" Section: %-16s %-16s (bfdname: %s)\n",
320 sec
->sectname
, sec
->segname
, sec
->bfdsection
->name
);
322 printf_vma (sec
->addr
);
324 printf_vma (sec
->size
);
325 printf (" offset: ");
326 printf_vma (sec
->offset
);
328 printf (" align: %ld", sec
->align
);
329 printf (" nreloc: %lu reloff: ", sec
->nreloc
);
330 printf_vma (sec
->reloff
);
332 printf (" flags: %08lx (type: %s", sec
->flags
,
333 bfd_mach_o_get_name (bfd_mach_o_section_type_name
,
334 sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
));
336 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name
,
337 sec
->flags
& BFD_MACH_O_SECTION_ATTRIBUTES_MASK
);
339 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
341 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS
:
342 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS
:
343 case BFD_MACH_O_S_SYMBOL_STUBS
:
344 printf (" first indirect sym: %lu", sec
->reserved1
);
345 printf (" (%u entries)",
346 bfd_mach_o_section_get_nbr_indirect (abfd
, sec
));
349 printf (" reserved1: 0x%lx", sec
->reserved1
);
352 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
354 case BFD_MACH_O_S_SYMBOL_STUBS
:
355 printf (" stub size: %lu", sec
->reserved2
);
358 printf (" reserved2: 0x%lx", sec
->reserved2
);
361 printf (" reserved3: 0x%lx\n", sec
->reserved3
);
365 dump_segment (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_load_command
*cmd
)
367 bfd_mach_o_segment_command
*seg
= &cmd
->command
.segment
;
368 bfd_mach_o_section
*sec
;
370 printf (" name: %s\n", *seg
->segname
? seg
->segname
: "*none*");
371 printf (" vmaddr: ");
372 printf_vma (seg
->vmaddr
);
373 printf (" vmsize: ");
374 printf_vma (seg
->vmsize
);
376 printf (" fileoff: ");
377 printf_vma (seg
->fileoff
);
378 printf (" filesize: ");
379 printf_vma ((bfd_vma
)seg
->filesize
);
380 printf (" endoff: ");
381 printf_vma ((bfd_vma
)(seg
->fileoff
+ seg
->filesize
));
383 printf (" nsects: %lu ", seg
->nsects
);
384 printf (" flags: %lx\n", seg
->flags
);
385 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
386 dump_section (abfd
, sec
);
390 dump_dysymtab (bfd
*abfd
, bfd_mach_o_load_command
*cmd
, bfd_boolean verbose
)
392 bfd_mach_o_dysymtab_command
*dysymtab
= &cmd
->command
.dysymtab
;
393 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
396 printf (" local symbols: idx: %10lu num: %-8lu",
397 dysymtab
->ilocalsym
, dysymtab
->nlocalsym
);
398 printf (" (nxtidx: %lu)\n",
399 dysymtab
->ilocalsym
+ dysymtab
->nlocalsym
);
400 printf (" external symbols: idx: %10lu num: %-8lu",
401 dysymtab
->iextdefsym
, dysymtab
->nextdefsym
);
402 printf (" (nxtidx: %lu)\n",
403 dysymtab
->iextdefsym
+ dysymtab
->nextdefsym
);
404 printf (" undefined symbols: idx: %10lu num: %-8lu",
405 dysymtab
->iundefsym
, dysymtab
->nundefsym
);
406 printf (" (nxtidx: %lu)\n",
407 dysymtab
->iundefsym
+ dysymtab
->nundefsym
);
408 printf (" table of content: off: 0x%08lx num: %-8lu",
409 dysymtab
->tocoff
, dysymtab
->ntoc
);
410 printf (" (endoff: 0x%08lx)\n",
411 dysymtab
->tocoff
+ dysymtab
->ntoc
* BFD_MACH_O_TABLE_OF_CONTENT_SIZE
);
412 printf (" module table: off: 0x%08lx num: %-8lu",
413 dysymtab
->modtaboff
, dysymtab
->nmodtab
);
414 printf (" (endoff: 0x%08lx)\n",
415 dysymtab
->modtaboff
+ dysymtab
->nmodtab
416 * (mdata
->header
.version
== 2 ?
417 BFD_MACH_O_DYLIB_MODULE_64_SIZE
: BFD_MACH_O_DYLIB_MODULE_SIZE
));
418 printf (" external reference table: off: 0x%08lx num: %-8lu",
419 dysymtab
->extrefsymoff
, dysymtab
->nextrefsyms
);
420 printf (" (endoff: 0x%08lx)\n",
421 dysymtab
->extrefsymoff
422 + dysymtab
->nextrefsyms
* BFD_MACH_O_REFERENCE_SIZE
);
423 printf (" indirect symbol table: off: 0x%08lx num: %-8lu",
424 dysymtab
->indirectsymoff
, dysymtab
->nindirectsyms
);
425 printf (" (endoff: 0x%08lx)\n",
426 dysymtab
->indirectsymoff
427 + dysymtab
->nindirectsyms
* BFD_MACH_O_INDIRECT_SYMBOL_SIZE
);
428 printf (" external relocation table: off: 0x%08lx num: %-8lu",
429 dysymtab
->extreloff
, dysymtab
->nextrel
);
430 printf (" (endoff: 0x%08lx)\n",
431 dysymtab
->extreloff
+ dysymtab
->nextrel
* BFD_MACH_O_RELENT_SIZE
);
432 printf (" local relocation table: off: 0x%08lx num: %-8lu",
433 dysymtab
->locreloff
, dysymtab
->nlocrel
);
434 printf (" (endoff: 0x%08lx)\n",
435 dysymtab
->locreloff
+ dysymtab
->nlocrel
* BFD_MACH_O_RELENT_SIZE
);
440 if (dysymtab
->ntoc
> 0
441 || dysymtab
->nindirectsyms
> 0
442 || dysymtab
->nextrefsyms
> 0)
444 /* Try to read the symbols to display the toc or indirect symbols. */
445 bfd_mach_o_read_symtab_symbols (abfd
);
447 else if (dysymtab
->nmodtab
> 0)
449 /* Try to read the strtab to display modules name. */
450 bfd_mach_o_read_symtab_strtab (abfd
);
453 for (i
= 0; i
< dysymtab
->nmodtab
; i
++)
455 bfd_mach_o_dylib_module
*module
= &dysymtab
->dylib_module
[i
];
456 printf (" module %u:\n", i
);
457 printf (" name: %lu", module
->module_name_idx
);
458 if (mdata
->symtab
&& mdata
->symtab
->strtab
)
460 mdata
->symtab
->strtab
+ module
->module_name_idx
);
462 printf (" extdefsym: idx: %8lu num: %lu\n",
463 module
->iextdefsym
, module
->nextdefsym
);
464 printf (" refsym: idx: %8lu num: %lu\n",
465 module
->irefsym
, module
->nrefsym
);
466 printf (" localsym: idx: %8lu num: %lu\n",
467 module
->ilocalsym
, module
->nlocalsym
);
468 printf (" extrel: idx: %8lu num: %lu\n",
469 module
->iextrel
, module
->nextrel
);
470 printf (" init: idx: %8u num: %u\n",
471 module
->iinit
, module
->ninit
);
472 printf (" term: idx: %8u num: %u\n",
473 module
->iterm
, module
->nterm
);
474 printf (" objc_module_info: addr: ");
475 printf_vma (module
->objc_module_info_addr
);
476 printf (" size: %lu\n", module
->objc_module_info_size
);
479 if (dysymtab
->ntoc
> 0)
481 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
483 printf (" table of content: (symbol/module)\n");
484 for (i
= 0; i
< dysymtab
->ntoc
; i
++)
486 bfd_mach_o_dylib_table_of_content
*toc
= &dysymtab
->dylib_toc
[i
];
488 printf (" %4u: ", i
);
489 if (symtab
&& symtab
->symbols
&& toc
->symbol_index
< symtab
->nsyms
)
491 const char *name
= symtab
->symbols
[toc
->symbol_index
].symbol
.name
;
492 printf ("%s (%lu)", name
? name
: "*invalid*",
496 printf ("%lu", toc
->symbol_index
);
499 if (symtab
&& symtab
->strtab
500 && toc
->module_index
< dysymtab
->nmodtab
)
502 bfd_mach_o_dylib_module
*mod
;
503 mod
= &dysymtab
->dylib_module
[toc
->module_index
];
505 symtab
->strtab
+ mod
->module_name_idx
,
509 printf ("%lu", toc
->module_index
);
515 if (dysymtab
->nindirectsyms
!= 0)
517 printf (" indirect symbols:\n");
519 for (i
= 0; i
< mdata
->nsects
; i
++)
521 bfd_mach_o_section
*sec
= mdata
->sections
[i
];
522 unsigned int j
, first
, last
;
523 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
527 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
529 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS
:
530 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS
:
531 case BFD_MACH_O_S_SYMBOL_STUBS
:
532 first
= sec
->reserved1
;
533 last
= first
+ bfd_mach_o_section_get_nbr_indirect (abfd
, sec
);
535 entry_size
= bfd_mach_o_section_get_entry_size (abfd
, sec
);
536 printf (" for section %s.%s:\n",
537 sec
->segname
, sec
->sectname
);
538 for (j
= first
; j
< last
; j
++)
540 unsigned int isym
= dysymtab
->indirect_syms
[j
];
544 printf (" %5u: 0x%08x", j
, isym
);
545 if (isym
& BFD_MACH_O_INDIRECT_SYMBOL_LOCAL
)
547 if (isym
& BFD_MACH_O_INDIRECT_SYMBOL_ABS
)
548 printf (" ABSOLUTE");
549 if (symtab
&& symtab
->symbols
550 && isym
< symtab
->nsyms
551 && symtab
->symbols
[isym
].symbol
.name
)
552 printf (" %s", symtab
->symbols
[isym
].symbol
.name
);
562 if (dysymtab
->nextrefsyms
> 0)
564 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
566 printf (" external reference table: (symbol flags)\n");
567 for (i
= 0; i
< dysymtab
->nextrefsyms
; i
++)
569 bfd_mach_o_dylib_reference
*ref
= &dysymtab
->ext_refs
[i
];
571 printf (" %4u: %5lu 0x%02lx", i
, ref
->isym
, ref
->flags
);
572 if (symtab
&& symtab
->symbols
573 && ref
->isym
< symtab
->nsyms
574 && symtab
->symbols
[ref
->isym
].symbol
.name
)
575 printf (" %s", symtab
->symbols
[ref
->isym
].symbol
.name
);
583 dump_dyld_info (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_load_command
*cmd
)
585 bfd_mach_o_dyld_info_command
*info
= &cmd
->command
.dyld_info
;
587 printf (" rebase: off: 0x%08x size: %-8u\n",
588 info
->rebase_off
, info
->rebase_size
);
589 printf (" bind: off: 0x%08x size: %-8u\n",
590 info
->bind_off
, info
->bind_size
);
591 printf (" weak bind: off: 0x%08x size: %-8u\n",
592 info
->weak_bind_off
, info
->weak_bind_size
);
593 printf (" lazy bind: off: 0x%08x size: %-8u\n",
594 info
->lazy_bind_off
, info
->lazy_bind_size
);
595 printf (" export: off: 0x%08x size: %-8u\n",
596 info
->export_off
, info
->export_size
);
600 dump_thread (bfd
*abfd
, bfd_mach_o_load_command
*cmd
)
602 bfd_mach_o_thread_command
*thread
= &cmd
->command
.thread
;
604 bfd_mach_o_backend_data
*bed
= bfd_mach_o_get_backend_data (abfd
);
605 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
607 printf (" nflavours: %lu\n", thread
->nflavours
);
608 for (j
= 0; j
< thread
->nflavours
; j
++)
610 bfd_mach_o_thread_flavour
*flavour
= &thread
->flavours
[j
];
611 const bfd_mach_o_xlat_name
*name_table
;
613 printf (" %2u: flavour: 0x%08lx", j
, flavour
->flavour
);
614 switch (mdata
->header
.cputype
)
616 case BFD_MACH_O_CPU_TYPE_I386
:
617 case BFD_MACH_O_CPU_TYPE_X86_64
:
618 name_table
= bfd_mach_o_thread_x86_name
;
624 if (name_table
!= NULL
)
625 printf (": %s", bfd_mach_o_get_name (name_table
, flavour
->flavour
));
628 printf (" offset: 0x%08lx size: 0x%08lx\n",
629 flavour
->offset
, flavour
->size
);
630 if (bed
->_bfd_mach_o_print_thread
)
632 char *buf
= xmalloc (flavour
->size
);
634 if (bfd_seek (abfd
, flavour
->offset
, SEEK_SET
) == 0
635 && bfd_bread (buf
, flavour
->size
, abfd
) == flavour
->size
)
636 (*bed
->_bfd_mach_o_print_thread
)(abfd
, flavour
, stdout
, buf
);
643 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic
[] =
645 { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE
},
646 { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT
},
647 { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS
},
648 { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY
},
649 { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS
},
650 { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER
},
654 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type
[] =
656 { "no-hash", BFD_MACH_O_CS_NO_HASH
},
657 { "sha1", BFD_MACH_O_CS_HASH_SHA1
},
658 { "sha256", BFD_MACH_O_CS_HASH_SHA256
},
659 { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256
},
660 { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512
},
665 dump_code_signature_blob (bfd
*abfd
, const unsigned char *buf
, unsigned int len
);
668 dump_code_signature_superblob (bfd
*abfd ATTRIBUTE_UNUSED
,
669 const unsigned char *buf
, unsigned int len
)
676 printf (_(" [bad block length]\n"));
679 count
= bfd_getb32 (buf
+ 8);
680 printf (_(" %u index entries:\n"), count
);
681 if (len
< 12 + 8 * count
)
683 printf (_(" [bad block length]\n"));
686 for (i
= 0; i
< count
; i
++)
691 type
= bfd_getb32 (buf
+ 12 + 8 * i
);
692 off
= bfd_getb32 (buf
+ 12 + 8 * i
+ 4);
693 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
696 dump_code_signature_blob (abfd
, buf
+ off
, len
- off
);
701 swap_code_codedirectory_v1_in
702 (const struct mach_o_codesign_codedirectory_external_v1
*src
,
703 struct mach_o_codesign_codedirectory_v1
*dst
)
705 dst
->version
= bfd_getb32 (src
->version
);
706 dst
->flags
= bfd_getb32 (src
->flags
);
707 dst
->hash_offset
= bfd_getb32 (src
->hash_offset
);
708 dst
->ident_offset
= bfd_getb32 (src
->ident_offset
);
709 dst
->nbr_special_slots
= bfd_getb32 (src
->nbr_special_slots
);
710 dst
->nbr_code_slots
= bfd_getb32 (src
->nbr_code_slots
);
711 dst
->code_limit
= bfd_getb32 (src
->code_limit
);
712 dst
->hash_size
= src
->hash_size
[0];
713 dst
->hash_type
= src
->hash_type
[0];
714 dst
->spare1
= src
->spare1
[0];
715 dst
->page_size
= src
->page_size
[0];
716 dst
->spare2
= bfd_getb32 (src
->spare2
);
720 hexdump (unsigned int start
, unsigned int len
,
721 const unsigned char *buf
)
725 for (i
= 0; i
< len
; i
+= 16)
727 printf ("%08x:", start
+ i
);
728 for (j
= 0; j
< 16; j
++)
730 fputc (j
== 8 ? '-' : ' ', stdout
);
732 printf ("%02x", buf
[i
+ j
]);
737 for (j
= 0; j
< 16; j
++)
740 fputc (ISPRINT (buf
[i
+ j
]) ? buf
[i
+ j
] : '.', stdout
);
744 fputc ('\n', stdout
);
749 dump_code_signature_codedirectory (bfd
*abfd ATTRIBUTE_UNUSED
,
750 const unsigned char *buf
, unsigned int len
)
752 struct mach_o_codesign_codedirectory_v1 cd
;
755 if (len
< sizeof (struct mach_o_codesign_codedirectory_external_v1
))
757 printf (_(" [bad block length]\n"));
761 swap_code_codedirectory_v1_in
762 ((const struct mach_o_codesign_codedirectory_external_v1
*) (buf
+ 8), &cd
);
764 printf (_(" version: %08x\n"), cd
.version
);
765 printf (_(" flags: %08x\n"), cd
.flags
);
766 printf (_(" hash offset: %08x\n"), cd
.hash_offset
);
767 id
= (const char *) buf
+ cd
.ident_offset
;
768 printf (_(" ident offset: %08x (- %08x)\n"),
769 cd
.ident_offset
, cd
.ident_offset
+ (unsigned) strlen (id
) + 1);
770 printf (_(" identity: %s\n"), id
);
771 printf (_(" nbr special slots: %08x (at offset %08x)\n"),
772 cd
.nbr_special_slots
,
773 cd
.hash_offset
- cd
.nbr_special_slots
* cd
.hash_size
);
774 printf (_(" nbr code slots: %08x\n"), cd
.nbr_code_slots
);
775 printf (_(" code limit: %08x\n"), cd
.code_limit
);
776 printf (_(" hash size: %02x\n"), cd
.hash_size
);
777 printf (_(" hash type: %02x (%s)\n"),
779 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type
, cd
.hash_type
));
780 printf (_(" spare1: %02x\n"), cd
.spare1
);
781 printf (_(" page size: %02x\n"), cd
.page_size
);
782 printf (_(" spare2: %08x\n"), cd
.spare2
);
783 if (cd
.version
>= 0x20100)
784 printf (_(" scatter offset: %08x\n"),
785 (unsigned) bfd_getb32 (buf
+ 44));
789 dump_code_signature_blob (bfd
*abfd
, const unsigned char *buf
, unsigned int len
)
796 printf (_(" [truncated block]\n"));
799 magic
= bfd_getb32 (buf
);
800 length
= bfd_getb32 (buf
+ 4);
801 if (magic
== 0 || length
== 0)
804 printf (_(" magic : %08x (%s)\n"), magic
,
805 bfd_mach_o_get_name (bfd_mach_o_cs_magic
, magic
));
806 printf (_(" length: %08x\n"), length
);
809 printf (_(" [bad block length]\n"));
815 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE
:
816 dump_code_signature_superblob (abfd
, buf
, length
);
818 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY
:
819 dump_code_signature_codedirectory (abfd
, buf
, length
);
822 hexdump (0, length
- 8, buf
+ 8);
829 dump_code_signature (bfd
*abfd
, bfd_mach_o_linkedit_command
*cmd
)
831 unsigned char *buf
= xmalloc (cmd
->datasize
);
834 if (bfd_seek (abfd
, cmd
->dataoff
, SEEK_SET
) != 0
835 || bfd_bread (buf
, cmd
->datasize
, abfd
) != cmd
->datasize
)
837 non_fatal (_("cannot read code signature data"));
841 for (off
= 0; off
< cmd
->datasize
;)
845 len
= dump_code_signature_blob (abfd
, buf
+ off
, cmd
->datasize
- off
);
855 dump_load_command (bfd
*abfd
, bfd_mach_o_load_command
*cmd
,
858 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
859 const char *cmd_name
;
861 cmd_name
= bfd_mach_o_get_name_or_null
862 (bfd_mach_o_load_command_name
, cmd
->type
);
863 printf ("Load command ");
864 if (cmd_name
== NULL
)
865 printf ("0x%02x:", cmd
->type
);
867 printf ("%s:", cmd_name
);
871 case BFD_MACH_O_LC_SEGMENT
:
872 case BFD_MACH_O_LC_SEGMENT_64
:
873 dump_segment (abfd
, cmd
);
875 case BFD_MACH_O_LC_UUID
:
877 bfd_mach_o_uuid_command
*uuid
= &cmd
->command
.uuid
;
880 for (j
= 0; j
< sizeof (uuid
->uuid
); j
++)
881 printf (" %02x", uuid
->uuid
[j
]);
885 case BFD_MACH_O_LC_LOAD_DYLIB
:
886 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB
:
887 case BFD_MACH_O_LC_REEXPORT_DYLIB
:
888 case BFD_MACH_O_LC_ID_DYLIB
:
889 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB
:
891 bfd_mach_o_dylib_command
*dylib
= &cmd
->command
.dylib
;
892 printf (" %s\n", dylib
->name_str
);
893 printf (" time stamp: 0x%08lx\n",
895 printf (" current version: 0x%08lx\n",
896 dylib
->current_version
);
897 printf (" comptibility version: 0x%08lx\n",
898 dylib
->compatibility_version
);
901 case BFD_MACH_O_LC_LOAD_DYLINKER
:
902 case BFD_MACH_O_LC_ID_DYLINKER
:
903 printf (" %s\n", cmd
->command
.dylinker
.name_str
);
905 case BFD_MACH_O_LC_SYMTAB
:
907 bfd_mach_o_symtab_command
*symtab
= &cmd
->command
.symtab
;
909 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
910 symtab
->symoff
, symtab
->nsyms
,
911 symtab
->symoff
+ symtab
->nsyms
912 * (mdata
->header
.version
== 2
913 ? BFD_MACH_O_NLIST_64_SIZE
: BFD_MACH_O_NLIST_SIZE
));
914 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
915 symtab
->stroff
, symtab
->strsize
,
916 symtab
->stroff
+ symtab
->strsize
);
919 case BFD_MACH_O_LC_DYSYMTAB
:
921 dump_dysymtab (abfd
, cmd
, verbose
);
923 case BFD_MACH_O_LC_LOADFVMLIB
:
924 case BFD_MACH_O_LC_IDFVMLIB
:
926 bfd_mach_o_fvmlib_command
*fvmlib
= &cmd
->command
.fvmlib
;
927 printf (" %s\n", fvmlib
->name_str
);
928 printf (" minor version: 0x%08x\n", fvmlib
->minor_version
);
929 printf (" header address: 0x%08x\n", fvmlib
->header_addr
);
932 case BFD_MACH_O_LC_CODE_SIGNATURE
:
933 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
:
934 case BFD_MACH_O_LC_FUNCTION_STARTS
:
936 bfd_mach_o_linkedit_command
*linkedit
= &cmd
->command
.linkedit
;
939 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
940 linkedit
->dataoff
, linkedit
->datasize
,
941 linkedit
->dataoff
+ linkedit
->datasize
);
943 if (verbose
&& cmd
->type
== BFD_MACH_O_LC_CODE_SIGNATURE
)
944 dump_code_signature (abfd
, linkedit
);
947 case BFD_MACH_O_LC_SUB_FRAMEWORK
:
948 case BFD_MACH_O_LC_SUB_UMBRELLA
:
949 case BFD_MACH_O_LC_SUB_LIBRARY
:
950 case BFD_MACH_O_LC_SUB_CLIENT
:
951 case BFD_MACH_O_LC_RPATH
:
953 bfd_mach_o_str_command
*str
= &cmd
->command
.str
;
954 printf (" %s\n", str
->str
);
957 case BFD_MACH_O_LC_THREAD
:
958 case BFD_MACH_O_LC_UNIXTHREAD
:
959 dump_thread (abfd
, cmd
);
961 case BFD_MACH_O_LC_ENCRYPTION_INFO
:
963 bfd_mach_o_encryption_info_command
*cryp
=
964 &cmd
->command
.encryption_info
;
967 " cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
969 cryp
->cryptoff
, cryp
->cryptsize
,
970 cryp
->cryptoff
+ cryp
->cryptsize
,
974 case BFD_MACH_O_LC_DYLD_INFO
:
976 dump_dyld_info (abfd
, cmd
);
978 case BFD_MACH_O_LC_VERSION_MIN_MACOSX
:
979 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS
:
981 bfd_mach_o_version_min_command
*ver
= &cmd
->command
.version_min
;
983 printf (" %u.%u.%u\n", ver
->rel
, ver
->maj
, ver
->min
);
988 printf (" offset: 0x%08lx\n", (unsigned long)cmd
->offset
);
989 printf (" size: 0x%08lx\n", (unsigned long)cmd
->len
);
996 dump_load_commands (bfd
*abfd
, unsigned int cmd32
, unsigned int cmd64
)
998 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1001 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1003 bfd_mach_o_load_command
*cmd
= &mdata
->commands
[i
];
1006 dump_load_command (abfd
, cmd
, FALSE
);
1007 else if (cmd
->type
== cmd32
|| cmd
->type
== cmd64
)
1008 dump_load_command (abfd
, cmd
, TRUE
);
1012 /* Dump ABFD (according to the options[] array). */
1015 mach_o_dump (bfd
*abfd
)
1017 if (options
[OPT_HEADER
].selected
)
1019 if (options
[OPT_SECTION
].selected
)
1020 dump_load_commands (abfd
, BFD_MACH_O_LC_SEGMENT
, BFD_MACH_O_LC_SEGMENT_64
);
1021 if (options
[OPT_MAP
].selected
)
1022 dump_section_map (abfd
);
1023 if (options
[OPT_LOAD
].selected
)
1024 dump_load_commands (abfd
, 0, 0);
1025 if (options
[OPT_DYSYMTAB
].selected
)
1026 dump_load_commands (abfd
, BFD_MACH_O_LC_DYSYMTAB
, 0);
1027 if (options
[OPT_CODESIGN
].selected
)
1028 dump_load_commands (abfd
, BFD_MACH_O_LC_CODE_SIGNATURE
, 0);
1031 /* Vector for Mach-O. */
1033 const struct objdump_private_desc objdump_private_desc_mach_o
=