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