1 /* od-macho.c -- dump information about an Mach-O object file.
2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
3 Written by Tristan Gingold, Adacore.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
25 #include "safe-ctype.h"
32 #include "mach-o/external.h"
33 #include "mach-o/codesign.h"
34 #include "mach-o/unwind.h"
36 /* Index of the options in the options[] array. */
41 #define OPT_DYSYMTAB 4
42 #define OPT_CODESIGN 5
43 #define OPT_SEG_SPLIT_INFO 6
44 #define OPT_COMPACT_UNWIND 7
45 #define OPT_FUNCTION_STARTS 8
46 #define OPT_DATA_IN_CODE 9
47 #define OPT_TWOLEVEL_HINTS 10
49 /* List of actions. */
50 static struct objdump_private_option options
[] =
58 { "seg_split_info", 0 },
59 { "compact_unwind", 0 },
60 { "function_starts", 0 },
61 { "data_in_code", 0 },
62 { "twolevel_hints", 0 },
69 mach_o_help (FILE *stream
)
73 header Display the file header\n\
74 section Display the segments and sections commands\n\
75 map Display the section map\n\
76 load Display the load commands\n\
77 dysymtab Display the dynamic symbol table\n\
78 codesign Display code signature\n\
79 seg_split_info Display segment split info\n\
80 compact_unwind Display compact unwinding info\n\
81 function_starts Display start address of functions\n\
82 data_in_code Display data in code entries\n\
83 twolevel_hints Display the two-level namespace lookup hints table\n\
87 /* Return TRUE if ABFD is handled. */
90 mach_o_filter (bfd
*abfd
)
92 return bfd_get_flavour (abfd
) == bfd_target_mach_o_flavour
;
95 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name
[] =
97 { "vax", BFD_MACH_O_CPU_TYPE_VAX
},
98 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0
},
99 { "i386", BFD_MACH_O_CPU_TYPE_I386
},
100 { "mips", BFD_MACH_O_CPU_TYPE_MIPS
},
101 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000
},
102 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA
},
103 { "arm", BFD_MACH_O_CPU_TYPE_ARM
},
104 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000
},
105 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC
},
106 { "i860", BFD_MACH_O_CPU_TYPE_I860
},
107 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA
},
108 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC
},
109 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64
},
110 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64
},
111 { "arm64", BFD_MACH_O_CPU_TYPE_ARM64
},
115 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name
[] =
117 { "object", BFD_MACH_O_MH_OBJECT
},
118 { "execute", BFD_MACH_O_MH_EXECUTE
},
119 { "fvmlib", BFD_MACH_O_MH_FVMLIB
},
120 { "core", BFD_MACH_O_MH_CORE
},
121 { "preload", BFD_MACH_O_MH_PRELOAD
},
122 { "dylib", BFD_MACH_O_MH_DYLIB
},
123 { "dylinker", BFD_MACH_O_MH_DYLINKER
},
124 { "bundle", BFD_MACH_O_MH_BUNDLE
},
125 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB
},
126 { "dym", BFD_MACH_O_MH_DSYM
},
127 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE
},
131 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name
[] =
133 { "noundefs", BFD_MACH_O_MH_NOUNDEFS
},
134 { "incrlink", BFD_MACH_O_MH_INCRLINK
},
135 { "dyldlink", BFD_MACH_O_MH_DYLDLINK
},
136 { "bindatload", BFD_MACH_O_MH_BINDATLOAD
},
137 { "prebound", BFD_MACH_O_MH_PREBOUND
},
138 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS
},
139 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT
},
140 { "twolevel", BFD_MACH_O_MH_TWOLEVEL
},
141 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT
},
142 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS
},
143 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING
},
144 { "prebindable", BFD_MACH_O_MH_PREBINDABLE
},
145 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND
},
146 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS
},
147 { "canonical", BFD_MACH_O_MH_CANONICAL
},
148 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES
},
149 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK
},
150 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION
},
151 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE
},
152 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE
},
153 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS
},
154 { "pie", BFD_MACH_O_MH_PIE
},
158 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name
[] =
160 { "segment", BFD_MACH_O_LC_SEGMENT
},
161 { "symtab", BFD_MACH_O_LC_SYMTAB
},
162 { "symseg", BFD_MACH_O_LC_SYMSEG
},
163 { "thread", BFD_MACH_O_LC_THREAD
},
164 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD
},
165 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB
},
166 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB
},
167 { "ident", BFD_MACH_O_LC_IDENT
},
168 { "fvmfile", BFD_MACH_O_LC_FVMFILE
},
169 { "prepage", BFD_MACH_O_LC_PREPAGE
},
170 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB
},
171 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB
},
172 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB
},
173 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER
},
174 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER
},
175 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB
},
176 { "routines", BFD_MACH_O_LC_ROUTINES
},
177 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK
},
178 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA
},
179 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT
},
180 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY
},
181 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS
},
182 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM
},
183 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB
},
184 { "segment_64", BFD_MACH_O_LC_SEGMENT_64
},
185 { "routines_64", BFD_MACH_O_LC_ROUTINES_64
},
186 { "uuid", BFD_MACH_O_LC_UUID
},
187 { "rpath", BFD_MACH_O_LC_RPATH
},
188 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE
},
189 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
},
190 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB
},
191 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB
},
192 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO
},
193 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO
},
194 { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB
},
195 { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX
},
196 { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS
},
197 { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS
},
198 { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT
},
199 { "main", BFD_MACH_O_LC_MAIN
},
200 { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE
},
201 { "source_version", BFD_MACH_O_LC_SOURCE_VERSION
},
202 { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS
},
206 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name
[] =
208 { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32
},
209 { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32
},
210 { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32
},
211 { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64
},
212 { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64
},
213 { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64
},
214 { "thread_state", BFD_MACH_O_x86_THREAD_STATE
},
215 { "float_state", BFD_MACH_O_x86_FLOAT_STATE
},
216 { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE
},
217 { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32
},
218 { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64
},
219 { "debug_state", BFD_MACH_O_x86_DEBUG_STATE
},
220 { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE
},
225 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name
*table
,
230 for (; table
->name
; table
++)
232 if (table
->val
& val
)
236 printf ("%s", table
->name
);
245 printf ("0x%lx", val
);
253 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name
*table
,
256 for (; table
->name
; table
++)
257 if (table
->val
== val
)
263 bfd_mach_o_get_name (const bfd_mach_o_xlat_name
*table
, unsigned long val
)
265 const char *res
= bfd_mach_o_get_name_or_null (table
, val
);
274 dump_header (bfd
*abfd
)
276 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
277 bfd_mach_o_header
*h
= &mdata
->header
;
279 fputs (_("Mach-O header:\n"), stdout
);
280 printf (_(" magic : %08lx\n"), h
->magic
);
281 printf (_(" cputype : %08lx (%s)\n"), h
->cputype
,
282 bfd_mach_o_get_name (bfd_mach_o_cpu_name
, h
->cputype
));
283 printf (_(" cpusubtype: %08lx\n"), h
->cpusubtype
);
284 printf (_(" filetype : %08lx (%s)\n"),
286 bfd_mach_o_get_name (bfd_mach_o_filetype_name
, h
->filetype
));
287 printf (_(" ncmds : %08lx (%lu)\n"), h
->ncmds
, h
->ncmds
);
288 printf (_(" sizeofcmds: %08lx\n"), h
->sizeofcmds
);
289 printf (_(" flags : %08lx ("), h
->flags
);
290 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name
, h
->flags
);
291 fputs (_(")\n"), stdout
);
292 printf (_(" reserved : %08x\n"), h
->reserved
);
297 disp_segment_prot (unsigned int prot
)
299 putchar (prot
& BFD_MACH_O_PROT_READ
? 'r' : '-');
300 putchar (prot
& BFD_MACH_O_PROT_WRITE
? 'w' : '-');
301 putchar (prot
& BFD_MACH_O_PROT_EXECUTE
? 'x' : '-');
305 dump_section_map (bfd
*abfd
)
307 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
309 unsigned int sec_nbr
= 0;
311 fputs (_("Segments and Sections:\n"), stdout
);
312 fputs (_(" #: Segment name Section name Address\n"), stdout
);
314 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
316 bfd_mach_o_segment_command
*seg
;
317 bfd_mach_o_section
*sec
;
319 if (mdata
->commands
[i
].type
!= BFD_MACH_O_LC_SEGMENT
320 && mdata
->commands
[i
].type
!= BFD_MACH_O_LC_SEGMENT_64
)
323 seg
= &mdata
->commands
[i
].command
.segment
;
325 printf ("[Segment %-16s ", seg
->segname
);
326 printf_vma (seg
->vmaddr
);
328 printf_vma (seg
->vmaddr
+ seg
->vmsize
- 1);
330 disp_segment_prot (seg
->initprot
);
333 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
335 printf ("%02u: %-16s %-16s ", ++sec_nbr
,
336 sec
->segname
, sec
->sectname
);
337 printf_vma (sec
->addr
);
339 printf_vma (sec
->size
);
340 printf (" %08lx\n", sec
->flags
);
346 dump_section_header (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_section
*sec
)
348 printf (" Section: %-16s %-16s (bfdname: %s)\n",
349 sec
->sectname
, sec
->segname
, sec
->bfdsection
->name
);
351 printf_vma (sec
->addr
);
353 printf_vma (sec
->size
);
354 printf (" offset: ");
355 printf_vma (sec
->offset
);
357 printf (" align: %ld", sec
->align
);
358 printf (" nreloc: %lu reloff: ", sec
->nreloc
);
359 printf_vma (sec
->reloff
);
361 printf (" flags: %08lx (type: %s", sec
->flags
,
362 bfd_mach_o_get_name (bfd_mach_o_section_type_name
,
363 sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
));
365 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name
,
366 sec
->flags
& BFD_MACH_O_SECTION_ATTRIBUTES_MASK
);
368 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
370 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS
:
371 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS
:
372 case BFD_MACH_O_S_SYMBOL_STUBS
:
373 printf (" first indirect sym: %lu", sec
->reserved1
);
374 printf (" (%u entries)",
375 bfd_mach_o_section_get_nbr_indirect (abfd
, sec
));
378 printf (" reserved1: 0x%lx", sec
->reserved1
);
381 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
383 case BFD_MACH_O_S_SYMBOL_STUBS
:
384 printf (" stub size: %lu", sec
->reserved2
);
387 printf (" reserved2: 0x%lx", sec
->reserved2
);
390 printf (" reserved3: 0x%lx\n", sec
->reserved3
);
394 dump_segment (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_load_command
*cmd
)
396 bfd_mach_o_segment_command
*seg
= &cmd
->command
.segment
;
397 bfd_mach_o_section
*sec
;
399 printf (" name: %s\n", *seg
->segname
? seg
->segname
: "*none*");
400 printf (" vmaddr: ");
401 printf_vma (seg
->vmaddr
);
402 printf (" vmsize: ");
403 printf_vma (seg
->vmsize
);
405 printf (" fileoff: ");
406 printf_vma (seg
->fileoff
);
407 printf (" filesize: ");
408 printf_vma ((bfd_vma
)seg
->filesize
);
409 printf (" endoff: ");
410 printf_vma ((bfd_vma
)(seg
->fileoff
+ seg
->filesize
));
412 printf (" nsects: %lu", seg
->nsects
);
413 printf (" flags: %lx", seg
->flags
);
414 printf (" initprot: ");
415 disp_segment_prot (seg
->initprot
);
416 printf (" maxprot: ");
417 disp_segment_prot (seg
->maxprot
);
419 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
420 dump_section_header (abfd
, sec
);
424 dump_dysymtab (bfd
*abfd
, bfd_mach_o_load_command
*cmd
, bfd_boolean verbose
)
426 bfd_mach_o_dysymtab_command
*dysymtab
= &cmd
->command
.dysymtab
;
427 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
430 printf (" local symbols: idx: %10lu num: %-8lu",
431 dysymtab
->ilocalsym
, dysymtab
->nlocalsym
);
432 printf (" (nxtidx: %lu)\n",
433 dysymtab
->ilocalsym
+ dysymtab
->nlocalsym
);
434 printf (" external symbols: idx: %10lu num: %-8lu",
435 dysymtab
->iextdefsym
, dysymtab
->nextdefsym
);
436 printf (" (nxtidx: %lu)\n",
437 dysymtab
->iextdefsym
+ dysymtab
->nextdefsym
);
438 printf (" undefined symbols: idx: %10lu num: %-8lu",
439 dysymtab
->iundefsym
, dysymtab
->nundefsym
);
440 printf (" (nxtidx: %lu)\n",
441 dysymtab
->iundefsym
+ dysymtab
->nundefsym
);
442 printf (" table of content: off: 0x%08lx num: %-8lu",
443 dysymtab
->tocoff
, dysymtab
->ntoc
);
444 printf (" (endoff: 0x%08lx)\n",
445 dysymtab
->tocoff
+ dysymtab
->ntoc
* BFD_MACH_O_TABLE_OF_CONTENT_SIZE
);
446 printf (" module table: off: 0x%08lx num: %-8lu",
447 dysymtab
->modtaboff
, dysymtab
->nmodtab
);
448 printf (" (endoff: 0x%08lx)\n",
449 dysymtab
->modtaboff
+ dysymtab
->nmodtab
450 * (mdata
->header
.version
== 2 ?
451 BFD_MACH_O_DYLIB_MODULE_64_SIZE
: BFD_MACH_O_DYLIB_MODULE_SIZE
));
452 printf (" external reference table: off: 0x%08lx num: %-8lu",
453 dysymtab
->extrefsymoff
, dysymtab
->nextrefsyms
);
454 printf (" (endoff: 0x%08lx)\n",
455 dysymtab
->extrefsymoff
456 + dysymtab
->nextrefsyms
* BFD_MACH_O_REFERENCE_SIZE
);
457 printf (" indirect symbol table: off: 0x%08lx num: %-8lu",
458 dysymtab
->indirectsymoff
, dysymtab
->nindirectsyms
);
459 printf (" (endoff: 0x%08lx)\n",
460 dysymtab
->indirectsymoff
461 + dysymtab
->nindirectsyms
* BFD_MACH_O_INDIRECT_SYMBOL_SIZE
);
462 printf (" external relocation table: off: 0x%08lx num: %-8lu",
463 dysymtab
->extreloff
, dysymtab
->nextrel
);
464 printf (" (endoff: 0x%08lx)\n",
465 dysymtab
->extreloff
+ dysymtab
->nextrel
* BFD_MACH_O_RELENT_SIZE
);
466 printf (" local relocation table: off: 0x%08lx num: %-8lu",
467 dysymtab
->locreloff
, dysymtab
->nlocrel
);
468 printf (" (endoff: 0x%08lx)\n",
469 dysymtab
->locreloff
+ dysymtab
->nlocrel
* BFD_MACH_O_RELENT_SIZE
);
474 if (dysymtab
->ntoc
> 0
475 || dysymtab
->nindirectsyms
> 0
476 || dysymtab
->nextrefsyms
> 0)
478 /* Try to read the symbols to display the toc or indirect symbols. */
479 bfd_mach_o_read_symtab_symbols (abfd
);
481 else if (dysymtab
->nmodtab
> 0)
483 /* Try to read the strtab to display modules name. */
484 bfd_mach_o_read_symtab_strtab (abfd
);
487 for (i
= 0; i
< dysymtab
->nmodtab
; i
++)
489 bfd_mach_o_dylib_module
*module
= &dysymtab
->dylib_module
[i
];
490 printf (" module %u:\n", i
);
491 printf (" name: %lu", module
->module_name_idx
);
492 if (mdata
->symtab
&& mdata
->symtab
->strtab
)
494 mdata
->symtab
->strtab
+ module
->module_name_idx
);
496 printf (" extdefsym: idx: %8lu num: %lu\n",
497 module
->iextdefsym
, module
->nextdefsym
);
498 printf (" refsym: idx: %8lu num: %lu\n",
499 module
->irefsym
, module
->nrefsym
);
500 printf (" localsym: idx: %8lu num: %lu\n",
501 module
->ilocalsym
, module
->nlocalsym
);
502 printf (" extrel: idx: %8lu num: %lu\n",
503 module
->iextrel
, module
->nextrel
);
504 printf (" init: idx: %8u num: %u\n",
505 module
->iinit
, module
->ninit
);
506 printf (" term: idx: %8u num: %u\n",
507 module
->iterm
, module
->nterm
);
508 printf (" objc_module_info: addr: ");
509 printf_vma (module
->objc_module_info_addr
);
510 printf (" size: %lu\n", module
->objc_module_info_size
);
513 if (dysymtab
->ntoc
> 0)
515 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
517 printf (" table of content: (symbol/module)\n");
518 for (i
= 0; i
< dysymtab
->ntoc
; i
++)
520 bfd_mach_o_dylib_table_of_content
*toc
= &dysymtab
->dylib_toc
[i
];
522 printf (" %4u: ", i
);
523 if (symtab
&& symtab
->symbols
&& toc
->symbol_index
< symtab
->nsyms
)
525 const char *name
= symtab
->symbols
[toc
->symbol_index
].symbol
.name
;
526 printf ("%s (%lu)", name
? name
: "*invalid*",
530 printf ("%lu", toc
->symbol_index
);
533 if (symtab
&& symtab
->strtab
534 && toc
->module_index
< dysymtab
->nmodtab
)
536 bfd_mach_o_dylib_module
*mod
;
537 mod
= &dysymtab
->dylib_module
[toc
->module_index
];
539 symtab
->strtab
+ mod
->module_name_idx
,
543 printf ("%lu", toc
->module_index
);
549 if (dysymtab
->nindirectsyms
!= 0)
551 printf (" indirect symbols:\n");
553 for (i
= 0; i
< mdata
->nsects
; i
++)
555 bfd_mach_o_section
*sec
= mdata
->sections
[i
];
556 unsigned int j
, first
, last
;
557 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
561 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
563 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS
:
564 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS
:
565 case BFD_MACH_O_S_SYMBOL_STUBS
:
566 first
= sec
->reserved1
;
567 last
= first
+ bfd_mach_o_section_get_nbr_indirect (abfd
, sec
);
569 entry_size
= bfd_mach_o_section_get_entry_size (abfd
, sec
);
570 printf (" for section %s.%s:\n",
571 sec
->segname
, sec
->sectname
);
572 for (j
= first
; j
< last
; j
++)
574 unsigned int isym
= dysymtab
->indirect_syms
[j
];
578 printf (" %5u: 0x%08x", j
, isym
);
579 if (isym
& BFD_MACH_O_INDIRECT_SYMBOL_LOCAL
)
581 if (isym
& BFD_MACH_O_INDIRECT_SYMBOL_ABS
)
582 printf (" ABSOLUTE");
583 if (symtab
&& symtab
->symbols
584 && isym
< symtab
->nsyms
585 && symtab
->symbols
[isym
].symbol
.name
)
586 printf (" %s", symtab
->symbols
[isym
].symbol
.name
);
596 if (dysymtab
->nextrefsyms
> 0)
598 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
600 printf (" external reference table: (symbol flags)\n");
601 for (i
= 0; i
< dysymtab
->nextrefsyms
; i
++)
603 bfd_mach_o_dylib_reference
*ref
= &dysymtab
->ext_refs
[i
];
605 printf (" %4u: %5lu 0x%02lx", i
, ref
->isym
, ref
->flags
);
606 if (symtab
&& symtab
->symbols
607 && ref
->isym
< symtab
->nsyms
608 && symtab
->symbols
[ref
->isym
].symbol
.name
)
609 printf (" %s", symtab
->symbols
[ref
->isym
].symbol
.name
);
617 dump_dyld_info (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_load_command
*cmd
)
619 bfd_mach_o_dyld_info_command
*info
= &cmd
->command
.dyld_info
;
621 printf (" rebase: off: 0x%08x size: %-8u\n",
622 info
->rebase_off
, info
->rebase_size
);
623 printf (" bind: off: 0x%08x size: %-8u\n",
624 info
->bind_off
, info
->bind_size
);
625 printf (" weak bind: off: 0x%08x size: %-8u\n",
626 info
->weak_bind_off
, info
->weak_bind_size
);
627 printf (" lazy bind: off: 0x%08x size: %-8u\n",
628 info
->lazy_bind_off
, info
->lazy_bind_size
);
629 printf (" export: off: 0x%08x size: %-8u\n",
630 info
->export_off
, info
->export_size
);
634 dump_thread (bfd
*abfd
, bfd_mach_o_load_command
*cmd
)
636 bfd_mach_o_thread_command
*thread
= &cmd
->command
.thread
;
638 bfd_mach_o_backend_data
*bed
= bfd_mach_o_get_backend_data (abfd
);
639 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
641 printf (" nflavours: %lu\n", thread
->nflavours
);
642 for (j
= 0; j
< thread
->nflavours
; j
++)
644 bfd_mach_o_thread_flavour
*flavour
= &thread
->flavours
[j
];
645 const bfd_mach_o_xlat_name
*name_table
;
647 printf (" %2u: flavour: 0x%08lx", j
, flavour
->flavour
);
648 switch (mdata
->header
.cputype
)
650 case BFD_MACH_O_CPU_TYPE_I386
:
651 case BFD_MACH_O_CPU_TYPE_X86_64
:
652 name_table
= bfd_mach_o_thread_x86_name
;
658 if (name_table
!= NULL
)
659 printf (": %s", bfd_mach_o_get_name (name_table
, flavour
->flavour
));
662 printf (" offset: 0x%08lx size: 0x%08lx\n",
663 flavour
->offset
, flavour
->size
);
664 if (bed
->_bfd_mach_o_print_thread
)
666 char *buf
= xmalloc (flavour
->size
);
668 if (bfd_seek (abfd
, flavour
->offset
, SEEK_SET
) == 0
669 && bfd_bread (buf
, flavour
->size
, abfd
) == flavour
->size
)
670 (*bed
->_bfd_mach_o_print_thread
)(abfd
, flavour
, stdout
, buf
);
677 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic
[] =
679 { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE
},
680 { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT
},
681 { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS
},
682 { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY
},
683 { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS
},
684 { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER
},
688 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type
[] =
690 { "no-hash", BFD_MACH_O_CS_NO_HASH
},
691 { "sha1", BFD_MACH_O_CS_HASH_SHA1
},
692 { "sha256", BFD_MACH_O_CS_HASH_SHA256
},
693 { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256
},
694 { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512
},
699 dump_code_signature_blob (bfd
*abfd
, const unsigned char *buf
, unsigned int len
);
702 dump_code_signature_superblob (bfd
*abfd ATTRIBUTE_UNUSED
,
703 const unsigned char *buf
, unsigned int len
)
710 printf (_(" [bad block length]\n"));
713 count
= bfd_getb32 (buf
+ 8);
714 printf (_(" %u index entries:\n"), count
);
715 if (len
< 12 + 8 * count
)
717 printf (_(" [bad block length]\n"));
720 for (i
= 0; i
< count
; i
++)
725 type
= bfd_getb32 (buf
+ 12 + 8 * i
);
726 off
= bfd_getb32 (buf
+ 12 + 8 * i
+ 4);
727 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
730 dump_code_signature_blob (abfd
, buf
+ off
, len
- off
);
735 swap_code_codedirectory_v1_in
736 (const struct mach_o_codesign_codedirectory_external_v1
*src
,
737 struct mach_o_codesign_codedirectory_v1
*dst
)
739 dst
->version
= bfd_getb32 (src
->version
);
740 dst
->flags
= bfd_getb32 (src
->flags
);
741 dst
->hash_offset
= bfd_getb32 (src
->hash_offset
);
742 dst
->ident_offset
= bfd_getb32 (src
->ident_offset
);
743 dst
->nbr_special_slots
= bfd_getb32 (src
->nbr_special_slots
);
744 dst
->nbr_code_slots
= bfd_getb32 (src
->nbr_code_slots
);
745 dst
->code_limit
= bfd_getb32 (src
->code_limit
);
746 dst
->hash_size
= src
->hash_size
[0];
747 dst
->hash_type
= src
->hash_type
[0];
748 dst
->spare1
= src
->spare1
[0];
749 dst
->page_size
= src
->page_size
[0];
750 dst
->spare2
= bfd_getb32 (src
->spare2
);
754 hexdump (unsigned int start
, unsigned int len
,
755 const unsigned char *buf
)
759 for (i
= 0; i
< len
; i
+= 16)
761 printf ("%08x:", start
+ i
);
762 for (j
= 0; j
< 16; j
++)
764 fputc (j
== 8 ? '-' : ' ', stdout
);
766 printf ("%02x", buf
[i
+ j
]);
771 for (j
= 0; j
< 16; j
++)
774 fputc (ISPRINT (buf
[i
+ j
]) ? buf
[i
+ j
] : '.', stdout
);
778 fputc ('\n', stdout
);
783 dump_code_signature_codedirectory (bfd
*abfd ATTRIBUTE_UNUSED
,
784 const unsigned char *buf
, unsigned int len
)
786 struct mach_o_codesign_codedirectory_v1 cd
;
789 if (len
< sizeof (struct mach_o_codesign_codedirectory_external_v1
))
791 printf (_(" [bad block length]\n"));
795 swap_code_codedirectory_v1_in
796 ((const struct mach_o_codesign_codedirectory_external_v1
*) (buf
+ 8), &cd
);
798 printf (_(" version: %08x\n"), cd
.version
);
799 printf (_(" flags: %08x\n"), cd
.flags
);
800 printf (_(" hash offset: %08x\n"), cd
.hash_offset
);
801 id
= (const char *) buf
+ cd
.ident_offset
;
802 printf (_(" ident offset: %08x (- %08x)\n"),
803 cd
.ident_offset
, cd
.ident_offset
+ (unsigned) strlen (id
) + 1);
804 printf (_(" identity: %s\n"), id
);
805 printf (_(" nbr special slots: %08x (at offset %08x)\n"),
806 cd
.nbr_special_slots
,
807 cd
.hash_offset
- cd
.nbr_special_slots
* cd
.hash_size
);
808 printf (_(" nbr code slots: %08x\n"), cd
.nbr_code_slots
);
809 printf (_(" code limit: %08x\n"), cd
.code_limit
);
810 printf (_(" hash size: %02x\n"), cd
.hash_size
);
811 printf (_(" hash type: %02x (%s)\n"),
813 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type
, cd
.hash_type
));
814 printf (_(" spare1: %02x\n"), cd
.spare1
);
815 printf (_(" page size: %02x\n"), cd
.page_size
);
816 printf (_(" spare2: %08x\n"), cd
.spare2
);
817 if (cd
.version
>= 0x20100)
818 printf (_(" scatter offset: %08x\n"),
819 (unsigned) bfd_getb32 (buf
+ 44));
823 dump_code_signature_blob (bfd
*abfd
, const unsigned char *buf
, unsigned int len
)
830 printf (_(" [truncated block]\n"));
833 magic
= bfd_getb32 (buf
);
834 length
= bfd_getb32 (buf
+ 4);
835 if (magic
== 0 || length
== 0)
838 printf (_(" magic : %08x (%s)\n"), magic
,
839 bfd_mach_o_get_name (bfd_mach_o_cs_magic
, magic
));
840 printf (_(" length: %08x\n"), length
);
843 printf (_(" [bad block length]\n"));
849 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE
:
850 dump_code_signature_superblob (abfd
, buf
, length
);
852 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY
:
853 dump_code_signature_codedirectory (abfd
, buf
, length
);
856 hexdump (0, length
- 8, buf
+ 8);
863 dump_code_signature (bfd
*abfd
, bfd_mach_o_linkedit_command
*cmd
)
865 unsigned char *buf
= xmalloc (cmd
->datasize
);
868 if (bfd_seek (abfd
, cmd
->dataoff
, SEEK_SET
) != 0
869 || bfd_bread (buf
, cmd
->datasize
, abfd
) != cmd
->datasize
)
871 non_fatal (_("cannot read code signature data"));
875 for (off
= 0; off
< cmd
->datasize
;)
879 len
= dump_code_signature_blob (abfd
, buf
+ off
, cmd
->datasize
- off
);
889 dump_segment_split_info (bfd
*abfd
, bfd_mach_o_linkedit_command
*cmd
)
891 unsigned char *buf
= xmalloc (cmd
->datasize
);
896 if (bfd_seek (abfd
, cmd
->dataoff
, SEEK_SET
) != 0
897 || bfd_bread (buf
, cmd
->datasize
, abfd
) != cmd
->datasize
)
899 non_fatal (_("cannot read segment split info"));
903 if (buf
[cmd
->datasize
- 1] != 0)
905 non_fatal (_("segment split info is not nul terminated"));
913 printf (_(" 32 bit pointers:\n"));
916 printf (_(" 64 bit pointers:\n"));
919 printf (_(" PPC hi-16:\n"));
922 printf (_(" Unhandled location type %u\n"), buf
[0]);
925 for (p
= buf
+ 1; *p
!= 0; p
+= len
)
927 addr
+= read_unsigned_leb128 (abfd
, p
, &len
);
929 bfd_printf_vma (abfd
, addr
);
936 dump_function_starts (bfd
*abfd
, bfd_mach_o_linkedit_command
*cmd
)
938 unsigned char *buf
= xmalloc (cmd
->datasize
);
939 unsigned char *end_buf
= buf
+ cmd
->datasize
;
943 if (bfd_seek (abfd
, cmd
->dataoff
, SEEK_SET
) != 0
944 || bfd_bread (buf
, cmd
->datasize
, abfd
) != cmd
->datasize
)
946 non_fatal (_("cannot read function starts"));
951 /* Function starts are delta encoded, starting from the base address. */
952 addr
= bfd_mach_o_get_base_address (abfd
);
957 unsigned int shift
= 0;
959 if (*p
== 0 || p
== end_buf
)
963 unsigned char b
= *p
++;
965 delta
|= (b
& 0x7f) << shift
;
970 fputs (" [truncated]\n", stdout
);
978 bfd_printf_vma (abfd
, addr
);
984 static const bfd_mach_o_xlat_name data_in_code_kind_name
[] =
986 { "data", BFD_MACH_O_DICE_KIND_DATA
},
987 { "1 byte jump table", BFD_MACH_O_DICE_JUMP_TABLES8
},
988 { "2 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES16
},
989 { "4 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES32
},
990 { "4 bytes abs jump table", BFD_MACH_O_DICE_ABS_JUMP_TABLES32
},
995 dump_data_in_code (bfd
*abfd
, bfd_mach_o_linkedit_command
*cmd
)
1000 if (cmd
->datasize
== 0)
1002 printf (" no data_in_code entries\n");
1006 buf
= xmalloc (cmd
->datasize
);
1007 if (bfd_seek (abfd
, cmd
->dataoff
, SEEK_SET
) != 0
1008 || bfd_bread (buf
, cmd
->datasize
, abfd
) != cmd
->datasize
)
1010 non_fatal (_("cannot read data_in_code"));
1015 printf (" offset length kind\n");
1016 for (p
= buf
; p
< buf
+ cmd
->datasize
; )
1018 struct mach_o_data_in_code_entry_external
*dice
;
1019 unsigned int offset
;
1020 unsigned int length
;
1023 dice
= (struct mach_o_data_in_code_entry_external
*) p
;
1025 offset
= bfd_get_32 (abfd
, dice
->offset
);
1026 length
= bfd_get_16 (abfd
, dice
->length
);
1027 kind
= bfd_get_16 (abfd
, dice
->kind
);
1029 printf (" 0x%08x 0x%04x 0x%04x %s\n", offset
, length
, kind
,
1030 bfd_mach_o_get_name (data_in_code_kind_name
, kind
));
1032 p
+= sizeof (*dice
);
1038 dump_twolevel_hints (bfd
*abfd
, bfd_mach_o_twolevel_hints_command
*cmd
)
1040 size_t sz
= 4 * cmd
->nhints
;
1045 if (bfd_seek (abfd
, cmd
->offset
, SEEK_SET
) != 0
1046 || bfd_bread (buf
, sz
, abfd
) != sz
)
1048 non_fatal (_("cannot read twolevel hints"));
1053 for (p
= buf
; p
< buf
+ sz
; p
+= 4)
1056 unsigned int isub_image
;
1059 v
= bfd_get_32 (abfd
, p
);
1060 if (bfd_big_endian (abfd
))
1062 isub_image
= (v
>> 24) & 0xff;
1063 itoc
= v
& 0xffffff;
1067 isub_image
= v
& 0xff;
1068 itoc
= (v
>> 8) & 0xffffff;
1071 printf (" %3u %8u\n", isub_image
, itoc
);
1077 dump_load_command (bfd
*abfd
, bfd_mach_o_load_command
*cmd
,
1078 bfd_boolean verbose
)
1080 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1081 const char *cmd_name
;
1083 cmd_name
= bfd_mach_o_get_name_or_null
1084 (bfd_mach_o_load_command_name
, cmd
->type
);
1085 printf ("Load command ");
1086 if (cmd_name
== NULL
)
1087 printf ("0x%02x:", cmd
->type
);
1089 printf ("%s:", cmd_name
);
1093 case BFD_MACH_O_LC_SEGMENT
:
1094 case BFD_MACH_O_LC_SEGMENT_64
:
1095 dump_segment (abfd
, cmd
);
1097 case BFD_MACH_O_LC_UUID
:
1099 bfd_mach_o_uuid_command
*uuid
= &cmd
->command
.uuid
;
1102 for (j
= 0; j
< sizeof (uuid
->uuid
); j
++)
1103 printf (" %02x", uuid
->uuid
[j
]);
1107 case BFD_MACH_O_LC_LOAD_DYLIB
:
1108 case BFD_MACH_O_LC_LAZY_LOAD_DYLIB
:
1109 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB
:
1110 case BFD_MACH_O_LC_REEXPORT_DYLIB
:
1111 case BFD_MACH_O_LC_ID_DYLIB
:
1112 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB
:
1114 bfd_mach_o_dylib_command
*dylib
= &cmd
->command
.dylib
;
1115 printf (" %s\n", dylib
->name_str
);
1116 printf (" time stamp: 0x%08lx\n",
1118 printf (" current version: 0x%08lx\n",
1119 dylib
->current_version
);
1120 printf (" comptibility version: 0x%08lx\n",
1121 dylib
->compatibility_version
);
1124 case BFD_MACH_O_LC_LOAD_DYLINKER
:
1125 case BFD_MACH_O_LC_ID_DYLINKER
:
1126 printf (" %s\n", cmd
->command
.dylinker
.name_str
);
1128 case BFD_MACH_O_LC_DYLD_ENVIRONMENT
:
1130 printf (" %s\n", cmd
->command
.dylinker
.name_str
);
1132 case BFD_MACH_O_LC_SYMTAB
:
1134 bfd_mach_o_symtab_command
*symtab
= &cmd
->command
.symtab
;
1136 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
1137 symtab
->symoff
, symtab
->nsyms
,
1138 symtab
->symoff
+ symtab
->nsyms
1139 * (mdata
->header
.version
== 2
1140 ? BFD_MACH_O_NLIST_64_SIZE
: BFD_MACH_O_NLIST_SIZE
));
1141 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
1142 symtab
->stroff
, symtab
->strsize
,
1143 symtab
->stroff
+ symtab
->strsize
);
1146 case BFD_MACH_O_LC_DYSYMTAB
:
1148 dump_dysymtab (abfd
, cmd
, verbose
);
1150 case BFD_MACH_O_LC_LOADFVMLIB
:
1151 case BFD_MACH_O_LC_IDFVMLIB
:
1153 bfd_mach_o_fvmlib_command
*fvmlib
= &cmd
->command
.fvmlib
;
1154 printf (" %s\n", fvmlib
->name_str
);
1155 printf (" minor version: 0x%08x\n", fvmlib
->minor_version
);
1156 printf (" header address: 0x%08x\n", fvmlib
->header_addr
);
1159 case BFD_MACH_O_LC_CODE_SIGNATURE
:
1160 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
:
1161 case BFD_MACH_O_LC_FUNCTION_STARTS
:
1162 case BFD_MACH_O_LC_DATA_IN_CODE
:
1163 case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS
:
1165 bfd_mach_o_linkedit_command
*linkedit
= &cmd
->command
.linkedit
;
1168 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
1169 linkedit
->dataoff
, linkedit
->datasize
,
1170 linkedit
->dataoff
+ linkedit
->datasize
);
1175 case BFD_MACH_O_LC_CODE_SIGNATURE
:
1176 dump_code_signature (abfd
, linkedit
);
1178 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
:
1179 dump_segment_split_info (abfd
, linkedit
);
1181 case BFD_MACH_O_LC_FUNCTION_STARTS
:
1182 dump_function_starts (abfd
, linkedit
);
1184 case BFD_MACH_O_LC_DATA_IN_CODE
:
1185 dump_data_in_code (abfd
, linkedit
);
1192 case BFD_MACH_O_LC_SUB_FRAMEWORK
:
1193 case BFD_MACH_O_LC_SUB_UMBRELLA
:
1194 case BFD_MACH_O_LC_SUB_LIBRARY
:
1195 case BFD_MACH_O_LC_SUB_CLIENT
:
1196 case BFD_MACH_O_LC_RPATH
:
1198 bfd_mach_o_str_command
*str
= &cmd
->command
.str
;
1199 printf (" %s\n", str
->str
);
1202 case BFD_MACH_O_LC_THREAD
:
1203 case BFD_MACH_O_LC_UNIXTHREAD
:
1204 dump_thread (abfd
, cmd
);
1206 case BFD_MACH_O_LC_ENCRYPTION_INFO
:
1208 bfd_mach_o_encryption_info_command
*cryp
=
1209 &cmd
->command
.encryption_info
;
1212 " cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1214 cryp
->cryptoff
, cryp
->cryptsize
,
1215 cryp
->cryptoff
+ cryp
->cryptsize
,
1219 case BFD_MACH_O_LC_DYLD_INFO
:
1221 dump_dyld_info (abfd
, cmd
);
1223 case BFD_MACH_O_LC_VERSION_MIN_MACOSX
:
1224 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS
:
1226 bfd_mach_o_version_min_command
*ver
= &cmd
->command
.version_min
;
1228 printf (" %u.%u.%u\n", ver
->rel
, ver
->maj
, ver
->min
);
1231 case BFD_MACH_O_LC_SOURCE_VERSION
:
1233 bfd_mach_o_source_version_command
*version
=
1234 &cmd
->command
.source_version
;
1236 " version a.b.c.d.e: %u.%u.%u.%u.%u\n",
1237 version
->a
, version
->b
, version
->c
, version
->d
, version
->e
);
1240 case BFD_MACH_O_LC_PREBOUND_DYLIB
:
1242 bfd_mach_o_prebound_dylib_command
*pbdy
= &cmd
->command
.prebound_dylib
;
1243 unsigned char *lm
= pbdy
->linked_modules
;
1247 printf (" %s\n", pbdy
->name_str
);
1248 printf (" nmodules: %u\n", pbdy
->nmodules
);
1249 printf (" linked modules (at %u): ",
1250 pbdy
->linked_modules_offset
- cmd
->offset
);
1251 last
= pbdy
->nmodules
> 32 ? 32 : pbdy
->nmodules
;
1252 for (j
= 0; j
< last
; j
++)
1253 printf ("%u", (lm
[j
>> 3] >> (j
& 7)) & 1);
1254 if (last
< pbdy
->nmodules
)
1259 case BFD_MACH_O_LC_PREBIND_CKSUM
:
1261 bfd_mach_o_prebind_cksum_command
*cksum
= &cmd
->command
.prebind_cksum
;
1262 printf (" 0x%08x\n", cksum
->cksum
);
1265 case BFD_MACH_O_LC_TWOLEVEL_HINTS
:
1267 bfd_mach_o_twolevel_hints_command
*hints
=
1268 &cmd
->command
.twolevel_hints
;
1271 " table offset: 0x%08x nbr hints: %u\n",
1272 hints
->offset
, hints
->nhints
);
1274 dump_twolevel_hints (abfd
, hints
);
1277 case BFD_MACH_O_LC_MAIN
:
1279 bfd_mach_o_main_command
*entry
= &cmd
->command
.main
;
1282 printf_vma (entry
->entryoff
);
1285 printf_vma (entry
->stacksize
);
1291 printf (" offset: 0x%08lx\n", (unsigned long)cmd
->offset
);
1292 printf (" size: 0x%08lx\n", (unsigned long)cmd
->len
);
1299 dump_load_commands (bfd
*abfd
, unsigned int cmd32
, unsigned int cmd64
)
1301 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1304 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1306 bfd_mach_o_load_command
*cmd
= &mdata
->commands
[i
];
1309 dump_load_command (abfd
, cmd
, FALSE
);
1310 else if (cmd
->type
== cmd32
|| cmd
->type
== cmd64
)
1311 dump_load_command (abfd
, cmd
, TRUE
);
1315 static const char * const unwind_x86_64_regs
[] =
1316 {"", "rbx", "r12", "r13", "r14", "r15", "rbp", "???" };
1318 static const char * const unwind_x86_regs
[] =
1319 {"", "ebx", "ecx", "edx", "edi", "edi", "ebp", "???" };
1321 /* Dump x86 or x86-64 compact unwind encoding. Works for both architecture,
1322 as the encoding is the same (but not register names). */
1325 dump_unwind_encoding_x86 (unsigned int encoding
, unsigned int sz
,
1326 const char * const regs_name
[])
1330 mode
= encoding
& MACH_O_UNWIND_X86_64_MODE_MASK
;
1333 case MACH_O_UNWIND_X86_64_MODE_RBP_FRAME
:
1336 char pfx
= sz
== 8 ? 'R' : 'E';
1338 regs
= encoding
& MACH_O_UNWIND_X86_64_RBP_FRAME_REGSITERS
;
1339 printf (" %cSP frame", pfx
);
1342 unsigned int offset
;
1345 offset
= (encoding
& MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET
) >> 16;
1346 printf (" at %cBP-%u:", pfx
, offset
* sz
);
1347 for (i
= 0; i
< 5; i
++)
1349 unsigned int reg
= (regs
>> (i
* 3)) & 0x7;
1350 if (reg
!= MACH_O_UNWIND_X86_64_REG_NONE
)
1351 printf (" %s", regs_name
[reg
]);
1356 case MACH_O_UNWIND_X86_64_MODE_STACK_IMMD
:
1357 case MACH_O_UNWIND_X86_64_MODE_STACK_IND
:
1359 unsigned int stack_size
;
1360 unsigned int reg_count
;
1361 unsigned int reg_perm
;
1362 unsigned int regs
[6];
1365 printf (" frameless");
1367 (encoding
& MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE
) >> 16;
1369 (encoding
& MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT
) >> 10;
1370 reg_perm
= encoding
& MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION
;
1372 if (mode
== MACH_O_UNWIND_X86_64_MODE_STACK_IMMD
)
1373 printf (" size: 0x%03x", stack_size
* sz
);
1376 unsigned int stack_adj
;
1379 (encoding
& MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST
) >> 13;
1380 printf (" size at 0x%03x + 0x%02x", stack_size
, stack_adj
* sz
);
1382 /* Registers are coded using arithmetic compression: the register
1383 is indexed in range 0-6, the second in range 0-5, the third in
1384 range 0-4, etc. Already used registers are removed in next
1386 #define DO_PERM(R, NUM) R = reg_perm / NUM; reg_perm -= R * NUM
1391 DO_PERM (regs
[0], 120);
1392 DO_PERM (regs
[1], 24);
1393 DO_PERM (regs
[2], 6);
1394 DO_PERM (regs
[3], 2);
1395 DO_PERM (regs
[4], 1);
1396 regs
[5] = 0; /* Not used if reg_count = 5. */
1399 DO_PERM (regs
[0], 60);
1400 DO_PERM (regs
[1], 12);
1401 DO_PERM (regs
[2], 3);
1402 DO_PERM (regs
[3], 1);
1405 DO_PERM (regs
[0], 20);
1406 DO_PERM (regs
[1], 4);
1407 DO_PERM (regs
[2], 1);
1410 DO_PERM (regs
[0], 5);
1411 DO_PERM (regs
[1], 1);
1414 DO_PERM (regs
[0], 1);
1419 printf (" [bad reg count]");
1424 for (i
= reg_count
- 1; i
>= 0; i
--)
1426 unsigned int inc
= 1;
1427 for (j
= 0; j
< i
; j
++)
1428 if (regs
[i
] >= regs
[j
])
1433 for (i
= 0; i
< (int) reg_count
; i
++)
1434 printf (" %s", regs_name
[regs
[i
]]);
1437 case MACH_O_UNWIND_X86_64_MODE_DWARF
:
1438 printf (" Dwarf offset: 0x%06x",
1439 encoding
& MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET
);
1442 printf (" [unhandled mode]");
1448 dump_unwind_encoding (bfd_mach_o_data_struct
*mdata
, unsigned int encoding
)
1450 printf ("0x%08x", encoding
);
1454 switch (mdata
->header
.cputype
)
1456 case BFD_MACH_O_CPU_TYPE_X86_64
:
1457 dump_unwind_encoding_x86 (encoding
, 8, unwind_x86_64_regs
);
1459 case BFD_MACH_O_CPU_TYPE_I386
:
1460 dump_unwind_encoding_x86 (encoding
, 4, unwind_x86_regs
);
1463 printf (" [unhandled cpu]");
1466 if (encoding
& MACH_O_UNWIND_HAS_LSDA
)
1468 if (encoding
& MACH_O_UNWIND_PERSONALITY_MASK
)
1469 printf (" PERS(%u)",
1470 ((encoding
& MACH_O_UNWIND_PERSONALITY_MASK
)
1471 >> MACH_O_UNWIND_PERSONALITY_SHIFT
));
1475 dump_obj_compact_unwind (bfd
*abfd
,
1476 const unsigned char *content
, bfd_size_type size
)
1478 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1479 int is_64
= mdata
->header
.version
== 2;
1480 const unsigned char *p
;
1482 printf ("Compact unwind info:\n");
1483 printf (" start length personality lsda\n");
1487 struct mach_o_compact_unwind_64
*e
=
1488 (struct mach_o_compact_unwind_64
*) content
;
1490 for (p
= content
; p
< content
+ size
; p
+= sizeof (*e
))
1492 e
= (struct mach_o_compact_unwind_64
*) p
;
1495 fprintf_vma (stdout
, bfd_get_64 (abfd
, e
->start
));
1496 printf (" %08lx", bfd_get_32 (abfd
, e
->length
));
1498 fprintf_vma (stdout
, bfd_get_64 (abfd
, e
->personnality
));
1500 fprintf_vma (stdout
, bfd_get_64 (abfd
, e
->lsda
));
1503 printf (" encoding: ");
1504 dump_unwind_encoding (mdata
, bfd_get_32 (abfd
, e
->encoding
));
1510 printf ("unhandled\n");
1515 dump_exe_compact_unwind (bfd
*abfd
,
1516 const unsigned char *content
, bfd_size_type size
)
1518 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1519 struct mach_o_unwind_info_header
*hdr
;
1520 unsigned int version
;
1521 unsigned int encodings_offset
;
1522 unsigned int encodings_count
;
1523 unsigned int personality_offset
;
1524 unsigned int personality_count
;
1525 unsigned int index_offset
;
1526 unsigned int index_count
;
1527 struct mach_o_unwind_index_entry
*index_entry
;
1531 printf ("Compact unwind info:\n");
1533 hdr
= (struct mach_o_unwind_info_header
*) content
;
1534 if (size
< sizeof (*hdr
))
1536 printf (" truncated!\n");
1540 version
= bfd_get_32 (abfd
, hdr
->version
);
1541 if (version
!= MACH_O_UNWIND_SECTION_VERSION
)
1543 printf (" unknown version: %u\n", version
);
1546 encodings_offset
= bfd_get_32 (abfd
, hdr
->encodings_array_offset
);
1547 encodings_count
= bfd_get_32 (abfd
, hdr
->encodings_array_count
);
1548 personality_offset
= bfd_get_32 (abfd
, hdr
->personality_array_offset
);
1549 personality_count
= bfd_get_32 (abfd
, hdr
->personality_array_count
);
1550 index_offset
= bfd_get_32 (abfd
, hdr
->index_offset
);
1551 index_count
= bfd_get_32 (abfd
, hdr
->index_count
);
1552 printf (" %u encodings, %u personalities, %u level-1 indexes:\n",
1553 encodings_count
, personality_count
, index_count
);
1555 /* Level-1 index. */
1556 printf (" idx function level2 off lsda off\n");
1558 index_entry
= (struct mach_o_unwind_index_entry
*) (content
+ index_offset
);
1559 for (i
= 0; i
< index_count
; i
++)
1561 unsigned int func_offset
;
1562 unsigned int level2_offset
;
1563 unsigned int lsda_offset
;
1565 func_offset
= bfd_get_32 (abfd
, index_entry
->function_offset
);
1566 level2_offset
= bfd_get_32 (abfd
, index_entry
->second_level_offset
);
1567 lsda_offset
= bfd_get_32 (abfd
, index_entry
->lsda_index_offset
);
1568 printf (" %3u 0x%08x 0x%08x 0x%08x\n",
1569 i
, func_offset
, level2_offset
, lsda_offset
);
1573 /* Level-1 index. */
1574 index_entry
= (struct mach_o_unwind_index_entry
*) (content
+ index_offset
);
1575 for (i
= 0; i
< index_count
; i
++)
1577 unsigned int func_offset
;
1578 unsigned int level2_offset
;
1579 const unsigned char *level2
;
1582 func_offset
= bfd_get_32 (abfd
, index_entry
->function_offset
);
1583 level2_offset
= bfd_get_32 (abfd
, index_entry
->second_level_offset
);
1585 /* No level-2 for this index (should be the last index). */
1586 if (level2_offset
== 0)
1589 level2
= content
+ level2_offset
;
1590 kind
= bfd_get_32 (abfd
, level2
);
1593 case MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED
:
1595 struct mach_o_unwind_compressed_second_level_page_header
*l2
;
1596 unsigned int entry_offset
;
1597 unsigned int entry_count
;
1598 unsigned int l2_encodings_offset
;
1599 unsigned int l2_encodings_count
;
1600 const unsigned char *en
;
1603 l2
= (struct mach_o_unwind_compressed_second_level_page_header
*)
1605 entry_offset
= bfd_get_16 (abfd
, l2
->entry_page_offset
);
1606 entry_count
= bfd_get_16 (abfd
, l2
->entry_count
);
1607 l2_encodings_offset
= bfd_get_16 (abfd
, l2
->encodings_offset
);
1608 l2_encodings_count
= bfd_get_16 (abfd
, l2
->encodings_count
);
1610 printf (" index %2u: compressed second level: "
1611 "%u entries, %u encodings (at 0x%08x)\n",
1612 i
, entry_count
, l2_encodings_count
, l2_encodings_offset
);
1613 printf (" # function eidx encoding\n");
1615 en
= level2
+ entry_offset
;
1616 for (j
= 0; j
< entry_count
; j
++)
1619 unsigned int en_func
;
1620 unsigned int enc_idx
;
1621 unsigned int encoding
;
1622 const unsigned char *enc_addr
;
1624 entry
= bfd_get_32 (abfd
, en
);
1626 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry
);
1628 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry
);
1629 if (enc_idx
< encodings_count
)
1630 enc_addr
= content
+ encodings_offset
1633 enc_addr
= level2
+ l2_encodings_offset
1634 + 4 * (enc_idx
- encodings_count
);
1635 encoding
= bfd_get_32 (abfd
, enc_addr
);
1637 printf (" %-4u 0x%08x [%3u] ", j
,
1638 func_offset
+ en_func
, enc_idx
);
1639 dump_unwind_encoding (mdata
, encoding
);
1647 case MACH_O_UNWIND_SECOND_LEVEL_REGULAR
:
1649 struct mach_o_unwind_regular_second_level_page_header
*l2
;
1650 struct mach_o_unwind_regular_second_level_entry
*en
;
1651 unsigned int entry_offset
;
1652 unsigned int entry_count
;
1655 l2
= (struct mach_o_unwind_regular_second_level_page_header
*)
1658 entry_offset
= bfd_get_16 (abfd
, l2
->entry_page_offset
);
1659 entry_count
= bfd_get_16 (abfd
, l2
->entry_count
);
1660 printf (" index %2u: regular level 2 at 0x%04x, %u entries\n",
1661 i
, entry_offset
, entry_count
);
1662 printf (" # function encoding\n");
1664 en
= (struct mach_o_unwind_regular_second_level_entry
*)
1665 (level2
+ entry_offset
);
1666 for (j
= 0; j
< entry_count
; j
++)
1668 unsigned int en_func
;
1669 unsigned int encoding
;
1671 en_func
= bfd_get_32 (abfd
, en
->function_offset
);
1672 encoding
= bfd_get_32 (abfd
, en
->encoding
);
1673 printf (" %-4u 0x%08x ", j
, en_func
);
1674 dump_unwind_encoding (mdata
, encoding
);
1682 printf (" index %2u: unhandled second level format (%u)\n",
1688 struct mach_o_unwind_lsda_index_entry
*lsda
;
1689 unsigned int lsda_offset
;
1690 unsigned int next_lsda_offset
;
1691 unsigned int nbr_lsda
;
1694 lsda_offset
= bfd_get_32 (abfd
, index_entry
->lsda_index_offset
);
1695 next_lsda_offset
= bfd_get_32 (abfd
, index_entry
[1].lsda_index_offset
);
1696 lsda
= (struct mach_o_unwind_lsda_index_entry
*)
1697 (content
+ lsda_offset
);
1698 nbr_lsda
= (next_lsda_offset
- lsda_offset
) / sizeof (*lsda
);
1699 for (j
= 0; j
< nbr_lsda
; j
++)
1701 printf (" lsda %3u: function 0x%08x lsda 0x%08x\n",
1702 j
, (unsigned int) bfd_get_32 (abfd
, lsda
->function_offset
),
1703 (unsigned int) bfd_get_32 (abfd
, lsda
->lsda_offset
));
1712 dump_section_content (bfd
*abfd
,
1713 const char *segname
, const char *sectname
,
1714 void (*dump
)(bfd
*, const unsigned char*, bfd_size_type
))
1716 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1719 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1721 bfd_mach_o_load_command
*cmd
= &mdata
->commands
[i
];
1722 if (cmd
->type
== BFD_MACH_O_LC_SEGMENT
1723 || cmd
->type
== BFD_MACH_O_LC_SEGMENT_64
)
1725 bfd_mach_o_segment_command
*seg
= &cmd
->command
.segment
;
1726 bfd_mach_o_section
*sec
;
1727 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
1728 if (strcmp (sec
->segname
, segname
) == 0
1729 && strcmp (sec
->sectname
, sectname
) == 0)
1732 asection
*bfdsec
= sec
->bfdsection
;
1733 unsigned char *content
;
1735 size
= bfd_get_section_size (bfdsec
);
1736 content
= (unsigned char *) xmalloc (size
);
1737 bfd_get_section_contents (abfd
, bfdsec
, content
, 0, size
);
1739 (*dump
)(abfd
, content
, size
);
1747 /* Dump ABFD (according to the options[] array). */
1750 mach_o_dump (bfd
*abfd
)
1752 if (options
[OPT_HEADER
].selected
)
1754 if (options
[OPT_SECTION
].selected
)
1755 dump_load_commands (abfd
, BFD_MACH_O_LC_SEGMENT
, BFD_MACH_O_LC_SEGMENT_64
);
1756 if (options
[OPT_MAP
].selected
)
1757 dump_section_map (abfd
);
1758 if (options
[OPT_LOAD
].selected
)
1759 dump_load_commands (abfd
, 0, 0);
1760 if (options
[OPT_DYSYMTAB
].selected
)
1761 dump_load_commands (abfd
, BFD_MACH_O_LC_DYSYMTAB
, 0);
1762 if (options
[OPT_CODESIGN
].selected
)
1763 dump_load_commands (abfd
, BFD_MACH_O_LC_CODE_SIGNATURE
, 0);
1764 if (options
[OPT_SEG_SPLIT_INFO
].selected
)
1765 dump_load_commands (abfd
, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
, 0);
1766 if (options
[OPT_FUNCTION_STARTS
].selected
)
1767 dump_load_commands (abfd
, BFD_MACH_O_LC_FUNCTION_STARTS
, 0);
1768 if (options
[OPT_DATA_IN_CODE
].selected
)
1769 dump_load_commands (abfd
, BFD_MACH_O_LC_DATA_IN_CODE
, 0);
1770 if (options
[OPT_TWOLEVEL_HINTS
].selected
)
1771 dump_load_commands (abfd
, BFD_MACH_O_LC_TWOLEVEL_HINTS
, 0);
1772 if (options
[OPT_COMPACT_UNWIND
].selected
)
1774 dump_section_content (abfd
, "__LD", "__compact_unwind",
1775 dump_obj_compact_unwind
);
1776 dump_section_content (abfd
, "__TEXT", "__unwind_info",
1777 dump_exe_compact_unwind
);
1781 /* Vector for Mach-O. */
1783 const struct objdump_private_desc objdump_private_desc_mach_o
=