1 /* od-macho.c -- dump information about an Mach-O object file.
2 Copyright 2011, 2012 Free Software Foundation, Inc.
3 Written by Tristan Gingold, Adacore.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
25 #include "safe-ctype.h"
32 #include "mach-o/external.h"
33 #include "mach-o/codesign.h"
35 /* Index of the options in the options[] array. */
40 #define OPT_DYSYMTAB 4
41 #define OPT_CODESIGN 5
42 #define OPT_SEG_SPLIT_INFO 6
44 /* List of actions. */
45 static struct objdump_private_option options
[] =
53 { "seg_split_info", 0 },
60 mach_o_help (FILE *stream
)
64 header Display the file header\n\
65 section Display the segments and sections commands\n\
66 map Display the section map\n\
67 load Display the load commands\n\
68 dysymtab Display the dynamic symbol table\n\
69 codesign Display code signature\n\
70 seg_split_info Display segment split info\n\
74 /* Return TRUE if ABFD is handled. */
77 mach_o_filter (bfd
*abfd
)
79 return bfd_get_flavour (abfd
) == bfd_target_mach_o_flavour
;
82 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name
[] =
84 { "vax", BFD_MACH_O_CPU_TYPE_VAX
},
85 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0
},
86 { "i386", BFD_MACH_O_CPU_TYPE_I386
},
87 { "mips", BFD_MACH_O_CPU_TYPE_MIPS
},
88 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000
},
89 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA
},
90 { "arm", BFD_MACH_O_CPU_TYPE_ARM
},
91 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000
},
92 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC
},
93 { "i860", BFD_MACH_O_CPU_TYPE_I860
},
94 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA
},
95 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC
},
96 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64
},
97 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64
},
101 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name
[] =
103 { "object", BFD_MACH_O_MH_OBJECT
},
104 { "execute", BFD_MACH_O_MH_EXECUTE
},
105 { "fvmlib", BFD_MACH_O_MH_FVMLIB
},
106 { "core", BFD_MACH_O_MH_CORE
},
107 { "preload", BFD_MACH_O_MH_PRELOAD
},
108 { "dylib", BFD_MACH_O_MH_DYLIB
},
109 { "dylinker", BFD_MACH_O_MH_DYLINKER
},
110 { "bundle", BFD_MACH_O_MH_BUNDLE
},
111 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB
},
112 { "dym", BFD_MACH_O_MH_DSYM
},
113 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE
},
117 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name
[] =
119 { "noundefs", BFD_MACH_O_MH_NOUNDEFS
},
120 { "incrlink", BFD_MACH_O_MH_INCRLINK
},
121 { "dyldlink", BFD_MACH_O_MH_DYLDLINK
},
122 { "bindatload", BFD_MACH_O_MH_BINDATLOAD
},
123 { "prebound", BFD_MACH_O_MH_PREBOUND
},
124 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS
},
125 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT
},
126 { "twolevel", BFD_MACH_O_MH_TWOLEVEL
},
127 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT
},
128 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS
},
129 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING
},
130 { "prebindable", BFD_MACH_O_MH_PREBINDABLE
},
131 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND
},
132 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS
},
133 { "canonical", BFD_MACH_O_MH_CANONICAL
},
134 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES
},
135 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK
},
136 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION
},
137 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE
},
138 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE
},
139 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS
},
140 { "pie", BFD_MACH_O_MH_PIE
},
144 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name
[] =
146 { "segment", BFD_MACH_O_LC_SEGMENT
},
147 { "symtab", BFD_MACH_O_LC_SYMTAB
},
148 { "symseg", BFD_MACH_O_LC_SYMSEG
},
149 { "thread", BFD_MACH_O_LC_THREAD
},
150 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD
},
151 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB
},
152 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB
},
153 { "ident", BFD_MACH_O_LC_IDENT
},
154 { "fvmfile", BFD_MACH_O_LC_FVMFILE
},
155 { "prepage", BFD_MACH_O_LC_PREPAGE
},
156 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB
},
157 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB
},
158 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB
},
159 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER
},
160 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER
},
161 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB
},
162 { "routines", BFD_MACH_O_LC_ROUTINES
},
163 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK
},
164 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA
},
165 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT
},
166 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY
},
167 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS
},
168 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM
},
169 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB
},
170 { "segment_64", BFD_MACH_O_LC_SEGMENT_64
},
171 { "routines_64", BFD_MACH_O_LC_ROUTINES_64
},
172 { "uuid", BFD_MACH_O_LC_UUID
},
173 { "rpath", BFD_MACH_O_LC_RPATH
},
174 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE
},
175 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
},
176 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB
},
177 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB
},
178 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO
},
179 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO
},
180 { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB
},
181 { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX
},
182 { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS
},
183 { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS
},
184 { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT
},
185 { "main", BFD_MACH_O_LC_MAIN
},
186 { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE
},
187 { "source_version", BFD_MACH_O_LC_SOURCE_VERSION
},
188 { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS
},
192 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name
[] =
194 { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32
},
195 { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32
},
196 { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32
},
197 { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64
},
198 { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64
},
199 { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64
},
200 { "thread_state", BFD_MACH_O_x86_THREAD_STATE
},
201 { "float_state", BFD_MACH_O_x86_FLOAT_STATE
},
202 { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE
},
203 { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32
},
204 { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64
},
205 { "debug_state", BFD_MACH_O_x86_DEBUG_STATE
},
206 { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE
},
211 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name
*table
,
216 for (; table
->name
; table
++)
218 if (table
->val
& val
)
222 printf ("%s", table
->name
);
231 printf ("0x%lx", val
);
239 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name
*table
,
242 for (; table
->name
; table
++)
243 if (table
->val
== val
)
249 bfd_mach_o_get_name (const bfd_mach_o_xlat_name
*table
, unsigned long val
)
251 const char *res
= bfd_mach_o_get_name_or_null (table
, val
);
260 dump_header (bfd
*abfd
)
262 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
263 bfd_mach_o_header
*h
= &mdata
->header
;
265 fputs (_("Mach-O header:\n"), stdout
);
266 printf (_(" magic : %08lx\n"), h
->magic
);
267 printf (_(" cputype : %08lx (%s)\n"), h
->cputype
,
268 bfd_mach_o_get_name (bfd_mach_o_cpu_name
, h
->cputype
));
269 printf (_(" cpusubtype: %08lx\n"), h
->cpusubtype
);
270 printf (_(" filetype : %08lx (%s)\n"),
272 bfd_mach_o_get_name (bfd_mach_o_filetype_name
, h
->filetype
));
273 printf (_(" ncmds : %08lx (%lu)\n"), h
->ncmds
, h
->ncmds
);
274 printf (_(" sizeofcmds: %08lx\n"), h
->sizeofcmds
);
275 printf (_(" flags : %08lx ("), h
->flags
);
276 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name
, h
->flags
);
277 fputs (_(")\n"), stdout
);
278 printf (_(" reserved : %08x\n"), h
->reserved
);
282 dump_section_map (bfd
*abfd
)
284 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
286 unsigned int sec_nbr
= 0;
288 fputs (_("Segments and Sections:\n"), stdout
);
289 fputs (_(" #: Segment name Section name Address\n"), stdout
);
291 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
293 bfd_mach_o_segment_command
*seg
;
294 bfd_mach_o_section
*sec
;
296 if (mdata
->commands
[i
].type
!= BFD_MACH_O_LC_SEGMENT
297 && mdata
->commands
[i
].type
!= BFD_MACH_O_LC_SEGMENT_64
)
300 seg
= &mdata
->commands
[i
].command
.segment
;
302 printf ("[Segment %-16s ", seg
->segname
);
303 printf_vma (seg
->vmaddr
);
305 printf_vma (seg
->vmaddr
+ seg
->vmsize
- 1);
307 putchar (seg
->initprot
& BFD_MACH_O_PROT_READ
? 'r' : '-');
308 putchar (seg
->initprot
& BFD_MACH_O_PROT_WRITE
? 'w' : '-');
309 putchar (seg
->initprot
& BFD_MACH_O_PROT_EXECUTE
? 'x' : '-');
312 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
314 printf ("%02u: %-16s %-16s ", ++sec_nbr
,
315 sec
->segname
, sec
->sectname
);
316 printf_vma (sec
->addr
);
318 printf_vma (sec
->size
);
319 printf (" %08lx\n", sec
->flags
);
325 dump_section (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_section
*sec
)
327 printf (" Section: %-16s %-16s (bfdname: %s)\n",
328 sec
->sectname
, sec
->segname
, sec
->bfdsection
->name
);
330 printf_vma (sec
->addr
);
332 printf_vma (sec
->size
);
333 printf (" offset: ");
334 printf_vma (sec
->offset
);
336 printf (" align: %ld", sec
->align
);
337 printf (" nreloc: %lu reloff: ", sec
->nreloc
);
338 printf_vma (sec
->reloff
);
340 printf (" flags: %08lx (type: %s", sec
->flags
,
341 bfd_mach_o_get_name (bfd_mach_o_section_type_name
,
342 sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
));
344 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name
,
345 sec
->flags
& BFD_MACH_O_SECTION_ATTRIBUTES_MASK
);
347 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
349 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS
:
350 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS
:
351 case BFD_MACH_O_S_SYMBOL_STUBS
:
352 printf (" first indirect sym: %lu", sec
->reserved1
);
353 printf (" (%u entries)",
354 bfd_mach_o_section_get_nbr_indirect (abfd
, sec
));
357 printf (" reserved1: 0x%lx", sec
->reserved1
);
360 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
362 case BFD_MACH_O_S_SYMBOL_STUBS
:
363 printf (" stub size: %lu", sec
->reserved2
);
366 printf (" reserved2: 0x%lx", sec
->reserved2
);
369 printf (" reserved3: 0x%lx\n", sec
->reserved3
);
373 dump_segment (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_load_command
*cmd
)
375 bfd_mach_o_segment_command
*seg
= &cmd
->command
.segment
;
376 bfd_mach_o_section
*sec
;
378 printf (" name: %s\n", *seg
->segname
? seg
->segname
: "*none*");
379 printf (" vmaddr: ");
380 printf_vma (seg
->vmaddr
);
381 printf (" vmsize: ");
382 printf_vma (seg
->vmsize
);
384 printf (" fileoff: ");
385 printf_vma (seg
->fileoff
);
386 printf (" filesize: ");
387 printf_vma ((bfd_vma
)seg
->filesize
);
388 printf (" endoff: ");
389 printf_vma ((bfd_vma
)(seg
->fileoff
+ seg
->filesize
));
391 printf (" nsects: %lu ", seg
->nsects
);
392 printf (" flags: %lx\n", seg
->flags
);
393 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
394 dump_section (abfd
, sec
);
398 dump_dysymtab (bfd
*abfd
, bfd_mach_o_load_command
*cmd
, bfd_boolean verbose
)
400 bfd_mach_o_dysymtab_command
*dysymtab
= &cmd
->command
.dysymtab
;
401 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
404 printf (" local symbols: idx: %10lu num: %-8lu",
405 dysymtab
->ilocalsym
, dysymtab
->nlocalsym
);
406 printf (" (nxtidx: %lu)\n",
407 dysymtab
->ilocalsym
+ dysymtab
->nlocalsym
);
408 printf (" external symbols: idx: %10lu num: %-8lu",
409 dysymtab
->iextdefsym
, dysymtab
->nextdefsym
);
410 printf (" (nxtidx: %lu)\n",
411 dysymtab
->iextdefsym
+ dysymtab
->nextdefsym
);
412 printf (" undefined symbols: idx: %10lu num: %-8lu",
413 dysymtab
->iundefsym
, dysymtab
->nundefsym
);
414 printf (" (nxtidx: %lu)\n",
415 dysymtab
->iundefsym
+ dysymtab
->nundefsym
);
416 printf (" table of content: off: 0x%08lx num: %-8lu",
417 dysymtab
->tocoff
, dysymtab
->ntoc
);
418 printf (" (endoff: 0x%08lx)\n",
419 dysymtab
->tocoff
+ dysymtab
->ntoc
* BFD_MACH_O_TABLE_OF_CONTENT_SIZE
);
420 printf (" module table: off: 0x%08lx num: %-8lu",
421 dysymtab
->modtaboff
, dysymtab
->nmodtab
);
422 printf (" (endoff: 0x%08lx)\n",
423 dysymtab
->modtaboff
+ dysymtab
->nmodtab
424 * (mdata
->header
.version
== 2 ?
425 BFD_MACH_O_DYLIB_MODULE_64_SIZE
: BFD_MACH_O_DYLIB_MODULE_SIZE
));
426 printf (" external reference table: off: 0x%08lx num: %-8lu",
427 dysymtab
->extrefsymoff
, dysymtab
->nextrefsyms
);
428 printf (" (endoff: 0x%08lx)\n",
429 dysymtab
->extrefsymoff
430 + dysymtab
->nextrefsyms
* BFD_MACH_O_REFERENCE_SIZE
);
431 printf (" indirect symbol table: off: 0x%08lx num: %-8lu",
432 dysymtab
->indirectsymoff
, dysymtab
->nindirectsyms
);
433 printf (" (endoff: 0x%08lx)\n",
434 dysymtab
->indirectsymoff
435 + dysymtab
->nindirectsyms
* BFD_MACH_O_INDIRECT_SYMBOL_SIZE
);
436 printf (" external relocation table: off: 0x%08lx num: %-8lu",
437 dysymtab
->extreloff
, dysymtab
->nextrel
);
438 printf (" (endoff: 0x%08lx)\n",
439 dysymtab
->extreloff
+ dysymtab
->nextrel
* BFD_MACH_O_RELENT_SIZE
);
440 printf (" local relocation table: off: 0x%08lx num: %-8lu",
441 dysymtab
->locreloff
, dysymtab
->nlocrel
);
442 printf (" (endoff: 0x%08lx)\n",
443 dysymtab
->locreloff
+ dysymtab
->nlocrel
* BFD_MACH_O_RELENT_SIZE
);
448 if (dysymtab
->ntoc
> 0
449 || dysymtab
->nindirectsyms
> 0
450 || dysymtab
->nextrefsyms
> 0)
452 /* Try to read the symbols to display the toc or indirect symbols. */
453 bfd_mach_o_read_symtab_symbols (abfd
);
455 else if (dysymtab
->nmodtab
> 0)
457 /* Try to read the strtab to display modules name. */
458 bfd_mach_o_read_symtab_strtab (abfd
);
461 for (i
= 0; i
< dysymtab
->nmodtab
; i
++)
463 bfd_mach_o_dylib_module
*module
= &dysymtab
->dylib_module
[i
];
464 printf (" module %u:\n", i
);
465 printf (" name: %lu", module
->module_name_idx
);
466 if (mdata
->symtab
&& mdata
->symtab
->strtab
)
468 mdata
->symtab
->strtab
+ module
->module_name_idx
);
470 printf (" extdefsym: idx: %8lu num: %lu\n",
471 module
->iextdefsym
, module
->nextdefsym
);
472 printf (" refsym: idx: %8lu num: %lu\n",
473 module
->irefsym
, module
->nrefsym
);
474 printf (" localsym: idx: %8lu num: %lu\n",
475 module
->ilocalsym
, module
->nlocalsym
);
476 printf (" extrel: idx: %8lu num: %lu\n",
477 module
->iextrel
, module
->nextrel
);
478 printf (" init: idx: %8u num: %u\n",
479 module
->iinit
, module
->ninit
);
480 printf (" term: idx: %8u num: %u\n",
481 module
->iterm
, module
->nterm
);
482 printf (" objc_module_info: addr: ");
483 printf_vma (module
->objc_module_info_addr
);
484 printf (" size: %lu\n", module
->objc_module_info_size
);
487 if (dysymtab
->ntoc
> 0)
489 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
491 printf (" table of content: (symbol/module)\n");
492 for (i
= 0; i
< dysymtab
->ntoc
; i
++)
494 bfd_mach_o_dylib_table_of_content
*toc
= &dysymtab
->dylib_toc
[i
];
496 printf (" %4u: ", i
);
497 if (symtab
&& symtab
->symbols
&& toc
->symbol_index
< symtab
->nsyms
)
499 const char *name
= symtab
->symbols
[toc
->symbol_index
].symbol
.name
;
500 printf ("%s (%lu)", name
? name
: "*invalid*",
504 printf ("%lu", toc
->symbol_index
);
507 if (symtab
&& symtab
->strtab
508 && toc
->module_index
< dysymtab
->nmodtab
)
510 bfd_mach_o_dylib_module
*mod
;
511 mod
= &dysymtab
->dylib_module
[toc
->module_index
];
513 symtab
->strtab
+ mod
->module_name_idx
,
517 printf ("%lu", toc
->module_index
);
523 if (dysymtab
->nindirectsyms
!= 0)
525 printf (" indirect symbols:\n");
527 for (i
= 0; i
< mdata
->nsects
; i
++)
529 bfd_mach_o_section
*sec
= mdata
->sections
[i
];
530 unsigned int j
, first
, last
;
531 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
535 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
537 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS
:
538 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS
:
539 case BFD_MACH_O_S_SYMBOL_STUBS
:
540 first
= sec
->reserved1
;
541 last
= first
+ bfd_mach_o_section_get_nbr_indirect (abfd
, sec
);
543 entry_size
= bfd_mach_o_section_get_entry_size (abfd
, sec
);
544 printf (" for section %s.%s:\n",
545 sec
->segname
, sec
->sectname
);
546 for (j
= first
; j
< last
; j
++)
548 unsigned int isym
= dysymtab
->indirect_syms
[j
];
552 printf (" %5u: 0x%08x", j
, isym
);
553 if (isym
& BFD_MACH_O_INDIRECT_SYMBOL_LOCAL
)
555 if (isym
& BFD_MACH_O_INDIRECT_SYMBOL_ABS
)
556 printf (" ABSOLUTE");
557 if (symtab
&& symtab
->symbols
558 && isym
< symtab
->nsyms
559 && symtab
->symbols
[isym
].symbol
.name
)
560 printf (" %s", symtab
->symbols
[isym
].symbol
.name
);
570 if (dysymtab
->nextrefsyms
> 0)
572 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
574 printf (" external reference table: (symbol flags)\n");
575 for (i
= 0; i
< dysymtab
->nextrefsyms
; i
++)
577 bfd_mach_o_dylib_reference
*ref
= &dysymtab
->ext_refs
[i
];
579 printf (" %4u: %5lu 0x%02lx", i
, ref
->isym
, ref
->flags
);
580 if (symtab
&& symtab
->symbols
581 && ref
->isym
< symtab
->nsyms
582 && symtab
->symbols
[ref
->isym
].symbol
.name
)
583 printf (" %s", symtab
->symbols
[ref
->isym
].symbol
.name
);
591 dump_dyld_info (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_load_command
*cmd
)
593 bfd_mach_o_dyld_info_command
*info
= &cmd
->command
.dyld_info
;
595 printf (" rebase: off: 0x%08x size: %-8u\n",
596 info
->rebase_off
, info
->rebase_size
);
597 printf (" bind: off: 0x%08x size: %-8u\n",
598 info
->bind_off
, info
->bind_size
);
599 printf (" weak bind: off: 0x%08x size: %-8u\n",
600 info
->weak_bind_off
, info
->weak_bind_size
);
601 printf (" lazy bind: off: 0x%08x size: %-8u\n",
602 info
->lazy_bind_off
, info
->lazy_bind_size
);
603 printf (" export: off: 0x%08x size: %-8u\n",
604 info
->export_off
, info
->export_size
);
608 dump_thread (bfd
*abfd
, bfd_mach_o_load_command
*cmd
)
610 bfd_mach_o_thread_command
*thread
= &cmd
->command
.thread
;
612 bfd_mach_o_backend_data
*bed
= bfd_mach_o_get_backend_data (abfd
);
613 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
615 printf (" nflavours: %lu\n", thread
->nflavours
);
616 for (j
= 0; j
< thread
->nflavours
; j
++)
618 bfd_mach_o_thread_flavour
*flavour
= &thread
->flavours
[j
];
619 const bfd_mach_o_xlat_name
*name_table
;
621 printf (" %2u: flavour: 0x%08lx", j
, flavour
->flavour
);
622 switch (mdata
->header
.cputype
)
624 case BFD_MACH_O_CPU_TYPE_I386
:
625 case BFD_MACH_O_CPU_TYPE_X86_64
:
626 name_table
= bfd_mach_o_thread_x86_name
;
632 if (name_table
!= NULL
)
633 printf (": %s", bfd_mach_o_get_name (name_table
, flavour
->flavour
));
636 printf (" offset: 0x%08lx size: 0x%08lx\n",
637 flavour
->offset
, flavour
->size
);
638 if (bed
->_bfd_mach_o_print_thread
)
640 char *buf
= xmalloc (flavour
->size
);
642 if (bfd_seek (abfd
, flavour
->offset
, SEEK_SET
) == 0
643 && bfd_bread (buf
, flavour
->size
, abfd
) == flavour
->size
)
644 (*bed
->_bfd_mach_o_print_thread
)(abfd
, flavour
, stdout
, buf
);
651 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic
[] =
653 { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE
},
654 { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT
},
655 { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS
},
656 { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY
},
657 { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS
},
658 { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER
},
662 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type
[] =
664 { "no-hash", BFD_MACH_O_CS_NO_HASH
},
665 { "sha1", BFD_MACH_O_CS_HASH_SHA1
},
666 { "sha256", BFD_MACH_O_CS_HASH_SHA256
},
667 { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256
},
668 { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512
},
673 dump_code_signature_blob (bfd
*abfd
, const unsigned char *buf
, unsigned int len
);
676 dump_code_signature_superblob (bfd
*abfd ATTRIBUTE_UNUSED
,
677 const unsigned char *buf
, unsigned int len
)
684 printf (_(" [bad block length]\n"));
687 count
= bfd_getb32 (buf
+ 8);
688 printf (_(" %u index entries:\n"), count
);
689 if (len
< 12 + 8 * count
)
691 printf (_(" [bad block length]\n"));
694 for (i
= 0; i
< count
; i
++)
699 type
= bfd_getb32 (buf
+ 12 + 8 * i
);
700 off
= bfd_getb32 (buf
+ 12 + 8 * i
+ 4);
701 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
704 dump_code_signature_blob (abfd
, buf
+ off
, len
- off
);
709 swap_code_codedirectory_v1_in
710 (const struct mach_o_codesign_codedirectory_external_v1
*src
,
711 struct mach_o_codesign_codedirectory_v1
*dst
)
713 dst
->version
= bfd_getb32 (src
->version
);
714 dst
->flags
= bfd_getb32 (src
->flags
);
715 dst
->hash_offset
= bfd_getb32 (src
->hash_offset
);
716 dst
->ident_offset
= bfd_getb32 (src
->ident_offset
);
717 dst
->nbr_special_slots
= bfd_getb32 (src
->nbr_special_slots
);
718 dst
->nbr_code_slots
= bfd_getb32 (src
->nbr_code_slots
);
719 dst
->code_limit
= bfd_getb32 (src
->code_limit
);
720 dst
->hash_size
= src
->hash_size
[0];
721 dst
->hash_type
= src
->hash_type
[0];
722 dst
->spare1
= src
->spare1
[0];
723 dst
->page_size
= src
->page_size
[0];
724 dst
->spare2
= bfd_getb32 (src
->spare2
);
728 hexdump (unsigned int start
, unsigned int len
,
729 const unsigned char *buf
)
733 for (i
= 0; i
< len
; i
+= 16)
735 printf ("%08x:", start
+ i
);
736 for (j
= 0; j
< 16; j
++)
738 fputc (j
== 8 ? '-' : ' ', stdout
);
740 printf ("%02x", buf
[i
+ j
]);
745 for (j
= 0; j
< 16; j
++)
748 fputc (ISPRINT (buf
[i
+ j
]) ? buf
[i
+ j
] : '.', stdout
);
752 fputc ('\n', stdout
);
757 dump_code_signature_codedirectory (bfd
*abfd ATTRIBUTE_UNUSED
,
758 const unsigned char *buf
, unsigned int len
)
760 struct mach_o_codesign_codedirectory_v1 cd
;
763 if (len
< sizeof (struct mach_o_codesign_codedirectory_external_v1
))
765 printf (_(" [bad block length]\n"));
769 swap_code_codedirectory_v1_in
770 ((const struct mach_o_codesign_codedirectory_external_v1
*) (buf
+ 8), &cd
);
772 printf (_(" version: %08x\n"), cd
.version
);
773 printf (_(" flags: %08x\n"), cd
.flags
);
774 printf (_(" hash offset: %08x\n"), cd
.hash_offset
);
775 id
= (const char *) buf
+ cd
.ident_offset
;
776 printf (_(" ident offset: %08x (- %08x)\n"),
777 cd
.ident_offset
, cd
.ident_offset
+ (unsigned) strlen (id
) + 1);
778 printf (_(" identity: %s\n"), id
);
779 printf (_(" nbr special slots: %08x (at offset %08x)\n"),
780 cd
.nbr_special_slots
,
781 cd
.hash_offset
- cd
.nbr_special_slots
* cd
.hash_size
);
782 printf (_(" nbr code slots: %08x\n"), cd
.nbr_code_slots
);
783 printf (_(" code limit: %08x\n"), cd
.code_limit
);
784 printf (_(" hash size: %02x\n"), cd
.hash_size
);
785 printf (_(" hash type: %02x (%s)\n"),
787 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type
, cd
.hash_type
));
788 printf (_(" spare1: %02x\n"), cd
.spare1
);
789 printf (_(" page size: %02x\n"), cd
.page_size
);
790 printf (_(" spare2: %08x\n"), cd
.spare2
);
791 if (cd
.version
>= 0x20100)
792 printf (_(" scatter offset: %08x\n"),
793 (unsigned) bfd_getb32 (buf
+ 44));
797 dump_code_signature_blob (bfd
*abfd
, const unsigned char *buf
, unsigned int len
)
804 printf (_(" [truncated block]\n"));
807 magic
= bfd_getb32 (buf
);
808 length
= bfd_getb32 (buf
+ 4);
809 if (magic
== 0 || length
== 0)
812 printf (_(" magic : %08x (%s)\n"), magic
,
813 bfd_mach_o_get_name (bfd_mach_o_cs_magic
, magic
));
814 printf (_(" length: %08x\n"), length
);
817 printf (_(" [bad block length]\n"));
823 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE
:
824 dump_code_signature_superblob (abfd
, buf
, length
);
826 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY
:
827 dump_code_signature_codedirectory (abfd
, buf
, length
);
830 hexdump (0, length
- 8, buf
+ 8);
837 dump_code_signature (bfd
*abfd
, bfd_mach_o_linkedit_command
*cmd
)
839 unsigned char *buf
= xmalloc (cmd
->datasize
);
842 if (bfd_seek (abfd
, cmd
->dataoff
, SEEK_SET
) != 0
843 || bfd_bread (buf
, cmd
->datasize
, abfd
) != cmd
->datasize
)
845 non_fatal (_("cannot read code signature data"));
849 for (off
= 0; off
< cmd
->datasize
;)
853 len
= dump_code_signature_blob (abfd
, buf
+ off
, cmd
->datasize
- off
);
863 dump_segment_split_info (bfd
*abfd
, bfd_mach_o_linkedit_command
*cmd
)
865 unsigned char *buf
= xmalloc (cmd
->datasize
);
870 if (bfd_seek (abfd
, cmd
->dataoff
, SEEK_SET
) != 0
871 || bfd_bread (buf
, cmd
->datasize
, abfd
) != cmd
->datasize
)
873 non_fatal (_("cannot read segment split info"));
877 if (buf
[cmd
->datasize
- 1] != 0)
879 non_fatal (_("segment split info is not nul terminated"));
887 printf (_(" 32 bit pointers:\n"));
890 printf (_(" 64 bit pointers:\n"));
893 printf (_(" PPC hi-16:\n"));
896 printf (_(" Unhandled location type %u\n"), buf
[0]);
899 for (p
= buf
+ 1; *p
!= 0; p
+= len
)
901 addr
+= read_unsigned_leb128 (abfd
, p
, &len
);
903 bfd_printf_vma (abfd
, addr
);
910 dump_load_command (bfd
*abfd
, bfd_mach_o_load_command
*cmd
,
913 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
914 const char *cmd_name
;
916 cmd_name
= bfd_mach_o_get_name_or_null
917 (bfd_mach_o_load_command_name
, cmd
->type
);
918 printf ("Load command ");
919 if (cmd_name
== NULL
)
920 printf ("0x%02x:", cmd
->type
);
922 printf ("%s:", cmd_name
);
926 case BFD_MACH_O_LC_SEGMENT
:
927 case BFD_MACH_O_LC_SEGMENT_64
:
928 dump_segment (abfd
, cmd
);
930 case BFD_MACH_O_LC_UUID
:
932 bfd_mach_o_uuid_command
*uuid
= &cmd
->command
.uuid
;
935 for (j
= 0; j
< sizeof (uuid
->uuid
); j
++)
936 printf (" %02x", uuid
->uuid
[j
]);
940 case BFD_MACH_O_LC_LOAD_DYLIB
:
941 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB
:
942 case BFD_MACH_O_LC_REEXPORT_DYLIB
:
943 case BFD_MACH_O_LC_ID_DYLIB
:
944 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB
:
946 bfd_mach_o_dylib_command
*dylib
= &cmd
->command
.dylib
;
947 printf (" %s\n", dylib
->name_str
);
948 printf (" time stamp: 0x%08lx\n",
950 printf (" current version: 0x%08lx\n",
951 dylib
->current_version
);
952 printf (" comptibility version: 0x%08lx\n",
953 dylib
->compatibility_version
);
956 case BFD_MACH_O_LC_LOAD_DYLINKER
:
957 case BFD_MACH_O_LC_ID_DYLINKER
:
958 printf (" %s\n", cmd
->command
.dylinker
.name_str
);
960 case BFD_MACH_O_LC_SYMTAB
:
962 bfd_mach_o_symtab_command
*symtab
= &cmd
->command
.symtab
;
964 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
965 symtab
->symoff
, symtab
->nsyms
,
966 symtab
->symoff
+ symtab
->nsyms
967 * (mdata
->header
.version
== 2
968 ? BFD_MACH_O_NLIST_64_SIZE
: BFD_MACH_O_NLIST_SIZE
));
969 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
970 symtab
->stroff
, symtab
->strsize
,
971 symtab
->stroff
+ symtab
->strsize
);
974 case BFD_MACH_O_LC_DYSYMTAB
:
976 dump_dysymtab (abfd
, cmd
, verbose
);
978 case BFD_MACH_O_LC_LOADFVMLIB
:
979 case BFD_MACH_O_LC_IDFVMLIB
:
981 bfd_mach_o_fvmlib_command
*fvmlib
= &cmd
->command
.fvmlib
;
982 printf (" %s\n", fvmlib
->name_str
);
983 printf (" minor version: 0x%08x\n", fvmlib
->minor_version
);
984 printf (" header address: 0x%08x\n", fvmlib
->header_addr
);
987 case BFD_MACH_O_LC_CODE_SIGNATURE
:
988 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
:
989 case BFD_MACH_O_LC_FUNCTION_STARTS
:
991 bfd_mach_o_linkedit_command
*linkedit
= &cmd
->command
.linkedit
;
994 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
995 linkedit
->dataoff
, linkedit
->datasize
,
996 linkedit
->dataoff
+ linkedit
->datasize
);
998 if (verbose
&& cmd
->type
== BFD_MACH_O_LC_CODE_SIGNATURE
)
999 dump_code_signature (abfd
, linkedit
);
1000 else if (verbose
&& cmd
->type
== BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
)
1001 dump_segment_split_info (abfd
, linkedit
);
1004 case BFD_MACH_O_LC_SUB_FRAMEWORK
:
1005 case BFD_MACH_O_LC_SUB_UMBRELLA
:
1006 case BFD_MACH_O_LC_SUB_LIBRARY
:
1007 case BFD_MACH_O_LC_SUB_CLIENT
:
1008 case BFD_MACH_O_LC_RPATH
:
1010 bfd_mach_o_str_command
*str
= &cmd
->command
.str
;
1011 printf (" %s\n", str
->str
);
1014 case BFD_MACH_O_LC_THREAD
:
1015 case BFD_MACH_O_LC_UNIXTHREAD
:
1016 dump_thread (abfd
, cmd
);
1018 case BFD_MACH_O_LC_ENCRYPTION_INFO
:
1020 bfd_mach_o_encryption_info_command
*cryp
=
1021 &cmd
->command
.encryption_info
;
1024 " cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1026 cryp
->cryptoff
, cryp
->cryptsize
,
1027 cryp
->cryptoff
+ cryp
->cryptsize
,
1031 case BFD_MACH_O_LC_DYLD_INFO
:
1033 dump_dyld_info (abfd
, cmd
);
1035 case BFD_MACH_O_LC_VERSION_MIN_MACOSX
:
1036 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS
:
1038 bfd_mach_o_version_min_command
*ver
= &cmd
->command
.version_min
;
1040 printf (" %u.%u.%u\n", ver
->rel
, ver
->maj
, ver
->min
);
1043 case BFD_MACH_O_LC_SOURCE_VERSION
:
1045 bfd_mach_o_source_version_command
*version
=
1046 &cmd
->command
.source_version
;
1048 " version a.b.c.d.e: %u.%u.%u.%u.%u\n",
1049 version
->a
, version
->b
, version
->c
, version
->d
, version
->e
);
1052 case BFD_MACH_O_LC_MAIN
:
1054 bfd_mach_o_main_command
*entry
= &cmd
->command
.main
;
1057 printf_vma (entry
->entryoff
);
1060 printf_vma (entry
->stacksize
);
1066 printf (" offset: 0x%08lx\n", (unsigned long)cmd
->offset
);
1067 printf (" size: 0x%08lx\n", (unsigned long)cmd
->len
);
1074 dump_load_commands (bfd
*abfd
, unsigned int cmd32
, unsigned int cmd64
)
1076 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1079 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1081 bfd_mach_o_load_command
*cmd
= &mdata
->commands
[i
];
1084 dump_load_command (abfd
, cmd
, FALSE
);
1085 else if (cmd
->type
== cmd32
|| cmd
->type
== cmd64
)
1086 dump_load_command (abfd
, cmd
, TRUE
);
1090 /* Dump ABFD (according to the options[] array). */
1093 mach_o_dump (bfd
*abfd
)
1095 if (options
[OPT_HEADER
].selected
)
1097 if (options
[OPT_SECTION
].selected
)
1098 dump_load_commands (abfd
, BFD_MACH_O_LC_SEGMENT
, BFD_MACH_O_LC_SEGMENT_64
);
1099 if (options
[OPT_MAP
].selected
)
1100 dump_section_map (abfd
);
1101 if (options
[OPT_LOAD
].selected
)
1102 dump_load_commands (abfd
, 0, 0);
1103 if (options
[OPT_DYSYMTAB
].selected
)
1104 dump_load_commands (abfd
, BFD_MACH_O_LC_DYSYMTAB
, 0);
1105 if (options
[OPT_CODESIGN
].selected
)
1106 dump_load_commands (abfd
, BFD_MACH_O_LC_CODE_SIGNATURE
, 0);
1107 if (options
[OPT_SEG_SPLIT_INFO
].selected
)
1108 dump_load_commands (abfd
, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
, 0);
1111 /* Vector for Mach-O. */
1113 const struct objdump_private_desc objdump_private_desc_mach_o
=