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
46 /* List of actions. */
47 static struct objdump_private_option options
[] =
55 { "seg_split_info", 0 },
56 { "compact_unwind", 0 },
63 mach_o_help (FILE *stream
)
67 header Display the file header\n\
68 section Display the segments and sections commands\n\
69 map Display the section map\n\
70 load Display the load commands\n\
71 dysymtab Display the dynamic symbol table\n\
72 codesign Display code signature\n\
73 seg_split_info Display segment split info\n\
74 compact_unwind Display compact unwinding info\n\
78 /* Return TRUE if ABFD is handled. */
81 mach_o_filter (bfd
*abfd
)
83 return bfd_get_flavour (abfd
) == bfd_target_mach_o_flavour
;
86 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name
[] =
88 { "vax", BFD_MACH_O_CPU_TYPE_VAX
},
89 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0
},
90 { "i386", BFD_MACH_O_CPU_TYPE_I386
},
91 { "mips", BFD_MACH_O_CPU_TYPE_MIPS
},
92 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000
},
93 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA
},
94 { "arm", BFD_MACH_O_CPU_TYPE_ARM
},
95 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000
},
96 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC
},
97 { "i860", BFD_MACH_O_CPU_TYPE_I860
},
98 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA
},
99 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC
},
100 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64
},
101 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64
},
105 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name
[] =
107 { "object", BFD_MACH_O_MH_OBJECT
},
108 { "execute", BFD_MACH_O_MH_EXECUTE
},
109 { "fvmlib", BFD_MACH_O_MH_FVMLIB
},
110 { "core", BFD_MACH_O_MH_CORE
},
111 { "preload", BFD_MACH_O_MH_PRELOAD
},
112 { "dylib", BFD_MACH_O_MH_DYLIB
},
113 { "dylinker", BFD_MACH_O_MH_DYLINKER
},
114 { "bundle", BFD_MACH_O_MH_BUNDLE
},
115 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB
},
116 { "dym", BFD_MACH_O_MH_DSYM
},
117 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE
},
121 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name
[] =
123 { "noundefs", BFD_MACH_O_MH_NOUNDEFS
},
124 { "incrlink", BFD_MACH_O_MH_INCRLINK
},
125 { "dyldlink", BFD_MACH_O_MH_DYLDLINK
},
126 { "bindatload", BFD_MACH_O_MH_BINDATLOAD
},
127 { "prebound", BFD_MACH_O_MH_PREBOUND
},
128 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS
},
129 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT
},
130 { "twolevel", BFD_MACH_O_MH_TWOLEVEL
},
131 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT
},
132 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS
},
133 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING
},
134 { "prebindable", BFD_MACH_O_MH_PREBINDABLE
},
135 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND
},
136 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS
},
137 { "canonical", BFD_MACH_O_MH_CANONICAL
},
138 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES
},
139 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK
},
140 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION
},
141 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE
},
142 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE
},
143 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS
},
144 { "pie", BFD_MACH_O_MH_PIE
},
148 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name
[] =
150 { "segment", BFD_MACH_O_LC_SEGMENT
},
151 { "symtab", BFD_MACH_O_LC_SYMTAB
},
152 { "symseg", BFD_MACH_O_LC_SYMSEG
},
153 { "thread", BFD_MACH_O_LC_THREAD
},
154 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD
},
155 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB
},
156 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB
},
157 { "ident", BFD_MACH_O_LC_IDENT
},
158 { "fvmfile", BFD_MACH_O_LC_FVMFILE
},
159 { "prepage", BFD_MACH_O_LC_PREPAGE
},
160 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB
},
161 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB
},
162 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB
},
163 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER
},
164 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER
},
165 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB
},
166 { "routines", BFD_MACH_O_LC_ROUTINES
},
167 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK
},
168 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA
},
169 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT
},
170 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY
},
171 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS
},
172 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM
},
173 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB
},
174 { "segment_64", BFD_MACH_O_LC_SEGMENT_64
},
175 { "routines_64", BFD_MACH_O_LC_ROUTINES_64
},
176 { "uuid", BFD_MACH_O_LC_UUID
},
177 { "rpath", BFD_MACH_O_LC_RPATH
},
178 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE
},
179 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
},
180 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB
},
181 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB
},
182 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO
},
183 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO
},
184 { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB
},
185 { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX
},
186 { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS
},
187 { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS
},
188 { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT
},
189 { "main", BFD_MACH_O_LC_MAIN
},
190 { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE
},
191 { "source_version", BFD_MACH_O_LC_SOURCE_VERSION
},
192 { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS
},
196 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name
[] =
198 { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32
},
199 { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32
},
200 { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32
},
201 { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64
},
202 { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64
},
203 { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64
},
204 { "thread_state", BFD_MACH_O_x86_THREAD_STATE
},
205 { "float_state", BFD_MACH_O_x86_FLOAT_STATE
},
206 { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE
},
207 { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32
},
208 { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64
},
209 { "debug_state", BFD_MACH_O_x86_DEBUG_STATE
},
210 { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE
},
215 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name
*table
,
220 for (; table
->name
; table
++)
222 if (table
->val
& val
)
226 printf ("%s", table
->name
);
235 printf ("0x%lx", val
);
243 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name
*table
,
246 for (; table
->name
; table
++)
247 if (table
->val
== val
)
253 bfd_mach_o_get_name (const bfd_mach_o_xlat_name
*table
, unsigned long val
)
255 const char *res
= bfd_mach_o_get_name_or_null (table
, val
);
264 dump_header (bfd
*abfd
)
266 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
267 bfd_mach_o_header
*h
= &mdata
->header
;
269 fputs (_("Mach-O header:\n"), stdout
);
270 printf (_(" magic : %08lx\n"), h
->magic
);
271 printf (_(" cputype : %08lx (%s)\n"), h
->cputype
,
272 bfd_mach_o_get_name (bfd_mach_o_cpu_name
, h
->cputype
));
273 printf (_(" cpusubtype: %08lx\n"), h
->cpusubtype
);
274 printf (_(" filetype : %08lx (%s)\n"),
276 bfd_mach_o_get_name (bfd_mach_o_filetype_name
, h
->filetype
));
277 printf (_(" ncmds : %08lx (%lu)\n"), h
->ncmds
, h
->ncmds
);
278 printf (_(" sizeofcmds: %08lx\n"), h
->sizeofcmds
);
279 printf (_(" flags : %08lx ("), h
->flags
);
280 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name
, h
->flags
);
281 fputs (_(")\n"), stdout
);
282 printf (_(" reserved : %08x\n"), h
->reserved
);
286 dump_section_map (bfd
*abfd
)
288 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
290 unsigned int sec_nbr
= 0;
292 fputs (_("Segments and Sections:\n"), stdout
);
293 fputs (_(" #: Segment name Section name Address\n"), stdout
);
295 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
297 bfd_mach_o_segment_command
*seg
;
298 bfd_mach_o_section
*sec
;
300 if (mdata
->commands
[i
].type
!= BFD_MACH_O_LC_SEGMENT
301 && mdata
->commands
[i
].type
!= BFD_MACH_O_LC_SEGMENT_64
)
304 seg
= &mdata
->commands
[i
].command
.segment
;
306 printf ("[Segment %-16s ", seg
->segname
);
307 printf_vma (seg
->vmaddr
);
309 printf_vma (seg
->vmaddr
+ seg
->vmsize
- 1);
311 putchar (seg
->initprot
& BFD_MACH_O_PROT_READ
? 'r' : '-');
312 putchar (seg
->initprot
& BFD_MACH_O_PROT_WRITE
? 'w' : '-');
313 putchar (seg
->initprot
& BFD_MACH_O_PROT_EXECUTE
? 'x' : '-');
316 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
318 printf ("%02u: %-16s %-16s ", ++sec_nbr
,
319 sec
->segname
, sec
->sectname
);
320 printf_vma (sec
->addr
);
322 printf_vma (sec
->size
);
323 printf (" %08lx\n", sec
->flags
);
329 dump_section_header (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_section
*sec
)
331 printf (" Section: %-16s %-16s (bfdname: %s)\n",
332 sec
->sectname
, sec
->segname
, sec
->bfdsection
->name
);
334 printf_vma (sec
->addr
);
336 printf_vma (sec
->size
);
337 printf (" offset: ");
338 printf_vma (sec
->offset
);
340 printf (" align: %ld", sec
->align
);
341 printf (" nreloc: %lu reloff: ", sec
->nreloc
);
342 printf_vma (sec
->reloff
);
344 printf (" flags: %08lx (type: %s", sec
->flags
,
345 bfd_mach_o_get_name (bfd_mach_o_section_type_name
,
346 sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
));
348 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name
,
349 sec
->flags
& BFD_MACH_O_SECTION_ATTRIBUTES_MASK
);
351 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
353 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS
:
354 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS
:
355 case BFD_MACH_O_S_SYMBOL_STUBS
:
356 printf (" first indirect sym: %lu", sec
->reserved1
);
357 printf (" (%u entries)",
358 bfd_mach_o_section_get_nbr_indirect (abfd
, sec
));
361 printf (" reserved1: 0x%lx", sec
->reserved1
);
364 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
366 case BFD_MACH_O_S_SYMBOL_STUBS
:
367 printf (" stub size: %lu", sec
->reserved2
);
370 printf (" reserved2: 0x%lx", sec
->reserved2
);
373 printf (" reserved3: 0x%lx\n", sec
->reserved3
);
377 dump_segment (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_load_command
*cmd
)
379 bfd_mach_o_segment_command
*seg
= &cmd
->command
.segment
;
380 bfd_mach_o_section
*sec
;
382 printf (" name: %s\n", *seg
->segname
? seg
->segname
: "*none*");
383 printf (" vmaddr: ");
384 printf_vma (seg
->vmaddr
);
385 printf (" vmsize: ");
386 printf_vma (seg
->vmsize
);
388 printf (" fileoff: ");
389 printf_vma (seg
->fileoff
);
390 printf (" filesize: ");
391 printf_vma ((bfd_vma
)seg
->filesize
);
392 printf (" endoff: ");
393 printf_vma ((bfd_vma
)(seg
->fileoff
+ seg
->filesize
));
395 printf (" nsects: %lu ", seg
->nsects
);
396 printf (" flags: %lx\n", seg
->flags
);
397 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
398 dump_section_header (abfd
, sec
);
402 dump_dysymtab (bfd
*abfd
, bfd_mach_o_load_command
*cmd
, bfd_boolean verbose
)
404 bfd_mach_o_dysymtab_command
*dysymtab
= &cmd
->command
.dysymtab
;
405 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
408 printf (" local symbols: idx: %10lu num: %-8lu",
409 dysymtab
->ilocalsym
, dysymtab
->nlocalsym
);
410 printf (" (nxtidx: %lu)\n",
411 dysymtab
->ilocalsym
+ dysymtab
->nlocalsym
);
412 printf (" external symbols: idx: %10lu num: %-8lu",
413 dysymtab
->iextdefsym
, dysymtab
->nextdefsym
);
414 printf (" (nxtidx: %lu)\n",
415 dysymtab
->iextdefsym
+ dysymtab
->nextdefsym
);
416 printf (" undefined symbols: idx: %10lu num: %-8lu",
417 dysymtab
->iundefsym
, dysymtab
->nundefsym
);
418 printf (" (nxtidx: %lu)\n",
419 dysymtab
->iundefsym
+ dysymtab
->nundefsym
);
420 printf (" table of content: off: 0x%08lx num: %-8lu",
421 dysymtab
->tocoff
, dysymtab
->ntoc
);
422 printf (" (endoff: 0x%08lx)\n",
423 dysymtab
->tocoff
+ dysymtab
->ntoc
* BFD_MACH_O_TABLE_OF_CONTENT_SIZE
);
424 printf (" module table: off: 0x%08lx num: %-8lu",
425 dysymtab
->modtaboff
, dysymtab
->nmodtab
);
426 printf (" (endoff: 0x%08lx)\n",
427 dysymtab
->modtaboff
+ dysymtab
->nmodtab
428 * (mdata
->header
.version
== 2 ?
429 BFD_MACH_O_DYLIB_MODULE_64_SIZE
: BFD_MACH_O_DYLIB_MODULE_SIZE
));
430 printf (" external reference table: off: 0x%08lx num: %-8lu",
431 dysymtab
->extrefsymoff
, dysymtab
->nextrefsyms
);
432 printf (" (endoff: 0x%08lx)\n",
433 dysymtab
->extrefsymoff
434 + dysymtab
->nextrefsyms
* BFD_MACH_O_REFERENCE_SIZE
);
435 printf (" indirect symbol table: off: 0x%08lx num: %-8lu",
436 dysymtab
->indirectsymoff
, dysymtab
->nindirectsyms
);
437 printf (" (endoff: 0x%08lx)\n",
438 dysymtab
->indirectsymoff
439 + dysymtab
->nindirectsyms
* BFD_MACH_O_INDIRECT_SYMBOL_SIZE
);
440 printf (" external relocation table: off: 0x%08lx num: %-8lu",
441 dysymtab
->extreloff
, dysymtab
->nextrel
);
442 printf (" (endoff: 0x%08lx)\n",
443 dysymtab
->extreloff
+ dysymtab
->nextrel
* BFD_MACH_O_RELENT_SIZE
);
444 printf (" local relocation table: off: 0x%08lx num: %-8lu",
445 dysymtab
->locreloff
, dysymtab
->nlocrel
);
446 printf (" (endoff: 0x%08lx)\n",
447 dysymtab
->locreloff
+ dysymtab
->nlocrel
* BFD_MACH_O_RELENT_SIZE
);
452 if (dysymtab
->ntoc
> 0
453 || dysymtab
->nindirectsyms
> 0
454 || dysymtab
->nextrefsyms
> 0)
456 /* Try to read the symbols to display the toc or indirect symbols. */
457 bfd_mach_o_read_symtab_symbols (abfd
);
459 else if (dysymtab
->nmodtab
> 0)
461 /* Try to read the strtab to display modules name. */
462 bfd_mach_o_read_symtab_strtab (abfd
);
465 for (i
= 0; i
< dysymtab
->nmodtab
; i
++)
467 bfd_mach_o_dylib_module
*module
= &dysymtab
->dylib_module
[i
];
468 printf (" module %u:\n", i
);
469 printf (" name: %lu", module
->module_name_idx
);
470 if (mdata
->symtab
&& mdata
->symtab
->strtab
)
472 mdata
->symtab
->strtab
+ module
->module_name_idx
);
474 printf (" extdefsym: idx: %8lu num: %lu\n",
475 module
->iextdefsym
, module
->nextdefsym
);
476 printf (" refsym: idx: %8lu num: %lu\n",
477 module
->irefsym
, module
->nrefsym
);
478 printf (" localsym: idx: %8lu num: %lu\n",
479 module
->ilocalsym
, module
->nlocalsym
);
480 printf (" extrel: idx: %8lu num: %lu\n",
481 module
->iextrel
, module
->nextrel
);
482 printf (" init: idx: %8u num: %u\n",
483 module
->iinit
, module
->ninit
);
484 printf (" term: idx: %8u num: %u\n",
485 module
->iterm
, module
->nterm
);
486 printf (" objc_module_info: addr: ");
487 printf_vma (module
->objc_module_info_addr
);
488 printf (" size: %lu\n", module
->objc_module_info_size
);
491 if (dysymtab
->ntoc
> 0)
493 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
495 printf (" table of content: (symbol/module)\n");
496 for (i
= 0; i
< dysymtab
->ntoc
; i
++)
498 bfd_mach_o_dylib_table_of_content
*toc
= &dysymtab
->dylib_toc
[i
];
500 printf (" %4u: ", i
);
501 if (symtab
&& symtab
->symbols
&& toc
->symbol_index
< symtab
->nsyms
)
503 const char *name
= symtab
->symbols
[toc
->symbol_index
].symbol
.name
;
504 printf ("%s (%lu)", name
? name
: "*invalid*",
508 printf ("%lu", toc
->symbol_index
);
511 if (symtab
&& symtab
->strtab
512 && toc
->module_index
< dysymtab
->nmodtab
)
514 bfd_mach_o_dylib_module
*mod
;
515 mod
= &dysymtab
->dylib_module
[toc
->module_index
];
517 symtab
->strtab
+ mod
->module_name_idx
,
521 printf ("%lu", toc
->module_index
);
527 if (dysymtab
->nindirectsyms
!= 0)
529 printf (" indirect symbols:\n");
531 for (i
= 0; i
< mdata
->nsects
; i
++)
533 bfd_mach_o_section
*sec
= mdata
->sections
[i
];
534 unsigned int j
, first
, last
;
535 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
539 switch (sec
->flags
& BFD_MACH_O_SECTION_TYPE_MASK
)
541 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS
:
542 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS
:
543 case BFD_MACH_O_S_SYMBOL_STUBS
:
544 first
= sec
->reserved1
;
545 last
= first
+ bfd_mach_o_section_get_nbr_indirect (abfd
, sec
);
547 entry_size
= bfd_mach_o_section_get_entry_size (abfd
, sec
);
548 printf (" for section %s.%s:\n",
549 sec
->segname
, sec
->sectname
);
550 for (j
= first
; j
< last
; j
++)
552 unsigned int isym
= dysymtab
->indirect_syms
[j
];
556 printf (" %5u: 0x%08x", j
, isym
);
557 if (isym
& BFD_MACH_O_INDIRECT_SYMBOL_LOCAL
)
559 if (isym
& BFD_MACH_O_INDIRECT_SYMBOL_ABS
)
560 printf (" ABSOLUTE");
561 if (symtab
&& symtab
->symbols
562 && isym
< symtab
->nsyms
563 && symtab
->symbols
[isym
].symbol
.name
)
564 printf (" %s", symtab
->symbols
[isym
].symbol
.name
);
574 if (dysymtab
->nextrefsyms
> 0)
576 bfd_mach_o_symtab_command
*symtab
= mdata
->symtab
;
578 printf (" external reference table: (symbol flags)\n");
579 for (i
= 0; i
< dysymtab
->nextrefsyms
; i
++)
581 bfd_mach_o_dylib_reference
*ref
= &dysymtab
->ext_refs
[i
];
583 printf (" %4u: %5lu 0x%02lx", i
, ref
->isym
, ref
->flags
);
584 if (symtab
&& symtab
->symbols
585 && ref
->isym
< symtab
->nsyms
586 && symtab
->symbols
[ref
->isym
].symbol
.name
)
587 printf (" %s", symtab
->symbols
[ref
->isym
].symbol
.name
);
595 dump_dyld_info (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_mach_o_load_command
*cmd
)
597 bfd_mach_o_dyld_info_command
*info
= &cmd
->command
.dyld_info
;
599 printf (" rebase: off: 0x%08x size: %-8u\n",
600 info
->rebase_off
, info
->rebase_size
);
601 printf (" bind: off: 0x%08x size: %-8u\n",
602 info
->bind_off
, info
->bind_size
);
603 printf (" weak bind: off: 0x%08x size: %-8u\n",
604 info
->weak_bind_off
, info
->weak_bind_size
);
605 printf (" lazy bind: off: 0x%08x size: %-8u\n",
606 info
->lazy_bind_off
, info
->lazy_bind_size
);
607 printf (" export: off: 0x%08x size: %-8u\n",
608 info
->export_off
, info
->export_size
);
612 dump_thread (bfd
*abfd
, bfd_mach_o_load_command
*cmd
)
614 bfd_mach_o_thread_command
*thread
= &cmd
->command
.thread
;
616 bfd_mach_o_backend_data
*bed
= bfd_mach_o_get_backend_data (abfd
);
617 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
619 printf (" nflavours: %lu\n", thread
->nflavours
);
620 for (j
= 0; j
< thread
->nflavours
; j
++)
622 bfd_mach_o_thread_flavour
*flavour
= &thread
->flavours
[j
];
623 const bfd_mach_o_xlat_name
*name_table
;
625 printf (" %2u: flavour: 0x%08lx", j
, flavour
->flavour
);
626 switch (mdata
->header
.cputype
)
628 case BFD_MACH_O_CPU_TYPE_I386
:
629 case BFD_MACH_O_CPU_TYPE_X86_64
:
630 name_table
= bfd_mach_o_thread_x86_name
;
636 if (name_table
!= NULL
)
637 printf (": %s", bfd_mach_o_get_name (name_table
, flavour
->flavour
));
640 printf (" offset: 0x%08lx size: 0x%08lx\n",
641 flavour
->offset
, flavour
->size
);
642 if (bed
->_bfd_mach_o_print_thread
)
644 char *buf
= xmalloc (flavour
->size
);
646 if (bfd_seek (abfd
, flavour
->offset
, SEEK_SET
) == 0
647 && bfd_bread (buf
, flavour
->size
, abfd
) == flavour
->size
)
648 (*bed
->_bfd_mach_o_print_thread
)(abfd
, flavour
, stdout
, buf
);
655 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic
[] =
657 { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE
},
658 { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT
},
659 { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS
},
660 { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY
},
661 { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS
},
662 { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER
},
666 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type
[] =
668 { "no-hash", BFD_MACH_O_CS_NO_HASH
},
669 { "sha1", BFD_MACH_O_CS_HASH_SHA1
},
670 { "sha256", BFD_MACH_O_CS_HASH_SHA256
},
671 { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256
},
672 { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512
},
677 dump_code_signature_blob (bfd
*abfd
, const unsigned char *buf
, unsigned int len
);
680 dump_code_signature_superblob (bfd
*abfd ATTRIBUTE_UNUSED
,
681 const unsigned char *buf
, unsigned int len
)
688 printf (_(" [bad block length]\n"));
691 count
= bfd_getb32 (buf
+ 8);
692 printf (_(" %u index entries:\n"), count
);
693 if (len
< 12 + 8 * count
)
695 printf (_(" [bad block length]\n"));
698 for (i
= 0; i
< count
; i
++)
703 type
= bfd_getb32 (buf
+ 12 + 8 * i
);
704 off
= bfd_getb32 (buf
+ 12 + 8 * i
+ 4);
705 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
708 dump_code_signature_blob (abfd
, buf
+ off
, len
- off
);
713 swap_code_codedirectory_v1_in
714 (const struct mach_o_codesign_codedirectory_external_v1
*src
,
715 struct mach_o_codesign_codedirectory_v1
*dst
)
717 dst
->version
= bfd_getb32 (src
->version
);
718 dst
->flags
= bfd_getb32 (src
->flags
);
719 dst
->hash_offset
= bfd_getb32 (src
->hash_offset
);
720 dst
->ident_offset
= bfd_getb32 (src
->ident_offset
);
721 dst
->nbr_special_slots
= bfd_getb32 (src
->nbr_special_slots
);
722 dst
->nbr_code_slots
= bfd_getb32 (src
->nbr_code_slots
);
723 dst
->code_limit
= bfd_getb32 (src
->code_limit
);
724 dst
->hash_size
= src
->hash_size
[0];
725 dst
->hash_type
= src
->hash_type
[0];
726 dst
->spare1
= src
->spare1
[0];
727 dst
->page_size
= src
->page_size
[0];
728 dst
->spare2
= bfd_getb32 (src
->spare2
);
732 hexdump (unsigned int start
, unsigned int len
,
733 const unsigned char *buf
)
737 for (i
= 0; i
< len
; i
+= 16)
739 printf ("%08x:", start
+ i
);
740 for (j
= 0; j
< 16; j
++)
742 fputc (j
== 8 ? '-' : ' ', stdout
);
744 printf ("%02x", buf
[i
+ j
]);
749 for (j
= 0; j
< 16; j
++)
752 fputc (ISPRINT (buf
[i
+ j
]) ? buf
[i
+ j
] : '.', stdout
);
756 fputc ('\n', stdout
);
761 dump_code_signature_codedirectory (bfd
*abfd ATTRIBUTE_UNUSED
,
762 const unsigned char *buf
, unsigned int len
)
764 struct mach_o_codesign_codedirectory_v1 cd
;
767 if (len
< sizeof (struct mach_o_codesign_codedirectory_external_v1
))
769 printf (_(" [bad block length]\n"));
773 swap_code_codedirectory_v1_in
774 ((const struct mach_o_codesign_codedirectory_external_v1
*) (buf
+ 8), &cd
);
776 printf (_(" version: %08x\n"), cd
.version
);
777 printf (_(" flags: %08x\n"), cd
.flags
);
778 printf (_(" hash offset: %08x\n"), cd
.hash_offset
);
779 id
= (const char *) buf
+ cd
.ident_offset
;
780 printf (_(" ident offset: %08x (- %08x)\n"),
781 cd
.ident_offset
, cd
.ident_offset
+ (unsigned) strlen (id
) + 1);
782 printf (_(" identity: %s\n"), id
);
783 printf (_(" nbr special slots: %08x (at offset %08x)\n"),
784 cd
.nbr_special_slots
,
785 cd
.hash_offset
- cd
.nbr_special_slots
* cd
.hash_size
);
786 printf (_(" nbr code slots: %08x\n"), cd
.nbr_code_slots
);
787 printf (_(" code limit: %08x\n"), cd
.code_limit
);
788 printf (_(" hash size: %02x\n"), cd
.hash_size
);
789 printf (_(" hash type: %02x (%s)\n"),
791 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type
, cd
.hash_type
));
792 printf (_(" spare1: %02x\n"), cd
.spare1
);
793 printf (_(" page size: %02x\n"), cd
.page_size
);
794 printf (_(" spare2: %08x\n"), cd
.spare2
);
795 if (cd
.version
>= 0x20100)
796 printf (_(" scatter offset: %08x\n"),
797 (unsigned) bfd_getb32 (buf
+ 44));
801 dump_code_signature_blob (bfd
*abfd
, const unsigned char *buf
, unsigned int len
)
808 printf (_(" [truncated block]\n"));
811 magic
= bfd_getb32 (buf
);
812 length
= bfd_getb32 (buf
+ 4);
813 if (magic
== 0 || length
== 0)
816 printf (_(" magic : %08x (%s)\n"), magic
,
817 bfd_mach_o_get_name (bfd_mach_o_cs_magic
, magic
));
818 printf (_(" length: %08x\n"), length
);
821 printf (_(" [bad block length]\n"));
827 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE
:
828 dump_code_signature_superblob (abfd
, buf
, length
);
830 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY
:
831 dump_code_signature_codedirectory (abfd
, buf
, length
);
834 hexdump (0, length
- 8, buf
+ 8);
841 dump_code_signature (bfd
*abfd
, bfd_mach_o_linkedit_command
*cmd
)
843 unsigned char *buf
= xmalloc (cmd
->datasize
);
846 if (bfd_seek (abfd
, cmd
->dataoff
, SEEK_SET
) != 0
847 || bfd_bread (buf
, cmd
->datasize
, abfd
) != cmd
->datasize
)
849 non_fatal (_("cannot read code signature data"));
853 for (off
= 0; off
< cmd
->datasize
;)
857 len
= dump_code_signature_blob (abfd
, buf
+ off
, cmd
->datasize
- off
);
867 dump_segment_split_info (bfd
*abfd
, bfd_mach_o_linkedit_command
*cmd
)
869 unsigned char *buf
= xmalloc (cmd
->datasize
);
874 if (bfd_seek (abfd
, cmd
->dataoff
, SEEK_SET
) != 0
875 || bfd_bread (buf
, cmd
->datasize
, abfd
) != cmd
->datasize
)
877 non_fatal (_("cannot read segment split info"));
881 if (buf
[cmd
->datasize
- 1] != 0)
883 non_fatal (_("segment split info is not nul terminated"));
891 printf (_(" 32 bit pointers:\n"));
894 printf (_(" 64 bit pointers:\n"));
897 printf (_(" PPC hi-16:\n"));
900 printf (_(" Unhandled location type %u\n"), buf
[0]);
903 for (p
= buf
+ 1; *p
!= 0; p
+= len
)
905 addr
+= read_unsigned_leb128 (abfd
, p
, &len
);
907 bfd_printf_vma (abfd
, addr
);
914 dump_load_command (bfd
*abfd
, bfd_mach_o_load_command
*cmd
,
917 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
918 const char *cmd_name
;
920 cmd_name
= bfd_mach_o_get_name_or_null
921 (bfd_mach_o_load_command_name
, cmd
->type
);
922 printf ("Load command ");
923 if (cmd_name
== NULL
)
924 printf ("0x%02x:", cmd
->type
);
926 printf ("%s:", cmd_name
);
930 case BFD_MACH_O_LC_SEGMENT
:
931 case BFD_MACH_O_LC_SEGMENT_64
:
932 dump_segment (abfd
, cmd
);
934 case BFD_MACH_O_LC_UUID
:
936 bfd_mach_o_uuid_command
*uuid
= &cmd
->command
.uuid
;
939 for (j
= 0; j
< sizeof (uuid
->uuid
); j
++)
940 printf (" %02x", uuid
->uuid
[j
]);
944 case BFD_MACH_O_LC_LOAD_DYLIB
:
945 case BFD_MACH_O_LC_LAZY_LOAD_DYLIB
:
946 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB
:
947 case BFD_MACH_O_LC_REEXPORT_DYLIB
:
948 case BFD_MACH_O_LC_ID_DYLIB
:
949 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB
:
951 bfd_mach_o_dylib_command
*dylib
= &cmd
->command
.dylib
;
952 printf (" %s\n", dylib
->name_str
);
953 printf (" time stamp: 0x%08lx\n",
955 printf (" current version: 0x%08lx\n",
956 dylib
->current_version
);
957 printf (" comptibility version: 0x%08lx\n",
958 dylib
->compatibility_version
);
961 case BFD_MACH_O_LC_LOAD_DYLINKER
:
962 case BFD_MACH_O_LC_ID_DYLINKER
:
963 printf (" %s\n", cmd
->command
.dylinker
.name_str
);
965 case BFD_MACH_O_LC_SYMTAB
:
967 bfd_mach_o_symtab_command
*symtab
= &cmd
->command
.symtab
;
969 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
970 symtab
->symoff
, symtab
->nsyms
,
971 symtab
->symoff
+ symtab
->nsyms
972 * (mdata
->header
.version
== 2
973 ? BFD_MACH_O_NLIST_64_SIZE
: BFD_MACH_O_NLIST_SIZE
));
974 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
975 symtab
->stroff
, symtab
->strsize
,
976 symtab
->stroff
+ symtab
->strsize
);
979 case BFD_MACH_O_LC_DYSYMTAB
:
981 dump_dysymtab (abfd
, cmd
, verbose
);
983 case BFD_MACH_O_LC_LOADFVMLIB
:
984 case BFD_MACH_O_LC_IDFVMLIB
:
986 bfd_mach_o_fvmlib_command
*fvmlib
= &cmd
->command
.fvmlib
;
987 printf (" %s\n", fvmlib
->name_str
);
988 printf (" minor version: 0x%08x\n", fvmlib
->minor_version
);
989 printf (" header address: 0x%08x\n", fvmlib
->header_addr
);
992 case BFD_MACH_O_LC_CODE_SIGNATURE
:
993 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
:
994 case BFD_MACH_O_LC_FUNCTION_STARTS
:
996 bfd_mach_o_linkedit_command
*linkedit
= &cmd
->command
.linkedit
;
999 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
1000 linkedit
->dataoff
, linkedit
->datasize
,
1001 linkedit
->dataoff
+ linkedit
->datasize
);
1003 if (verbose
&& cmd
->type
== BFD_MACH_O_LC_CODE_SIGNATURE
)
1004 dump_code_signature (abfd
, linkedit
);
1005 else if (verbose
&& cmd
->type
== BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
)
1006 dump_segment_split_info (abfd
, linkedit
);
1009 case BFD_MACH_O_LC_SUB_FRAMEWORK
:
1010 case BFD_MACH_O_LC_SUB_UMBRELLA
:
1011 case BFD_MACH_O_LC_SUB_LIBRARY
:
1012 case BFD_MACH_O_LC_SUB_CLIENT
:
1013 case BFD_MACH_O_LC_RPATH
:
1015 bfd_mach_o_str_command
*str
= &cmd
->command
.str
;
1016 printf (" %s\n", str
->str
);
1019 case BFD_MACH_O_LC_THREAD
:
1020 case BFD_MACH_O_LC_UNIXTHREAD
:
1021 dump_thread (abfd
, cmd
);
1023 case BFD_MACH_O_LC_ENCRYPTION_INFO
:
1025 bfd_mach_o_encryption_info_command
*cryp
=
1026 &cmd
->command
.encryption_info
;
1029 " cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1031 cryp
->cryptoff
, cryp
->cryptsize
,
1032 cryp
->cryptoff
+ cryp
->cryptsize
,
1036 case BFD_MACH_O_LC_DYLD_INFO
:
1038 dump_dyld_info (abfd
, cmd
);
1040 case BFD_MACH_O_LC_VERSION_MIN_MACOSX
:
1041 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS
:
1043 bfd_mach_o_version_min_command
*ver
= &cmd
->command
.version_min
;
1045 printf (" %u.%u.%u\n", ver
->rel
, ver
->maj
, ver
->min
);
1048 case BFD_MACH_O_LC_SOURCE_VERSION
:
1050 bfd_mach_o_source_version_command
*version
=
1051 &cmd
->command
.source_version
;
1053 " version a.b.c.d.e: %u.%u.%u.%u.%u\n",
1054 version
->a
, version
->b
, version
->c
, version
->d
, version
->e
);
1057 case BFD_MACH_O_LC_MAIN
:
1059 bfd_mach_o_main_command
*entry
= &cmd
->command
.main
;
1062 printf_vma (entry
->entryoff
);
1065 printf_vma (entry
->stacksize
);
1071 printf (" offset: 0x%08lx\n", (unsigned long)cmd
->offset
);
1072 printf (" size: 0x%08lx\n", (unsigned long)cmd
->len
);
1079 dump_load_commands (bfd
*abfd
, unsigned int cmd32
, unsigned int cmd64
)
1081 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1084 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1086 bfd_mach_o_load_command
*cmd
= &mdata
->commands
[i
];
1089 dump_load_command (abfd
, cmd
, FALSE
);
1090 else if (cmd
->type
== cmd32
|| cmd
->type
== cmd64
)
1091 dump_load_command (abfd
, cmd
, TRUE
);
1095 static const char * const unwind_x86_64_regs
[] =
1096 {"", "rbx", "r12", "r13", "r14", "r15", "rbp", "???" };
1098 static const char * const unwind_x86_regs
[] =
1099 {"", "ebx", "ecx", "edx", "edi", "edi", "ebp", "???" };
1101 /* Dump x86 or x86-64 compact unwind encoding. Works for both architecture,
1102 as the encoding is the same (but not register names). */
1105 dump_unwind_encoding_x86 (unsigned int encoding
, unsigned int sz
,
1106 const char * const regs_name
[])
1110 mode
= encoding
& MACH_O_UNWIND_X86_64_MODE_MASK
;
1113 case MACH_O_UNWIND_X86_64_MODE_RBP_FRAME
:
1116 char pfx
= sz
== 8 ? 'R' : 'E';
1118 regs
= encoding
& MACH_O_UNWIND_X86_64_RBP_FRAME_REGSITERS
;
1119 printf (" %cSP frame", pfx
);
1122 unsigned int offset
;
1125 offset
= (encoding
& MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET
) >> 16;
1126 printf (" at %cBP-%u:", pfx
, offset
* sz
);
1127 for (i
= 0; i
< 5; i
++)
1129 unsigned int reg
= (regs
>> (i
* 3)) & 0x7;
1130 if (reg
!= MACH_O_UNWIND_X86_64_REG_NONE
)
1131 printf (" %s", regs_name
[reg
]);
1136 case MACH_O_UNWIND_X86_64_MODE_STACK_IMMD
:
1137 case MACH_O_UNWIND_X86_64_MODE_STACK_IND
:
1139 unsigned int stack_size
;
1140 unsigned int reg_count
;
1141 unsigned int reg_perm
;
1142 unsigned int regs
[6];
1145 printf (" frameless");
1147 (encoding
& MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE
) >> 16;
1149 (encoding
& MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT
) >> 10;
1150 reg_perm
= encoding
& MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION
;
1152 if (mode
== MACH_O_UNWIND_X86_64_MODE_STACK_IMMD
)
1153 printf (" size: 0x%03x", stack_size
* sz
);
1156 unsigned int stack_adj
;
1159 (encoding
& MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST
) >> 13;
1160 printf (" size at 0x%03x + 0x%02x", stack_size
, stack_adj
);
1162 /* Registers are coded using arithmetic compression: the register
1163 is indexed in range 0-6, the second in range 0-5, the third in
1164 range 0-4, etc. Already used registers are removed in next
1166 #define DO_PERM(R, NUM) R = reg_perm / NUM; reg_perm -= R * NUM
1171 DO_PERM (regs
[0], 120);
1172 DO_PERM (regs
[1], 24);
1173 DO_PERM (regs
[2], 6);
1174 DO_PERM (regs
[3], 2);
1175 DO_PERM (regs
[4], 1);
1176 regs
[5] = 0; /* Not used if reg_count = 5. */
1179 DO_PERM (regs
[0], 60);
1180 DO_PERM (regs
[1], 12);
1181 DO_PERM (regs
[2], 3);
1182 DO_PERM (regs
[3], 1);
1185 DO_PERM (regs
[0], 20);
1186 DO_PERM (regs
[1], 4);
1187 DO_PERM (regs
[2], 1);
1190 DO_PERM (regs
[0], 5);
1191 DO_PERM (regs
[1], 1);
1194 DO_PERM (regs
[0], 1);
1199 printf (" [bad reg count]");
1204 for (i
= reg_count
- 1; i
>= 0; i
--)
1206 unsigned int inc
= 1;
1207 for (j
= 0; j
< i
; j
++)
1208 if (regs
[i
] >= regs
[j
])
1213 for (i
= 0; i
< (int) reg_count
; i
++)
1214 printf (" %s", regs_name
[regs
[i
]]);
1217 case MACH_O_UNWIND_X86_64_MODE_DWARF
:
1218 printf (" Dwarf offset: 0x%06x",
1219 encoding
& MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET
);
1222 printf (" [unhandled mode]");
1228 dump_unwind_encoding (bfd_mach_o_data_struct
*mdata
, unsigned int encoding
)
1230 printf ("0x%08x", encoding
);
1234 switch (mdata
->header
.cputype
)
1236 case BFD_MACH_O_CPU_TYPE_X86_64
:
1237 dump_unwind_encoding_x86 (encoding
, 8, unwind_x86_64_regs
);
1239 case BFD_MACH_O_CPU_TYPE_I386
:
1240 dump_unwind_encoding_x86 (encoding
, 4, unwind_x86_regs
);
1243 printf (" [unhandled cpu]");
1246 if (encoding
& MACH_O_UNWIND_HAS_LSDA
)
1248 if (encoding
& MACH_O_UNWIND_PERSONALITY_MASK
)
1249 printf (" PERS(%u)",
1250 ((encoding
& MACH_O_UNWIND_PERSONALITY_MASK
)
1251 >> MACH_O_UNWIND_PERSONALITY_SHIFT
));
1255 dump_obj_compact_unwind (bfd
*abfd
,
1256 const unsigned char *content
, bfd_size_type size
)
1258 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1259 int is_64
= mdata
->header
.version
== 2;
1260 const unsigned char *p
;
1262 printf (" compact unwind info:\n");
1263 printf (" start length personality lsda\n");
1267 struct mach_o_compact_unwind_64
*e
=
1268 (struct mach_o_compact_unwind_64
*) content
;
1270 for (p
= content
; p
< content
+ size
; p
+= sizeof (*e
))
1272 e
= (struct mach_o_compact_unwind_64
*) p
;
1275 fprintf_vma (stdout
, bfd_get_64 (abfd
, e
->start
));
1276 printf (" %08lx", bfd_get_32 (abfd
, e
->length
));
1278 fprintf_vma (stdout
, bfd_get_64 (abfd
, e
->personnality
));
1280 fprintf_vma (stdout
, bfd_get_64 (abfd
, e
->lsda
));
1283 printf (" encoding: ");
1284 dump_unwind_encoding (mdata
, bfd_get_32 (abfd
, e
->encoding
));
1290 printf ("unhandled\n");
1295 dump_exe_compact_unwind (bfd
*abfd
,
1296 const unsigned char *content
, bfd_size_type size
)
1298 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1299 struct mach_o_unwind_info_header
*hdr
;
1300 unsigned int version
;
1301 unsigned int encodings_offset
;
1302 unsigned int encodings_count
;
1303 unsigned int personality_offset
;
1304 unsigned int personality_count
;
1305 unsigned int index_offset
;
1306 unsigned int index_count
;
1307 struct mach_o_unwind_index_entry
*index_entry
;
1311 printf (" compact unwind info:\n");
1313 hdr
= (struct mach_o_unwind_info_header
*) content
;
1314 if (size
< sizeof (*hdr
))
1316 printf (" truncated!\n");
1320 version
= bfd_get_32 (abfd
, hdr
->version
);
1321 if (version
!= MACH_O_UNWIND_SECTION_VERSION
)
1323 printf (" unknown version: %u\n", version
);
1326 encodings_offset
= bfd_get_32 (abfd
, hdr
->encodings_array_offset
);
1327 encodings_count
= bfd_get_32 (abfd
, hdr
->encodings_array_count
);
1328 personality_offset
= bfd_get_32 (abfd
, hdr
->personality_array_offset
);
1329 personality_count
= bfd_get_32 (abfd
, hdr
->personality_array_count
);
1330 index_offset
= bfd_get_32 (abfd
, hdr
->index_offset
);
1331 index_count
= bfd_get_32 (abfd
, hdr
->index_count
);
1332 printf (" %u encodings, %u personalities, %u level-1 indexes:\n",
1333 encodings_count
, personality_count
, index_count
);
1335 /* Level-1 index. */
1336 printf (" idx function level2 off lsda off\n");
1338 index_entry
= (struct mach_o_unwind_index_entry
*) (content
+ index_offset
);
1339 for (i
= 0; i
< index_count
; i
++)
1341 unsigned int func_offset
;
1342 unsigned int level2_offset
;
1343 unsigned int lsda_offset
;
1345 func_offset
= bfd_get_32 (abfd
, index_entry
->function_offset
);
1346 level2_offset
= bfd_get_32 (abfd
, index_entry
->second_level_offset
);
1347 lsda_offset
= bfd_get_32 (abfd
, index_entry
->lsda_index_offset
);
1348 printf (" %3u 0x%08x 0x%08x 0x%08x\n",
1349 i
, func_offset
, level2_offset
, lsda_offset
);
1353 /* Level-1 index. */
1354 index_entry
= (struct mach_o_unwind_index_entry
*) (content
+ index_offset
);
1355 for (i
= 0; i
< index_count
; i
++)
1357 unsigned int func_offset
;
1358 unsigned int level2_offset
;
1359 const unsigned char *level2
;
1362 if (i
== index_count
- 1)
1365 func_offset
= bfd_get_32 (abfd
, index_entry
->function_offset
);
1366 level2_offset
= bfd_get_32 (abfd
, index_entry
->second_level_offset
);
1368 level2
= content
+ level2_offset
;
1369 kind
= bfd_get_32 (abfd
, level2
);
1372 case MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED
:
1374 struct mach_o_unwind_compressed_second_level_page_header
*l2
;
1375 unsigned int entry_offset
;
1376 unsigned int entry_count
;
1377 unsigned int l2_encodings_offset
;
1378 unsigned int l2_encodings_count
;
1379 const unsigned char *en
;
1382 l2
= (struct mach_o_unwind_compressed_second_level_page_header
*)
1384 entry_offset
= bfd_get_16 (abfd
, l2
->entry_page_offset
);
1385 entry_count
= bfd_get_16 (abfd
, l2
->entry_count
);
1386 l2_encodings_offset
= bfd_get_16 (abfd
, l2
->encodings_offset
);
1387 l2_encodings_count
= bfd_get_16 (abfd
, l2
->encodings_count
);
1389 printf (" index %2u: compressed second level: "
1390 "%u entries, %u encodings (at 0x%08x)\n",
1391 i
, entry_count
, l2_encodings_count
, l2_encodings_offset
);
1392 printf (" # function eidx encoding\n");
1394 en
= level2
+ entry_offset
;
1395 for (j
= 0; j
< entry_count
; j
++)
1398 unsigned int en_func
;
1399 unsigned int enc_idx
;
1400 unsigned int encoding
;
1401 const unsigned char *enc_addr
;
1403 entry
= bfd_get_32 (abfd
, en
);
1405 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry
);
1407 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry
);
1408 if (enc_idx
< encodings_count
)
1409 enc_addr
= content
+ encodings_offset
1412 enc_addr
= level2
+ l2_encodings_offset
1413 + 4 * (enc_idx
- encodings_count
);
1414 encoding
= bfd_get_32 (abfd
, enc_addr
);
1416 printf (" %-4u 0x%08x [%3u] ", j
,
1417 func_offset
+ en_func
, enc_idx
);
1418 dump_unwind_encoding (mdata
, encoding
);
1426 case MACH_O_UNWIND_SECOND_LEVEL_REGULAR
:
1428 struct mach_o_unwind_regular_second_level_page_header
*l2
;
1429 struct mach_o_unwind_regular_second_level_entry
*en
;
1430 unsigned int entry_offset
;
1431 unsigned int entry_count
;
1434 l2
= (struct mach_o_unwind_regular_second_level_page_header
*)
1437 entry_offset
= bfd_get_16 (abfd
, l2
->entry_page_offset
);
1438 entry_count
= bfd_get_16 (abfd
, l2
->entry_count
);
1439 printf (" index %2u: regular level 2 at 0x%04x, %u entries\n",
1440 i
, entry_offset
, entry_count
);
1441 printf (" # function encoding\n");
1443 en
= (struct mach_o_unwind_regular_second_level_entry
*)
1444 (level2
+ entry_offset
);
1445 for (j
= 0; j
< entry_count
; j
++)
1447 unsigned int en_func
;
1448 unsigned int encoding
;
1450 en_func
= bfd_get_32 (abfd
, en
->function_offset
);
1451 encoding
= bfd_get_32 (abfd
, en
->encoding
);
1452 printf (" %-4u 0x%08x ", j
, en_func
);
1453 dump_unwind_encoding (mdata
, encoding
);
1461 printf (" index %2u: unhandled second level format (%u)\n",
1467 struct mach_o_unwind_lsda_index_entry
*lsda
;
1468 unsigned int lsda_offset
;
1469 unsigned int next_lsda_offset
;
1470 unsigned int nbr_lsda
;
1473 lsda_offset
= bfd_get_32 (abfd
, index_entry
->lsda_index_offset
);
1474 next_lsda_offset
= bfd_get_32 (abfd
, index_entry
[1].lsda_index_offset
);
1475 lsda
= (struct mach_o_unwind_lsda_index_entry
*)
1476 (content
+ lsda_offset
);
1477 nbr_lsda
= (next_lsda_offset
- lsda_offset
) / sizeof (*lsda
);
1478 for (j
= 0; j
< nbr_lsda
; j
++)
1480 printf (" lsda %-3u: function 0x%08x lsda 0x%08x\n",
1481 j
, (unsigned int) bfd_get_32 (abfd
, lsda
->function_offset
),
1482 (unsigned int) bfd_get_32 (abfd
, lsda
->lsda_offset
));
1491 dump_section_content (bfd
*abfd
,
1492 const char *segname
, const char *sectname
,
1493 void (*dump
)(bfd
*, const unsigned char*, bfd_size_type
))
1495 bfd_mach_o_data_struct
*mdata
= bfd_mach_o_get_data (abfd
);
1498 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1500 bfd_mach_o_load_command
*cmd
= &mdata
->commands
[i
];
1501 if (cmd
->type
== BFD_MACH_O_LC_SEGMENT
1502 || cmd
->type
== BFD_MACH_O_LC_SEGMENT_64
)
1504 bfd_mach_o_segment_command
*seg
= &cmd
->command
.segment
;
1505 bfd_mach_o_section
*sec
;
1506 for (sec
= seg
->sect_head
; sec
!= NULL
; sec
= sec
->next
)
1507 if (strcmp (sec
->segname
, segname
) == 0
1508 && strcmp (sec
->sectname
, sectname
) == 0)
1511 asection
*bfdsec
= sec
->bfdsection
;
1512 unsigned char *content
;
1514 size
= bfd_get_section_size (bfdsec
);
1515 content
= (unsigned char *) xmalloc (size
);
1516 bfd_get_section_contents (abfd
, bfdsec
, content
, 0, size
);
1518 (*dump
)(abfd
, content
, size
);
1526 /* Dump ABFD (according to the options[] array). */
1529 mach_o_dump (bfd
*abfd
)
1531 if (options
[OPT_HEADER
].selected
)
1533 if (options
[OPT_SECTION
].selected
)
1534 dump_load_commands (abfd
, BFD_MACH_O_LC_SEGMENT
, BFD_MACH_O_LC_SEGMENT_64
);
1535 if (options
[OPT_MAP
].selected
)
1536 dump_section_map (abfd
);
1537 if (options
[OPT_LOAD
].selected
)
1538 dump_load_commands (abfd
, 0, 0);
1539 if (options
[OPT_DYSYMTAB
].selected
)
1540 dump_load_commands (abfd
, BFD_MACH_O_LC_DYSYMTAB
, 0);
1541 if (options
[OPT_CODESIGN
].selected
)
1542 dump_load_commands (abfd
, BFD_MACH_O_LC_CODE_SIGNATURE
, 0);
1543 if (options
[OPT_SEG_SPLIT_INFO
].selected
)
1544 dump_load_commands (abfd
, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO
, 0);
1545 if (options
[OPT_COMPACT_UNWIND
].selected
)
1547 dump_section_content (abfd
, "__LD", "__compact_unwind",
1548 dump_obj_compact_unwind
);
1549 dump_section_content (abfd
, "__TEXT", "__unwind_info",
1550 dump_exe_compact_unwind
);
1554 /* Vector for Mach-O. */
1556 const struct objdump_private_desc objdump_private_desc_mach_o
=