Automatic date update in version.in
[binutils-gdb.git] / binutils / od-macho.c
blob710dfc33db906a08db83b24c6d6cef9d67f30751
1 /* od-macho.c -- dump information about an Mach-O object file.
2 Copyright (C) 2011-2022 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 "elfcomm.h"
30 #include "dwarf.h"
31 #include "bfdlink.h"
32 #include "mach-o.h"
33 #include "mach-o/external.h"
34 #include "mach-o/codesign.h"
35 #include "mach-o/unwind.h"
37 /* Index of the options in the options[] array. */
38 #define OPT_HEADER 0
39 #define OPT_SECTION 1
40 #define OPT_MAP 2
41 #define OPT_LOAD 3
42 #define OPT_DYSYMTAB 4
43 #define OPT_CODESIGN 5
44 #define OPT_SEG_SPLIT_INFO 6
45 #define OPT_COMPACT_UNWIND 7
46 #define OPT_FUNCTION_STARTS 8
47 #define OPT_DATA_IN_CODE 9
48 #define OPT_TWOLEVEL_HINTS 10
49 #define OPT_DYLD_INFO 11
51 /* List of actions. */
52 static struct objdump_private_option options[] =
54 { "header", 0 },
55 { "section", 0 },
56 { "map", 0 },
57 { "load", 0 },
58 { "dysymtab", 0 },
59 { "codesign", 0 },
60 { "seg_split_info", 0 },
61 { "compact_unwind", 0 },
62 { "function_starts", 0 },
63 { "data_in_code", 0 },
64 { "twolevel_hints", 0 },
65 { "dyld_info", 0 },
66 { NULL, 0 }
69 /* Display help. */
71 static void
72 mach_o_help (FILE *stream)
74 fprintf (stream, _("\
75 For Mach-O files:\n\
76 header Display the file header\n\
77 section Display the segments and sections commands\n\
78 map Display the section map\n\
79 load Display the load commands\n\
80 dysymtab Display the dynamic symbol table\n\
81 codesign Display code signature\n\
82 seg_split_info Display segment split info\n\
83 compact_unwind Display compact unwinding info\n\
84 function_starts Display start address of functions\n\
85 data_in_code Display data in code entries\n\
86 twolevel_hints Display the two-level namespace lookup hints table\n\
87 dyld_info Display dyld information\n\
88 "));
91 /* Return TRUE if ABFD is handled. */
93 static int
94 mach_o_filter (bfd *abfd)
96 return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
99 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
101 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
102 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
103 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
104 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
105 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
106 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
107 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
108 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
109 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
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 { "version_min_tvos", BFD_MACH_O_LC_VERSION_MIN_TVOS},
214 { "version_min_watchos", BFD_MACH_O_LC_VERSION_MIN_WATCHOS},
215 { "note", BFD_MACH_O_LC_NOTE},
216 { "build_version", BFD_MACH_O_LC_BUILD_VERSION},
217 { "exports_trie", BFD_MACH_O_LC_DYLD_EXPORTS_TRIE},
218 { "chained_fixups", BFD_MACH_O_LC_DYLD_CHAINED_FIXUPS},
219 { NULL, 0}
222 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
224 { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32},
225 { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32},
226 { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32},
227 { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64},
228 { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64},
229 { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64},
230 { "thread_state", BFD_MACH_O_x86_THREAD_STATE},
231 { "float_state", BFD_MACH_O_x86_FLOAT_STATE},
232 { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE},
233 { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32},
234 { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64},
235 { "debug_state", BFD_MACH_O_x86_DEBUG_STATE},
236 { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
237 { NULL, 0 }
240 static const bfd_mach_o_xlat_name bfd_mach_o_platform_name[] =
242 { "macos", BFD_MACH_O_PLATFORM_MACOS},
243 { "ios", BFD_MACH_O_PLATFORM_IOS},
244 { "tvos", BFD_MACH_O_PLATFORM_TVOS},
245 { "watchos", BFD_MACH_O_PLATFORM_WATCHOS},
246 { "bridgeos", BFD_MACH_O_PLATFORM_BRIDGEOS},
247 { NULL, 0 }
250 static const bfd_mach_o_xlat_name bfd_mach_o_tool_name[] =
252 { "clang", BFD_MACH_O_TOOL_CLANG},
253 { "swift", BFD_MACH_O_TOOL_SWIFT},
254 { "ld", BFD_MACH_O_TOOL_LD},
255 { NULL, 0 }
258 static void
259 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
260 unsigned long val)
262 int first = 1;
264 for (; table->name; table++)
266 if (table->val & val)
268 if (!first)
269 printf ("+");
270 printf ("%s", table->name);
271 val &= ~table->val;
272 first = 0;
275 if (val)
277 if (!first)
278 printf ("+");
279 printf ("0x%lx", val);
280 return;
282 if (first)
283 printf ("-");
286 static const char *
287 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
288 unsigned long val)
290 for (; table->name; table++)
291 if (table->val == val)
292 return table->name;
293 return NULL;
296 static const char *
297 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
299 const char *res = bfd_mach_o_get_name_or_null (table, val);
301 if (res == NULL)
302 return "*UNKNOWN*";
303 else
304 return res;
307 static void
308 dump_header (bfd *abfd)
310 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
311 bfd_mach_o_header *h = &mdata->header;
313 fputs (_("Mach-O header:\n"), stdout);
314 printf (_(" magic : %08lx\n"), h->magic);
315 printf (_(" cputype : %08lx (%s)\n"), h->cputype,
316 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
317 printf (_(" cpusubtype: %08lx\n"), h->cpusubtype);
318 printf (_(" filetype : %08lx (%s)\n"),
319 h->filetype,
320 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
321 printf (_(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
322 printf (_(" sizeofcmds: %08lx (%lu)\n"), h->sizeofcmds, h->sizeofcmds);
323 printf (_(" flags : %08lx ("), h->flags);
324 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
325 fputs (_(")\n"), stdout);
326 printf (_(" reserved : %08x\n"), h->reserved);
327 putchar ('\n');
330 static void
331 disp_segment_prot (unsigned int prot)
333 putchar (prot & BFD_MACH_O_PROT_READ ? 'r' : '-');
334 putchar (prot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
335 putchar (prot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
338 static void
339 dump_section_map (bfd *abfd)
341 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
342 bfd_mach_o_load_command *cmd;
343 unsigned int sec_nbr = 0;
345 fputs (_("Segments and Sections:\n"), stdout);
346 fputs (_(" #: Segment name Section name Address\n"), stdout);
348 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
350 bfd_mach_o_segment_command *seg;
351 bfd_mach_o_section *sec;
353 if (cmd->type != BFD_MACH_O_LC_SEGMENT
354 && cmd->type != BFD_MACH_O_LC_SEGMENT_64)
355 continue;
357 seg = &cmd->command.segment;
359 printf ("[Segment %-16s ", seg->segname);
360 bfd_printf_vma (abfd, seg->vmaddr);
361 putchar ('-');
362 bfd_printf_vma (abfd, seg->vmaddr + seg->vmsize - 1);
363 putchar (' ');
364 disp_segment_prot (seg->initprot);
365 printf ("]\n");
367 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
369 printf ("%02u: %-16s %-16s ", ++sec_nbr,
370 sec->segname, sec->sectname);
371 bfd_printf_vma (abfd, sec->addr);
372 putchar (' ');
373 bfd_printf_vma (abfd, sec->size);
374 printf (" %08lx\n", sec->flags);
379 static void
380 dump_section_header (bfd *abfd, bfd_mach_o_section *sec)
382 printf (" Section: %-16s %-16s (bfdname: %s)\n",
383 sec->sectname, sec->segname, sec->bfdsection->name);
384 printf (" addr: ");
385 bfd_printf_vma (abfd, sec->addr);
386 printf (" size: ");
387 bfd_printf_vma (abfd, sec->size);
388 printf (" offset: ");
389 bfd_printf_vma (abfd, sec->offset);
390 printf ("\n");
391 printf (" align: %ld", sec->align);
392 printf (" nreloc: %lu reloff: ", sec->nreloc);
393 bfd_printf_vma (abfd, sec->reloff);
394 printf ("\n");
395 printf (" flags: %08lx (type: %s", sec->flags,
396 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
397 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
398 printf (" attr: ");
399 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
400 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
401 printf (")\n");
402 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
404 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
405 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
406 case BFD_MACH_O_S_SYMBOL_STUBS:
407 printf (" first indirect sym: %lu", sec->reserved1);
408 printf (" (%u entries)",
409 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
410 break;
411 default:
412 printf (" reserved1: 0x%lx", sec->reserved1);
413 break;
415 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
417 case BFD_MACH_O_S_SYMBOL_STUBS:
418 printf (" stub size: %lu", sec->reserved2);
419 break;
420 default:
421 printf (" reserved2: 0x%lx", sec->reserved2);
422 break;
424 printf (" reserved3: 0x%lx\n", sec->reserved3);
427 static void
428 dump_segment (bfd *abfd, bfd_mach_o_load_command *cmd)
430 bfd_mach_o_segment_command *seg = &cmd->command.segment;
431 bfd_mach_o_section *sec;
433 printf (" name: %16s", *seg->segname ? seg->segname : "*none*");
434 printf (" nsects: %lu", seg->nsects);
435 printf (" flags: %lx", seg->flags);
436 printf (" initprot: ");
437 disp_segment_prot (seg->initprot);
438 printf (" maxprot: ");
439 disp_segment_prot (seg->maxprot);
440 printf ("\n");
441 printf (" vmaddr: ");
442 bfd_printf_vma (abfd, seg->vmaddr);
443 printf (" vmsize: ");
444 bfd_printf_vma (abfd, seg->vmsize);
445 printf ("\n");
446 printf (" fileoff: ");
447 bfd_printf_vma (abfd, seg->fileoff);
448 printf (" filesize: ");
449 bfd_printf_vma (abfd, (bfd_vma) seg->filesize);
450 printf (" endoff: ");
451 bfd_printf_vma (abfd, (bfd_vma) (seg->fileoff + seg->filesize));
452 printf ("\n");
453 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
454 dump_section_header (abfd, sec);
457 static void
458 dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bool verbose)
460 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
461 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
462 unsigned int i;
464 printf (" local symbols: idx: %10lu num: %-8lu",
465 dysymtab->ilocalsym, dysymtab->nlocalsym);
466 printf (" (nxtidx: %lu)\n",
467 dysymtab->ilocalsym + dysymtab->nlocalsym);
468 printf (" external symbols: idx: %10lu num: %-8lu",
469 dysymtab->iextdefsym, dysymtab->nextdefsym);
470 printf (" (nxtidx: %lu)\n",
471 dysymtab->iextdefsym + dysymtab->nextdefsym);
472 printf (" undefined symbols: idx: %10lu num: %-8lu",
473 dysymtab->iundefsym, dysymtab->nundefsym);
474 printf (" (nxtidx: %lu)\n",
475 dysymtab->iundefsym + dysymtab->nundefsym);
476 printf (" table of content: off: 0x%08lx num: %-8lu",
477 dysymtab->tocoff, dysymtab->ntoc);
478 printf (" (endoff: 0x%08lx)\n",
479 dysymtab->tocoff + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
480 printf (" module table: off: 0x%08lx num: %-8lu",
481 dysymtab->modtaboff, dysymtab->nmodtab);
482 printf (" (endoff: 0x%08lx)\n",
483 dysymtab->modtaboff + dysymtab->nmodtab
484 * (mdata->header.version == 2 ?
485 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
486 printf (" external reference table: off: 0x%08lx num: %-8lu",
487 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
488 printf (" (endoff: 0x%08lx)\n",
489 dysymtab->extrefsymoff
490 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
491 printf (" indirect symbol table: off: 0x%08lx num: %-8lu",
492 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
493 printf (" (endoff: 0x%08lx)\n",
494 dysymtab->indirectsymoff
495 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
496 printf (" external relocation table: off: 0x%08lx num: %-8lu",
497 dysymtab->extreloff, dysymtab->nextrel);
498 printf (" (endoff: 0x%08lx)\n",
499 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
500 printf (" local relocation table: off: 0x%08lx num: %-8lu",
501 dysymtab->locreloff, dysymtab->nlocrel);
502 printf (" (endoff: 0x%08lx)\n",
503 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
505 if (!verbose)
506 return;
508 if (dysymtab->ntoc > 0
509 || dysymtab->nindirectsyms > 0
510 || dysymtab->nextrefsyms > 0)
512 /* Try to read the symbols to display the toc or indirect symbols. */
513 bfd_mach_o_read_symtab_symbols (abfd);
515 else if (dysymtab->nmodtab > 0)
517 /* Try to read the strtab to display modules name. */
518 bfd_mach_o_read_symtab_strtab (abfd);
521 for (i = 0; i < dysymtab->nmodtab; i++)
523 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
524 printf (" module %u:\n", i);
525 printf (" name: %lu", module->module_name_idx);
526 if (mdata->symtab && mdata->symtab->strtab)
527 printf (": %s",
528 mdata->symtab->strtab + module->module_name_idx);
529 printf ("\n");
530 printf (" extdefsym: idx: %8lu num: %lu\n",
531 module->iextdefsym, module->nextdefsym);
532 printf (" refsym: idx: %8lu num: %lu\n",
533 module->irefsym, module->nrefsym);
534 printf (" localsym: idx: %8lu num: %lu\n",
535 module->ilocalsym, module->nlocalsym);
536 printf (" extrel: idx: %8lu num: %lu\n",
537 module->iextrel, module->nextrel);
538 printf (" init: idx: %8u num: %u\n",
539 module->iinit, module->ninit);
540 printf (" term: idx: %8u num: %u\n",
541 module->iterm, module->nterm);
542 printf (" objc_module_info: addr: ");
543 bfd_printf_vma (abfd, module->objc_module_info_addr);
544 printf (" size: %lu\n", module->objc_module_info_size);
547 if (dysymtab->ntoc > 0)
549 bfd_mach_o_symtab_command *symtab = mdata->symtab;
551 printf (" table of content: (symbol/module)\n");
552 for (i = 0; i < dysymtab->ntoc; i++)
554 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
556 printf (" %4u: ", i);
557 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
559 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
560 printf ("%s (%lu)", name ? name : "*invalid*",
561 toc->symbol_index);
563 else
564 printf ("%lu", toc->symbol_index);
566 printf (" / ");
567 if (symtab && symtab->strtab
568 && toc->module_index < dysymtab->nmodtab)
570 bfd_mach_o_dylib_module *mod;
571 mod = &dysymtab->dylib_module[toc->module_index];
572 printf ("%s (%lu)",
573 symtab->strtab + mod->module_name_idx,
574 toc->module_index);
576 else
577 printf ("%lu", toc->module_index);
579 printf ("\n");
583 if (dysymtab->nindirectsyms != 0)
585 printf (" indirect symbols:\n");
587 for (i = 0; i < mdata->nsects; i++)
589 bfd_mach_o_section *sec = mdata->sections[i];
590 unsigned int j, first, last;
591 bfd_mach_o_symtab_command *symtab = mdata->symtab;
592 bfd_vma addr;
593 bfd_vma entry_size;
595 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
597 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
598 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
599 case BFD_MACH_O_S_SYMBOL_STUBS:
600 first = sec->reserved1;
601 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
602 addr = sec->addr;
603 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
604 printf (" for section %s.%s:\n",
605 sec->segname, sec->sectname);
606 for (j = first; j < last; j++)
608 unsigned int isym = dysymtab->indirect_syms[j];
610 printf (" ");
611 bfd_printf_vma (abfd, addr);
612 printf (" %5u: 0x%08x", j, isym);
613 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
614 printf (" LOCAL");
615 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
616 printf (" ABSOLUTE");
617 if (symtab && symtab->symbols
618 && isym < symtab->nsyms
619 && symtab->symbols[isym].symbol.name)
620 printf (" %s", symtab->symbols[isym].symbol.name);
621 printf ("\n");
622 addr += entry_size;
624 break;
625 default:
626 break;
630 if (dysymtab->nextrefsyms > 0)
632 bfd_mach_o_symtab_command *symtab = mdata->symtab;
634 printf (" external reference table: (symbol flags)\n");
635 for (i = 0; i < dysymtab->nextrefsyms; i++)
637 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
639 printf (" %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
640 if (symtab && symtab->symbols
641 && ref->isym < symtab->nsyms
642 && symtab->symbols[ref->isym].symbol.name)
643 printf (" %s", symtab->symbols[ref->isym].symbol.name);
644 printf ("\n");
650 static bool
651 load_and_dump (bfd *abfd, ufile_ptr off, unsigned int len,
652 void (*dump)(bfd *abfd, unsigned char *buf, unsigned int len,
653 ufile_ptr off))
655 unsigned char *buf;
657 if (len == 0)
658 return true;
660 buf = xmalloc (len);
662 if (bfd_seek (abfd, off, SEEK_SET) == 0
663 && bfd_bread (buf, len, abfd) == len)
664 dump (abfd, buf, len, off);
665 else
666 return false;
668 free (buf);
669 return true;
672 static const bfd_mach_o_xlat_name bfd_mach_o_dyld_rebase_type_name[] =
674 { "pointer", BFD_MACH_O_REBASE_TYPE_POINTER },
675 { "text_abs32", BFD_MACH_O_REBASE_TYPE_TEXT_ABSOLUTE32 },
676 { "text_pcrel32", BFD_MACH_O_REBASE_TYPE_TEXT_PCREL32 },
677 { NULL, 0 }
680 static void
681 dump_dyld_info_rebase (bfd *abfd, unsigned char *buf, unsigned int len,
682 ufile_ptr off ATTRIBUTE_UNUSED)
684 unsigned int i;
685 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
686 unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
688 for (i = 0; i < len; )
690 unsigned char b = buf[i++];
691 unsigned char imm = b & BFD_MACH_O_REBASE_IMMEDIATE_MASK;
692 bfd_vma leb;
693 unsigned int leblen;
695 printf (" [0x%04x] 0x%02x: ", i, b);
696 switch (b & BFD_MACH_O_REBASE_OPCODE_MASK)
698 case BFD_MACH_O_REBASE_OPCODE_DONE:
699 printf ("done\n");
700 return;
701 case BFD_MACH_O_REBASE_OPCODE_SET_TYPE_IMM:
702 printf ("set_type %s\n",
703 bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
704 break;
705 case BFD_MACH_O_REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
706 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
707 printf ("set segment: %u and offset: 0x%08x\n",
708 imm, (unsigned) leb);
709 i += leblen;
710 break;
711 case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_ULEB:
712 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
713 printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
714 i += leblen;
715 break;
716 case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
717 printf ("add addr imm scaled: %u\n", imm * ptrsize);
718 break;
719 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_IMM_TIMES:
720 printf ("rebase imm times: %u\n", imm);
721 break;
722 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
723 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
724 printf ("rebase uleb times: %u\n", (unsigned) leb);
725 i += leblen;
726 break;
727 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
728 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
729 printf ("rebase add addr uleb: %u\n", (unsigned) leb);
730 i += leblen;
731 break;
732 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
733 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
734 printf ("rebase uleb times (%u)", (unsigned) leb);
735 i += leblen;
736 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
737 printf (" skipping uleb (%u)\n", (unsigned) leb);
738 i += leblen;
739 break;
740 default:
741 printf ("unknown\n");
742 return;
745 printf (" rebase commands without end!\n");
748 static void
749 dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len,
750 ufile_ptr off ATTRIBUTE_UNUSED)
752 unsigned int i;
753 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
754 unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
756 for (i = 0; i < len; )
758 unsigned char b = buf[i++];
759 unsigned char imm = b & BFD_MACH_O_BIND_IMMEDIATE_MASK;
760 bfd_vma leb;
761 unsigned int leblen;
763 printf (" [0x%04x] 0x%02x: ", i, b);
764 switch (b & BFD_MACH_O_BIND_OPCODE_MASK)
766 case BFD_MACH_O_BIND_OPCODE_DONE:
767 printf ("done\n");
768 return;
769 case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
770 printf ("set dylib ordinal imm: %u\n", imm);
771 break;
772 case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
773 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
774 printf ("set dylib ordinal uleb: %u\n", imm);
775 i += leblen;
776 break;
777 case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
778 imm = (imm != 0) ? imm | BFD_MACH_O_BIND_OPCODE_MASK : imm;
779 printf ("set dylib special imm: %d\n", imm);
780 break;
781 case BFD_MACH_O_BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
782 printf ("set symbol trailing flags imm: 0x%02x, ", imm);
783 for (; i < len && buf[i] != 0; i++)
784 putchar (buf[i] >= ' ' && buf[i] < 0x7f ? buf[i] : '?');
785 putchar ('\n');
786 i++;
787 break;
788 case BFD_MACH_O_BIND_OPCODE_SET_TYPE_IMM:
789 /* Kludge: use the same table as rebase type. */
790 printf ("set_type %s\n",
791 bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
792 break;
793 case BFD_MACH_O_BIND_OPCODE_SET_ADDEND_SLEB:
795 bfd_signed_vma svma;
796 svma = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
797 printf ("set addend sleb: 0x%08x\n", (unsigned) svma);
798 i += leblen;
800 break;
801 case BFD_MACH_O_BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
802 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
803 printf ("set segment: %u and offset: 0x%08x\n",
804 imm, (unsigned) leb);
805 i += leblen;
806 break;
807 case BFD_MACH_O_BIND_OPCODE_ADD_ADDR_ULEB:
808 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
809 printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
810 i += leblen;
811 break;
812 case BFD_MACH_O_BIND_OPCODE_DO_BIND:
813 printf ("do bind\n");
814 break;
815 case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
816 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
817 printf ("do bind add addr uleb: 0x%08x\n", (unsigned) leb);
818 i += leblen;
819 break;
820 case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
821 printf ("do bind add addr imm scaled: %u\n", imm * ptrsize);
822 break;
823 case BFD_MACH_O_BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
824 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
825 printf ("do bind uleb times (%u)", (unsigned) leb);
826 i += leblen;
827 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
828 printf (" skipping uleb (%u)\n", (unsigned) leb);
829 i += leblen;
830 break;
831 default:
832 printf ("unknown\n");
833 return;
836 printf (" bind commands without end!\n");
839 struct export_info_data
841 const unsigned char *name;
842 struct export_info_data *next;
845 static void
846 dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
847 unsigned int off, struct export_info_data *parent,
848 struct export_info_data *base)
850 bfd_vma size;
851 unsigned int leblen;
852 unsigned int child_count;
853 unsigned int i;
855 size = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
856 off += leblen;
858 if (size != 0)
860 bfd_vma flags;
861 struct export_info_data *d;
863 flags = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
864 off += leblen;
866 fputs (" ", stdout);
867 switch (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_MASK)
869 case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_REGULAR:
870 putchar ('-');
871 break;
872 case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL:
873 putchar ('T');
874 break;
875 default:
876 putchar ('?');
877 break;
879 putchar ((flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION) ?
880 'W' : '-');
882 if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_REEXPORT)
884 bfd_vma lib;
886 lib = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
887 off += leblen;
889 fputs (" [reexport] ", stdout);
890 for (d = base; d != NULL; d = d->next)
891 printf ("%s", d->name);
893 fputs (" (", stdout);
894 if (buf[off] != 0)
896 fputs ((const char *)buf + off, stdout);
897 putchar (' ');
898 off += strlen ((const char *)buf + off);
900 printf ("from dylib %u)\n", (unsigned) lib);
901 off++;
903 else
905 bfd_vma offset;
906 bfd_vma resolv = 0;
908 offset = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
909 off += leblen;
911 if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
913 resolv = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
914 off += leblen;
917 printf (" 0x%08x ", (unsigned) offset);
918 for (d = base; d != NULL; d = d->next)
919 printf ("%s", d->name);
920 if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
921 printf (" [resolv: 0x%08x]", (unsigned) resolv);
922 printf ("\n");
926 child_count = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
927 off += leblen;
929 for (i = 0; i < child_count; i++)
931 struct export_info_data sub_data;
932 bfd_vma sub_off;
934 sub_data.name = buf + off;
935 sub_data.next = NULL;
936 parent->next = &sub_data;
938 off += strlen ((const char *)buf + off) + 1;
940 sub_off = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
941 off += leblen;
943 dump_dyld_info_export_1 (abfd, buf, len, sub_off, &sub_data, base);
947 static void
948 dump_dyld_info_export (bfd *abfd, unsigned char *buf, unsigned int len,
949 ufile_ptr off ATTRIBUTE_UNUSED)
951 struct export_info_data data;
953 data.name = (const unsigned char *) "";
954 data.next = NULL;
956 printf (" fl offset sym (Flags: Tls Weak)\n");
957 dump_dyld_info_export_1 (abfd, buf, len, 0, &data, &data);
960 static void
961 dump_dyld_info (bfd *abfd, bfd_mach_o_load_command *cmd,
962 bool verbose)
964 bfd_mach_o_dyld_info_command *dinfo = &cmd->command.dyld_info;
966 printf (" rebase: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
967 dinfo->rebase_off, dinfo->rebase_size,
968 dinfo->rebase_off + dinfo->rebase_size);
969 printf (" bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
970 dinfo->bind_off, dinfo->bind_size,
971 dinfo->bind_off + dinfo->bind_size);
972 printf (" weak bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
973 dinfo->weak_bind_off, dinfo->weak_bind_size,
974 dinfo->weak_bind_off + dinfo->weak_bind_size);
975 printf (" lazy bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
976 dinfo->lazy_bind_off, dinfo->lazy_bind_size,
977 dinfo->lazy_bind_off + dinfo->lazy_bind_size);
978 printf (" export: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
979 dinfo->export_off, dinfo->export_size,
980 dinfo->export_off + dinfo->export_size);
982 if (!verbose)
983 return;
985 printf (" rebase:\n");
986 if (!load_and_dump (abfd, dinfo->rebase_off, dinfo->rebase_size,
987 dump_dyld_info_rebase))
988 non_fatal (_("cannot read rebase dyld info"));
990 printf (" bind:\n");
991 if (!load_and_dump (abfd, dinfo->bind_off, dinfo->bind_size,
992 dump_dyld_info_bind))
993 non_fatal (_("cannot read bind dyld info"));
995 printf (" weak bind:\n");
996 if (!load_and_dump (abfd, dinfo->weak_bind_off, dinfo->weak_bind_size,
997 dump_dyld_info_bind))
998 non_fatal (_("cannot read weak bind dyld info"));
1000 printf (" lazy bind:\n");
1001 if (!load_and_dump (abfd, dinfo->lazy_bind_off, dinfo->lazy_bind_size,
1002 dump_dyld_info_bind))
1003 non_fatal (_("cannot read lazy bind dyld info"));
1005 printf (" exported symbols:\n");
1006 if (!load_and_dump (abfd, dinfo->export_off, dinfo->export_size,
1007 dump_dyld_info_export))
1008 non_fatal (_("cannot read export symbols dyld info"));
1011 static void
1012 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
1014 bfd_mach_o_thread_command *thread = &cmd->command.thread;
1015 unsigned int j;
1016 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1017 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1019 printf (" nflavours: %lu\n", thread->nflavours);
1020 for (j = 0; j < thread->nflavours; j++)
1022 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
1023 const bfd_mach_o_xlat_name *name_table;
1025 printf (" %2u: flavour: 0x%08lx", j, flavour->flavour);
1026 switch (mdata->header.cputype)
1028 case BFD_MACH_O_CPU_TYPE_I386:
1029 case BFD_MACH_O_CPU_TYPE_X86_64:
1030 name_table = bfd_mach_o_thread_x86_name;
1031 break;
1032 default:
1033 name_table = NULL;
1034 break;
1036 if (name_table != NULL)
1037 printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
1038 putchar ('\n');
1040 printf (" offset: 0x%08lx size: 0x%08lx\n",
1041 flavour->offset, flavour->size);
1042 if (bed->_bfd_mach_o_print_thread)
1044 char *buf = xmalloc (flavour->size);
1046 if (bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
1047 && bfd_bread (buf, flavour->size, abfd) == flavour->size)
1048 (*bed->_bfd_mach_o_print_thread)(abfd, flavour, stdout, buf);
1050 free (buf);
1055 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic[] =
1057 { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE },
1058 { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT },
1059 { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS },
1060 { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY },
1061 { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS },
1062 { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER },
1063 { NULL, 0 }
1066 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type[] =
1068 { "no-hash", BFD_MACH_O_CS_NO_HASH },
1069 { "sha1", BFD_MACH_O_CS_HASH_SHA1 },
1070 { "sha256", BFD_MACH_O_CS_HASH_SHA256 },
1071 { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256 },
1072 { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512 },
1073 { NULL, 0 }
1076 static unsigned int
1077 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
1079 static void
1080 dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
1081 const unsigned char *buf, unsigned int len)
1083 unsigned int count;
1084 unsigned int i;
1086 if (len < 12)
1088 printf (_(" [bad block length]\n"));
1089 return;
1091 count = bfd_getb32 (buf + 8);
1092 printf (ngettext (" %u index entry:\n",
1093 " %u index entries:\n",
1094 count),
1095 count);
1096 if (len < 12 + 8 * count)
1098 printf (_(" [bad block length]\n"));
1099 return;
1101 for (i = 0; i < count; i++)
1103 unsigned int type;
1104 unsigned int off;
1106 type = bfd_getb32 (buf + 12 + 8 * i);
1107 off = bfd_getb32 (buf + 12 + 8 * i + 4);
1108 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
1109 i, type, off);
1111 dump_code_signature_blob (abfd, buf + off, len - off);
1115 static void
1116 swap_code_codedirectory_v1_in
1117 (const struct mach_o_codesign_codedirectory_external_v1 *src,
1118 struct mach_o_codesign_codedirectory_v1 *dst)
1120 dst->version = bfd_getb32 (src->version);
1121 dst->flags = bfd_getb32 (src->flags);
1122 dst->hash_offset = bfd_getb32 (src->hash_offset);
1123 dst->ident_offset = bfd_getb32 (src->ident_offset);
1124 dst->nbr_special_slots = bfd_getb32 (src->nbr_special_slots);
1125 dst->nbr_code_slots = bfd_getb32 (src->nbr_code_slots);
1126 dst->code_limit = bfd_getb32 (src->code_limit);
1127 dst->hash_size = src->hash_size[0];
1128 dst->hash_type = src->hash_type[0];
1129 dst->spare1 = src->spare1[0];
1130 dst->page_size = src->page_size[0];
1131 dst->spare2 = bfd_getb32 (src->spare2);
1134 static void
1135 hexdump (unsigned int start, unsigned int len,
1136 const unsigned char *buf)
1138 unsigned int i, j;
1140 for (i = 0; i < len; i += 16)
1142 printf ("%08x:", start + i);
1143 for (j = 0; j < 16; j++)
1145 fputc (j == 8 ? '-' : ' ', stdout);
1146 if (i + j < len)
1147 printf ("%02x", buf[i + j]);
1148 else
1149 fputs (" ", stdout);
1151 fputc (' ', stdout);
1152 for (j = 0; j < 16; j++)
1154 if (i + j < len)
1155 fputc (ISPRINT (buf[i + j]) ? buf[i + j] : '.', stdout);
1156 else
1157 fputc (' ', stdout);
1159 fputc ('\n', stdout);
1163 static void
1164 dump_code_signature_codedirectory (bfd *abfd ATTRIBUTE_UNUSED,
1165 const unsigned char *buf, unsigned int len)
1167 struct mach_o_codesign_codedirectory_v1 cd;
1168 const char *id;
1170 if (len < sizeof (struct mach_o_codesign_codedirectory_external_v1))
1172 printf (_(" [bad block length]\n"));
1173 return;
1176 swap_code_codedirectory_v1_in
1177 ((const struct mach_o_codesign_codedirectory_external_v1 *) (buf + 8), &cd);
1179 printf (_(" version: %08x\n"), cd.version);
1180 printf (_(" flags: %08x\n"), cd.flags);
1181 printf (_(" hash offset: %08x\n"), cd.hash_offset);
1182 id = (const char *) buf + cd.ident_offset;
1183 printf (_(" ident offset: %08x (- %08x)\n"),
1184 cd.ident_offset, cd.ident_offset + (unsigned) strlen (id) + 1);
1185 printf (_(" identity: %s\n"), id);
1186 printf (_(" nbr special slots: %08x (at offset %08x)\n"),
1187 cd.nbr_special_slots,
1188 cd.hash_offset - cd.nbr_special_slots * cd.hash_size);
1189 printf (_(" nbr code slots: %08x\n"), cd.nbr_code_slots);
1190 printf (_(" code limit: %08x\n"), cd.code_limit);
1191 printf (_(" hash size: %02x\n"), cd.hash_size);
1192 printf (_(" hash type: %02x (%s)\n"),
1193 cd.hash_type,
1194 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type, cd.hash_type));
1195 printf (_(" spare1: %02x\n"), cd.spare1);
1196 printf (_(" page size: %02x\n"), cd.page_size);
1197 printf (_(" spare2: %08x\n"), cd.spare2);
1198 if (cd.version >= 0x20100)
1199 printf (_(" scatter offset: %08x\n"),
1200 (unsigned) bfd_getb32 (buf + 44));
1203 static unsigned int
1204 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len)
1206 unsigned int magic;
1207 unsigned int length;
1209 if (len < 8)
1211 printf (_(" [truncated block]\n"));
1212 return 0;
1214 magic = bfd_getb32 (buf);
1215 length = bfd_getb32 (buf + 4);
1216 if (magic == 0 || length == 0)
1217 return 0;
1219 printf (_(" magic : %08x (%s)\n"), magic,
1220 bfd_mach_o_get_name (bfd_mach_o_cs_magic, magic));
1221 printf (_(" length: %08x\n"), length);
1222 if (length > len)
1224 printf (_(" [bad block length]\n"));
1225 return 0;
1228 switch (magic)
1230 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE:
1231 dump_code_signature_superblob (abfd, buf, length);
1232 break;
1233 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY:
1234 dump_code_signature_codedirectory (abfd, buf, length);
1235 break;
1236 default:
1237 hexdump (0, length - 8, buf + 8);
1238 break;
1240 return length;
1243 static void
1244 dump_code_signature (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1246 unsigned char *buf = xmalloc (cmd->datasize);
1247 unsigned int off;
1249 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1250 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1252 non_fatal (_("cannot read code signature data"));
1253 free (buf);
1254 return;
1256 for (off = 0; off < cmd->datasize;)
1258 unsigned int len;
1260 len = dump_code_signature_blob (abfd, buf + off, cmd->datasize - off);
1262 if (len == 0)
1263 break;
1264 off += len;
1266 free (buf);
1269 static void
1270 dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1272 unsigned char *buf = xmalloc (cmd->datasize);
1273 unsigned char *p;
1274 unsigned int len;
1275 bfd_vma addr = 0;
1277 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1278 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1280 non_fatal (_("cannot read segment split info"));
1281 free (buf);
1282 return;
1284 if (buf[cmd->datasize - 1] != 0)
1286 non_fatal (_("segment split info is not nul terminated"));
1287 free (buf);
1288 return;
1291 switch (buf[0])
1293 case 0:
1294 printf (_(" 32 bit pointers:\n"));
1295 break;
1296 case 1:
1297 printf (_(" 64 bit pointers:\n"));
1298 break;
1299 case 2:
1300 printf (_(" PPC hi-16:\n"));
1301 break;
1302 default:
1303 printf (_(" Unhandled location type %u\n"), buf[0]);
1304 break;
1306 for (p = buf + 1; *p != 0; p += len)
1308 addr += read_leb128 (p, buf + cmd->datasize, 0, &len, NULL);
1309 fputs (" ", stdout);
1310 bfd_printf_vma (abfd, addr);
1311 putchar ('\n');
1313 free (buf);
1316 static void
1317 dump_function_starts (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1319 unsigned char *buf = xmalloc (cmd->datasize);
1320 unsigned char *end_buf = buf + cmd->datasize;
1321 unsigned char *p;
1322 bfd_vma addr;
1324 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1325 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1327 non_fatal (_("cannot read function starts"));
1328 free (buf);
1329 return;
1332 /* Function starts are delta encoded, starting from the base address. */
1333 addr = bfd_mach_o_get_base_address (abfd);
1335 for (p = buf; ;)
1337 bfd_vma delta = 0;
1338 unsigned int shift = 0;
1340 if (*p == 0 || p == end_buf)
1341 break;
1342 while (1)
1344 unsigned char b = *p++;
1346 delta |= (b & 0x7f) << shift;
1347 if ((b & 0x80) == 0)
1348 break;
1349 if (p == end_buf)
1351 fputs (" [truncated]\n", stdout);
1352 break;
1354 shift += 7;
1357 addr += delta;
1358 fputs (" ", stdout);
1359 bfd_printf_vma (abfd, addr);
1360 putchar ('\n');
1362 free (buf);
1365 static const bfd_mach_o_xlat_name data_in_code_kind_name[] =
1367 { "data", BFD_MACH_O_DICE_KIND_DATA },
1368 { "1 byte jump table", BFD_MACH_O_DICE_JUMP_TABLES8 },
1369 { "2 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES16 },
1370 { "4 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES32 },
1371 { "4 bytes abs jump table", BFD_MACH_O_DICE_ABS_JUMP_TABLES32 },
1372 { NULL, 0 }
1375 static void
1376 dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1378 unsigned char *buf;
1379 unsigned char *p;
1381 if (cmd->datasize == 0)
1383 printf (" no data_in_code entries\n");
1384 return;
1387 buf = xmalloc (cmd->datasize);
1388 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1389 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1391 non_fatal (_("cannot read data_in_code"));
1392 free (buf);
1393 return;
1396 printf (" offset length kind\n");
1397 for (p = buf; p < buf + cmd->datasize; )
1399 struct mach_o_data_in_code_entry_external *dice;
1400 unsigned int offset;
1401 unsigned int length;
1402 unsigned int kind;
1404 dice = (struct mach_o_data_in_code_entry_external *) p;
1406 offset = bfd_get_32 (abfd, dice->offset);
1407 length = bfd_get_16 (abfd, dice->length);
1408 kind = bfd_get_16 (abfd, dice->kind);
1410 printf (" 0x%08x 0x%04x 0x%04x %s\n", offset, length, kind,
1411 bfd_mach_o_get_name (data_in_code_kind_name, kind));
1413 p += sizeof (*dice);
1415 free (buf);
1418 static void
1419 dump_twolevel_hints (bfd *abfd, bfd_mach_o_twolevel_hints_command *cmd)
1421 size_t sz = 4 * cmd->nhints;
1422 unsigned char *buf;
1423 unsigned char *p;
1425 buf = xmalloc (sz);
1426 if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
1427 || bfd_bread (buf, sz, abfd) != sz)
1429 non_fatal (_("cannot read twolevel hints"));
1430 free (buf);
1431 return;
1434 for (p = buf; p < buf + sz; p += 4)
1436 unsigned int v;
1437 unsigned int isub_image;
1438 unsigned int itoc;
1440 v = bfd_get_32 (abfd, p);
1441 if (bfd_big_endian (abfd))
1443 isub_image = (v >> 24) & 0xff;
1444 itoc = v & 0xffffff;
1446 else
1448 isub_image = v & 0xff;
1449 itoc = (v >> 8) & 0xffffff;
1452 printf (" %3u %8u\n", isub_image, itoc);
1454 free (buf);
1457 static void
1458 printf_version (uint32_t version)
1460 uint32_t maj, min, upd;
1462 maj = (version >> 16) & 0xffff;
1463 min = (version >> 8) & 0xff;
1464 upd = version & 0xff;
1466 printf ("%u.%u.%u", maj, min, upd);
1469 static void
1470 dump_build_version (bfd *abfd, bfd_mach_o_load_command *cmd)
1472 const char *platform_name;
1473 size_t tools_len, tools_offset;
1474 bfd_mach_o_build_version_tool *tools, *tool;
1475 bfd_mach_o_build_version_command *ver = &cmd->command.build_version;
1476 uint32_t i;
1478 platform_name = bfd_mach_o_get_name_or_null
1479 (bfd_mach_o_platform_name, ver->platform);
1480 if (platform_name == NULL)
1481 printf (" platform: 0x%08x\n", ver->platform);
1482 else
1483 printf (" platform: %s\n", platform_name);
1484 printf (" os: ");
1485 printf_version (ver->minos);
1486 printf ("\n sdk: ");
1487 printf_version (ver->sdk);
1488 printf ("\n ntools: %u\n", ver->ntools);
1490 tools_len = sizeof (bfd_mach_o_build_version_tool) * ver->ntools;
1491 tools_offset = cmd->offset + cmd->len - tools_len;
1493 tools = xmalloc (tools_len);
1494 if (bfd_seek (abfd, tools_offset, SEEK_SET) != 0
1495 || bfd_bread (tools, tools_len, abfd) != tools_len)
1497 non_fatal (_("cannot read build tools"));
1498 free (tools);
1499 return;
1502 for (i = 0, tool = tools; i < ver->ntools; i++, tool++)
1504 const char * tool_name;
1506 tool_name = bfd_mach_o_get_name_or_null
1507 (bfd_mach_o_tool_name, tool->tool);
1508 if (tool_name == NULL)
1509 printf (" tool: 0x%08x\n", tool->tool);
1510 else
1511 printf (" tool: %s\n", tool_name);
1512 printf (" version: ");
1513 printf_version (tool->version);
1514 printf ("\n");
1516 free (tools);
1519 static void
1520 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
1521 unsigned int idx, bool verbose)
1523 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1524 const char *cmd_name;
1526 cmd_name = bfd_mach_o_get_name_or_null
1527 (bfd_mach_o_load_command_name, cmd->type);
1528 printf ("Load command #%-2u (size: %3u, offset: %4u): ",
1529 idx, cmd->len, cmd->offset);
1530 if (cmd_name == NULL)
1531 printf ("0x%02x\n", cmd->type);
1532 else
1533 printf ("%s\n", cmd_name);
1535 switch (cmd->type)
1537 case BFD_MACH_O_LC_SEGMENT:
1538 case BFD_MACH_O_LC_SEGMENT_64:
1539 dump_segment (abfd, cmd);
1540 break;
1541 case BFD_MACH_O_LC_UUID:
1543 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
1544 unsigned int j;
1546 printf (" ");
1547 for (j = 0; j < sizeof (uuid->uuid); j ++)
1548 printf (" %02x", uuid->uuid[j]);
1549 putchar ('\n');
1551 break;
1552 case BFD_MACH_O_LC_LOAD_DYLIB:
1553 case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
1554 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1555 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1556 case BFD_MACH_O_LC_ID_DYLIB:
1557 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
1559 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
1560 printf (" name: %s\n", dylib->name_str);
1561 printf (" time stamp: 0x%08lx\n",
1562 dylib->timestamp);
1563 printf (" current version: 0x%08lx\n",
1564 dylib->current_version);
1565 printf (" comptibility version: 0x%08lx\n",
1566 dylib->compatibility_version);
1568 break;
1569 case BFD_MACH_O_LC_LOAD_DYLINKER:
1570 case BFD_MACH_O_LC_ID_DYLINKER:
1571 printf (" %s\n", cmd->command.dylinker.name_str);
1572 break;
1573 case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
1574 printf (" %s\n", cmd->command.dylinker.name_str);
1575 break;
1576 case BFD_MACH_O_LC_SYMTAB:
1578 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
1579 printf (" symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
1580 symtab->symoff, symtab->nsyms,
1581 symtab->symoff + symtab->nsyms
1582 * (mdata->header.version == 2
1583 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
1584 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
1585 symtab->stroff, symtab->strsize,
1586 symtab->stroff + symtab->strsize);
1587 break;
1589 case BFD_MACH_O_LC_DYSYMTAB:
1590 dump_dysymtab (abfd, cmd, verbose);
1591 break;
1592 case BFD_MACH_O_LC_LOADFVMLIB:
1593 case BFD_MACH_O_LC_IDFVMLIB:
1595 bfd_mach_o_fvmlib_command *fvmlib = &cmd->command.fvmlib;
1596 printf (" fvmlib: %s\n", fvmlib->name_str);
1597 printf (" minor version: 0x%08x\n", fvmlib->minor_version);
1598 printf (" header address: 0x%08x\n", fvmlib->header_addr);
1600 break;
1601 case BFD_MACH_O_LC_CODE_SIGNATURE:
1602 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1603 case BFD_MACH_O_LC_FUNCTION_STARTS:
1604 case BFD_MACH_O_LC_DATA_IN_CODE:
1605 case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
1606 case BFD_MACH_O_LC_DYLD_EXPORTS_TRIE:
1607 case BFD_MACH_O_LC_DYLD_CHAINED_FIXUPS:
1609 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
1610 printf
1611 (" dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
1612 linkedit->dataoff, linkedit->datasize,
1613 linkedit->dataoff + linkedit->datasize);
1615 if (verbose)
1616 switch (cmd->type)
1618 case BFD_MACH_O_LC_CODE_SIGNATURE:
1619 dump_code_signature (abfd, linkedit);
1620 break;
1621 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1622 dump_segment_split_info (abfd, linkedit);
1623 break;
1624 case BFD_MACH_O_LC_FUNCTION_STARTS:
1625 dump_function_starts (abfd, linkedit);
1626 break;
1627 case BFD_MACH_O_LC_DATA_IN_CODE:
1628 dump_data_in_code (abfd, linkedit);
1629 break;
1630 default:
1631 break;
1634 break;
1635 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1636 case BFD_MACH_O_LC_SUB_UMBRELLA:
1637 case BFD_MACH_O_LC_SUB_LIBRARY:
1638 case BFD_MACH_O_LC_SUB_CLIENT:
1639 case BFD_MACH_O_LC_RPATH:
1641 bfd_mach_o_str_command *strc = &cmd->command.str;
1642 printf (" %s\n", strc->str);
1643 break;
1645 case BFD_MACH_O_LC_THREAD:
1646 case BFD_MACH_O_LC_UNIXTHREAD:
1647 dump_thread (abfd, cmd);
1648 break;
1649 case BFD_MACH_O_LC_ENCRYPTION_INFO:
1651 bfd_mach_o_encryption_info_command *cryp =
1652 &cmd->command.encryption_info;
1653 printf (" cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1654 " cryptid: %u\n",
1655 cryp->cryptoff, cryp->cryptsize,
1656 cryp->cryptoff + cryp->cryptsize,
1657 cryp->cryptid);
1659 break;
1660 case BFD_MACH_O_LC_DYLD_INFO:
1661 dump_dyld_info (abfd, cmd, verbose);
1662 break;
1663 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
1664 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
1665 case BFD_MACH_O_LC_VERSION_MIN_WATCHOS:
1666 case BFD_MACH_O_LC_VERSION_MIN_TVOS:
1668 bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
1670 printf (" os: ");
1671 printf_version (ver->version);
1672 printf ("\n sdk: ");
1673 printf_version (ver->sdk);
1674 printf ("\n");
1676 break;
1677 case BFD_MACH_O_LC_SOURCE_VERSION:
1679 bfd_mach_o_source_version_command *version =
1680 &cmd->command.source_version;
1681 printf (" version a.b.c.d.e: %u.%u.%u.%u.%u\n",
1682 version->a, version->b, version->c, version->d, version->e);
1683 break;
1685 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1687 bfd_mach_o_prebound_dylib_command *pbdy = &cmd->command.prebound_dylib;
1688 unsigned char *lm = pbdy->linked_modules;
1689 unsigned int j;
1690 unsigned int last;
1692 printf (" dylib: %s\n", pbdy->name_str);
1693 printf (" nmodules: %u\n", pbdy->nmodules);
1694 printf (" linked modules (at %u): ",
1695 pbdy->linked_modules_offset - cmd->offset);
1696 last = pbdy->nmodules > 32 ? 32 : pbdy->nmodules;
1697 for (j = 0; j < last; j++)
1698 printf ("%u", (lm[j >> 3] >> (j & 7)) & 1);
1699 if (last < pbdy->nmodules)
1700 printf ("...");
1701 putchar ('\n');
1702 break;
1704 case BFD_MACH_O_LC_PREBIND_CKSUM:
1706 bfd_mach_o_prebind_cksum_command *cksum = &cmd->command.prebind_cksum;
1707 printf (" 0x%08x\n", cksum->cksum);
1708 break;
1710 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1712 bfd_mach_o_twolevel_hints_command *hints =
1713 &cmd->command.twolevel_hints;
1715 printf (" table offset: 0x%08x nbr hints: %u\n",
1716 hints->offset, hints->nhints);
1717 if (verbose)
1718 dump_twolevel_hints (abfd, hints);
1719 break;
1721 case BFD_MACH_O_LC_MAIN:
1723 bfd_mach_o_main_command *entry = &cmd->command.main;
1724 printf (" entry offset: %#016" PRIx64 "\n"
1725 " stack size: %#016" PRIx64 "\n",
1726 entry->entryoff, entry->stacksize);
1727 break;
1729 case BFD_MACH_O_LC_NOTE:
1731 bfd_mach_o_note_command *note = &cmd->command.note;
1732 printf (" data owner: %.16s\n"
1733 " offset: %#016" PRIx64 "\n"
1734 " size: %#016" PRIx64 "\n",
1735 note->data_owner, note->offset, note->size);
1736 break;
1738 case BFD_MACH_O_LC_BUILD_VERSION:
1739 dump_build_version (abfd, cmd);
1740 break;
1741 default:
1742 break;
1744 putchar ('\n');
1747 static void
1748 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
1750 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1751 bfd_mach_o_load_command *cmd;
1752 unsigned int i;
1754 for (cmd = mdata->first_command, i = 0; cmd != NULL; cmd = cmd->next, i++)
1756 if (cmd32 == 0)
1757 dump_load_command (abfd, cmd, i, false);
1758 else if (cmd->type == cmd32 || cmd->type == cmd64)
1759 dump_load_command (abfd, cmd, i, true);
1763 static const char * const unwind_x86_64_regs[] =
1764 {"", "rbx", "r12", "r13", "r14", "r15", "rbp", "???" };
1766 static const char * const unwind_x86_regs[] =
1767 {"", "ebx", "ecx", "edx", "edi", "edi", "ebp", "???" };
1769 /* Dump x86 or x86-64 compact unwind encoding. Works for both architecture,
1770 as the encoding is the same (but not register names). */
1772 static void
1773 dump_unwind_encoding_x86 (unsigned int encoding, unsigned int sz,
1774 const char * const regs_name[])
1776 unsigned int mode;
1778 mode = encoding & MACH_O_UNWIND_X86_64_MODE_MASK;
1779 switch (mode)
1781 case MACH_O_UNWIND_X86_64_MODE_RBP_FRAME:
1783 unsigned int regs;
1784 char pfx = sz == 8 ? 'R' : 'E';
1786 regs = encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_REGISTERS;
1787 printf (" %cSP frame", pfx);
1788 if (regs != 0)
1790 unsigned int offset;
1791 int i;
1793 offset = (encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET) >> 16;
1794 printf (" at %cBP-%u:", pfx, offset * sz);
1795 for (i = 0; i < 5; i++)
1797 unsigned int reg = (regs >> (i * 3)) & 0x7;
1798 if (reg != MACH_O_UNWIND_X86_64_REG_NONE)
1799 printf (" %s", regs_name[reg]);
1803 break;
1804 case MACH_O_UNWIND_X86_64_MODE_STACK_IMMD:
1805 case MACH_O_UNWIND_X86_64_MODE_STACK_IND:
1807 unsigned int stack_size;
1808 unsigned int reg_count;
1809 unsigned int reg_perm;
1810 unsigned int regs[6];
1811 int i, j;
1813 printf (" frameless");
1814 stack_size =
1815 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE) >> 16;
1816 reg_count =
1817 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT) >> 10;
1818 reg_perm = encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION;
1820 if (mode == MACH_O_UNWIND_X86_64_MODE_STACK_IMMD)
1821 printf (" size: 0x%03x", stack_size * sz);
1822 else
1824 unsigned int stack_adj;
1826 stack_adj =
1827 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST) >> 13;
1828 printf (" size at 0x%03x + 0x%02x", stack_size, stack_adj * sz);
1830 /* Registers are coded using arithmetic compression: the register
1831 is indexed in range 0-6, the second in range 0-5, the third in
1832 range 0-4, etc. Already used registers are removed in next
1833 ranges. */
1834 #define DO_PERM(R, NUM) R = reg_perm / NUM; reg_perm -= R * NUM
1835 switch (reg_count)
1837 case 6:
1838 case 5:
1839 DO_PERM (regs[0], 120);
1840 DO_PERM (regs[1], 24);
1841 DO_PERM (regs[2], 6);
1842 DO_PERM (regs[3], 2);
1843 DO_PERM (regs[4], 1);
1844 regs[5] = 0; /* Not used if reg_count = 5. */
1845 break;
1846 case 4:
1847 DO_PERM (regs[0], 60);
1848 DO_PERM (regs[1], 12);
1849 DO_PERM (regs[2], 3);
1850 DO_PERM (regs[3], 1);
1851 break;
1852 case 3:
1853 DO_PERM (regs[0], 20);
1854 DO_PERM (regs[1], 4);
1855 DO_PERM (regs[2], 1);
1856 break;
1857 case 2:
1858 DO_PERM (regs[0], 5);
1859 DO_PERM (regs[1], 1);
1860 break;
1861 case 1:
1862 DO_PERM (regs[0], 1);
1863 break;
1864 case 0:
1865 break;
1866 default:
1867 printf (" [bad reg count]");
1868 return;
1870 #undef DO_PERM
1871 /* Renumber. */
1872 for (i = reg_count - 1; i >= 0; i--)
1874 unsigned int inc = 1;
1875 for (j = 0; j < i; j++)
1876 if (regs[i] >= regs[j])
1877 inc++;
1878 regs[i] += inc;
1880 /* Display. */
1881 for (i = 0; i < (int) reg_count; i++)
1882 printf (" %s", regs_name[regs[i]]);
1884 break;
1885 case MACH_O_UNWIND_X86_64_MODE_DWARF:
1886 printf (" Dwarf offset: 0x%06x",
1887 encoding & MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET);
1888 break;
1889 default:
1890 printf (" [unhandled mode]");
1891 break;
1895 /* Dump arm64 compact unwind entries. */
1897 static void
1898 dump_unwind_encoding_arm64 (unsigned int encoding)
1900 switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1902 case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1903 printf (" frameless");
1904 break;
1905 case MACH_O_UNWIND_ARM64_MODE_DWARF:
1906 printf (" Dwarf offset: 0x%06x",
1907 encoding & MACH_O_UNWIND_ARM64_DWARF_SECTION_OFFSET);
1908 return;
1909 case MACH_O_UNWIND_ARM64_MODE_FRAME:
1910 printf (" frame");
1911 break;
1912 default:
1913 printf (" [unhandled mode]");
1914 return;
1916 switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1918 case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1919 case MACH_O_UNWIND_ARM64_MODE_FRAME:
1920 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X19_X20_PAIR)
1921 printf (" x19-x20");
1922 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X21_X22_PAIR)
1923 printf (" x21-x22");
1924 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X23_X24_PAIR)
1925 printf (" x23-x24");
1926 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X25_X26_PAIR)
1927 printf (" x25-x26");
1928 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X27_X28_PAIR)
1929 printf (" x27-x28");
1930 break;
1932 switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1934 case MACH_O_UNWIND_ARM64_MODE_FRAME:
1935 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D8_D9_PAIR)
1936 printf (" d8-d9");
1937 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D10_D11_PAIR)
1938 printf (" d10-d11");
1939 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D12_D13_PAIR)
1940 printf (" d12-d13");
1941 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D14_D15_PAIR)
1942 printf (" d14-d15");
1943 break;
1944 case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1945 printf (" size: %u",
1946 (encoding & MACH_O_UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK) >> 8);
1947 break;
1951 static void
1952 dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding)
1954 printf ("0x%08x", encoding);
1955 if (encoding == 0)
1956 return;
1958 switch (mdata->header.cputype)
1960 case BFD_MACH_O_CPU_TYPE_X86_64:
1961 dump_unwind_encoding_x86 (encoding, 8, unwind_x86_64_regs);
1962 break;
1963 case BFD_MACH_O_CPU_TYPE_I386:
1964 dump_unwind_encoding_x86 (encoding, 4, unwind_x86_regs);
1965 break;
1966 case BFD_MACH_O_CPU_TYPE_ARM64:
1967 dump_unwind_encoding_arm64 (encoding);
1968 break;
1969 default:
1970 printf (" [unhandled cpu]");
1971 break;
1973 if (encoding & MACH_O_UNWIND_HAS_LSDA)
1974 printf (" LSDA");
1975 if (encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1976 printf (" PERS(%u)",
1977 ((encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1978 >> MACH_O_UNWIND_PERSONALITY_SHIFT));
1981 static void
1982 dump_obj_compact_unwind (bfd *abfd,
1983 const unsigned char *content, bfd_size_type size)
1985 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1986 int is_64 = mdata->header.version == 2;
1987 const unsigned char *p;
1989 printf ("Compact unwind info:\n");
1990 printf (" start length personality lsda\n");
1992 if (is_64)
1994 struct mach_o_compact_unwind_64 *e =
1995 (struct mach_o_compact_unwind_64 *) content;
1997 for (p = content; p < content + size; p += sizeof (*e))
1999 e = (struct mach_o_compact_unwind_64 *) p;
2001 printf (" %#016" PRIx64 " %#08x %#016" PRIx64 " %#016" PRIx64 "\n",
2002 (uint64_t) bfd_get_64 (abfd, e->start),
2003 (unsigned int) bfd_get_32 (abfd, e->length),
2004 (uint64_t) bfd_get_64 (abfd, e->personality),
2005 (uint64_t) bfd_get_64 (abfd, e->lsda));
2007 printf (" encoding: ");
2008 dump_unwind_encoding (mdata, bfd_get_32 (abfd, e->encoding));
2009 putchar ('\n');
2012 else
2014 printf ("unhandled\n");
2018 static void
2019 dump_exe_compact_unwind (bfd *abfd,
2020 const unsigned char *content, bfd_size_type size)
2022 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2023 struct mach_o_unwind_info_header *hdr;
2024 unsigned int version;
2025 unsigned int encodings_offset;
2026 unsigned int encodings_count;
2027 unsigned int personality_offset;
2028 unsigned int personality_count;
2029 unsigned int index_offset;
2030 unsigned int index_count;
2031 struct mach_o_unwind_index_entry *index_entry;
2032 unsigned int i;
2034 /* The header. */
2035 printf ("Compact unwind info:\n");
2037 hdr = (struct mach_o_unwind_info_header *) content;
2038 if (size < sizeof (*hdr))
2040 printf (" truncated!\n");
2041 return;
2044 version = bfd_get_32 (abfd, hdr->version);
2045 if (version != MACH_O_UNWIND_SECTION_VERSION)
2047 printf (" unknown version: %u\n", version);
2048 return;
2050 encodings_offset = bfd_get_32 (abfd, hdr->encodings_array_offset);
2051 encodings_count = bfd_get_32 (abfd, hdr->encodings_array_count);
2052 personality_offset = bfd_get_32 (abfd, hdr->personality_array_offset);
2053 personality_count = bfd_get_32 (abfd, hdr->personality_array_count);
2054 index_offset = bfd_get_32 (abfd, hdr->index_offset);
2055 index_count = bfd_get_32 (abfd, hdr->index_count);
2056 printf (" %u encodings, %u personalities, %u level-1 indexes:\n",
2057 encodings_count, personality_count, index_count);
2059 /* Personality. */
2060 if (personality_count > 0)
2062 const unsigned char *pers = content + personality_offset;
2064 printf (" personalities\n");
2065 for (i = 0; i < personality_count; i++)
2066 printf (" %u: 0x%08x\n", i,
2067 (unsigned) bfd_get_32 (abfd, pers + 4 * i));
2070 /* Level-1 index. */
2071 printf (" idx function level2 off lsda off\n");
2073 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
2074 for (i = 0; i < index_count; i++)
2076 unsigned int func_offset;
2077 unsigned int level2_offset;
2078 unsigned int lsda_offset;
2080 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
2081 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
2082 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
2083 printf (" %3u 0x%08x 0x%08x 0x%08x\n",
2084 i, func_offset, level2_offset, lsda_offset);
2085 index_entry++;
2088 /* Level-1 index. */
2089 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
2090 for (i = 0; i < index_count; i++)
2092 unsigned int func_offset;
2093 unsigned int level2_offset;
2094 const unsigned char *level2;
2095 unsigned int kind;
2097 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
2098 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
2100 /* No level-2 for this index (should be the last index). */
2101 if (level2_offset == 0)
2102 continue;
2104 level2 = content + level2_offset;
2105 kind = bfd_get_32 (abfd, level2);
2106 switch (kind)
2108 case MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED:
2110 struct mach_o_unwind_compressed_second_level_page_header *l2;
2111 unsigned int entry_offset;
2112 unsigned int entry_count;
2113 unsigned int l2_encodings_offset;
2114 unsigned int l2_encodings_count;
2115 const unsigned char *en;
2116 unsigned int j;
2118 l2 = (struct mach_o_unwind_compressed_second_level_page_header *)
2119 level2;
2120 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
2121 entry_count = bfd_get_16 (abfd, l2->entry_count);
2122 l2_encodings_offset = bfd_get_16 (abfd, l2->encodings_offset);
2123 l2_encodings_count = bfd_get_16 (abfd, l2->encodings_count);
2125 printf (" index %2u: compressed second level: "
2126 "%u entries, %u encodings (at 0x%08x)\n",
2127 i, entry_count, l2_encodings_count, l2_encodings_offset);
2128 printf (" # function eidx encoding\n");
2130 en = level2 + entry_offset;
2131 for (j = 0; j < entry_count; j++)
2133 unsigned int entry;
2134 unsigned int en_func;
2135 unsigned int enc_idx;
2136 unsigned int encoding;
2137 const unsigned char *enc_addr;
2139 entry = bfd_get_32 (abfd, en);
2140 en_func =
2141 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry);
2142 enc_idx =
2143 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry);
2144 if (enc_idx < encodings_count)
2145 enc_addr = content + encodings_offset
2146 + 4 * enc_idx;
2147 else
2148 enc_addr = level2 + l2_encodings_offset
2149 + 4 * (enc_idx - encodings_count);
2150 encoding = bfd_get_32 (abfd, enc_addr);
2152 printf (" %4u 0x%08x [%3u] ", j,
2153 func_offset + en_func, enc_idx);
2154 dump_unwind_encoding (mdata, encoding);
2155 putchar ('\n');
2157 en += 4;
2160 break;
2162 case MACH_O_UNWIND_SECOND_LEVEL_REGULAR:
2164 struct mach_o_unwind_regular_second_level_page_header *l2;
2165 struct mach_o_unwind_regular_second_level_entry *en;
2166 unsigned int entry_offset;
2167 unsigned int entry_count;
2168 unsigned int j;
2170 l2 = (struct mach_o_unwind_regular_second_level_page_header *)
2171 level2;
2173 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
2174 entry_count = bfd_get_16 (abfd, l2->entry_count);
2175 printf (" index %2u: regular level 2 at 0x%04x, %u entries\n",
2176 i, entry_offset, entry_count);
2177 printf (" # function encoding\n");
2179 en = (struct mach_o_unwind_regular_second_level_entry *)
2180 (level2 + entry_offset);
2181 for (j = 0; j < entry_count; j++)
2183 unsigned int en_func;
2184 unsigned int encoding;
2186 en_func = bfd_get_32 (abfd, en->function_offset);
2187 encoding = bfd_get_32 (abfd, en->encoding);
2188 printf (" %-4u 0x%08x ", j, en_func);
2189 dump_unwind_encoding (mdata, encoding);
2190 putchar ('\n');
2191 en++;
2194 break;
2196 default:
2197 printf (" index %2u: unhandled second level format (%u)\n",
2198 i, kind);
2199 break;
2203 struct mach_o_unwind_lsda_index_entry *lsda;
2204 unsigned int lsda_offset;
2205 unsigned int next_lsda_offset;
2206 unsigned int nbr_lsda;
2207 unsigned int j;
2209 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
2210 next_lsda_offset = bfd_get_32 (abfd, index_entry[1].lsda_index_offset);
2211 lsda = (struct mach_o_unwind_lsda_index_entry *)
2212 (content + lsda_offset);
2213 nbr_lsda = (next_lsda_offset - lsda_offset) / sizeof (*lsda);
2214 for (j = 0; j < nbr_lsda; j++)
2216 printf (" lsda %3u: function 0x%08x lsda 0x%08x\n",
2217 j, (unsigned int) bfd_get_32 (abfd, lsda->function_offset),
2218 (unsigned int) bfd_get_32 (abfd, lsda->lsda_offset));
2219 lsda++;
2222 index_entry++;
2226 static void
2227 dump_section_content (bfd *abfd,
2228 const char *segname, const char *sectname,
2229 void (*dump)(bfd*, const unsigned char*, bfd_size_type))
2231 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2232 bfd_mach_o_load_command *cmd;
2234 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
2236 if (cmd->type == BFD_MACH_O_LC_SEGMENT
2237 || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
2239 bfd_mach_o_segment_command *seg = &cmd->command.segment;
2240 bfd_mach_o_section *sec;
2241 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
2242 if (strcmp (sec->segname, segname) == 0
2243 && strcmp (sec->sectname, sectname) == 0)
2245 bfd_size_type size;
2246 asection *bfdsec = sec->bfdsection;
2247 unsigned char *content;
2249 size = bfd_section_size (bfdsec);
2250 content = (unsigned char *) xmalloc (size);
2251 bfd_get_section_contents (abfd, bfdsec, content, 0, size);
2253 (*dump)(abfd, content, size);
2255 free (content);
2261 /* Dump ABFD (according to the options[] array). */
2263 static void
2264 mach_o_dump (bfd *abfd)
2266 if (options[OPT_HEADER].selected)
2267 dump_header (abfd);
2268 if (options[OPT_SECTION].selected)
2269 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT, BFD_MACH_O_LC_SEGMENT_64);
2270 if (options[OPT_MAP].selected)
2271 dump_section_map (abfd);
2272 if (options[OPT_LOAD].selected)
2273 dump_load_commands (abfd, 0, 0);
2274 if (options[OPT_DYSYMTAB].selected)
2275 dump_load_commands (abfd, BFD_MACH_O_LC_DYSYMTAB, 0);
2276 if (options[OPT_CODESIGN].selected)
2277 dump_load_commands (abfd, BFD_MACH_O_LC_CODE_SIGNATURE, 0);
2278 if (options[OPT_SEG_SPLIT_INFO].selected)
2279 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO, 0);
2280 if (options[OPT_FUNCTION_STARTS].selected)
2281 dump_load_commands (abfd, BFD_MACH_O_LC_FUNCTION_STARTS, 0);
2282 if (options[OPT_DATA_IN_CODE].selected)
2283 dump_load_commands (abfd, BFD_MACH_O_LC_DATA_IN_CODE, 0);
2284 if (options[OPT_TWOLEVEL_HINTS].selected)
2285 dump_load_commands (abfd, BFD_MACH_O_LC_TWOLEVEL_HINTS, 0);
2286 if (options[OPT_COMPACT_UNWIND].selected)
2288 dump_section_content (abfd, "__LD", "__compact_unwind",
2289 dump_obj_compact_unwind);
2290 dump_section_content (abfd, "__TEXT", "__unwind_info",
2291 dump_exe_compact_unwind);
2293 if (options[OPT_DYLD_INFO].selected)
2294 dump_load_commands (abfd, BFD_MACH_O_LC_DYLD_INFO, 0);
2297 /* Vector for Mach-O. */
2299 const struct objdump_private_desc objdump_private_desc_mach_o =
2301 mach_o_help,
2302 mach_o_filter,
2303 mach_o_dump,
2304 options