Update my e-mail address.
[binutils-gdb.git] / binutils / od-macho.c
blobf5d2cf5cde03c8eee3027e47f1ce726c9163967d
1 /* od-macho.c -- dump information about an Mach-O object file.
2 Copyright (C) 2011-2017 Free Software Foundation, Inc.
3 Written by Tristan Gingold, Adacore.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 #include "sysdep.h"
23 #include <stddef.h>
24 #include <time.h>
25 #include "safe-ctype.h"
26 #include "bfd.h"
27 #include "objdump.h"
28 #include "bucomm.h"
29 #include "dwarf.h"
30 #include "bfdlink.h"
31 #include "mach-o.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. */
37 #define OPT_HEADER 0
38 #define OPT_SECTION 1
39 #define OPT_MAP 2
40 #define OPT_LOAD 3
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
48 #define OPT_DYLD_INFO 11
50 /* List of actions. */
51 static struct objdump_private_option options[] =
53 { "header", 0 },
54 { "section", 0 },
55 { "map", 0 },
56 { "load", 0 },
57 { "dysymtab", 0 },
58 { "codesign", 0 },
59 { "seg_split_info", 0 },
60 { "compact_unwind", 0 },
61 { "function_starts", 0 },
62 { "data_in_code", 0 },
63 { "twolevel_hints", 0 },
64 { "dyld_info", 0 },
65 { NULL, 0 }
68 /* Display help. */
70 static void
71 mach_o_help (FILE *stream)
73 fprintf (stream, _("\
74 For Mach-O files:\n\
75 header Display the file header\n\
76 section Display the segments and sections commands\n\
77 map Display the section map\n\
78 load Display the load commands\n\
79 dysymtab Display the dynamic symbol table\n\
80 codesign Display code signature\n\
81 seg_split_info Display segment split info\n\
82 compact_unwind Display compact unwinding info\n\
83 function_starts Display start address of functions\n\
84 data_in_code Display data in code entries\n\
85 twolevel_hints Display the two-level namespace lookup hints table\n\
86 dyld_info Display dyld information\n\
87 "));
90 /* Return TRUE if ABFD is handled. */
92 static int
93 mach_o_filter (bfd *abfd)
95 return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
98 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
100 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
101 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
102 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
103 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
104 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
105 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
106 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
107 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
108 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
109 { "i860", BFD_MACH_O_CPU_TYPE_I860 },
110 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
111 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
112 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
113 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
114 { "arm64", BFD_MACH_O_CPU_TYPE_ARM64 },
115 { NULL, 0}
118 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
120 { "object", BFD_MACH_O_MH_OBJECT },
121 { "execute", BFD_MACH_O_MH_EXECUTE },
122 { "fvmlib", BFD_MACH_O_MH_FVMLIB },
123 { "core", BFD_MACH_O_MH_CORE },
124 { "preload", BFD_MACH_O_MH_PRELOAD },
125 { "dylib", BFD_MACH_O_MH_DYLIB },
126 { "dylinker", BFD_MACH_O_MH_DYLINKER },
127 { "bundle", BFD_MACH_O_MH_BUNDLE },
128 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
129 { "dym", BFD_MACH_O_MH_DSYM },
130 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
131 { NULL, 0}
134 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
136 { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
137 { "incrlink", BFD_MACH_O_MH_INCRLINK },
138 { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
139 { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
140 { "prebound", BFD_MACH_O_MH_PREBOUND },
141 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
142 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
143 { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
144 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
145 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
146 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
147 { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
148 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
149 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
150 { "canonical", BFD_MACH_O_MH_CANONICAL },
151 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
152 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
153 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
154 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
155 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
156 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
157 { "pie", BFD_MACH_O_MH_PIE },
158 { "dead_strippable_dylib", BFD_MACH_O_MH_DEAD_STRIPPABLE_DYLIB },
159 { "has_tlv", BFD_MACH_O_MH_HAS_TLV_DESCRIPTORS },
160 { "no_heap_execution", BFD_MACH_O_MH_NO_HEAP_EXECUTION },
161 { "app_extension_safe", BFD_MACH_O_MH_APP_EXTENSION_SAFE },
162 { NULL, 0}
165 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
167 { "segment", BFD_MACH_O_LC_SEGMENT},
168 { "symtab", BFD_MACH_O_LC_SYMTAB},
169 { "symseg", BFD_MACH_O_LC_SYMSEG},
170 { "thread", BFD_MACH_O_LC_THREAD},
171 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
172 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
173 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
174 { "ident", BFD_MACH_O_LC_IDENT},
175 { "fvmfile", BFD_MACH_O_LC_FVMFILE},
176 { "prepage", BFD_MACH_O_LC_PREPAGE},
177 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
178 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
179 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
180 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
181 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
182 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
183 { "routines", BFD_MACH_O_LC_ROUTINES},
184 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
185 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
186 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
187 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
188 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
189 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
190 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
191 { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
192 { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
193 { "uuid", BFD_MACH_O_LC_UUID},
194 { "rpath", BFD_MACH_O_LC_RPATH},
195 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
196 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
197 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
198 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
199 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
200 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
201 { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
202 { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
203 { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
204 { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
205 { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
206 { "main", BFD_MACH_O_LC_MAIN},
207 { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE},
208 { "source_version", BFD_MACH_O_LC_SOURCE_VERSION},
209 { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS},
210 { "encryption_info_64", BFD_MACH_O_LC_ENCRYPTION_INFO_64},
211 { "linker_options", BFD_MACH_O_LC_LINKER_OPTIONS},
212 { "linker_optimization_hint", BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT},
213 { NULL, 0}
216 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
218 { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32},
219 { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32},
220 { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32},
221 { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64},
222 { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64},
223 { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64},
224 { "thread_state", BFD_MACH_O_x86_THREAD_STATE},
225 { "float_state", BFD_MACH_O_x86_FLOAT_STATE},
226 { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE},
227 { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32},
228 { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64},
229 { "debug_state", BFD_MACH_O_x86_DEBUG_STATE},
230 { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
231 { NULL, 0 }
234 static void
235 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
236 unsigned long val)
238 int first = 1;
240 for (; table->name; table++)
242 if (table->val & val)
244 if (!first)
245 printf ("+");
246 printf ("%s", table->name);
247 val &= ~table->val;
248 first = 0;
251 if (val)
253 if (!first)
254 printf ("+");
255 printf ("0x%lx", val);
256 return;
258 if (first)
259 printf ("-");
262 /* Print a bfd_uint64_t, using a platform independent style. */
264 static void
265 printf_uint64 (bfd_uint64_t v)
267 printf ("0x%08lx%08lx",
268 (unsigned long)((v >> 16) >> 16), (unsigned long)(v & 0xffffffffUL));
271 static const char *
272 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
273 unsigned long val)
275 for (; table->name; table++)
276 if (table->val == val)
277 return table->name;
278 return NULL;
281 static const char *
282 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
284 const char *res = bfd_mach_o_get_name_or_null (table, val);
286 if (res == NULL)
287 return "*UNKNOWN*";
288 else
289 return res;
292 static void
293 dump_header (bfd *abfd)
295 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
296 bfd_mach_o_header *h = &mdata->header;
298 fputs (_("Mach-O header:\n"), stdout);
299 printf (_(" magic : %08lx\n"), h->magic);
300 printf (_(" cputype : %08lx (%s)\n"), h->cputype,
301 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
302 printf (_(" cpusubtype: %08lx\n"), h->cpusubtype);
303 printf (_(" filetype : %08lx (%s)\n"),
304 h->filetype,
305 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
306 printf (_(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
307 printf (_(" sizeofcmds: %08lx (%lu)\n"), h->sizeofcmds, h->sizeofcmds);
308 printf (_(" flags : %08lx ("), h->flags);
309 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
310 fputs (_(")\n"), stdout);
311 printf (_(" reserved : %08x\n"), h->reserved);
312 putchar ('\n');
315 static void
316 disp_segment_prot (unsigned int prot)
318 putchar (prot & BFD_MACH_O_PROT_READ ? 'r' : '-');
319 putchar (prot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
320 putchar (prot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
323 static void
324 dump_section_map (bfd *abfd)
326 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
327 bfd_mach_o_load_command *cmd;
328 unsigned int sec_nbr = 0;
330 fputs (_("Segments and Sections:\n"), stdout);
331 fputs (_(" #: Segment name Section name Address\n"), stdout);
333 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
335 bfd_mach_o_segment_command *seg;
336 bfd_mach_o_section *sec;
338 if (cmd->type != BFD_MACH_O_LC_SEGMENT
339 && cmd->type != BFD_MACH_O_LC_SEGMENT_64)
340 continue;
342 seg = &cmd->command.segment;
344 printf ("[Segment %-16s ", seg->segname);
345 printf_vma (seg->vmaddr);
346 putchar ('-');
347 printf_vma (seg->vmaddr + seg->vmsize - 1);
348 putchar (' ');
349 disp_segment_prot (seg->initprot);
350 printf ("]\n");
352 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
354 printf ("%02u: %-16s %-16s ", ++sec_nbr,
355 sec->segname, sec->sectname);
356 printf_vma (sec->addr);
357 putchar (' ');
358 printf_vma (sec->size);
359 printf (" %08lx\n", sec->flags);
364 static void
365 dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
367 printf (" Section: %-16s %-16s (bfdname: %s)\n",
368 sec->sectname, sec->segname, sec->bfdsection->name);
369 printf (" addr: ");
370 printf_vma (sec->addr);
371 printf (" size: ");
372 printf_vma (sec->size);
373 printf (" offset: ");
374 printf_vma (sec->offset);
375 printf ("\n");
376 printf (" align: %ld", sec->align);
377 printf (" nreloc: %lu reloff: ", sec->nreloc);
378 printf_vma (sec->reloff);
379 printf ("\n");
380 printf (" flags: %08lx (type: %s", sec->flags,
381 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
382 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
383 printf (" attr: ");
384 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
385 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
386 printf (")\n");
387 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
389 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
390 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
391 case BFD_MACH_O_S_SYMBOL_STUBS:
392 printf (" first indirect sym: %lu", sec->reserved1);
393 printf (" (%u entries)",
394 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
395 break;
396 default:
397 printf (" reserved1: 0x%lx", sec->reserved1);
398 break;
400 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
402 case BFD_MACH_O_S_SYMBOL_STUBS:
403 printf (" stub size: %lu", sec->reserved2);
404 break;
405 default:
406 printf (" reserved2: 0x%lx", sec->reserved2);
407 break;
409 printf (" reserved3: 0x%lx\n", sec->reserved3);
412 static void
413 dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
415 bfd_mach_o_segment_command *seg = &cmd->command.segment;
416 bfd_mach_o_section *sec;
418 printf (" name: %16s", *seg->segname ? seg->segname : "*none*");
419 printf (" nsects: %lu", seg->nsects);
420 printf (" flags: %lx", seg->flags);
421 printf (" initprot: ");
422 disp_segment_prot (seg->initprot);
423 printf (" maxprot: ");
424 disp_segment_prot (seg->maxprot);
425 printf ("\n");
426 printf (" vmaddr: ");
427 printf_vma (seg->vmaddr);
428 printf (" vmsize: ");
429 printf_vma (seg->vmsize);
430 printf ("\n");
431 printf (" fileoff: ");
432 printf_vma (seg->fileoff);
433 printf (" filesize: ");
434 printf_vma ((bfd_vma)seg->filesize);
435 printf (" endoff: ");
436 printf_vma ((bfd_vma)(seg->fileoff + seg->filesize));
437 printf ("\n");
438 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
439 dump_section_header (abfd, sec);
442 static void
443 dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose)
445 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
446 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
447 unsigned int i;
449 printf (" local symbols: idx: %10lu num: %-8lu",
450 dysymtab->ilocalsym, dysymtab->nlocalsym);
451 printf (" (nxtidx: %lu)\n",
452 dysymtab->ilocalsym + dysymtab->nlocalsym);
453 printf (" external symbols: idx: %10lu num: %-8lu",
454 dysymtab->iextdefsym, dysymtab->nextdefsym);
455 printf (" (nxtidx: %lu)\n",
456 dysymtab->iextdefsym + dysymtab->nextdefsym);
457 printf (" undefined symbols: idx: %10lu num: %-8lu",
458 dysymtab->iundefsym, dysymtab->nundefsym);
459 printf (" (nxtidx: %lu)\n",
460 dysymtab->iundefsym + dysymtab->nundefsym);
461 printf (" table of content: off: 0x%08lx num: %-8lu",
462 dysymtab->tocoff, dysymtab->ntoc);
463 printf (" (endoff: 0x%08lx)\n",
464 dysymtab->tocoff + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
465 printf (" module table: off: 0x%08lx num: %-8lu",
466 dysymtab->modtaboff, dysymtab->nmodtab);
467 printf (" (endoff: 0x%08lx)\n",
468 dysymtab->modtaboff + dysymtab->nmodtab
469 * (mdata->header.version == 2 ?
470 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
471 printf (" external reference table: off: 0x%08lx num: %-8lu",
472 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
473 printf (" (endoff: 0x%08lx)\n",
474 dysymtab->extrefsymoff
475 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
476 printf (" indirect symbol table: off: 0x%08lx num: %-8lu",
477 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
478 printf (" (endoff: 0x%08lx)\n",
479 dysymtab->indirectsymoff
480 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
481 printf (" external relocation table: off: 0x%08lx num: %-8lu",
482 dysymtab->extreloff, dysymtab->nextrel);
483 printf (" (endoff: 0x%08lx)\n",
484 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
485 printf (" local relocation table: off: 0x%08lx num: %-8lu",
486 dysymtab->locreloff, dysymtab->nlocrel);
487 printf (" (endoff: 0x%08lx)\n",
488 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
490 if (!verbose)
491 return;
493 if (dysymtab->ntoc > 0
494 || dysymtab->nindirectsyms > 0
495 || dysymtab->nextrefsyms > 0)
497 /* Try to read the symbols to display the toc or indirect symbols. */
498 bfd_mach_o_read_symtab_symbols (abfd);
500 else if (dysymtab->nmodtab > 0)
502 /* Try to read the strtab to display modules name. */
503 bfd_mach_o_read_symtab_strtab (abfd);
506 for (i = 0; i < dysymtab->nmodtab; i++)
508 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
509 printf (" module %u:\n", i);
510 printf (" name: %lu", module->module_name_idx);
511 if (mdata->symtab && mdata->symtab->strtab)
512 printf (": %s",
513 mdata->symtab->strtab + module->module_name_idx);
514 printf ("\n");
515 printf (" extdefsym: idx: %8lu num: %lu\n",
516 module->iextdefsym, module->nextdefsym);
517 printf (" refsym: idx: %8lu num: %lu\n",
518 module->irefsym, module->nrefsym);
519 printf (" localsym: idx: %8lu num: %lu\n",
520 module->ilocalsym, module->nlocalsym);
521 printf (" extrel: idx: %8lu num: %lu\n",
522 module->iextrel, module->nextrel);
523 printf (" init: idx: %8u num: %u\n",
524 module->iinit, module->ninit);
525 printf (" term: idx: %8u num: %u\n",
526 module->iterm, module->nterm);
527 printf (" objc_module_info: addr: ");
528 printf_vma (module->objc_module_info_addr);
529 printf (" size: %lu\n", module->objc_module_info_size);
532 if (dysymtab->ntoc > 0)
534 bfd_mach_o_symtab_command *symtab = mdata->symtab;
536 printf (" table of content: (symbol/module)\n");
537 for (i = 0; i < dysymtab->ntoc; i++)
539 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
541 printf (" %4u: ", i);
542 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
544 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
545 printf ("%s (%lu)", name ? name : "*invalid*",
546 toc->symbol_index);
548 else
549 printf ("%lu", toc->symbol_index);
551 printf (" / ");
552 if (symtab && symtab->strtab
553 && toc->module_index < dysymtab->nmodtab)
555 bfd_mach_o_dylib_module *mod;
556 mod = &dysymtab->dylib_module[toc->module_index];
557 printf ("%s (%lu)",
558 symtab->strtab + mod->module_name_idx,
559 toc->module_index);
561 else
562 printf ("%lu", toc->module_index);
564 printf ("\n");
568 if (dysymtab->nindirectsyms != 0)
570 printf (" indirect symbols:\n");
572 for (i = 0; i < mdata->nsects; i++)
574 bfd_mach_o_section *sec = mdata->sections[i];
575 unsigned int j, first, last;
576 bfd_mach_o_symtab_command *symtab = mdata->symtab;
577 bfd_vma addr;
578 bfd_vma entry_size;
580 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
582 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
583 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
584 case BFD_MACH_O_S_SYMBOL_STUBS:
585 first = sec->reserved1;
586 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
587 addr = sec->addr;
588 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
589 printf (" for section %s.%s:\n",
590 sec->segname, sec->sectname);
591 for (j = first; j < last; j++)
593 unsigned int isym = dysymtab->indirect_syms[j];
595 printf (" ");
596 printf_vma (addr);
597 printf (" %5u: 0x%08x", j, isym);
598 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
599 printf (" LOCAL");
600 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
601 printf (" ABSOLUTE");
602 if (symtab && symtab->symbols
603 && isym < symtab->nsyms
604 && symtab->symbols[isym].symbol.name)
605 printf (" %s", symtab->symbols[isym].symbol.name);
606 printf ("\n");
607 addr += entry_size;
609 break;
610 default:
611 break;
615 if (dysymtab->nextrefsyms > 0)
617 bfd_mach_o_symtab_command *symtab = mdata->symtab;
619 printf (" external reference table: (symbol flags)\n");
620 for (i = 0; i < dysymtab->nextrefsyms; i++)
622 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
624 printf (" %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
625 if (symtab && symtab->symbols
626 && ref->isym < symtab->nsyms
627 && symtab->symbols[ref->isym].symbol.name)
628 printf (" %s", symtab->symbols[ref->isym].symbol.name);
629 printf ("\n");
635 static bfd_boolean
636 load_and_dump (bfd *abfd, ufile_ptr off, unsigned int len,
637 void (*dump)(bfd *abfd, unsigned char *buf, unsigned int len,
638 ufile_ptr off))
640 unsigned char *buf;
642 if (len == 0)
643 return TRUE;
645 buf = xmalloc (len);
647 if (bfd_seek (abfd, off, SEEK_SET) == 0
648 && bfd_bread (buf, len, abfd) == len)
649 dump (abfd, buf, len, off);
650 else
651 return FALSE;
653 free (buf);
654 return TRUE;
657 static const bfd_mach_o_xlat_name bfd_mach_o_dyld_rebase_type_name[] =
659 { "pointer", BFD_MACH_O_REBASE_TYPE_POINTER },
660 { "text_abs32", BFD_MACH_O_REBASE_TYPE_TEXT_ABSOLUTE32 },
661 { "text_pcrel32", BFD_MACH_O_REBASE_TYPE_TEXT_PCREL32 },
662 { NULL, 0 }
665 static void
666 dump_dyld_info_rebase (bfd *abfd, unsigned char *buf, unsigned int len,
667 ufile_ptr off ATTRIBUTE_UNUSED)
669 unsigned int i;
670 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
671 unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
673 for (i = 0; i < len; )
675 unsigned char b = buf[i++];
676 unsigned char imm = b & BFD_MACH_O_REBASE_IMMEDIATE_MASK;
677 bfd_vma leb;
678 unsigned int leblen;
680 printf (" [0x%04x] 0x%02x: ", i, b);
681 switch (b & BFD_MACH_O_REBASE_OPCODE_MASK)
683 case BFD_MACH_O_REBASE_OPCODE_DONE:
684 printf ("done\n");
685 return;
686 case BFD_MACH_O_REBASE_OPCODE_SET_TYPE_IMM:
687 printf ("set_type %s\n",
688 bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
689 break;
690 case BFD_MACH_O_REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
691 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
692 printf ("set segment: %u and offset: 0x%08x\n",
693 imm, (unsigned) leb);
694 i += leblen;
695 break;
696 case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_ULEB:
697 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
698 printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
699 i += leblen;
700 break;
701 case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
702 printf ("add addr imm scaled: %u\n", imm * ptrsize);
703 break;
704 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_IMM_TIMES:
705 printf ("rebase imm times: %u\n", imm);
706 break;
707 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
708 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
709 printf ("rebase uleb times: %u\n", (unsigned) leb);
710 i += leblen;
711 break;
712 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
713 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
714 printf ("rebase add addr uleb: %u\n", (unsigned) leb);
715 i += leblen;
716 break;
717 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
718 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
719 printf ("rebase uleb times (%u)", (unsigned) leb);
720 i += leblen;
721 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
722 printf (" skipping uleb (%u)\n", (unsigned) leb);
723 i += leblen;
724 break;
725 default:
726 printf ("unknown\n");
727 return;
730 printf (" rebase commands without end!\n");
733 static void
734 dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len,
735 ufile_ptr off ATTRIBUTE_UNUSED)
737 unsigned int i;
738 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
739 unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
741 for (i = 0; i < len; )
743 unsigned char b = buf[i++];
744 unsigned char imm = b & BFD_MACH_O_BIND_IMMEDIATE_MASK;
745 bfd_vma leb;
746 unsigned int leblen;
748 printf (" [0x%04x] 0x%02x: ", i, b);
749 switch (b & BFD_MACH_O_BIND_OPCODE_MASK)
751 case BFD_MACH_O_BIND_OPCODE_DONE:
752 printf ("done\n");
753 return;
754 case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
755 printf ("set dylib ordinal imm: %u\n", imm);
756 break;
757 case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
758 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
759 printf ("set dylib ordinal uleb: %u\n", imm);
760 i += leblen;
761 break;
762 case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
763 imm = (imm != 0) ? imm | BFD_MACH_O_BIND_OPCODE_MASK : imm;
764 printf ("set dylib special imm: %d\n", imm);
765 break;
766 case BFD_MACH_O_BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
767 printf ("set symbol trailing flags imm: 0x%02x, ", imm);
768 for (; i < len && buf[i] != 0; i++)
769 putchar (buf[i] >= ' ' && buf[i] < 0x7f ? buf[i] : '?');
770 putchar ('\n');
771 i++;
772 break;
773 case BFD_MACH_O_BIND_OPCODE_SET_TYPE_IMM:
774 /* Kludge: use the same table as rebase type. */
775 printf ("set_type %s\n",
776 bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
777 break;
778 case BFD_MACH_O_BIND_OPCODE_SET_ADDEND_SLEB:
780 bfd_signed_vma svma;
781 svma = read_leb128 (buf + i, &leblen, 0, buf + len);
782 printf ("set addend sleb: 0x%08x\n", (unsigned) svma);
783 i += leblen;
785 break;
786 case BFD_MACH_O_BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
787 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
788 printf ("set segment: %u and offset: 0x%08x\n",
789 imm, (unsigned) leb);
790 i += leblen;
791 break;
792 case BFD_MACH_O_BIND_OPCODE_ADD_ADDR_ULEB:
793 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
794 printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
795 i += leblen;
796 break;
797 case BFD_MACH_O_BIND_OPCODE_DO_BIND:
798 printf ("do bind\n");
799 break;
800 case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
801 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
802 printf ("do bind add addr uleb: 0x%08x\n", (unsigned) leb);
803 i += leblen;
804 break;
805 case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
806 printf ("do bind add addr imm scaled: %u\n", imm * ptrsize);
807 break;
808 case BFD_MACH_O_BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
809 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
810 printf ("do bind uleb times (%u)", (unsigned) leb);
811 i += leblen;
812 leb = read_leb128 (buf + i, &leblen, 0, buf + len);
813 printf (" skipping uleb (%u)\n", (unsigned) leb);
814 i += leblen;
815 break;
816 default:
817 printf ("unknown\n");
818 return;
821 printf (" bind commands without end!\n");
824 struct export_info_data
826 const unsigned char *name;
827 struct export_info_data *next;
830 static void
831 dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
832 unsigned int off, struct export_info_data *parent,
833 struct export_info_data *base)
835 bfd_vma size;
836 unsigned int leblen;
837 unsigned int child_count;
838 unsigned int i;
840 size = read_leb128 (buf + off, &leblen, 0, buf + len);
841 off += leblen;
843 if (size != 0)
845 bfd_vma flags;
846 struct export_info_data *d;
848 flags = read_leb128 (buf + off, &leblen, 0, buf + len);
849 off += leblen;
851 fputs (" ", stdout);
852 switch (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_MASK)
854 case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_REGULAR:
855 putchar ('-');
856 break;
857 case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL:
858 putchar ('T');
859 break;
860 default:
861 putchar ('?');
862 break;
864 putchar ((flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION) ?
865 'W' : '-');
867 if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_REEXPORT)
869 bfd_vma lib;
871 lib = read_leb128 (buf + off, &leblen, 0, buf + len);
872 off += leblen;
874 fputs (" [reexport] ", stdout);
875 for (d = base; d != NULL; d = d->next)
876 printf ("%s", d->name);
878 fputs (" (", stdout);
879 if (buf[off] != 0)
881 fputs ((const char *)buf + off, stdout);
882 putchar (' ');
883 off += strlen ((const char *)buf + off);
885 printf ("from dylib %u)\n", (unsigned) lib);
886 off++;
888 else
890 bfd_vma offset;
891 bfd_vma resolv = 0;
893 offset = read_leb128 (buf + off, &leblen, 0, buf + len);
894 off += leblen;
896 if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
898 resolv = read_leb128 (buf + off, &leblen, 0, buf + len);
899 off += leblen;
902 printf (" 0x%08x ", (unsigned) offset);
903 for (d = base; d != NULL; d = d->next)
904 printf ("%s", d->name);
905 if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
906 printf (" [resolv: 0x%08x]", (unsigned) resolv);
907 printf ("\n");
911 child_count = read_leb128 (buf + off, &leblen, 0, buf + len);
912 off += leblen;
914 for (i = 0; i < child_count; i++)
916 struct export_info_data sub_data;
917 bfd_vma sub_off;
919 sub_data.name = buf + off;
920 sub_data.next = NULL;
921 parent->next = &sub_data;
923 off += strlen ((const char *)buf + off) + 1;
925 sub_off = read_leb128 (buf + off, &leblen, 0, buf + len);
926 off += leblen;
928 dump_dyld_info_export_1 (abfd, buf, len, sub_off, &sub_data, base);
932 static void
933 dump_dyld_info_export (bfd *abfd, unsigned char *buf, unsigned int len,
934 ufile_ptr off ATTRIBUTE_UNUSED)
936 struct export_info_data data;
938 data.name = (const unsigned char *) "";
939 data.next = NULL;
941 printf (" fl offset sym (Flags: Tls Weak)\n");
942 dump_dyld_info_export_1 (abfd, buf, len, 0, &data, &data);
945 static void
946 dump_dyld_info (bfd *abfd, bfd_mach_o_load_command *cmd,
947 bfd_boolean verbose)
949 bfd_mach_o_dyld_info_command *dinfo = &cmd->command.dyld_info;
951 printf (" rebase: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
952 dinfo->rebase_off, dinfo->rebase_size,
953 dinfo->rebase_off + dinfo->rebase_size);
954 printf (" bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
955 dinfo->bind_off, dinfo->bind_size,
956 dinfo->bind_off + dinfo->bind_size);
957 printf (" weak bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
958 dinfo->weak_bind_off, dinfo->weak_bind_size,
959 dinfo->weak_bind_off + dinfo->weak_bind_size);
960 printf (" lazy bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
961 dinfo->lazy_bind_off, dinfo->lazy_bind_size,
962 dinfo->lazy_bind_off + dinfo->lazy_bind_size);
963 printf (" export: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
964 dinfo->export_off, dinfo->export_size,
965 dinfo->export_off + dinfo->export_size);
967 if (!verbose)
968 return;
970 printf (" rebase:\n");
971 if (!load_and_dump (abfd, dinfo->rebase_off, dinfo->rebase_size,
972 dump_dyld_info_rebase))
973 non_fatal (_("cannot read rebase dyld info"));
975 printf (" bind:\n");
976 if (!load_and_dump (abfd, dinfo->bind_off, dinfo->bind_size,
977 dump_dyld_info_bind))
978 non_fatal (_("cannot read bind dyld info"));
980 printf (" weak bind:\n");
981 if (!load_and_dump (abfd, dinfo->weak_bind_off, dinfo->weak_bind_size,
982 dump_dyld_info_bind))
983 non_fatal (_("cannot read weak bind dyld info"));
985 printf (" lazy bind:\n");
986 if (!load_and_dump (abfd, dinfo->lazy_bind_off, dinfo->lazy_bind_size,
987 dump_dyld_info_bind))
988 non_fatal (_("cannot read lazy bind dyld info"));
990 printf (" exported symbols:\n");
991 if (!load_and_dump (abfd, dinfo->export_off, dinfo->export_size,
992 dump_dyld_info_export))
993 non_fatal (_("cannot read export symbols dyld info"));
996 static void
997 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
999 bfd_mach_o_thread_command *thread = &cmd->command.thread;
1000 unsigned int j;
1001 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1002 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1004 printf (" nflavours: %lu\n", thread->nflavours);
1005 for (j = 0; j < thread->nflavours; j++)
1007 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
1008 const bfd_mach_o_xlat_name *name_table;
1010 printf (" %2u: flavour: 0x%08lx", j, flavour->flavour);
1011 switch (mdata->header.cputype)
1013 case BFD_MACH_O_CPU_TYPE_I386:
1014 case BFD_MACH_O_CPU_TYPE_X86_64:
1015 name_table = bfd_mach_o_thread_x86_name;
1016 break;
1017 default:
1018 name_table = NULL;
1019 break;
1021 if (name_table != NULL)
1022 printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
1023 putchar ('\n');
1025 printf (" offset: 0x%08lx size: 0x%08lx\n",
1026 flavour->offset, flavour->size);
1027 if (bed->_bfd_mach_o_print_thread)
1029 char *buf = xmalloc (flavour->size);
1031 if (bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
1032 && bfd_bread (buf, flavour->size, abfd) == flavour->size)
1033 (*bed->_bfd_mach_o_print_thread)(abfd, flavour, stdout, buf);
1035 free (buf);
1040 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic[] =
1042 { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE },
1043 { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT },
1044 { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS },
1045 { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY },
1046 { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS },
1047 { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER },
1048 { NULL, 0 }
1051 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type[] =
1053 { "no-hash", BFD_MACH_O_CS_NO_HASH },
1054 { "sha1", BFD_MACH_O_CS_HASH_SHA1 },
1055 { "sha256", BFD_MACH_O_CS_HASH_SHA256 },
1056 { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256 },
1057 { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512 },
1058 { NULL, 0 }
1061 static unsigned int
1062 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
1064 static void
1065 dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
1066 const unsigned char *buf, unsigned int len)
1068 unsigned int count;
1069 unsigned int i;
1071 if (len < 12)
1073 printf (_(" [bad block length]\n"));
1074 return;
1076 count = bfd_getb32 (buf + 8);
1077 printf (_(" %u index entries:\n"), count);
1078 if (len < 12 + 8 * count)
1080 printf (_(" [bad block length]\n"));
1081 return;
1083 for (i = 0; i < count; i++)
1085 unsigned int type;
1086 unsigned int off;
1088 type = bfd_getb32 (buf + 12 + 8 * i);
1089 off = bfd_getb32 (buf + 12 + 8 * i + 4);
1090 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
1091 i, type, off);
1093 dump_code_signature_blob (abfd, buf + off, len - off);
1097 static void
1098 swap_code_codedirectory_v1_in
1099 (const struct mach_o_codesign_codedirectory_external_v1 *src,
1100 struct mach_o_codesign_codedirectory_v1 *dst)
1102 dst->version = bfd_getb32 (src->version);
1103 dst->flags = bfd_getb32 (src->flags);
1104 dst->hash_offset = bfd_getb32 (src->hash_offset);
1105 dst->ident_offset = bfd_getb32 (src->ident_offset);
1106 dst->nbr_special_slots = bfd_getb32 (src->nbr_special_slots);
1107 dst->nbr_code_slots = bfd_getb32 (src->nbr_code_slots);
1108 dst->code_limit = bfd_getb32 (src->code_limit);
1109 dst->hash_size = src->hash_size[0];
1110 dst->hash_type = src->hash_type[0];
1111 dst->spare1 = src->spare1[0];
1112 dst->page_size = src->page_size[0];
1113 dst->spare2 = bfd_getb32 (src->spare2);
1116 static void
1117 hexdump (unsigned int start, unsigned int len,
1118 const unsigned char *buf)
1120 unsigned int i, j;
1122 for (i = 0; i < len; i += 16)
1124 printf ("%08x:", start + i);
1125 for (j = 0; j < 16; j++)
1127 fputc (j == 8 ? '-' : ' ', stdout);
1128 if (i + j < len)
1129 printf ("%02x", buf[i + j]);
1130 else
1131 fputs (" ", stdout);
1133 fputc (' ', stdout);
1134 for (j = 0; j < 16; j++)
1136 if (i + j < len)
1137 fputc (ISPRINT (buf[i + j]) ? buf[i + j] : '.', stdout);
1138 else
1139 fputc (' ', stdout);
1141 fputc ('\n', stdout);
1145 static void
1146 dump_code_signature_codedirectory (bfd *abfd ATTRIBUTE_UNUSED,
1147 const unsigned char *buf, unsigned int len)
1149 struct mach_o_codesign_codedirectory_v1 cd;
1150 const char *id;
1152 if (len < sizeof (struct mach_o_codesign_codedirectory_external_v1))
1154 printf (_(" [bad block length]\n"));
1155 return;
1158 swap_code_codedirectory_v1_in
1159 ((const struct mach_o_codesign_codedirectory_external_v1 *) (buf + 8), &cd);
1161 printf (_(" version: %08x\n"), cd.version);
1162 printf (_(" flags: %08x\n"), cd.flags);
1163 printf (_(" hash offset: %08x\n"), cd.hash_offset);
1164 id = (const char *) buf + cd.ident_offset;
1165 printf (_(" ident offset: %08x (- %08x)\n"),
1166 cd.ident_offset, cd.ident_offset + (unsigned) strlen (id) + 1);
1167 printf (_(" identity: %s\n"), id);
1168 printf (_(" nbr special slots: %08x (at offset %08x)\n"),
1169 cd.nbr_special_slots,
1170 cd.hash_offset - cd.nbr_special_slots * cd.hash_size);
1171 printf (_(" nbr code slots: %08x\n"), cd.nbr_code_slots);
1172 printf (_(" code limit: %08x\n"), cd.code_limit);
1173 printf (_(" hash size: %02x\n"), cd.hash_size);
1174 printf (_(" hash type: %02x (%s)\n"),
1175 cd.hash_type,
1176 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type, cd.hash_type));
1177 printf (_(" spare1: %02x\n"), cd.spare1);
1178 printf (_(" page size: %02x\n"), cd.page_size);
1179 printf (_(" spare2: %08x\n"), cd.spare2);
1180 if (cd.version >= 0x20100)
1181 printf (_(" scatter offset: %08x\n"),
1182 (unsigned) bfd_getb32 (buf + 44));
1185 static unsigned int
1186 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len)
1188 unsigned int magic;
1189 unsigned int length;
1191 if (len < 8)
1193 printf (_(" [truncated block]\n"));
1194 return 0;
1196 magic = bfd_getb32 (buf);
1197 length = bfd_getb32 (buf + 4);
1198 if (magic == 0 || length == 0)
1199 return 0;
1201 printf (_(" magic : %08x (%s)\n"), magic,
1202 bfd_mach_o_get_name (bfd_mach_o_cs_magic, magic));
1203 printf (_(" length: %08x\n"), length);
1204 if (length > len)
1206 printf (_(" [bad block length]\n"));
1207 return 0;
1210 switch (magic)
1212 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE:
1213 dump_code_signature_superblob (abfd, buf, length);
1214 break;
1215 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY:
1216 dump_code_signature_codedirectory (abfd, buf, length);
1217 break;
1218 default:
1219 hexdump (0, length - 8, buf + 8);
1220 break;
1222 return length;
1225 static void
1226 dump_code_signature (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1228 unsigned char *buf = xmalloc (cmd->datasize);
1229 unsigned int off;
1231 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1232 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1234 non_fatal (_("cannot read code signature data"));
1235 free (buf);
1236 return;
1238 for (off = 0; off < cmd->datasize;)
1240 unsigned int len;
1242 len = dump_code_signature_blob (abfd, buf + off, cmd->datasize - off);
1244 if (len == 0)
1245 break;
1246 off += len;
1248 free (buf);
1251 static void
1252 dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1254 unsigned char *buf = xmalloc (cmd->datasize);
1255 unsigned char *p;
1256 unsigned int len;
1257 bfd_vma addr = 0;
1259 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1260 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1262 non_fatal (_("cannot read segment split info"));
1263 free (buf);
1264 return;
1266 if (buf[cmd->datasize - 1] != 0)
1268 non_fatal (_("segment split info is not nul terminated"));
1269 free (buf);
1270 return;
1273 switch (buf[0])
1275 case 0:
1276 printf (_(" 32 bit pointers:\n"));
1277 break;
1278 case 1:
1279 printf (_(" 64 bit pointers:\n"));
1280 break;
1281 case 2:
1282 printf (_(" PPC hi-16:\n"));
1283 break;
1284 default:
1285 printf (_(" Unhandled location type %u\n"), buf[0]);
1286 break;
1288 for (p = buf + 1; *p != 0; p += len)
1290 addr += read_leb128 (p, &len, 0, buf + cmd->datasize);
1291 fputs (" ", stdout);
1292 bfd_printf_vma (abfd, addr);
1293 putchar ('\n');
1295 free (buf);
1298 static void
1299 dump_function_starts (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1301 unsigned char *buf = xmalloc (cmd->datasize);
1302 unsigned char *end_buf = buf + cmd->datasize;
1303 unsigned char *p;
1304 bfd_vma addr;
1306 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1307 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1309 non_fatal (_("cannot read function starts"));
1310 free (buf);
1311 return;
1314 /* Function starts are delta encoded, starting from the base address. */
1315 addr = bfd_mach_o_get_base_address (abfd);
1317 for (p = buf; ;)
1319 bfd_vma delta = 0;
1320 unsigned int shift = 0;
1322 if (*p == 0 || p == end_buf)
1323 break;
1324 while (1)
1326 unsigned char b = *p++;
1328 delta |= (b & 0x7f) << shift;
1329 if ((b & 0x80) == 0)
1330 break;
1331 if (p == end_buf)
1333 fputs (" [truncated]\n", stdout);
1334 break;
1336 shift += 7;
1339 addr += delta;
1340 fputs (" ", stdout);
1341 bfd_printf_vma (abfd, addr);
1342 putchar ('\n');
1344 free (buf);
1347 static const bfd_mach_o_xlat_name data_in_code_kind_name[] =
1349 { "data", BFD_MACH_O_DICE_KIND_DATA },
1350 { "1 byte jump table", BFD_MACH_O_DICE_JUMP_TABLES8 },
1351 { "2 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES16 },
1352 { "4 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES32 },
1353 { "4 bytes abs jump table", BFD_MACH_O_DICE_ABS_JUMP_TABLES32 },
1354 { NULL, 0 }
1357 static void
1358 dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1360 unsigned char *buf;
1361 unsigned char *p;
1363 if (cmd->datasize == 0)
1365 printf (" no data_in_code entries\n");
1366 return;
1369 buf = xmalloc (cmd->datasize);
1370 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1371 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1373 non_fatal (_("cannot read data_in_code"));
1374 free (buf);
1375 return;
1378 printf (" offset length kind\n");
1379 for (p = buf; p < buf + cmd->datasize; )
1381 struct mach_o_data_in_code_entry_external *dice;
1382 unsigned int offset;
1383 unsigned int length;
1384 unsigned int kind;
1386 dice = (struct mach_o_data_in_code_entry_external *) p;
1388 offset = bfd_get_32 (abfd, dice->offset);
1389 length = bfd_get_16 (abfd, dice->length);
1390 kind = bfd_get_16 (abfd, dice->kind);
1392 printf (" 0x%08x 0x%04x 0x%04x %s\n", offset, length, kind,
1393 bfd_mach_o_get_name (data_in_code_kind_name, kind));
1395 p += sizeof (*dice);
1397 free (buf);
1400 static void
1401 dump_twolevel_hints (bfd *abfd, bfd_mach_o_twolevel_hints_command *cmd)
1403 size_t sz = 4 * cmd->nhints;
1404 unsigned char *buf;
1405 unsigned char *p;
1407 buf = xmalloc (sz);
1408 if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
1409 || bfd_bread (buf, sz, abfd) != sz)
1411 non_fatal (_("cannot read twolevel hints"));
1412 free (buf);
1413 return;
1416 for (p = buf; p < buf + sz; p += 4)
1418 unsigned int v;
1419 unsigned int isub_image;
1420 unsigned int itoc;
1422 v = bfd_get_32 (abfd, p);
1423 if (bfd_big_endian (abfd))
1425 isub_image = (v >> 24) & 0xff;
1426 itoc = v & 0xffffff;
1428 else
1430 isub_image = v & 0xff;
1431 itoc = (v >> 8) & 0xffffff;
1434 printf (" %3u %8u\n", isub_image, itoc);
1436 free (buf);
1439 static void
1440 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
1441 unsigned int idx, bfd_boolean verbose)
1443 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1444 const char *cmd_name;
1446 cmd_name = bfd_mach_o_get_name_or_null
1447 (bfd_mach_o_load_command_name, cmd->type);
1448 printf ("Load command #%-2u (size: %3u, offset: %4u): ",
1449 idx, cmd->len, cmd->offset);
1450 if (cmd_name == NULL)
1451 printf ("0x%02x\n", cmd->type);
1452 else
1453 printf ("%s\n", cmd_name);
1455 switch (cmd->type)
1457 case BFD_MACH_O_LC_SEGMENT:
1458 case BFD_MACH_O_LC_SEGMENT_64:
1459 dump_segment (abfd, cmd);
1460 break;
1461 case BFD_MACH_O_LC_UUID:
1463 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
1464 unsigned int j;
1466 printf (" ");
1467 for (j = 0; j < sizeof (uuid->uuid); j ++)
1468 printf (" %02x", uuid->uuid[j]);
1469 putchar ('\n');
1471 break;
1472 case BFD_MACH_O_LC_LOAD_DYLIB:
1473 case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
1474 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1475 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1476 case BFD_MACH_O_LC_ID_DYLIB:
1477 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
1479 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
1480 printf (" name: %s\n", dylib->name_str);
1481 printf (" time stamp: 0x%08lx\n",
1482 dylib->timestamp);
1483 printf (" current version: 0x%08lx\n",
1484 dylib->current_version);
1485 printf (" comptibility version: 0x%08lx\n",
1486 dylib->compatibility_version);
1488 break;
1489 case BFD_MACH_O_LC_LOAD_DYLINKER:
1490 case BFD_MACH_O_LC_ID_DYLINKER:
1491 printf (" %s\n", cmd->command.dylinker.name_str);
1492 break;
1493 case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
1494 printf (" %s\n", cmd->command.dylinker.name_str);
1495 break;
1496 case BFD_MACH_O_LC_SYMTAB:
1498 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
1499 printf (" symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
1500 symtab->symoff, symtab->nsyms,
1501 symtab->symoff + symtab->nsyms
1502 * (mdata->header.version == 2
1503 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
1504 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
1505 symtab->stroff, symtab->strsize,
1506 symtab->stroff + symtab->strsize);
1507 break;
1509 case BFD_MACH_O_LC_DYSYMTAB:
1510 dump_dysymtab (abfd, cmd, verbose);
1511 break;
1512 case BFD_MACH_O_LC_LOADFVMLIB:
1513 case BFD_MACH_O_LC_IDFVMLIB:
1515 bfd_mach_o_fvmlib_command *fvmlib = &cmd->command.fvmlib;
1516 printf (" fvmlib: %s\n", fvmlib->name_str);
1517 printf (" minor version: 0x%08x\n", fvmlib->minor_version);
1518 printf (" header address: 0x%08x\n", fvmlib->header_addr);
1520 break;
1521 case BFD_MACH_O_LC_CODE_SIGNATURE:
1522 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1523 case BFD_MACH_O_LC_FUNCTION_STARTS:
1524 case BFD_MACH_O_LC_DATA_IN_CODE:
1525 case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
1527 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
1528 printf
1529 (" dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
1530 linkedit->dataoff, linkedit->datasize,
1531 linkedit->dataoff + linkedit->datasize);
1533 if (verbose)
1534 switch (cmd->type)
1536 case BFD_MACH_O_LC_CODE_SIGNATURE:
1537 dump_code_signature (abfd, linkedit);
1538 break;
1539 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1540 dump_segment_split_info (abfd, linkedit);
1541 break;
1542 case BFD_MACH_O_LC_FUNCTION_STARTS:
1543 dump_function_starts (abfd, linkedit);
1544 break;
1545 case BFD_MACH_O_LC_DATA_IN_CODE:
1546 dump_data_in_code (abfd, linkedit);
1547 break;
1548 default:
1549 break;
1552 break;
1553 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1554 case BFD_MACH_O_LC_SUB_UMBRELLA:
1555 case BFD_MACH_O_LC_SUB_LIBRARY:
1556 case BFD_MACH_O_LC_SUB_CLIENT:
1557 case BFD_MACH_O_LC_RPATH:
1559 bfd_mach_o_str_command *strc = &cmd->command.str;
1560 printf (" %s\n", strc->str);
1561 break;
1563 case BFD_MACH_O_LC_THREAD:
1564 case BFD_MACH_O_LC_UNIXTHREAD:
1565 dump_thread (abfd, cmd);
1566 break;
1567 case BFD_MACH_O_LC_ENCRYPTION_INFO:
1569 bfd_mach_o_encryption_info_command *cryp =
1570 &cmd->command.encryption_info;
1571 printf (" cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1572 " cryptid: %u\n",
1573 cryp->cryptoff, cryp->cryptsize,
1574 cryp->cryptoff + cryp->cryptsize,
1575 cryp->cryptid);
1577 break;
1578 case BFD_MACH_O_LC_DYLD_INFO:
1579 dump_dyld_info (abfd, cmd, verbose);
1580 break;
1581 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
1582 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
1584 bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
1586 printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
1588 break;
1589 case BFD_MACH_O_LC_SOURCE_VERSION:
1591 bfd_mach_o_source_version_command *version =
1592 &cmd->command.source_version;
1593 printf (" version a.b.c.d.e: %u.%u.%u.%u.%u\n",
1594 version->a, version->b, version->c, version->d, version->e);
1595 break;
1597 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1599 bfd_mach_o_prebound_dylib_command *pbdy = &cmd->command.prebound_dylib;
1600 unsigned char *lm = pbdy->linked_modules;
1601 unsigned int j;
1602 unsigned int last;
1604 printf (" dylib: %s\n", pbdy->name_str);
1605 printf (" nmodules: %u\n", pbdy->nmodules);
1606 printf (" linked modules (at %u): ",
1607 pbdy->linked_modules_offset - cmd->offset);
1608 last = pbdy->nmodules > 32 ? 32 : pbdy->nmodules;
1609 for (j = 0; j < last; j++)
1610 printf ("%u", (lm[j >> 3] >> (j & 7)) & 1);
1611 if (last < pbdy->nmodules)
1612 printf ("...");
1613 putchar ('\n');
1614 break;
1616 case BFD_MACH_O_LC_PREBIND_CKSUM:
1618 bfd_mach_o_prebind_cksum_command *cksum = &cmd->command.prebind_cksum;
1619 printf (" 0x%08x\n", cksum->cksum);
1620 break;
1622 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1624 bfd_mach_o_twolevel_hints_command *hints =
1625 &cmd->command.twolevel_hints;
1627 printf (" table offset: 0x%08x nbr hints: %u\n",
1628 hints->offset, hints->nhints);
1629 if (verbose)
1630 dump_twolevel_hints (abfd, hints);
1631 break;
1633 case BFD_MACH_O_LC_MAIN:
1635 bfd_mach_o_main_command *entry = &cmd->command.main;
1636 printf (" entry offset: ");
1637 printf_uint64 (entry->entryoff);
1638 printf ("\n"
1639 " stack size: ");
1640 printf_uint64 (entry->stacksize);
1641 printf ("\n");
1642 break;
1644 default:
1645 break;
1647 putchar ('\n');
1650 static void
1651 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
1653 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1654 bfd_mach_o_load_command *cmd;
1655 unsigned int i;
1657 for (cmd = mdata->first_command, i = 0; cmd != NULL; cmd = cmd->next, i++)
1659 if (cmd32 == 0)
1660 dump_load_command (abfd, cmd, i, FALSE);
1661 else if (cmd->type == cmd32 || cmd->type == cmd64)
1662 dump_load_command (abfd, cmd, i, TRUE);
1666 static const char * const unwind_x86_64_regs[] =
1667 {"", "rbx", "r12", "r13", "r14", "r15", "rbp", "???" };
1669 static const char * const unwind_x86_regs[] =
1670 {"", "ebx", "ecx", "edx", "edi", "edi", "ebp", "???" };
1672 /* Dump x86 or x86-64 compact unwind encoding. Works for both architecture,
1673 as the encoding is the same (but not register names). */
1675 static void
1676 dump_unwind_encoding_x86 (unsigned int encoding, unsigned int sz,
1677 const char * const regs_name[])
1679 unsigned int mode;
1681 mode = encoding & MACH_O_UNWIND_X86_64_MODE_MASK;
1682 switch (mode)
1684 case MACH_O_UNWIND_X86_64_MODE_RBP_FRAME:
1686 unsigned int regs;
1687 char pfx = sz == 8 ? 'R' : 'E';
1689 regs = encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_REGSITERS;
1690 printf (" %cSP frame", pfx);
1691 if (regs != 0)
1693 unsigned int offset;
1694 int i;
1696 offset = (encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET) >> 16;
1697 printf (" at %cBP-%u:", pfx, offset * sz);
1698 for (i = 0; i < 5; i++)
1700 unsigned int reg = (regs >> (i * 3)) & 0x7;
1701 if (reg != MACH_O_UNWIND_X86_64_REG_NONE)
1702 printf (" %s", regs_name[reg]);
1706 break;
1707 case MACH_O_UNWIND_X86_64_MODE_STACK_IMMD:
1708 case MACH_O_UNWIND_X86_64_MODE_STACK_IND:
1710 unsigned int stack_size;
1711 unsigned int reg_count;
1712 unsigned int reg_perm;
1713 unsigned int regs[6];
1714 int i, j;
1716 printf (" frameless");
1717 stack_size =
1718 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE) >> 16;
1719 reg_count =
1720 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT) >> 10;
1721 reg_perm = encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION;
1723 if (mode == MACH_O_UNWIND_X86_64_MODE_STACK_IMMD)
1724 printf (" size: 0x%03x", stack_size * sz);
1725 else
1727 unsigned int stack_adj;
1729 stack_adj =
1730 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST) >> 13;
1731 printf (" size at 0x%03x + 0x%02x", stack_size, stack_adj * sz);
1733 /* Registers are coded using arithmetic compression: the register
1734 is indexed in range 0-6, the second in range 0-5, the third in
1735 range 0-4, etc. Already used registers are removed in next
1736 ranges. */
1737 #define DO_PERM(R, NUM) R = reg_perm / NUM; reg_perm -= R * NUM
1738 switch (reg_count)
1740 case 6:
1741 case 5:
1742 DO_PERM (regs[0], 120);
1743 DO_PERM (regs[1], 24);
1744 DO_PERM (regs[2], 6);
1745 DO_PERM (regs[3], 2);
1746 DO_PERM (regs[4], 1);
1747 regs[5] = 0; /* Not used if reg_count = 5. */
1748 break;
1749 case 4:
1750 DO_PERM (regs[0], 60);
1751 DO_PERM (regs[1], 12);
1752 DO_PERM (regs[2], 3);
1753 DO_PERM (regs[3], 1);
1754 break;
1755 case 3:
1756 DO_PERM (regs[0], 20);
1757 DO_PERM (regs[1], 4);
1758 DO_PERM (regs[2], 1);
1759 break;
1760 case 2:
1761 DO_PERM (regs[0], 5);
1762 DO_PERM (regs[1], 1);
1763 break;
1764 case 1:
1765 DO_PERM (regs[0], 1);
1766 break;
1767 case 0:
1768 break;
1769 default:
1770 printf (" [bad reg count]");
1771 return;
1773 #undef DO_PERM
1774 /* Renumber. */
1775 for (i = reg_count - 1; i >= 0; i--)
1777 unsigned int inc = 1;
1778 for (j = 0; j < i; j++)
1779 if (regs[i] >= regs[j])
1780 inc++;
1781 regs[i] += inc;
1783 /* Display. */
1784 for (i = 0; i < (int) reg_count; i++)
1785 printf (" %s", regs_name[regs[i]]);
1787 break;
1788 case MACH_O_UNWIND_X86_64_MODE_DWARF:
1789 printf (" Dwarf offset: 0x%06x",
1790 encoding & MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET);
1791 break;
1792 default:
1793 printf (" [unhandled mode]");
1794 break;
1798 /* Dump arm64 compact unwind entries. */
1800 static void
1801 dump_unwind_encoding_arm64 (unsigned int encoding)
1803 switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1805 case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1806 printf (" frameless");
1807 break;
1808 case MACH_O_UNWIND_ARM64_MODE_DWARF:
1809 printf (" Dwarf offset: 0x%06x",
1810 encoding & MACH_O_UNWIND_ARM64_DWARF_SECTION_OFFSET);
1811 return;
1812 case MACH_O_UNWIND_ARM64_MODE_FRAME:
1813 printf (" frame");
1814 break;
1815 default:
1816 printf (" [unhandled mode]");
1817 return;
1819 switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1821 case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1822 case MACH_O_UNWIND_ARM64_MODE_FRAME:
1823 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X19_X20_PAIR)
1824 printf (" x19-x20");
1825 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X21_X22_PAIR)
1826 printf (" x21-x22");
1827 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X23_X24_PAIR)
1828 printf (" x23-x24");
1829 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X25_X26_PAIR)
1830 printf (" x25-x26");
1831 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X27_X28_PAIR)
1832 printf (" x27-x28");
1833 break;
1835 switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1837 case MACH_O_UNWIND_ARM64_MODE_FRAME:
1838 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D8_D9_PAIR)
1839 printf (" d8-d9");
1840 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D10_D11_PAIR)
1841 printf (" d10-d11");
1842 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D12_D13_PAIR)
1843 printf (" d12-d13");
1844 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D14_D15_PAIR)
1845 printf (" d14-d15");
1846 break;
1847 case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1848 printf (" size: %u",
1849 (encoding & MACH_O_UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK) >> 8);
1850 break;
1854 static void
1855 dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding)
1857 printf ("0x%08x", encoding);
1858 if (encoding == 0)
1859 return;
1861 switch (mdata->header.cputype)
1863 case BFD_MACH_O_CPU_TYPE_X86_64:
1864 dump_unwind_encoding_x86 (encoding, 8, unwind_x86_64_regs);
1865 break;
1866 case BFD_MACH_O_CPU_TYPE_I386:
1867 dump_unwind_encoding_x86 (encoding, 4, unwind_x86_regs);
1868 break;
1869 case BFD_MACH_O_CPU_TYPE_ARM64:
1870 dump_unwind_encoding_arm64 (encoding);
1871 break;
1872 default:
1873 printf (" [unhandled cpu]");
1874 break;
1876 if (encoding & MACH_O_UNWIND_HAS_LSDA)
1877 printf (" LSDA");
1878 if (encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1879 printf (" PERS(%u)",
1880 ((encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1881 >> MACH_O_UNWIND_PERSONALITY_SHIFT));
1884 static void
1885 dump_obj_compact_unwind (bfd *abfd,
1886 const unsigned char *content, bfd_size_type size)
1888 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1889 int is_64 = mdata->header.version == 2;
1890 const unsigned char *p;
1892 printf ("Compact unwind info:\n");
1893 printf (" start length personality lsda\n");
1895 if (is_64)
1897 struct mach_o_compact_unwind_64 *e =
1898 (struct mach_o_compact_unwind_64 *) content;
1900 for (p = content; p < content + size; p += sizeof (*e))
1902 e = (struct mach_o_compact_unwind_64 *) p;
1904 putchar (' ');
1905 printf_uint64 (bfd_get_64 (abfd, e->start));
1906 printf (" %08lx", bfd_get_32 (abfd, e->length));
1907 putchar (' ');
1908 printf_uint64 (bfd_get_64 (abfd, e->personality));
1909 putchar (' ');
1910 printf_uint64 (bfd_get_64 (abfd, e->lsda));
1911 putchar ('\n');
1913 printf (" encoding: ");
1914 dump_unwind_encoding (mdata, bfd_get_32 (abfd, e->encoding));
1915 putchar ('\n');
1918 else
1920 printf ("unhandled\n");
1924 static void
1925 dump_exe_compact_unwind (bfd *abfd,
1926 const unsigned char *content, bfd_size_type size)
1928 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1929 struct mach_o_unwind_info_header *hdr;
1930 unsigned int version;
1931 unsigned int encodings_offset;
1932 unsigned int encodings_count;
1933 unsigned int personality_offset;
1934 unsigned int personality_count;
1935 unsigned int index_offset;
1936 unsigned int index_count;
1937 struct mach_o_unwind_index_entry *index_entry;
1938 unsigned int i;
1940 /* The header. */
1941 printf ("Compact unwind info:\n");
1943 hdr = (struct mach_o_unwind_info_header *) content;
1944 if (size < sizeof (*hdr))
1946 printf (" truncated!\n");
1947 return;
1950 version = bfd_get_32 (abfd, hdr->version);
1951 if (version != MACH_O_UNWIND_SECTION_VERSION)
1953 printf (" unknown version: %u\n", version);
1954 return;
1956 encodings_offset = bfd_get_32 (abfd, hdr->encodings_array_offset);
1957 encodings_count = bfd_get_32 (abfd, hdr->encodings_array_count);
1958 personality_offset = bfd_get_32 (abfd, hdr->personality_array_offset);
1959 personality_count = bfd_get_32 (abfd, hdr->personality_array_count);
1960 index_offset = bfd_get_32 (abfd, hdr->index_offset);
1961 index_count = bfd_get_32 (abfd, hdr->index_count);
1962 printf (" %u encodings, %u personalities, %u level-1 indexes:\n",
1963 encodings_count, personality_count, index_count);
1965 /* Personality. */
1966 if (personality_count > 0)
1968 const unsigned char *pers = content + personality_offset;
1970 printf (" personalities\n");
1971 for (i = 0; i < personality_count; i++)
1972 printf (" %u: 0x%08x\n", i,
1973 (unsigned) bfd_get_32 (abfd, pers + 4 * i));
1976 /* Level-1 index. */
1977 printf (" idx function level2 off lsda off\n");
1979 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
1980 for (i = 0; i < index_count; i++)
1982 unsigned int func_offset;
1983 unsigned int level2_offset;
1984 unsigned int lsda_offset;
1986 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
1987 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
1988 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
1989 printf (" %3u 0x%08x 0x%08x 0x%08x\n",
1990 i, func_offset, level2_offset, lsda_offset);
1991 index_entry++;
1994 /* Level-1 index. */
1995 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
1996 for (i = 0; i < index_count; i++)
1998 unsigned int func_offset;
1999 unsigned int level2_offset;
2000 const unsigned char *level2;
2001 unsigned int kind;
2003 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
2004 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
2006 /* No level-2 for this index (should be the last index). */
2007 if (level2_offset == 0)
2008 continue;
2010 level2 = content + level2_offset;
2011 kind = bfd_get_32 (abfd, level2);
2012 switch (kind)
2014 case MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED:
2016 struct mach_o_unwind_compressed_second_level_page_header *l2;
2017 unsigned int entry_offset;
2018 unsigned int entry_count;
2019 unsigned int l2_encodings_offset;
2020 unsigned int l2_encodings_count;
2021 const unsigned char *en;
2022 unsigned int j;
2024 l2 = (struct mach_o_unwind_compressed_second_level_page_header *)
2025 level2;
2026 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
2027 entry_count = bfd_get_16 (abfd, l2->entry_count);
2028 l2_encodings_offset = bfd_get_16 (abfd, l2->encodings_offset);
2029 l2_encodings_count = bfd_get_16 (abfd, l2->encodings_count);
2031 printf (" index %2u: compressed second level: "
2032 "%u entries, %u encodings (at 0x%08x)\n",
2033 i, entry_count, l2_encodings_count, l2_encodings_offset);
2034 printf (" # function eidx encoding\n");
2036 en = level2 + entry_offset;
2037 for (j = 0; j < entry_count; j++)
2039 unsigned int entry;
2040 unsigned int en_func;
2041 unsigned int enc_idx;
2042 unsigned int encoding;
2043 const unsigned char *enc_addr;
2045 entry = bfd_get_32 (abfd, en);
2046 en_func =
2047 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry);
2048 enc_idx =
2049 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry);
2050 if (enc_idx < encodings_count)
2051 enc_addr = content + encodings_offset
2052 + 4 * enc_idx;
2053 else
2054 enc_addr = level2 + l2_encodings_offset
2055 + 4 * (enc_idx - encodings_count);
2056 encoding = bfd_get_32 (abfd, enc_addr);
2058 printf (" %4u 0x%08x [%3u] ", j,
2059 func_offset + en_func, enc_idx);
2060 dump_unwind_encoding (mdata, encoding);
2061 putchar ('\n');
2063 en += 4;
2066 break;
2068 case MACH_O_UNWIND_SECOND_LEVEL_REGULAR:
2070 struct mach_o_unwind_regular_second_level_page_header *l2;
2071 struct mach_o_unwind_regular_second_level_entry *en;
2072 unsigned int entry_offset;
2073 unsigned int entry_count;
2074 unsigned int j;
2076 l2 = (struct mach_o_unwind_regular_second_level_page_header *)
2077 level2;
2079 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
2080 entry_count = bfd_get_16 (abfd, l2->entry_count);
2081 printf (" index %2u: regular level 2 at 0x%04x, %u entries\n",
2082 i, entry_offset, entry_count);
2083 printf (" # function encoding\n");
2085 en = (struct mach_o_unwind_regular_second_level_entry *)
2086 (level2 + entry_offset);
2087 for (j = 0; j < entry_count; j++)
2089 unsigned int en_func;
2090 unsigned int encoding;
2092 en_func = bfd_get_32 (abfd, en->function_offset);
2093 encoding = bfd_get_32 (abfd, en->encoding);
2094 printf (" %-4u 0x%08x ", j, en_func);
2095 dump_unwind_encoding (mdata, encoding);
2096 putchar ('\n');
2097 en++;
2100 break;
2102 default:
2103 printf (" index %2u: unhandled second level format (%u)\n",
2104 i, kind);
2105 break;
2109 struct mach_o_unwind_lsda_index_entry *lsda;
2110 unsigned int lsda_offset;
2111 unsigned int next_lsda_offset;
2112 unsigned int nbr_lsda;
2113 unsigned int j;
2115 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
2116 next_lsda_offset = bfd_get_32 (abfd, index_entry[1].lsda_index_offset);
2117 lsda = (struct mach_o_unwind_lsda_index_entry *)
2118 (content + lsda_offset);
2119 nbr_lsda = (next_lsda_offset - lsda_offset) / sizeof (*lsda);
2120 for (j = 0; j < nbr_lsda; j++)
2122 printf (" lsda %3u: function 0x%08x lsda 0x%08x\n",
2123 j, (unsigned int) bfd_get_32 (abfd, lsda->function_offset),
2124 (unsigned int) bfd_get_32 (abfd, lsda->lsda_offset));
2125 lsda++;
2128 index_entry++;
2132 static void
2133 dump_section_content (bfd *abfd,
2134 const char *segname, const char *sectname,
2135 void (*dump)(bfd*, const unsigned char*, bfd_size_type))
2137 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2138 bfd_mach_o_load_command *cmd;
2140 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
2142 if (cmd->type == BFD_MACH_O_LC_SEGMENT
2143 || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
2145 bfd_mach_o_segment_command *seg = &cmd->command.segment;
2146 bfd_mach_o_section *sec;
2147 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
2148 if (strcmp (sec->segname, segname) == 0
2149 && strcmp (sec->sectname, sectname) == 0)
2151 bfd_size_type size;
2152 asection *bfdsec = sec->bfdsection;
2153 unsigned char *content;
2155 size = bfd_get_section_size (bfdsec);
2156 content = (unsigned char *) xmalloc (size);
2157 bfd_get_section_contents (abfd, bfdsec, content, 0, size);
2159 (*dump)(abfd, content, size);
2161 free (content);
2167 /* Dump ABFD (according to the options[] array). */
2169 static void
2170 mach_o_dump (bfd *abfd)
2172 if (options[OPT_HEADER].selected)
2173 dump_header (abfd);
2174 if (options[OPT_SECTION].selected)
2175 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT, BFD_MACH_O_LC_SEGMENT_64);
2176 if (options[OPT_MAP].selected)
2177 dump_section_map (abfd);
2178 if (options[OPT_LOAD].selected)
2179 dump_load_commands (abfd, 0, 0);
2180 if (options[OPT_DYSYMTAB].selected)
2181 dump_load_commands (abfd, BFD_MACH_O_LC_DYSYMTAB, 0);
2182 if (options[OPT_CODESIGN].selected)
2183 dump_load_commands (abfd, BFD_MACH_O_LC_CODE_SIGNATURE, 0);
2184 if (options[OPT_SEG_SPLIT_INFO].selected)
2185 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO, 0);
2186 if (options[OPT_FUNCTION_STARTS].selected)
2187 dump_load_commands (abfd, BFD_MACH_O_LC_FUNCTION_STARTS, 0);
2188 if (options[OPT_DATA_IN_CODE].selected)
2189 dump_load_commands (abfd, BFD_MACH_O_LC_DATA_IN_CODE, 0);
2190 if (options[OPT_TWOLEVEL_HINTS].selected)
2191 dump_load_commands (abfd, BFD_MACH_O_LC_TWOLEVEL_HINTS, 0);
2192 if (options[OPT_COMPACT_UNWIND].selected)
2194 dump_section_content (abfd, "__LD", "__compact_unwind",
2195 dump_obj_compact_unwind);
2196 dump_section_content (abfd, "__TEXT", "__unwind_info",
2197 dump_exe_compact_unwind);
2199 if (options[OPT_DYLD_INFO].selected)
2200 dump_load_commands (abfd, BFD_MACH_O_LC_DYLD_INFO, 0);
2203 /* Vector for Mach-O. */
2205 const struct objdump_private_desc objdump_private_desc_mach_o =
2207 mach_o_help,
2208 mach_o_filter,
2209 mach_o_dump,
2210 options