]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/od-macho.c
c2bd7d38a89c0153cc1fd6ca1a460e23eac166a9
[thirdparty/binutils-gdb.git] / binutils / od-macho.c
1 /* od-macho.c -- dump information about an Mach-O object file.
2 Copyright (C) 2011-2023 Free Software Foundation, Inc.
3 Written by Tristan Gingold, Adacore.
4
5 This file is part of GNU Binutils.
6
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.
11
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.
16
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. */
21
22 #include "sysdep.h"
23 #include <stddef.h>
24 #include <time.h>
25 #include "safe-ctype.h"
26 #include "libiberty.h"
27 #include "bfd.h"
28 #include "objdump.h"
29 #include "bucomm.h"
30 #include "elfcomm.h"
31 #include "dwarf.h"
32 #include "bfdlink.h"
33 #include "mach-o.h"
34 #include "mach-o/external.h"
35 #include "mach-o/codesign.h"
36 #include "mach-o/unwind.h"
37
38 /* Index of the options in the options[] array. */
39 #define OPT_HEADER 0
40 #define OPT_SECTION 1
41 #define OPT_MAP 2
42 #define OPT_LOAD 3
43 #define OPT_DYSYMTAB 4
44 #define OPT_CODESIGN 5
45 #define OPT_SEG_SPLIT_INFO 6
46 #define OPT_COMPACT_UNWIND 7
47 #define OPT_FUNCTION_STARTS 8
48 #define OPT_DATA_IN_CODE 9
49 #define OPT_TWOLEVEL_HINTS 10
50 #define OPT_DYLD_INFO 11
51
52 /* List of actions. */
53 static struct objdump_private_option options[] =
54 {
55 { "header", 0 },
56 { "section", 0 },
57 { "map", 0 },
58 { "load", 0 },
59 { "dysymtab", 0 },
60 { "codesign", 0 },
61 { "seg_split_info", 0 },
62 { "compact_unwind", 0 },
63 { "function_starts", 0 },
64 { "data_in_code", 0 },
65 { "twolevel_hints", 0 },
66 { "dyld_info", 0 },
67 { NULL, 0 }
68 };
69
70 /* Display help. */
71
72 static void
73 mach_o_help (FILE *stream)
74 {
75 fprintf (stream, _("\
76 For Mach-O files:\n\
77 header Display the file header\n\
78 section Display the segments and sections commands\n\
79 map Display the section map\n\
80 load Display the load commands\n\
81 dysymtab Display the dynamic symbol table\n\
82 codesign Display code signature\n\
83 seg_split_info Display segment split info\n\
84 compact_unwind Display compact unwinding info\n\
85 function_starts Display start address of functions\n\
86 data_in_code Display data in code entries\n\
87 twolevel_hints Display the two-level namespace lookup hints table\n\
88 dyld_info Display dyld information\n\
89 "));
90 }
91
92 /* Return TRUE if ABFD is handled. */
93
94 static int
95 mach_o_filter (bfd *abfd)
96 {
97 return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
98 }
99 \f
100 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
101 {
102 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
103 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
104 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
105 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
106 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
107 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
108 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
109 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
110 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
111 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
112 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
113 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
114 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
115 { "arm64", BFD_MACH_O_CPU_TYPE_ARM64 },
116 { NULL, 0}
117 };
118
119 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
120 {
121 { "object", BFD_MACH_O_MH_OBJECT },
122 { "execute", BFD_MACH_O_MH_EXECUTE },
123 { "fvmlib", BFD_MACH_O_MH_FVMLIB },
124 { "core", BFD_MACH_O_MH_CORE },
125 { "preload", BFD_MACH_O_MH_PRELOAD },
126 { "dylib", BFD_MACH_O_MH_DYLIB },
127 { "dylinker", BFD_MACH_O_MH_DYLINKER },
128 { "bundle", BFD_MACH_O_MH_BUNDLE },
129 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
130 { "dym", BFD_MACH_O_MH_DSYM },
131 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
132 { NULL, 0}
133 };
134
135 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
136 {
137 { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
138 { "incrlink", BFD_MACH_O_MH_INCRLINK },
139 { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
140 { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
141 { "prebound", BFD_MACH_O_MH_PREBOUND },
142 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
143 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
144 { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
145 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
146 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
147 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
148 { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
149 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
150 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
151 { "canonical", BFD_MACH_O_MH_CANONICAL },
152 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
153 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
154 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
155 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
156 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
157 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
158 { "pie", BFD_MACH_O_MH_PIE },
159 { "dead_strippable_dylib", BFD_MACH_O_MH_DEAD_STRIPPABLE_DYLIB },
160 { "has_tlv", BFD_MACH_O_MH_HAS_TLV_DESCRIPTORS },
161 { "no_heap_execution", BFD_MACH_O_MH_NO_HEAP_EXECUTION },
162 { "app_extension_safe", BFD_MACH_O_MH_APP_EXTENSION_SAFE },
163 { NULL, 0}
164 };
165
166 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
167 {
168 { "segment", BFD_MACH_O_LC_SEGMENT},
169 { "symtab", BFD_MACH_O_LC_SYMTAB},
170 { "symseg", BFD_MACH_O_LC_SYMSEG},
171 { "thread", BFD_MACH_O_LC_THREAD},
172 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
173 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
174 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
175 { "ident", BFD_MACH_O_LC_IDENT},
176 { "fvmfile", BFD_MACH_O_LC_FVMFILE},
177 { "prepage", BFD_MACH_O_LC_PREPAGE},
178 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
179 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
180 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
181 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
182 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
183 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
184 { "routines", BFD_MACH_O_LC_ROUTINES},
185 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
186 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
187 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
188 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
189 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
190 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
191 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
192 { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
193 { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
194 { "uuid", BFD_MACH_O_LC_UUID},
195 { "rpath", BFD_MACH_O_LC_RPATH},
196 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
197 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
198 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
199 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
200 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
201 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
202 { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
203 { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
204 { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
205 { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
206 { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
207 { "main", BFD_MACH_O_LC_MAIN},
208 { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE},
209 { "source_version", BFD_MACH_O_LC_SOURCE_VERSION},
210 { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS},
211 { "encryption_info_64", BFD_MACH_O_LC_ENCRYPTION_INFO_64},
212 { "linker_options", BFD_MACH_O_LC_LINKER_OPTIONS},
213 { "linker_optimization_hint", BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT},
214 { "version_min_tvos", BFD_MACH_O_LC_VERSION_MIN_TVOS},
215 { "version_min_watchos", BFD_MACH_O_LC_VERSION_MIN_WATCHOS},
216 { "note", BFD_MACH_O_LC_NOTE},
217 { "build_version", BFD_MACH_O_LC_BUILD_VERSION},
218 { "exports_trie", BFD_MACH_O_LC_DYLD_EXPORTS_TRIE},
219 { "chained_fixups", BFD_MACH_O_LC_DYLD_CHAINED_FIXUPS},
220 { NULL, 0}
221 };
222
223 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
224 {
225 { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32},
226 { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32},
227 { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32},
228 { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64},
229 { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64},
230 { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64},
231 { "thread_state", BFD_MACH_O_x86_THREAD_STATE},
232 { "float_state", BFD_MACH_O_x86_FLOAT_STATE},
233 { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE},
234 { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32},
235 { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64},
236 { "debug_state", BFD_MACH_O_x86_DEBUG_STATE},
237 { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
238 { NULL, 0 }
239 };
240
241 static const bfd_mach_o_xlat_name bfd_mach_o_platform_name[] =
242 {
243 { "macos", BFD_MACH_O_PLATFORM_MACOS},
244 { "ios", BFD_MACH_O_PLATFORM_IOS},
245 { "tvos", BFD_MACH_O_PLATFORM_TVOS},
246 { "watchos", BFD_MACH_O_PLATFORM_WATCHOS},
247 { "bridgeos", BFD_MACH_O_PLATFORM_BRIDGEOS},
248 { NULL, 0 }
249 };
250
251 static const bfd_mach_o_xlat_name bfd_mach_o_tool_name[] =
252 {
253 { "clang", BFD_MACH_O_TOOL_CLANG},
254 { "swift", BFD_MACH_O_TOOL_SWIFT},
255 { "ld", BFD_MACH_O_TOOL_LD},
256 { NULL, 0 }
257 };
258
259 static void
260 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
261 unsigned long val)
262 {
263 int first = 1;
264
265 for (; table->name; table++)
266 {
267 if (table->val & val)
268 {
269 if (!first)
270 printf ("+");
271 printf ("%s", table->name);
272 val &= ~table->val;
273 first = 0;
274 }
275 }
276 if (val)
277 {
278 if (!first)
279 printf ("+");
280 printf ("0x%lx", val);
281 return;
282 }
283 if (first)
284 printf ("-");
285 }
286
287 static const char *
288 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
289 unsigned long val)
290 {
291 for (; table->name; table++)
292 if (table->val == val)
293 return table->name;
294 return NULL;
295 }
296
297 static const char *
298 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
299 {
300 const char *res = bfd_mach_o_get_name_or_null (table, val);
301
302 if (res == NULL)
303 return "*UNKNOWN*";
304 else
305 return res;
306 }
307
308 static void
309 dump_header (bfd *abfd)
310 {
311 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
312 bfd_mach_o_header *h = &mdata->header;
313
314 fputs (_("Mach-O header:\n"), stdout);
315 printf (_(" magic : %08lx\n"), h->magic);
316 printf (_(" cputype : %08lx (%s)\n"), h->cputype,
317 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
318 printf (_(" cpusubtype: %08lx\n"), h->cpusubtype);
319 printf (_(" filetype : %08lx (%s)\n"),
320 h->filetype,
321 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
322 printf (_(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
323 printf (_(" sizeofcmds: %08lx (%lu)\n"), h->sizeofcmds, h->sizeofcmds);
324 printf (_(" flags : %08lx ("), h->flags);
325 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
326 fputs (_(")\n"), stdout);
327 printf (_(" reserved : %08x\n"), h->reserved);
328 putchar ('\n');
329 }
330
331 static void
332 disp_segment_prot (unsigned int prot)
333 {
334 putchar (prot & BFD_MACH_O_PROT_READ ? 'r' : '-');
335 putchar (prot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
336 putchar (prot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
337 }
338
339 static void
340 dump_section_map (bfd *abfd)
341 {
342 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
343 bfd_mach_o_load_command *cmd;
344 unsigned int sec_nbr = 0;
345
346 fputs (_("Segments and Sections:\n"), stdout);
347 fputs (_(" #: Segment name Section name Address\n"), stdout);
348
349 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
350 {
351 bfd_mach_o_segment_command *seg;
352 bfd_mach_o_section *sec;
353
354 if (cmd->type != BFD_MACH_O_LC_SEGMENT
355 && cmd->type != BFD_MACH_O_LC_SEGMENT_64)
356 continue;
357
358 seg = &cmd->command.segment;
359
360 printf ("[Segment %-16s ", seg->segname);
361 bfd_printf_vma (abfd, seg->vmaddr);
362 putchar ('-');
363 bfd_printf_vma (abfd, seg->vmaddr + seg->vmsize - 1);
364 putchar (' ');
365 disp_segment_prot (seg->initprot);
366 printf ("]\n");
367
368 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
369 {
370 printf ("%02u: %-16s %-16s ", ++sec_nbr,
371 sec->segname, sec->sectname);
372 bfd_printf_vma (abfd, sec->addr);
373 putchar (' ');
374 bfd_printf_vma (abfd, sec->size);
375 printf (" %08lx\n", sec->flags);
376 }
377 }
378 }
379
380 static void
381 dump_section_header (bfd *abfd, bfd_mach_o_section *sec)
382 {
383 printf (" Section: %-16s %-16s (bfdname: %s)\n",
384 sec->sectname, sec->segname, sec->bfdsection->name);
385 printf (" addr: ");
386 bfd_printf_vma (abfd, sec->addr);
387 printf (" size: ");
388 bfd_printf_vma (abfd, sec->size);
389 printf (" offset: ");
390 bfd_printf_vma (abfd, sec->offset);
391 printf ("\n");
392 printf (" align: %ld", sec->align);
393 printf (" nreloc: %lu reloff: ", sec->nreloc);
394 bfd_printf_vma (abfd, sec->reloff);
395 printf ("\n");
396 printf (" flags: %08lx (type: %s", sec->flags,
397 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
398 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
399 printf (" attr: ");
400 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
401 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
402 printf (")\n");
403 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
404 {
405 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
406 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
407 case BFD_MACH_O_S_SYMBOL_STUBS:
408 printf (" first indirect sym: %lu", sec->reserved1);
409 printf (" (%u entries)",
410 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
411 break;
412 default:
413 printf (" reserved1: 0x%lx", sec->reserved1);
414 break;
415 }
416 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
417 {
418 case BFD_MACH_O_S_SYMBOL_STUBS:
419 printf (" stub size: %lu", sec->reserved2);
420 break;
421 default:
422 printf (" reserved2: 0x%lx", sec->reserved2);
423 break;
424 }
425 printf (" reserved3: 0x%lx\n", sec->reserved3);
426 }
427
428 static void
429 dump_segment (bfd *abfd, bfd_mach_o_load_command *cmd)
430 {
431 bfd_mach_o_segment_command *seg = &cmd->command.segment;
432 bfd_mach_o_section *sec;
433
434 printf (" name: %16s", *seg->segname ? seg->segname : "*none*");
435 printf (" nsects: %lu", seg->nsects);
436 printf (" flags: %lx", seg->flags);
437 printf (" initprot: ");
438 disp_segment_prot (seg->initprot);
439 printf (" maxprot: ");
440 disp_segment_prot (seg->maxprot);
441 printf ("\n");
442 printf (" vmaddr: ");
443 bfd_printf_vma (abfd, seg->vmaddr);
444 printf (" vmsize: ");
445 bfd_printf_vma (abfd, seg->vmsize);
446 printf ("\n");
447 printf (" fileoff: ");
448 bfd_printf_vma (abfd, seg->fileoff);
449 printf (" filesize: ");
450 bfd_printf_vma (abfd, (bfd_vma) seg->filesize);
451 printf (" endoff: ");
452 bfd_printf_vma (abfd, (bfd_vma) (seg->fileoff + seg->filesize));
453 printf ("\n");
454 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
455 dump_section_header (abfd, sec);
456 }
457
458 static void
459 dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bool verbose)
460 {
461 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
462 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
463 unsigned int i;
464
465 printf (" local symbols: idx: %10lu num: %-8lu",
466 dysymtab->ilocalsym, dysymtab->nlocalsym);
467 printf (" (nxtidx: %lu)\n",
468 dysymtab->ilocalsym + dysymtab->nlocalsym);
469 printf (" external symbols: idx: %10lu num: %-8lu",
470 dysymtab->iextdefsym, dysymtab->nextdefsym);
471 printf (" (nxtidx: %lu)\n",
472 dysymtab->iextdefsym + dysymtab->nextdefsym);
473 printf (" undefined symbols: idx: %10lu num: %-8lu",
474 dysymtab->iundefsym, dysymtab->nundefsym);
475 printf (" (nxtidx: %lu)\n",
476 dysymtab->iundefsym + dysymtab->nundefsym);
477 printf (" table of content: off: 0x%08lx num: %-8lu",
478 dysymtab->tocoff, dysymtab->ntoc);
479 printf (" (endoff: 0x%08lx)\n",
480 dysymtab->tocoff + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
481 printf (" module table: off: 0x%08lx num: %-8lu",
482 dysymtab->modtaboff, dysymtab->nmodtab);
483 printf (" (endoff: 0x%08lx)\n",
484 dysymtab->modtaboff + dysymtab->nmodtab
485 * (mdata->header.version == 2 ?
486 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
487 printf (" external reference table: off: 0x%08lx num: %-8lu",
488 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
489 printf (" (endoff: 0x%08lx)\n",
490 dysymtab->extrefsymoff
491 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
492 printf (" indirect symbol table: off: 0x%08lx num: %-8lu",
493 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
494 printf (" (endoff: 0x%08lx)\n",
495 dysymtab->indirectsymoff
496 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
497 printf (" external relocation table: off: 0x%08lx num: %-8lu",
498 dysymtab->extreloff, dysymtab->nextrel);
499 printf (" (endoff: 0x%08lx)\n",
500 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
501 printf (" local relocation table: off: 0x%08lx num: %-8lu",
502 dysymtab->locreloff, dysymtab->nlocrel);
503 printf (" (endoff: 0x%08lx)\n",
504 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
505
506 if (!verbose)
507 return;
508
509 if (dysymtab->ntoc > 0
510 || dysymtab->nindirectsyms > 0
511 || dysymtab->nextrefsyms > 0)
512 {
513 /* Try to read the symbols to display the toc or indirect symbols. */
514 bfd_mach_o_read_symtab_symbols (abfd);
515 }
516 else if (dysymtab->nmodtab > 0)
517 {
518 /* Try to read the strtab to display modules name. */
519 bfd_mach_o_read_symtab_strtab (abfd);
520 }
521
522 for (i = 0; i < dysymtab->nmodtab; i++)
523 {
524 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
525 printf (" module %u:\n", i);
526 printf (" name: %lu", module->module_name_idx);
527 if (mdata->symtab && mdata->symtab->strtab)
528 printf (": %s",
529 mdata->symtab->strtab + module->module_name_idx);
530 printf ("\n");
531 printf (" extdefsym: idx: %8lu num: %lu\n",
532 module->iextdefsym, module->nextdefsym);
533 printf (" refsym: idx: %8lu num: %lu\n",
534 module->irefsym, module->nrefsym);
535 printf (" localsym: idx: %8lu num: %lu\n",
536 module->ilocalsym, module->nlocalsym);
537 printf (" extrel: idx: %8lu num: %lu\n",
538 module->iextrel, module->nextrel);
539 printf (" init: idx: %8u num: %u\n",
540 module->iinit, module->ninit);
541 printf (" term: idx: %8u num: %u\n",
542 module->iterm, module->nterm);
543 printf (" objc_module_info: addr: ");
544 bfd_printf_vma (abfd, module->objc_module_info_addr);
545 printf (" size: %lu\n", module->objc_module_info_size);
546 }
547
548 if (dysymtab->ntoc > 0)
549 {
550 bfd_mach_o_symtab_command *symtab = mdata->symtab;
551
552 printf (" table of content: (symbol/module)\n");
553 for (i = 0; i < dysymtab->ntoc; i++)
554 {
555 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
556
557 printf (" %4u: ", i);
558 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
559 {
560 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
561 printf ("%s (%lu)", name ? name : "*invalid*",
562 toc->symbol_index);
563 }
564 else
565 printf ("%lu", toc->symbol_index);
566
567 printf (" / ");
568 if (symtab && symtab->strtab
569 && toc->module_index < dysymtab->nmodtab)
570 {
571 bfd_mach_o_dylib_module *mod;
572 mod = &dysymtab->dylib_module[toc->module_index];
573 printf ("%s (%lu)",
574 symtab->strtab + mod->module_name_idx,
575 toc->module_index);
576 }
577 else
578 printf ("%lu", toc->module_index);
579
580 printf ("\n");
581 }
582 }
583
584 if (dysymtab->nindirectsyms != 0)
585 {
586 printf (" indirect symbols:\n");
587
588 for (i = 0; i < mdata->nsects; i++)
589 {
590 bfd_mach_o_section *sec = mdata->sections[i];
591 unsigned int j, first, last;
592 bfd_mach_o_symtab_command *symtab = mdata->symtab;
593 bfd_vma addr;
594 bfd_vma entry_size;
595
596 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
597 {
598 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
599 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
600 case BFD_MACH_O_S_SYMBOL_STUBS:
601 first = sec->reserved1;
602 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
603 addr = sec->addr;
604 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
605 printf (" for section %s.%s:\n",
606 sec->segname, sec->sectname);
607 for (j = first; j < last; j++)
608 {
609 unsigned int isym = dysymtab->indirect_syms[j];
610
611 printf (" ");
612 bfd_printf_vma (abfd, addr);
613 printf (" %5u: 0x%08x", j, isym);
614 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
615 printf (" LOCAL");
616 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
617 printf (" ABSOLUTE");
618 if (symtab && symtab->symbols
619 && isym < symtab->nsyms
620 && symtab->symbols[isym].symbol.name)
621 printf (" %s", symtab->symbols[isym].symbol.name);
622 printf ("\n");
623 addr += entry_size;
624 }
625 break;
626 default:
627 break;
628 }
629 }
630 }
631 if (dysymtab->nextrefsyms > 0)
632 {
633 bfd_mach_o_symtab_command *symtab = mdata->symtab;
634
635 printf (" external reference table: (symbol flags)\n");
636 for (i = 0; i < dysymtab->nextrefsyms; i++)
637 {
638 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
639
640 printf (" %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
641 if (symtab && symtab->symbols
642 && ref->isym < symtab->nsyms
643 && symtab->symbols[ref->isym].symbol.name)
644 printf (" %s", symtab->symbols[ref->isym].symbol.name);
645 printf ("\n");
646 }
647 }
648
649 }
650
651 static bool
652 load_and_dump (bfd *abfd, ufile_ptr off, unsigned int len,
653 void (*dump)(bfd *abfd, unsigned char *buf, unsigned int len,
654 ufile_ptr off))
655 {
656 unsigned char *buf;
657
658 if (len == 0)
659 return true;
660
661 buf = xmalloc (len);
662
663 if (bfd_seek (abfd, off, SEEK_SET) == 0
664 && bfd_bread (buf, len, abfd) == len)
665 dump (abfd, buf, len, off);
666 else
667 return false;
668
669 free (buf);
670 return true;
671 }
672
673 static const bfd_mach_o_xlat_name bfd_mach_o_dyld_rebase_type_name[] =
674 {
675 { "pointer", BFD_MACH_O_REBASE_TYPE_POINTER },
676 { "text_abs32", BFD_MACH_O_REBASE_TYPE_TEXT_ABSOLUTE32 },
677 { "text_pcrel32", BFD_MACH_O_REBASE_TYPE_TEXT_PCREL32 },
678 { NULL, 0 }
679 };
680
681 static void
682 dump_dyld_info_rebase (bfd *abfd, unsigned char *buf, unsigned int len,
683 ufile_ptr off ATTRIBUTE_UNUSED)
684 {
685 unsigned int i;
686 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
687 unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
688
689 for (i = 0; i < len; )
690 {
691 unsigned char b = buf[i++];
692 unsigned char imm = b & BFD_MACH_O_REBASE_IMMEDIATE_MASK;
693 bfd_vma leb;
694 unsigned int leblen;
695
696 printf (" [0x%04x] 0x%02x: ", i, b);
697 switch (b & BFD_MACH_O_REBASE_OPCODE_MASK)
698 {
699 case BFD_MACH_O_REBASE_OPCODE_DONE:
700 printf ("done\n");
701 return;
702 case BFD_MACH_O_REBASE_OPCODE_SET_TYPE_IMM:
703 printf ("set_type %s\n",
704 bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
705 break;
706 case BFD_MACH_O_REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
707 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
708 printf ("set segment: %u and offset: 0x%08x\n",
709 imm, (unsigned) leb);
710 i += leblen;
711 break;
712 case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_ULEB:
713 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
714 printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
715 i += leblen;
716 break;
717 case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
718 printf ("add addr imm scaled: %u\n", imm * ptrsize);
719 break;
720 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_IMM_TIMES:
721 printf ("rebase imm times: %u\n", imm);
722 break;
723 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
724 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
725 printf ("rebase uleb times: %u\n", (unsigned) leb);
726 i += leblen;
727 break;
728 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
729 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
730 printf ("rebase add addr uleb: %u\n", (unsigned) leb);
731 i += leblen;
732 break;
733 case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
734 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
735 printf ("rebase uleb times (%u)", (unsigned) leb);
736 i += leblen;
737 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
738 printf (" skipping uleb (%u)\n", (unsigned) leb);
739 i += leblen;
740 break;
741 default:
742 printf ("unknown\n");
743 return;
744 }
745 }
746 printf (" rebase commands without end!\n");
747 }
748
749 static void
750 dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len,
751 ufile_ptr off ATTRIBUTE_UNUSED)
752 {
753 unsigned int i;
754 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
755 unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4;
756
757 for (i = 0; i < len; )
758 {
759 unsigned char b = buf[i++];
760 unsigned char imm = b & BFD_MACH_O_BIND_IMMEDIATE_MASK;
761 bfd_vma leb;
762 unsigned int leblen;
763
764 printf (" [0x%04x] 0x%02x: ", i, b);
765 switch (b & BFD_MACH_O_BIND_OPCODE_MASK)
766 {
767 case BFD_MACH_O_BIND_OPCODE_DONE:
768 printf ("done\n");
769 return;
770 case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
771 printf ("set dylib ordinal imm: %u\n", imm);
772 break;
773 case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
774 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
775 printf ("set dylib ordinal uleb: %u\n", imm);
776 i += leblen;
777 break;
778 case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
779 imm = (imm != 0) ? imm | BFD_MACH_O_BIND_OPCODE_MASK : imm;
780 printf ("set dylib special imm: %d\n", imm);
781 break;
782 case BFD_MACH_O_BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
783 printf ("set symbol trailing flags imm: 0x%02x, ", imm);
784 for (; i < len && buf[i] != 0; i++)
785 putchar (buf[i] >= ' ' && buf[i] < 0x7f ? buf[i] : '?');
786 putchar ('\n');
787 i++;
788 break;
789 case BFD_MACH_O_BIND_OPCODE_SET_TYPE_IMM:
790 /* Kludge: use the same table as rebase type. */
791 printf ("set_type %s\n",
792 bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm));
793 break;
794 case BFD_MACH_O_BIND_OPCODE_SET_ADDEND_SLEB:
795 {
796 bfd_signed_vma svma;
797 svma = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
798 printf ("set addend sleb: 0x%08x\n", (unsigned) svma);
799 i += leblen;
800 }
801 break;
802 case BFD_MACH_O_BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
803 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
804 printf ("set segment: %u and offset: 0x%08x\n",
805 imm, (unsigned) leb);
806 i += leblen;
807 break;
808 case BFD_MACH_O_BIND_OPCODE_ADD_ADDR_ULEB:
809 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
810 printf ("add addr uleb: 0x%08x\n", (unsigned) leb);
811 i += leblen;
812 break;
813 case BFD_MACH_O_BIND_OPCODE_DO_BIND:
814 printf ("do bind\n");
815 break;
816 case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
817 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
818 printf ("do bind add addr uleb: 0x%08x\n", (unsigned) leb);
819 i += leblen;
820 break;
821 case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
822 printf ("do bind add addr imm scaled: %u\n", imm * ptrsize);
823 break;
824 case BFD_MACH_O_BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
825 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
826 printf ("do bind uleb times (%u)", (unsigned) leb);
827 i += leblen;
828 leb = read_leb128 (buf + i, buf + len, 0, &leblen, NULL);
829 printf (" skipping uleb (%u)\n", (unsigned) leb);
830 i += leblen;
831 break;
832 default:
833 printf ("unknown\n");
834 return;
835 }
836 }
837 printf (" bind commands without end!\n");
838 }
839
840 struct export_info_data
841 {
842 const unsigned char *name;
843 struct export_info_data *next;
844 };
845
846 static void
847 dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len,
848 unsigned int off, struct export_info_data *parent,
849 struct export_info_data *base)
850 {
851 bfd_vma size;
852 unsigned int leblen;
853 unsigned int child_count;
854 unsigned int i;
855
856 size = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
857 off += leblen;
858
859 if (size != 0)
860 {
861 bfd_vma flags;
862 struct export_info_data *d;
863
864 flags = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
865 off += leblen;
866
867 fputs (" ", stdout);
868 switch (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_MASK)
869 {
870 case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_REGULAR:
871 putchar ('-');
872 break;
873 case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL:
874 putchar ('T');
875 break;
876 default:
877 putchar ('?');
878 break;
879 }
880 putchar ((flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION) ?
881 'W' : '-');
882
883 if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_REEXPORT)
884 {
885 bfd_vma lib;
886
887 lib = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
888 off += leblen;
889
890 fputs (" [reexport] ", stdout);
891 for (d = base; d != NULL; d = d->next)
892 printf ("%s", d->name);
893
894 fputs (" (", stdout);
895 if (buf[off] != 0)
896 {
897 fputs ((const char *)buf + off, stdout);
898 putchar (' ');
899 off += strlen ((const char *)buf + off);
900 }
901 printf ("from dylib %u)\n", (unsigned) lib);
902 off++;
903 }
904 else
905 {
906 bfd_vma offset;
907 bfd_vma resolv = 0;
908
909 offset = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
910 off += leblen;
911
912 if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
913 {
914 resolv = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
915 off += leblen;
916 }
917
918 printf (" 0x%08x ", (unsigned) offset);
919 for (d = base; d != NULL; d = d->next)
920 printf ("%s", d->name);
921 if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
922 printf (" [resolv: 0x%08x]", (unsigned) resolv);
923 printf ("\n");
924 }
925 }
926
927 child_count = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
928 off += leblen;
929
930 for (i = 0; i < child_count; i++)
931 {
932 struct export_info_data sub_data;
933 bfd_vma sub_off;
934
935 sub_data.name = buf + off;
936 sub_data.next = NULL;
937 parent->next = &sub_data;
938
939 off += strlen ((const char *)buf + off) + 1;
940
941 sub_off = read_leb128 (buf + off, buf + len, 0, &leblen, NULL);
942 off += leblen;
943
944 dump_dyld_info_export_1 (abfd, buf, len, sub_off, &sub_data, base);
945 }
946 }
947
948 static void
949 dump_dyld_info_export (bfd *abfd, unsigned char *buf, unsigned int len,
950 ufile_ptr off ATTRIBUTE_UNUSED)
951 {
952 struct export_info_data data;
953
954 data.name = (const unsigned char *) "";
955 data.next = NULL;
956
957 printf (" fl offset sym (Flags: Tls Weak)\n");
958 dump_dyld_info_export_1 (abfd, buf, len, 0, &data, &data);
959 }
960
961 static void
962 dump_dyld_info (bfd *abfd, bfd_mach_o_load_command *cmd,
963 bool verbose)
964 {
965 bfd_mach_o_dyld_info_command *dinfo = &cmd->command.dyld_info;
966
967 printf (" rebase: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
968 dinfo->rebase_off, dinfo->rebase_size,
969 dinfo->rebase_off + dinfo->rebase_size);
970 printf (" bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
971 dinfo->bind_off, dinfo->bind_size,
972 dinfo->bind_off + dinfo->bind_size);
973 printf (" weak bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
974 dinfo->weak_bind_off, dinfo->weak_bind_size,
975 dinfo->weak_bind_off + dinfo->weak_bind_size);
976 printf (" lazy bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
977 dinfo->lazy_bind_off, dinfo->lazy_bind_size,
978 dinfo->lazy_bind_off + dinfo->lazy_bind_size);
979 printf (" export: off: 0x%08x size: %-8u (endoff: 0x%08x)\n",
980 dinfo->export_off, dinfo->export_size,
981 dinfo->export_off + dinfo->export_size);
982
983 if (!verbose)
984 return;
985
986 printf (" rebase:\n");
987 if (!load_and_dump (abfd, dinfo->rebase_off, dinfo->rebase_size,
988 dump_dyld_info_rebase))
989 non_fatal (_("cannot read rebase dyld info"));
990
991 printf (" bind:\n");
992 if (!load_and_dump (abfd, dinfo->bind_off, dinfo->bind_size,
993 dump_dyld_info_bind))
994 non_fatal (_("cannot read bind dyld info"));
995
996 printf (" weak bind:\n");
997 if (!load_and_dump (abfd, dinfo->weak_bind_off, dinfo->weak_bind_size,
998 dump_dyld_info_bind))
999 non_fatal (_("cannot read weak bind dyld info"));
1000
1001 printf (" lazy bind:\n");
1002 if (!load_and_dump (abfd, dinfo->lazy_bind_off, dinfo->lazy_bind_size,
1003 dump_dyld_info_bind))
1004 non_fatal (_("cannot read lazy bind dyld info"));
1005
1006 printf (" exported symbols:\n");
1007 if (!load_and_dump (abfd, dinfo->export_off, dinfo->export_size,
1008 dump_dyld_info_export))
1009 non_fatal (_("cannot read export symbols dyld info"));
1010 }
1011
1012 static void
1013 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
1014 {
1015 bfd_mach_o_thread_command *thread = &cmd->command.thread;
1016 unsigned int j;
1017 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
1018 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1019
1020 printf (" nflavours: %lu\n", thread->nflavours);
1021 for (j = 0; j < thread->nflavours; j++)
1022 {
1023 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
1024 const bfd_mach_o_xlat_name *name_table;
1025
1026 printf (" %2u: flavour: 0x%08lx", j, flavour->flavour);
1027 switch (mdata->header.cputype)
1028 {
1029 case BFD_MACH_O_CPU_TYPE_I386:
1030 case BFD_MACH_O_CPU_TYPE_X86_64:
1031 name_table = bfd_mach_o_thread_x86_name;
1032 break;
1033 default:
1034 name_table = NULL;
1035 break;
1036 }
1037 if (name_table != NULL)
1038 printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
1039 putchar ('\n');
1040
1041 printf (" offset: 0x%08lx size: 0x%08lx\n",
1042 flavour->offset, flavour->size);
1043 if (bed->_bfd_mach_o_print_thread)
1044 {
1045 char *buf = xmalloc (flavour->size);
1046
1047 if (bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
1048 && bfd_bread (buf, flavour->size, abfd) == flavour->size)
1049 (*bed->_bfd_mach_o_print_thread)(abfd, flavour, stdout, buf);
1050
1051 free (buf);
1052 }
1053 }
1054 }
1055
1056 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic[] =
1057 {
1058 { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE },
1059 { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT },
1060 { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS },
1061 { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY },
1062 { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS },
1063 { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER },
1064 { NULL, 0 }
1065 };
1066
1067 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type[] =
1068 {
1069 { "no-hash", BFD_MACH_O_CS_NO_HASH },
1070 { "sha1", BFD_MACH_O_CS_HASH_SHA1 },
1071 { "sha256", BFD_MACH_O_CS_HASH_SHA256 },
1072 { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256 },
1073 { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512 },
1074 { NULL, 0 }
1075 };
1076
1077 static unsigned int
1078 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
1079
1080 static void
1081 dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
1082 const unsigned char *buf, unsigned int len)
1083 {
1084 unsigned int count;
1085 unsigned int i;
1086
1087 if (len < 12)
1088 {
1089 printf (_(" [bad block length]\n"));
1090 return;
1091 }
1092 count = bfd_getb32 (buf + 8);
1093 printf (ngettext (" %u index entry:\n",
1094 " %u index entries:\n",
1095 count),
1096 count);
1097 if (len < 12 + 8 * count)
1098 {
1099 printf (_(" [bad block length]\n"));
1100 return;
1101 }
1102 for (i = 0; i < count; i++)
1103 {
1104 unsigned int type;
1105 unsigned int off;
1106
1107 type = bfd_getb32 (buf + 12 + 8 * i);
1108 off = bfd_getb32 (buf + 12 + 8 * i + 4);
1109 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
1110 i, type, off);
1111
1112 dump_code_signature_blob (abfd, buf + off, len - off);
1113 }
1114 }
1115
1116 static void
1117 swap_code_codedirectory_v1_in
1118 (const struct mach_o_codesign_codedirectory_external_v1 *src,
1119 struct mach_o_codesign_codedirectory_v1 *dst)
1120 {
1121 dst->version = bfd_getb32 (src->version);
1122 dst->flags = bfd_getb32 (src->flags);
1123 dst->hash_offset = bfd_getb32 (src->hash_offset);
1124 dst->ident_offset = bfd_getb32 (src->ident_offset);
1125 dst->nbr_special_slots = bfd_getb32 (src->nbr_special_slots);
1126 dst->nbr_code_slots = bfd_getb32 (src->nbr_code_slots);
1127 dst->code_limit = bfd_getb32 (src->code_limit);
1128 dst->hash_size = src->hash_size[0];
1129 dst->hash_type = src->hash_type[0];
1130 dst->spare1 = src->spare1[0];
1131 dst->page_size = src->page_size[0];
1132 dst->spare2 = bfd_getb32 (src->spare2);
1133 }
1134
1135 static void
1136 hexdump (unsigned int start, unsigned int len,
1137 const unsigned char *buf)
1138 {
1139 unsigned int i, j;
1140
1141 for (i = 0; i < len; i += 16)
1142 {
1143 printf ("%08x:", start + i);
1144 for (j = 0; j < 16; j++)
1145 {
1146 fputc (j == 8 ? '-' : ' ', stdout);
1147 if (i + j < len)
1148 printf ("%02x", buf[i + j]);
1149 else
1150 fputs (" ", stdout);
1151 }
1152 fputc (' ', stdout);
1153 for (j = 0; j < 16; j++)
1154 {
1155 if (i + j < len)
1156 fputc (ISPRINT (buf[i + j]) ? buf[i + j] : '.', stdout);
1157 else
1158 fputc (' ', stdout);
1159 }
1160 fputc ('\n', stdout);
1161 }
1162 }
1163
1164 static void
1165 dump_code_signature_codedirectory (bfd *abfd ATTRIBUTE_UNUSED,
1166 const unsigned char *buf, unsigned int len)
1167 {
1168 struct mach_o_codesign_codedirectory_v1 cd;
1169 const char *id;
1170
1171 if (len < sizeof (struct mach_o_codesign_codedirectory_external_v1))
1172 {
1173 printf (_(" [bad block length]\n"));
1174 return;
1175 }
1176
1177 swap_code_codedirectory_v1_in
1178 ((const struct mach_o_codesign_codedirectory_external_v1 *) (buf + 8), &cd);
1179
1180 printf (_(" version: %08x\n"), cd.version);
1181 printf (_(" flags: %08x\n"), cd.flags);
1182 printf (_(" hash offset: %08x\n"), cd.hash_offset);
1183 id = (const char *) buf + cd.ident_offset;
1184 printf (_(" ident offset: %08x (- %08x)\n"),
1185 cd.ident_offset, cd.ident_offset + (unsigned) strlen (id) + 1);
1186 printf (_(" identity: %s\n"), id);
1187 printf (_(" nbr special slots: %08x (at offset %08x)\n"),
1188 cd.nbr_special_slots,
1189 cd.hash_offset - cd.nbr_special_slots * cd.hash_size);
1190 printf (_(" nbr code slots: %08x\n"), cd.nbr_code_slots);
1191 printf (_(" code limit: %08x\n"), cd.code_limit);
1192 printf (_(" hash size: %02x\n"), cd.hash_size);
1193 printf (_(" hash type: %02x (%s)\n"),
1194 cd.hash_type,
1195 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type, cd.hash_type));
1196 printf (_(" spare1: %02x\n"), cd.spare1);
1197 printf (_(" page size: %02x\n"), cd.page_size);
1198 printf (_(" spare2: %08x\n"), cd.spare2);
1199 if (cd.version >= 0x20100)
1200 printf (_(" scatter offset: %08x\n"),
1201 (unsigned) bfd_getb32 (buf + 44));
1202 }
1203
1204 static unsigned int
1205 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len)
1206 {
1207 unsigned int magic;
1208 unsigned int length;
1209
1210 if (len < 8)
1211 {
1212 printf (_(" [truncated block]\n"));
1213 return 0;
1214 }
1215 magic = bfd_getb32 (buf);
1216 length = bfd_getb32 (buf + 4);
1217 if (magic == 0 || length == 0)
1218 return 0;
1219
1220 printf (_(" magic : %08x (%s)\n"), magic,
1221 bfd_mach_o_get_name (bfd_mach_o_cs_magic, magic));
1222 printf (_(" length: %08x\n"), length);
1223 if (length > len)
1224 {
1225 printf (_(" [bad block length]\n"));
1226 return 0;
1227 }
1228
1229 switch (magic)
1230 {
1231 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE:
1232 dump_code_signature_superblob (abfd, buf, length);
1233 break;
1234 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY:
1235 dump_code_signature_codedirectory (abfd, buf, length);
1236 break;
1237 default:
1238 hexdump (0, length - 8, buf + 8);
1239 break;
1240 }
1241 return length;
1242 }
1243
1244 static void
1245 dump_code_signature (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1246 {
1247 unsigned char *buf = xmalloc (cmd->datasize);
1248 unsigned int off;
1249
1250 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1251 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1252 {
1253 non_fatal (_("cannot read code signature data"));
1254 free (buf);
1255 return;
1256 }
1257 for (off = 0; off < cmd->datasize;)
1258 {
1259 unsigned int len;
1260
1261 len = dump_code_signature_blob (abfd, buf + off, cmd->datasize - off);
1262
1263 if (len == 0)
1264 break;
1265 off += len;
1266 }
1267 free (buf);
1268 }
1269
1270 static void
1271 dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1272 {
1273 unsigned char *buf = xmalloc (cmd->datasize);
1274 unsigned char *p;
1275 unsigned int len;
1276 bfd_vma addr = 0;
1277
1278 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1279 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1280 {
1281 non_fatal (_("cannot read segment split info"));
1282 free (buf);
1283 return;
1284 }
1285 if (buf[cmd->datasize - 1] != 0)
1286 {
1287 non_fatal (_("segment split info is not nul terminated"));
1288 free (buf);
1289 return;
1290 }
1291
1292 switch (buf[0])
1293 {
1294 case 0:
1295 printf (_(" 32 bit pointers:\n"));
1296 break;
1297 case 1:
1298 printf (_(" 64 bit pointers:\n"));
1299 break;
1300 case 2:
1301 printf (_(" PPC hi-16:\n"));
1302 break;
1303 default:
1304 printf (_(" Unhandled location type %u\n"), buf[0]);
1305 break;
1306 }
1307 for (p = buf + 1; *p != 0; p += len)
1308 {
1309 addr += read_leb128 (p, buf + cmd->datasize, 0, &len, NULL);
1310 fputs (" ", stdout);
1311 bfd_printf_vma (abfd, addr);
1312 putchar ('\n');
1313 }
1314 free (buf);
1315 }
1316
1317 static void
1318 dump_function_starts (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1319 {
1320 unsigned char *buf = xmalloc (cmd->datasize);
1321 unsigned char *end_buf = buf + cmd->datasize;
1322 unsigned char *p;
1323 bfd_vma addr;
1324
1325 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1326 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1327 {
1328 non_fatal (_("cannot read function starts"));
1329 free (buf);
1330 return;
1331 }
1332
1333 /* Function starts are delta encoded, starting from the base address. */
1334 addr = bfd_mach_o_get_base_address (abfd);
1335
1336 for (p = buf; ;)
1337 {
1338 bfd_vma delta = 0;
1339 unsigned int shift = 0;
1340
1341 if (*p == 0 || p == end_buf)
1342 break;
1343 while (1)
1344 {
1345 unsigned char b = *p++;
1346
1347 delta |= (b & 0x7f) << shift;
1348 if ((b & 0x80) == 0)
1349 break;
1350 if (p == end_buf)
1351 {
1352 fputs (" [truncated]\n", stdout);
1353 break;
1354 }
1355 shift += 7;
1356 }
1357
1358 addr += delta;
1359 fputs (" ", stdout);
1360 bfd_printf_vma (abfd, addr);
1361 putchar ('\n');
1362 }
1363 free (buf);
1364 }
1365
1366 static const bfd_mach_o_xlat_name data_in_code_kind_name[] =
1367 {
1368 { "data", BFD_MACH_O_DICE_KIND_DATA },
1369 { "1 byte jump table", BFD_MACH_O_DICE_JUMP_TABLES8 },
1370 { "2 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES16 },
1371 { "4 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES32 },
1372 { "4 bytes abs jump table", BFD_MACH_O_DICE_ABS_JUMP_TABLES32 },
1373 { NULL, 0 }
1374 };
1375
1376 static void
1377 dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1378 {
1379 unsigned char *buf;
1380 unsigned char *p;
1381
1382 if (cmd->datasize == 0)
1383 {
1384 printf (" no data_in_code entries\n");
1385 return;
1386 }
1387
1388 buf = xmalloc (cmd->datasize);
1389 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1390 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1391 {
1392 non_fatal (_("cannot read data_in_code"));
1393 free (buf);
1394 return;
1395 }
1396
1397 printf (" offset length kind\n");
1398 for (p = buf; p < buf + cmd->datasize; )
1399 {
1400 struct mach_o_data_in_code_entry_external *dice;
1401 unsigned int offset;
1402 unsigned int length;
1403 unsigned int kind;
1404
1405 dice = (struct mach_o_data_in_code_entry_external *) p;
1406
1407 offset = bfd_get_32 (abfd, dice->offset);
1408 length = bfd_get_16 (abfd, dice->length);
1409 kind = bfd_get_16 (abfd, dice->kind);
1410
1411 printf (" 0x%08x 0x%04x 0x%04x %s\n", offset, length, kind,
1412 bfd_mach_o_get_name (data_in_code_kind_name, kind));
1413
1414 p += sizeof (*dice);
1415 }
1416 free (buf);
1417 }
1418
1419 static void
1420 dump_twolevel_hints (bfd *abfd, bfd_mach_o_twolevel_hints_command *cmd)
1421 {
1422 size_t sz = 4 * cmd->nhints;
1423 unsigned char *buf;
1424 unsigned char *p;
1425
1426 buf = xmalloc (sz);
1427 if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
1428 || bfd_bread (buf, sz, abfd) != sz)
1429 {
1430 non_fatal (_("cannot read twolevel hints"));
1431 free (buf);
1432 return;
1433 }
1434
1435 for (p = buf; p < buf + sz; p += 4)
1436 {
1437 unsigned int v;
1438 unsigned int isub_image;
1439 unsigned int itoc;
1440
1441 v = bfd_get_32 (abfd, p);
1442 if (bfd_big_endian (abfd))
1443 {
1444 isub_image = (v >> 24) & 0xff;
1445 itoc = v & 0xffffff;
1446 }
1447 else
1448 {
1449 isub_image = v & 0xff;
1450 itoc = (v >> 8) & 0xffffff;
1451 }
1452
1453 printf (" %3u %8u\n", isub_image, itoc);
1454 }
1455 free (buf);
1456 }
1457
1458 static void
1459 printf_version (uint32_t version)
1460 {
1461 uint32_t maj, min, upd;
1462
1463 maj = (version >> 16) & 0xffff;
1464 min = (version >> 8) & 0xff;
1465 upd = version & 0xff;
1466
1467 printf ("%u.%u.%u", maj, min, upd);
1468 }
1469
1470 static void
1471 dump_build_version (bfd *abfd, bfd_mach_o_load_command *cmd)
1472 {
1473 const char *platform_name;
1474 size_t tools_len, tools_offset;
1475 bfd_mach_o_build_version_tool *tools, *tool;
1476 bfd_mach_o_build_version_command *ver = &cmd->command.build_version;
1477 uint32_t i;
1478
1479 platform_name = bfd_mach_o_get_name_or_null
1480 (bfd_mach_o_platform_name, ver->platform);
1481 if (platform_name == NULL)
1482 printf (" platform: 0x%08x\n", ver->platform);
1483 else
1484 printf (" platform: %s\n", platform_name);
1485 printf (" os: ");
1486 printf_version (ver->minos);
1487 printf ("\n sdk: ");
1488 printf_version (ver->sdk);
1489 printf ("\n ntools: %u\n", ver->ntools);
1490
1491 tools_len = sizeof (bfd_mach_o_build_version_tool) * ver->ntools;
1492 tools_offset = cmd->offset + cmd->len - tools_len;
1493
1494 tools = xmalloc (tools_len);
1495 if (bfd_seek (abfd, tools_offset, SEEK_SET) != 0
1496 || bfd_bread (tools, tools_len, abfd) != tools_len)
1497 {
1498 non_fatal (_("cannot read build tools"));
1499 free (tools);
1500 return;
1501 }
1502
1503 for (i = 0, tool = tools; i < ver->ntools; i++, tool++)
1504 {
1505 const char * tool_name;
1506
1507 tool_name = bfd_mach_o_get_name_or_null
1508 (bfd_mach_o_tool_name, tool->tool);
1509 if (tool_name == NULL)
1510 printf (" tool: 0x%08x\n", tool->tool);
1511 else
1512 printf (" tool: %s\n", tool_name);
1513 printf (" version: ");
1514 printf_version (tool->version);
1515 printf ("\n");
1516 }
1517 free (tools);
1518 }
1519
1520 static void
1521 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
1522 unsigned int idx, bool verbose)
1523 {
1524 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1525 const char *cmd_name;
1526
1527 cmd_name = bfd_mach_o_get_name_or_null
1528 (bfd_mach_o_load_command_name, cmd->type);
1529 printf ("Load command #%-2u (size: %3u, offset: %4u): ",
1530 idx, cmd->len, cmd->offset);
1531 if (cmd_name == NULL)
1532 printf ("0x%02x\n", cmd->type);
1533 else
1534 printf ("%s\n", cmd_name);
1535
1536 switch (cmd->type)
1537 {
1538 case BFD_MACH_O_LC_SEGMENT:
1539 case BFD_MACH_O_LC_SEGMENT_64:
1540 dump_segment (abfd, cmd);
1541 break;
1542 case BFD_MACH_O_LC_UUID:
1543 {
1544 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
1545 unsigned int j;
1546
1547 printf (" ");
1548 for (j = 0; j < sizeof (uuid->uuid); j ++)
1549 printf (" %02x", uuid->uuid[j]);
1550 putchar ('\n');
1551 }
1552 break;
1553 case BFD_MACH_O_LC_LOAD_DYLIB:
1554 case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
1555 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1556 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1557 case BFD_MACH_O_LC_ID_DYLIB:
1558 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
1559 {
1560 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
1561 printf (" name: %s\n", dylib->name_str);
1562 printf (" time stamp: 0x%08lx\n",
1563 dylib->timestamp);
1564 printf (" current version: 0x%08lx\n",
1565 dylib->current_version);
1566 printf (" comptibility version: 0x%08lx\n",
1567 dylib->compatibility_version);
1568 }
1569 break;
1570 case BFD_MACH_O_LC_LOAD_DYLINKER:
1571 case BFD_MACH_O_LC_ID_DYLINKER:
1572 printf (" %s\n", cmd->command.dylinker.name_str);
1573 break;
1574 case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
1575 printf (" %s\n", cmd->command.dylinker.name_str);
1576 break;
1577 case BFD_MACH_O_LC_SYMTAB:
1578 {
1579 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
1580 printf (" symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
1581 symtab->symoff, symtab->nsyms,
1582 symtab->symoff + symtab->nsyms
1583 * (mdata->header.version == 2
1584 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
1585 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
1586 symtab->stroff, symtab->strsize,
1587 symtab->stroff + symtab->strsize);
1588 break;
1589 }
1590 case BFD_MACH_O_LC_DYSYMTAB:
1591 dump_dysymtab (abfd, cmd, verbose);
1592 break;
1593 case BFD_MACH_O_LC_LOADFVMLIB:
1594 case BFD_MACH_O_LC_IDFVMLIB:
1595 {
1596 bfd_mach_o_fvmlib_command *fvmlib = &cmd->command.fvmlib;
1597 printf (" fvmlib: %s\n", fvmlib->name_str);
1598 printf (" minor version: 0x%08x\n", fvmlib->minor_version);
1599 printf (" header address: 0x%08x\n", fvmlib->header_addr);
1600 }
1601 break;
1602 case BFD_MACH_O_LC_CODE_SIGNATURE:
1603 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1604 case BFD_MACH_O_LC_FUNCTION_STARTS:
1605 case BFD_MACH_O_LC_DATA_IN_CODE:
1606 case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
1607 case BFD_MACH_O_LC_DYLD_EXPORTS_TRIE:
1608 case BFD_MACH_O_LC_DYLD_CHAINED_FIXUPS:
1609 {
1610 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
1611 printf
1612 (" dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
1613 linkedit->dataoff, linkedit->datasize,
1614 linkedit->dataoff + linkedit->datasize);
1615
1616 if (verbose)
1617 switch (cmd->type)
1618 {
1619 case BFD_MACH_O_LC_CODE_SIGNATURE:
1620 dump_code_signature (abfd, linkedit);
1621 break;
1622 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1623 dump_segment_split_info (abfd, linkedit);
1624 break;
1625 case BFD_MACH_O_LC_FUNCTION_STARTS:
1626 dump_function_starts (abfd, linkedit);
1627 break;
1628 case BFD_MACH_O_LC_DATA_IN_CODE:
1629 dump_data_in_code (abfd, linkedit);
1630 break;
1631 default:
1632 break;
1633 }
1634 }
1635 break;
1636 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1637 case BFD_MACH_O_LC_SUB_UMBRELLA:
1638 case BFD_MACH_O_LC_SUB_LIBRARY:
1639 case BFD_MACH_O_LC_SUB_CLIENT:
1640 case BFD_MACH_O_LC_RPATH:
1641 {
1642 bfd_mach_o_str_command *strc = &cmd->command.str;
1643 printf (" %s\n", strc->str);
1644 break;
1645 }
1646 case BFD_MACH_O_LC_THREAD:
1647 case BFD_MACH_O_LC_UNIXTHREAD:
1648 dump_thread (abfd, cmd);
1649 break;
1650 case BFD_MACH_O_LC_ENCRYPTION_INFO:
1651 {
1652 bfd_mach_o_encryption_info_command *cryp =
1653 &cmd->command.encryption_info;
1654 printf (" cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1655 " cryptid: %u\n",
1656 cryp->cryptoff, cryp->cryptsize,
1657 cryp->cryptoff + cryp->cryptsize,
1658 cryp->cryptid);
1659 }
1660 break;
1661 case BFD_MACH_O_LC_DYLD_INFO:
1662 dump_dyld_info (abfd, cmd, verbose);
1663 break;
1664 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
1665 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
1666 case BFD_MACH_O_LC_VERSION_MIN_WATCHOS:
1667 case BFD_MACH_O_LC_VERSION_MIN_TVOS:
1668 {
1669 bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
1670
1671 printf (" os: ");
1672 printf_version (ver->version);
1673 printf ("\n sdk: ");
1674 printf_version (ver->sdk);
1675 printf ("\n");
1676 }
1677 break;
1678 case BFD_MACH_O_LC_SOURCE_VERSION:
1679 {
1680 bfd_mach_o_source_version_command *version =
1681 &cmd->command.source_version;
1682 printf (" version a.b.c.d.e: %u.%u.%u.%u.%u\n",
1683 version->a, version->b, version->c, version->d, version->e);
1684 break;
1685 }
1686 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1687 {
1688 bfd_mach_o_prebound_dylib_command *pbdy = &cmd->command.prebound_dylib;
1689 unsigned char *lm = pbdy->linked_modules;
1690 unsigned int j;
1691 unsigned int last;
1692
1693 printf (" dylib: %s\n", pbdy->name_str);
1694 printf (" nmodules: %u\n", pbdy->nmodules);
1695 printf (" linked modules (at %u): ",
1696 pbdy->linked_modules_offset - cmd->offset);
1697 last = pbdy->nmodules > 32 ? 32 : pbdy->nmodules;
1698 for (j = 0; j < last; j++)
1699 printf ("%u", (lm[j >> 3] >> (j & 7)) & 1);
1700 if (last < pbdy->nmodules)
1701 printf ("...");
1702 putchar ('\n');
1703 break;
1704 }
1705 case BFD_MACH_O_LC_PREBIND_CKSUM:
1706 {
1707 bfd_mach_o_prebind_cksum_command *cksum = &cmd->command.prebind_cksum;
1708 printf (" 0x%08x\n", cksum->cksum);
1709 break;
1710 }
1711 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1712 {
1713 bfd_mach_o_twolevel_hints_command *hints =
1714 &cmd->command.twolevel_hints;
1715
1716 printf (" table offset: 0x%08x nbr hints: %u\n",
1717 hints->offset, hints->nhints);
1718 if (verbose)
1719 dump_twolevel_hints (abfd, hints);
1720 break;
1721 }
1722 case BFD_MACH_O_LC_MAIN:
1723 {
1724 bfd_mach_o_main_command *entry = &cmd->command.main;
1725 printf (" entry offset: %#016" PRIx64 "\n"
1726 " stack size: %#016" PRIx64 "\n",
1727 entry->entryoff, entry->stacksize);
1728 break;
1729 }
1730 case BFD_MACH_O_LC_NOTE:
1731 {
1732 bfd_mach_o_note_command *note = &cmd->command.note;
1733 printf (" data owner: %.16s\n"
1734 " offset: %#016" PRIx64 "\n"
1735 " size: %#016" PRIx64 "\n",
1736 note->data_owner, note->offset, note->size);
1737 break;
1738 }
1739 case BFD_MACH_O_LC_BUILD_VERSION:
1740 dump_build_version (abfd, cmd);
1741 break;
1742 default:
1743 break;
1744 }
1745 putchar ('\n');
1746 }
1747
1748 static void
1749 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
1750 {
1751 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1752 bfd_mach_o_load_command *cmd;
1753 unsigned int i;
1754
1755 for (cmd = mdata->first_command, i = 0; cmd != NULL; cmd = cmd->next, i++)
1756 {
1757 if (cmd32 == 0)
1758 dump_load_command (abfd, cmd, i, false);
1759 else if (cmd->type == cmd32 || cmd->type == cmd64)
1760 dump_load_command (abfd, cmd, i, true);
1761 }
1762 }
1763
1764 static const char * const unwind_x86_64_regs[] =
1765 {"", "rbx", "r12", "r13", "r14", "r15", "rbp", "???" };
1766
1767 static const char * const unwind_x86_regs[] =
1768 {"", "ebx", "ecx", "edx", "edi", "edi", "ebp", "???" };
1769
1770 /* Dump x86 or x86-64 compact unwind encoding. Works for both architecture,
1771 as the encoding is the same (but not register names). */
1772
1773 static void
1774 dump_unwind_encoding_x86 (unsigned int encoding, unsigned int sz,
1775 const char * const regs_name[])
1776 {
1777 unsigned int mode;
1778
1779 mode = encoding & MACH_O_UNWIND_X86_64_MODE_MASK;
1780 switch (mode)
1781 {
1782 case MACH_O_UNWIND_X86_64_MODE_RBP_FRAME:
1783 {
1784 unsigned int regs;
1785 char pfx = sz == 8 ? 'R' : 'E';
1786
1787 regs = encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_REGISTERS;
1788 printf (" %cSP frame", pfx);
1789 if (regs != 0)
1790 {
1791 unsigned int offset;
1792 int i;
1793
1794 offset = (encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET) >> 16;
1795 printf (" at %cBP-%u:", pfx, offset * sz);
1796 for (i = 0; i < 5; i++)
1797 {
1798 unsigned int reg = (regs >> (i * 3)) & 0x7;
1799 if (reg != MACH_O_UNWIND_X86_64_REG_NONE)
1800 printf (" %s", regs_name[reg]);
1801 }
1802 }
1803 }
1804 break;
1805 case MACH_O_UNWIND_X86_64_MODE_STACK_IMMD:
1806 case MACH_O_UNWIND_X86_64_MODE_STACK_IND:
1807 {
1808 unsigned int stack_size;
1809 unsigned int reg_count;
1810 unsigned int reg_perm;
1811 unsigned int regs[6];
1812 int i, j;
1813
1814 printf (" frameless");
1815 stack_size =
1816 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE) >> 16;
1817 reg_count =
1818 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT) >> 10;
1819 reg_perm = encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION;
1820
1821 if (mode == MACH_O_UNWIND_X86_64_MODE_STACK_IMMD)
1822 printf (" size: 0x%03x", stack_size * sz);
1823 else
1824 {
1825 unsigned int stack_adj;
1826
1827 stack_adj =
1828 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST) >> 13;
1829 printf (" size at 0x%03x + 0x%02x", stack_size, stack_adj * sz);
1830 }
1831 /* Registers are coded using arithmetic compression: the register
1832 is indexed in range 0-6, the second in range 0-5, the third in
1833 range 0-4, etc. Already used registers are removed in next
1834 ranges. */
1835 #define DO_PERM(R, NUM) R = reg_perm / NUM; reg_perm -= R * NUM
1836 switch (reg_count)
1837 {
1838 case 6:
1839 case 5:
1840 DO_PERM (regs[0], 120);
1841 DO_PERM (regs[1], 24);
1842 DO_PERM (regs[2], 6);
1843 DO_PERM (regs[3], 2);
1844 DO_PERM (regs[4], 1);
1845 regs[5] = 0; /* Not used if reg_count = 5. */
1846 break;
1847 case 4:
1848 DO_PERM (regs[0], 60);
1849 DO_PERM (regs[1], 12);
1850 DO_PERM (regs[2], 3);
1851 DO_PERM (regs[3], 1);
1852 break;
1853 case 3:
1854 DO_PERM (regs[0], 20);
1855 DO_PERM (regs[1], 4);
1856 DO_PERM (regs[2], 1);
1857 break;
1858 case 2:
1859 DO_PERM (regs[0], 5);
1860 DO_PERM (regs[1], 1);
1861 break;
1862 case 1:
1863 DO_PERM (regs[0], 1);
1864 break;
1865 case 0:
1866 break;
1867 default:
1868 printf (" [bad reg count]");
1869 return;
1870 }
1871 #undef DO_PERM
1872 /* Renumber. */
1873 for (i = reg_count - 1; i >= 0; i--)
1874 {
1875 unsigned int inc = 1;
1876 for (j = 0; j < i; j++)
1877 if (regs[i] >= regs[j])
1878 inc++;
1879 regs[i] += inc;
1880 }
1881 /* Display. */
1882 for (i = 0; i < (int) reg_count; i++)
1883 printf (" %s", regs_name[regs[i]]);
1884 }
1885 break;
1886 case MACH_O_UNWIND_X86_64_MODE_DWARF:
1887 printf (" Dwarf offset: 0x%06x",
1888 encoding & MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET);
1889 break;
1890 default:
1891 printf (" [unhandled mode]");
1892 break;
1893 }
1894 }
1895
1896 /* Dump arm64 compact unwind entries. */
1897
1898 static void
1899 dump_unwind_encoding_arm64 (unsigned int encoding)
1900 {
1901 switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1902 {
1903 case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1904 printf (" frameless");
1905 break;
1906 case MACH_O_UNWIND_ARM64_MODE_DWARF:
1907 printf (" Dwarf offset: 0x%06x",
1908 encoding & MACH_O_UNWIND_ARM64_DWARF_SECTION_OFFSET);
1909 return;
1910 case MACH_O_UNWIND_ARM64_MODE_FRAME:
1911 printf (" frame");
1912 break;
1913 default:
1914 printf (" [unhandled mode]");
1915 return;
1916 }
1917 switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1918 {
1919 case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1920 case MACH_O_UNWIND_ARM64_MODE_FRAME:
1921 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X19_X20_PAIR)
1922 printf (" x19-x20");
1923 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X21_X22_PAIR)
1924 printf (" x21-x22");
1925 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X23_X24_PAIR)
1926 printf (" x23-x24");
1927 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X25_X26_PAIR)
1928 printf (" x25-x26");
1929 if (encoding & MACH_O_UNWIND_ARM64_FRAME_X27_X28_PAIR)
1930 printf (" x27-x28");
1931 break;
1932 }
1933 switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK)
1934 {
1935 case MACH_O_UNWIND_ARM64_MODE_FRAME:
1936 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D8_D9_PAIR)
1937 printf (" d8-d9");
1938 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D10_D11_PAIR)
1939 printf (" d10-d11");
1940 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D12_D13_PAIR)
1941 printf (" d12-d13");
1942 if (encoding & MACH_O_UNWIND_ARM64_FRAME_D14_D15_PAIR)
1943 printf (" d14-d15");
1944 break;
1945 case MACH_O_UNWIND_ARM64_MODE_FRAMELESS:
1946 printf (" size: %u",
1947 (encoding & MACH_O_UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK) >> 8);
1948 break;
1949 }
1950 }
1951
1952 static void
1953 dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding)
1954 {
1955 printf ("0x%08x", encoding);
1956 if (encoding == 0)
1957 return;
1958
1959 switch (mdata->header.cputype)
1960 {
1961 case BFD_MACH_O_CPU_TYPE_X86_64:
1962 dump_unwind_encoding_x86 (encoding, 8, unwind_x86_64_regs);
1963 break;
1964 case BFD_MACH_O_CPU_TYPE_I386:
1965 dump_unwind_encoding_x86 (encoding, 4, unwind_x86_regs);
1966 break;
1967 case BFD_MACH_O_CPU_TYPE_ARM64:
1968 dump_unwind_encoding_arm64 (encoding);
1969 break;
1970 default:
1971 printf (" [unhandled cpu]");
1972 break;
1973 }
1974 if (encoding & MACH_O_UNWIND_HAS_LSDA)
1975 printf (" LSDA");
1976 if (encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1977 printf (" PERS(%u)",
1978 ((encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1979 >> MACH_O_UNWIND_PERSONALITY_SHIFT));
1980 }
1981
1982 static void
1983 dump_obj_compact_unwind (bfd *abfd,
1984 const unsigned char *content, bfd_size_type size)
1985 {
1986 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1987 int is_64 = mdata->header.version == 2;
1988 const unsigned char *p;
1989
1990 printf ("Compact unwind info:\n");
1991 printf (" start length personality lsda\n");
1992
1993 if (is_64)
1994 {
1995 struct mach_o_compact_unwind_64 *e =
1996 (struct mach_o_compact_unwind_64 *) content;
1997
1998 for (p = content; p < content + size; p += sizeof (*e))
1999 {
2000 e = (struct mach_o_compact_unwind_64 *) p;
2001
2002 printf (" %#016" PRIx64 " %#08x %#016" PRIx64 " %#016" PRIx64 "\n",
2003 (uint64_t) bfd_get_64 (abfd, e->start),
2004 (unsigned int) bfd_get_32 (abfd, e->length),
2005 (uint64_t) bfd_get_64 (abfd, e->personality),
2006 (uint64_t) bfd_get_64 (abfd, e->lsda));
2007
2008 printf (" encoding: ");
2009 dump_unwind_encoding (mdata, bfd_get_32 (abfd, e->encoding));
2010 putchar ('\n');
2011 }
2012 }
2013 else
2014 {
2015 printf ("unhandled\n");
2016 }
2017 }
2018
2019 static void
2020 dump_exe_compact_unwind (bfd *abfd,
2021 const unsigned char *content, bfd_size_type size)
2022 {
2023 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2024 struct mach_o_unwind_info_header *hdr;
2025 unsigned int version;
2026 unsigned int encodings_offset;
2027 unsigned int encodings_count;
2028 unsigned int personality_offset;
2029 unsigned int personality_count;
2030 unsigned int index_offset;
2031 unsigned int index_count;
2032 struct mach_o_unwind_index_entry *index_entry;
2033 unsigned int i;
2034
2035 /* The header. */
2036 printf ("Compact unwind info:\n");
2037
2038 hdr = (struct mach_o_unwind_info_header *) content;
2039 if (size < sizeof (*hdr))
2040 {
2041 printf (" truncated!\n");
2042 return;
2043 }
2044
2045 version = bfd_get_32 (abfd, hdr->version);
2046 if (version != MACH_O_UNWIND_SECTION_VERSION)
2047 {
2048 printf (" unknown version: %u\n", version);
2049 return;
2050 }
2051 encodings_offset = bfd_get_32 (abfd, hdr->encodings_array_offset);
2052 encodings_count = bfd_get_32 (abfd, hdr->encodings_array_count);
2053 personality_offset = bfd_get_32 (abfd, hdr->personality_array_offset);
2054 personality_count = bfd_get_32 (abfd, hdr->personality_array_count);
2055 index_offset = bfd_get_32 (abfd, hdr->index_offset);
2056 index_count = bfd_get_32 (abfd, hdr->index_count);
2057 printf (" %u encodings, %u personalities, %u level-1 indexes:\n",
2058 encodings_count, personality_count, index_count);
2059
2060 /* Personality. */
2061 if (personality_count > 0)
2062 {
2063 const unsigned char *pers = content + personality_offset;
2064
2065 printf (" personalities\n");
2066 for (i = 0; i < personality_count; i++)
2067 printf (" %u: 0x%08x\n", i,
2068 (unsigned) bfd_get_32 (abfd, pers + 4 * i));
2069 }
2070
2071 /* Level-1 index. */
2072 printf (" idx function level2 off lsda off\n");
2073
2074 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
2075 for (i = 0; i < index_count; i++)
2076 {
2077 unsigned int func_offset;
2078 unsigned int level2_offset;
2079 unsigned int lsda_offset;
2080
2081 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
2082 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
2083 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
2084 printf (" %3u 0x%08x 0x%08x 0x%08x\n",
2085 i, func_offset, level2_offset, lsda_offset);
2086 index_entry++;
2087 }
2088
2089 /* Level-1 index. */
2090 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
2091 for (i = 0; i < index_count; i++)
2092 {
2093 unsigned int func_offset;
2094 unsigned int level2_offset;
2095 const unsigned char *level2;
2096 unsigned int kind;
2097
2098 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
2099 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
2100
2101 /* No level-2 for this index (should be the last index). */
2102 if (level2_offset == 0)
2103 continue;
2104
2105 level2 = content + level2_offset;
2106 kind = bfd_get_32 (abfd, level2);
2107 switch (kind)
2108 {
2109 case MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED:
2110 {
2111 struct mach_o_unwind_compressed_second_level_page_header *l2;
2112 unsigned int entry_offset;
2113 unsigned int entry_count;
2114 unsigned int l2_encodings_offset;
2115 unsigned int l2_encodings_count;
2116 const unsigned char *en;
2117 unsigned int j;
2118
2119 l2 = (struct mach_o_unwind_compressed_second_level_page_header *)
2120 level2;
2121 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
2122 entry_count = bfd_get_16 (abfd, l2->entry_count);
2123 l2_encodings_offset = bfd_get_16 (abfd, l2->encodings_offset);
2124 l2_encodings_count = bfd_get_16 (abfd, l2->encodings_count);
2125
2126 printf (" index %2u: compressed second level: "
2127 "%u entries, %u encodings (at 0x%08x)\n",
2128 i, entry_count, l2_encodings_count, l2_encodings_offset);
2129 printf (" # function eidx encoding\n");
2130
2131 en = level2 + entry_offset;
2132 for (j = 0; j < entry_count; j++)
2133 {
2134 unsigned int entry;
2135 unsigned int en_func;
2136 unsigned int enc_idx;
2137 unsigned int encoding;
2138 const unsigned char *enc_addr;
2139
2140 entry = bfd_get_32 (abfd, en);
2141 en_func =
2142 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry);
2143 enc_idx =
2144 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry);
2145 if (enc_idx < encodings_count)
2146 enc_addr = content + encodings_offset
2147 + 4 * enc_idx;
2148 else
2149 enc_addr = level2 + l2_encodings_offset
2150 + 4 * (enc_idx - encodings_count);
2151 encoding = bfd_get_32 (abfd, enc_addr);
2152
2153 printf (" %4u 0x%08x [%3u] ", j,
2154 func_offset + en_func, enc_idx);
2155 dump_unwind_encoding (mdata, encoding);
2156 putchar ('\n');
2157
2158 en += 4;
2159 }
2160 }
2161 break;
2162
2163 case MACH_O_UNWIND_SECOND_LEVEL_REGULAR:
2164 {
2165 struct mach_o_unwind_regular_second_level_page_header *l2;
2166 struct mach_o_unwind_regular_second_level_entry *en;
2167 unsigned int entry_offset;
2168 unsigned int entry_count;
2169 unsigned int j;
2170
2171 l2 = (struct mach_o_unwind_regular_second_level_page_header *)
2172 level2;
2173
2174 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
2175 entry_count = bfd_get_16 (abfd, l2->entry_count);
2176 printf (" index %2u: regular level 2 at 0x%04x, %u entries\n",
2177 i, entry_offset, entry_count);
2178 printf (" # function encoding\n");
2179
2180 en = (struct mach_o_unwind_regular_second_level_entry *)
2181 (level2 + entry_offset);
2182 for (j = 0; j < entry_count; j++)
2183 {
2184 unsigned int en_func;
2185 unsigned int encoding;
2186
2187 en_func = bfd_get_32 (abfd, en->function_offset);
2188 encoding = bfd_get_32 (abfd, en->encoding);
2189 printf (" %-4u 0x%08x ", j, en_func);
2190 dump_unwind_encoding (mdata, encoding);
2191 putchar ('\n');
2192 en++;
2193 }
2194 }
2195 break;
2196
2197 default:
2198 printf (" index %2u: unhandled second level format (%u)\n",
2199 i, kind);
2200 break;
2201 }
2202
2203 {
2204 struct mach_o_unwind_lsda_index_entry *lsda;
2205 unsigned int lsda_offset;
2206 unsigned int next_lsda_offset;
2207 unsigned int nbr_lsda;
2208 unsigned int j;
2209
2210 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
2211 next_lsda_offset = bfd_get_32 (abfd, index_entry[1].lsda_index_offset);
2212 lsda = (struct mach_o_unwind_lsda_index_entry *)
2213 (content + lsda_offset);
2214 nbr_lsda = (next_lsda_offset - lsda_offset) / sizeof (*lsda);
2215 for (j = 0; j < nbr_lsda; j++)
2216 {
2217 printf (" lsda %3u: function 0x%08x lsda 0x%08x\n",
2218 j, (unsigned int) bfd_get_32 (abfd, lsda->function_offset),
2219 (unsigned int) bfd_get_32 (abfd, lsda->lsda_offset));
2220 lsda++;
2221 }
2222 }
2223 index_entry++;
2224 }
2225 }
2226
2227 static void
2228 dump_section_content (bfd *abfd,
2229 const char *segname, const char *sectname,
2230 void (*dump)(bfd*, const unsigned char*, bfd_size_type))
2231 {
2232 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2233 bfd_mach_o_load_command *cmd;
2234
2235 for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
2236 {
2237 if (cmd->type == BFD_MACH_O_LC_SEGMENT
2238 || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
2239 {
2240 bfd_mach_o_segment_command *seg = &cmd->command.segment;
2241 bfd_mach_o_section *sec;
2242 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
2243 if (strcmp (sec->segname, segname) == 0
2244 && strcmp (sec->sectname, sectname) == 0)
2245 {
2246 bfd_size_type size;
2247 asection *bfdsec = sec->bfdsection;
2248 unsigned char *content;
2249
2250 size = bfd_section_size (bfdsec);
2251 content = (unsigned char *) xmalloc (size);
2252 bfd_get_section_contents (abfd, bfdsec, content, 0, size);
2253
2254 (*dump)(abfd, content, size);
2255
2256 free (content);
2257 }
2258 }
2259 }
2260 }
2261
2262 /* Dump ABFD (according to the options[] array). */
2263
2264 static void
2265 mach_o_dump (bfd *abfd)
2266 {
2267 if (options[OPT_HEADER].selected)
2268 dump_header (abfd);
2269 if (options[OPT_SECTION].selected)
2270 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT, BFD_MACH_O_LC_SEGMENT_64);
2271 if (options[OPT_MAP].selected)
2272 dump_section_map (abfd);
2273 if (options[OPT_LOAD].selected)
2274 dump_load_commands (abfd, 0, 0);
2275 if (options[OPT_DYSYMTAB].selected)
2276 dump_load_commands (abfd, BFD_MACH_O_LC_DYSYMTAB, 0);
2277 if (options[OPT_CODESIGN].selected)
2278 dump_load_commands (abfd, BFD_MACH_O_LC_CODE_SIGNATURE, 0);
2279 if (options[OPT_SEG_SPLIT_INFO].selected)
2280 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO, 0);
2281 if (options[OPT_FUNCTION_STARTS].selected)
2282 dump_load_commands (abfd, BFD_MACH_O_LC_FUNCTION_STARTS, 0);
2283 if (options[OPT_DATA_IN_CODE].selected)
2284 dump_load_commands (abfd, BFD_MACH_O_LC_DATA_IN_CODE, 0);
2285 if (options[OPT_TWOLEVEL_HINTS].selected)
2286 dump_load_commands (abfd, BFD_MACH_O_LC_TWOLEVEL_HINTS, 0);
2287 if (options[OPT_COMPACT_UNWIND].selected)
2288 {
2289 dump_section_content (abfd, "__LD", "__compact_unwind",
2290 dump_obj_compact_unwind);
2291 dump_section_content (abfd, "__TEXT", "__unwind_info",
2292 dump_exe_compact_unwind);
2293 }
2294 if (options[OPT_DYLD_INFO].selected)
2295 dump_load_commands (abfd, BFD_MACH_O_LC_DYLD_INFO, 0);
2296 }
2297
2298 /* Vector for Mach-O. */
2299
2300 const struct objdump_private_desc objdump_private_desc_mach_o =
2301 {
2302 mach_o_help,
2303 mach_o_filter,
2304 mach_o_dump,
2305 options
2306 };