Remove unused globals in mi-simplerun.exp.
[binutils-gdb.git] / binutils / od-macho.c
1 /* od-macho.c -- dump information about an Mach-O object file.
2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
3 Written by Tristan Gingold, Adacore.
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 "bfdlink.h"
30 #include "libbfd.h"
31 #include "mach-o.h"
32 #include "mach-o/external.h"
33 #include "mach-o/codesign.h"
34 #include "mach-o/unwind.h"
35
36 /* Index of the options in the options[] array. */
37 #define OPT_HEADER 0
38 #define OPT_SECTION 1
39 #define OPT_MAP 2
40 #define OPT_LOAD 3
41 #define OPT_DYSYMTAB 4
42 #define OPT_CODESIGN 5
43 #define OPT_SEG_SPLIT_INFO 6
44 #define OPT_COMPACT_UNWIND 7
45 #define OPT_FUNCTION_STARTS 8
46 #define OPT_DATA_IN_CODE 9
47 #define OPT_TWOLEVEL_HINTS 10
48
49 /* List of actions. */
50 static struct objdump_private_option options[] =
51 {
52 { "header", 0 },
53 { "section", 0 },
54 { "map", 0 },
55 { "load", 0 },
56 { "dysymtab", 0 },
57 { "codesign", 0 },
58 { "seg_split_info", 0 },
59 { "compact_unwind", 0 },
60 { "function_starts", 0 },
61 { "data_in_code", 0 },
62 { "twolevel_hints", 0 },
63 { NULL, 0 }
64 };
65
66 /* Display help. */
67
68 static void
69 mach_o_help (FILE *stream)
70 {
71 fprintf (stream, _("\
72 For Mach-O files:\n\
73 header Display the file header\n\
74 section Display the segments and sections commands\n\
75 map Display the section map\n\
76 load Display the load commands\n\
77 dysymtab Display the dynamic symbol table\n\
78 codesign Display code signature\n\
79 seg_split_info Display segment split info\n\
80 compact_unwind Display compact unwinding info\n\
81 function_starts Display start address of functions\n\
82 data_in_code Display data in code entries\n\
83 twolevel_hints Display the two-level namespace lookup hints table\n\
84 "));
85 }
86
87 /* Return TRUE if ABFD is handled. */
88
89 static int
90 mach_o_filter (bfd *abfd)
91 {
92 return bfd_get_flavour (abfd) == bfd_target_mach_o_flavour;
93 }
94 \f
95 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
96 {
97 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
98 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
99 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
100 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
101 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
102 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
103 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
104 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
105 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
106 { "i860", BFD_MACH_O_CPU_TYPE_I860 },
107 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
108 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
109 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
110 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
111 { "arm64", BFD_MACH_O_CPU_TYPE_ARM64 },
112 { NULL, 0}
113 };
114
115 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
116 {
117 { "object", BFD_MACH_O_MH_OBJECT },
118 { "execute", BFD_MACH_O_MH_EXECUTE },
119 { "fvmlib", BFD_MACH_O_MH_FVMLIB },
120 { "core", BFD_MACH_O_MH_CORE },
121 { "preload", BFD_MACH_O_MH_PRELOAD },
122 { "dylib", BFD_MACH_O_MH_DYLIB },
123 { "dylinker", BFD_MACH_O_MH_DYLINKER },
124 { "bundle", BFD_MACH_O_MH_BUNDLE },
125 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
126 { "dym", BFD_MACH_O_MH_DSYM },
127 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
128 { NULL, 0}
129 };
130
131 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
132 {
133 { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
134 { "incrlink", BFD_MACH_O_MH_INCRLINK },
135 { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
136 { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
137 { "prebound", BFD_MACH_O_MH_PREBOUND },
138 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
139 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
140 { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
141 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
142 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
143 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
144 { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
145 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
146 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
147 { "canonical", BFD_MACH_O_MH_CANONICAL },
148 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
149 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
150 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
151 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
152 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
153 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
154 { "pie", BFD_MACH_O_MH_PIE },
155 { NULL, 0}
156 };
157
158 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
159 {
160 { "segment", BFD_MACH_O_LC_SEGMENT},
161 { "symtab", BFD_MACH_O_LC_SYMTAB},
162 { "symseg", BFD_MACH_O_LC_SYMSEG},
163 { "thread", BFD_MACH_O_LC_THREAD},
164 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
165 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
166 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
167 { "ident", BFD_MACH_O_LC_IDENT},
168 { "fvmfile", BFD_MACH_O_LC_FVMFILE},
169 { "prepage", BFD_MACH_O_LC_PREPAGE},
170 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
171 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
172 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
173 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
174 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
175 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
176 { "routines", BFD_MACH_O_LC_ROUTINES},
177 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
178 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
179 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
180 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
181 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
182 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
183 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
184 { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
185 { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
186 { "uuid", BFD_MACH_O_LC_UUID},
187 { "rpath", BFD_MACH_O_LC_RPATH},
188 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
189 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
190 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
191 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
192 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
193 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
194 { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
195 { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
196 { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
197 { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
198 { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
199 { "main", BFD_MACH_O_LC_MAIN},
200 { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE},
201 { "source_version", BFD_MACH_O_LC_SOURCE_VERSION},
202 { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS},
203 { NULL, 0}
204 };
205
206 static const bfd_mach_o_xlat_name bfd_mach_o_thread_x86_name[] =
207 {
208 { "thread_state32", BFD_MACH_O_x86_THREAD_STATE32},
209 { "float_state32", BFD_MACH_O_x86_FLOAT_STATE32},
210 { "exception_state32", BFD_MACH_O_x86_EXCEPTION_STATE32},
211 { "thread_state64", BFD_MACH_O_x86_THREAD_STATE64},
212 { "float_state64", BFD_MACH_O_x86_FLOAT_STATE64},
213 { "exception_state64", BFD_MACH_O_x86_EXCEPTION_STATE64},
214 { "thread_state", BFD_MACH_O_x86_THREAD_STATE},
215 { "float_state", BFD_MACH_O_x86_FLOAT_STATE},
216 { "exception_state", BFD_MACH_O_x86_EXCEPTION_STATE},
217 { "debug_state32", BFD_MACH_O_x86_DEBUG_STATE32},
218 { "debug_state64", BFD_MACH_O_x86_DEBUG_STATE64},
219 { "debug_state", BFD_MACH_O_x86_DEBUG_STATE},
220 { "state_none", BFD_MACH_O_x86_THREAD_STATE_NONE},
221 { NULL, 0 }
222 };
223 \f
224 static void
225 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
226 unsigned long val)
227 {
228 int first = 1;
229
230 for (; table->name; table++)
231 {
232 if (table->val & val)
233 {
234 if (!first)
235 printf ("+");
236 printf ("%s", table->name);
237 val &= ~table->val;
238 first = 0;
239 }
240 }
241 if (val)
242 {
243 if (!first)
244 printf ("+");
245 printf ("0x%lx", val);
246 return;
247 }
248 if (first)
249 printf ("-");
250 }
251
252 /* Print a bfd_uint64_t, using a platform independant style. */
253
254 static void
255 printf_uint64 (bfd_uint64_t v)
256 {
257 printf ("0x%08lx%08lx",
258 (unsigned long)((v >> 16) >> 16), (unsigned long)(v & 0xffffffffUL));
259 }
260
261 static const char *
262 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
263 unsigned long val)
264 {
265 for (; table->name; table++)
266 if (table->val == val)
267 return table->name;
268 return NULL;
269 }
270
271 static const char *
272 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
273 {
274 const char *res = bfd_mach_o_get_name_or_null (table, val);
275
276 if (res == NULL)
277 return "*UNKNOWN*";
278 else
279 return res;
280 }
281
282 static void
283 dump_header (bfd *abfd)
284 {
285 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
286 bfd_mach_o_header *h = &mdata->header;
287
288 fputs (_("Mach-O header:\n"), stdout);
289 printf (_(" magic : %08lx\n"), h->magic);
290 printf (_(" cputype : %08lx (%s)\n"), h->cputype,
291 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
292 printf (_(" cpusubtype: %08lx\n"), h->cpusubtype);
293 printf (_(" filetype : %08lx (%s)\n"),
294 h->filetype,
295 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
296 printf (_(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
297 printf (_(" sizeofcmds: %08lx\n"), h->sizeofcmds);
298 printf (_(" flags : %08lx ("), h->flags);
299 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags);
300 fputs (_(")\n"), stdout);
301 printf (_(" reserved : %08x\n"), h->reserved);
302 putchar ('\n');
303 }
304
305 static void
306 disp_segment_prot (unsigned int prot)
307 {
308 putchar (prot & BFD_MACH_O_PROT_READ ? 'r' : '-');
309 putchar (prot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
310 putchar (prot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
311 }
312
313 static void
314 dump_section_map (bfd *abfd)
315 {
316 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
317 unsigned int i;
318 unsigned int sec_nbr = 0;
319
320 fputs (_("Segments and Sections:\n"), stdout);
321 fputs (_(" #: Segment name Section name Address\n"), stdout);
322
323 for (i = 0; i < mdata->header.ncmds; i++)
324 {
325 bfd_mach_o_segment_command *seg;
326 bfd_mach_o_section *sec;
327
328 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
329 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
330 continue;
331
332 seg = &mdata->commands[i].command.segment;
333
334 printf ("[Segment %-16s ", seg->segname);
335 printf_vma (seg->vmaddr);
336 putchar ('-');
337 printf_vma (seg->vmaddr + seg->vmsize - 1);
338 putchar (' ');
339 disp_segment_prot (seg->initprot);
340 printf ("]\n");
341
342 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
343 {
344 printf ("%02u: %-16s %-16s ", ++sec_nbr,
345 sec->segname, sec->sectname);
346 printf_vma (sec->addr);
347 putchar (' ');
348 printf_vma (sec->size);
349 printf (" %08lx\n", sec->flags);
350 }
351 }
352 }
353
354 static void
355 dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_section *sec)
356 {
357 printf (" Section: %-16s %-16s (bfdname: %s)\n",
358 sec->sectname, sec->segname, sec->bfdsection->name);
359 printf (" addr: ");
360 printf_vma (sec->addr);
361 printf (" size: ");
362 printf_vma (sec->size);
363 printf (" offset: ");
364 printf_vma (sec->offset);
365 printf ("\n");
366 printf (" align: %ld", sec->align);
367 printf (" nreloc: %lu reloff: ", sec->nreloc);
368 printf_vma (sec->reloff);
369 printf ("\n");
370 printf (" flags: %08lx (type: %s", sec->flags,
371 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
372 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
373 printf (" attr: ");
374 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
375 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK);
376 printf (")\n");
377 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
378 {
379 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
380 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
381 case BFD_MACH_O_S_SYMBOL_STUBS:
382 printf (" first indirect sym: %lu", sec->reserved1);
383 printf (" (%u entries)",
384 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
385 break;
386 default:
387 printf (" reserved1: 0x%lx", sec->reserved1);
388 break;
389 }
390 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
391 {
392 case BFD_MACH_O_S_SYMBOL_STUBS:
393 printf (" stub size: %lu", sec->reserved2);
394 break;
395 default:
396 printf (" reserved2: 0x%lx", sec->reserved2);
397 break;
398 }
399 printf (" reserved3: 0x%lx\n", sec->reserved3);
400 }
401
402 static void
403 dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
404 {
405 bfd_mach_o_segment_command *seg = &cmd->command.segment;
406 bfd_mach_o_section *sec;
407
408 printf (" name: %s\n", *seg->segname ? seg->segname : "*none*");
409 printf (" vmaddr: ");
410 printf_vma (seg->vmaddr);
411 printf (" vmsize: ");
412 printf_vma (seg->vmsize);
413 printf ("\n");
414 printf (" fileoff: ");
415 printf_vma (seg->fileoff);
416 printf (" filesize: ");
417 printf_vma ((bfd_vma)seg->filesize);
418 printf (" endoff: ");
419 printf_vma ((bfd_vma)(seg->fileoff + seg->filesize));
420 printf ("\n");
421 printf (" nsects: %lu", seg->nsects);
422 printf (" flags: %lx", seg->flags);
423 printf (" initprot: ");
424 disp_segment_prot (seg->initprot);
425 printf (" maxprot: ");
426 disp_segment_prot (seg->maxprot);
427 printf ("\n");
428 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
429 dump_section_header (abfd, sec);
430 }
431
432 static void
433 dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose)
434 {
435 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
436 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
437 unsigned int i;
438
439 printf (" local symbols: idx: %10lu num: %-8lu",
440 dysymtab->ilocalsym, dysymtab->nlocalsym);
441 printf (" (nxtidx: %lu)\n",
442 dysymtab->ilocalsym + dysymtab->nlocalsym);
443 printf (" external symbols: idx: %10lu num: %-8lu",
444 dysymtab->iextdefsym, dysymtab->nextdefsym);
445 printf (" (nxtidx: %lu)\n",
446 dysymtab->iextdefsym + dysymtab->nextdefsym);
447 printf (" undefined symbols: idx: %10lu num: %-8lu",
448 dysymtab->iundefsym, dysymtab->nundefsym);
449 printf (" (nxtidx: %lu)\n",
450 dysymtab->iundefsym + dysymtab->nundefsym);
451 printf (" table of content: off: 0x%08lx num: %-8lu",
452 dysymtab->tocoff, dysymtab->ntoc);
453 printf (" (endoff: 0x%08lx)\n",
454 dysymtab->tocoff + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
455 printf (" module table: off: 0x%08lx num: %-8lu",
456 dysymtab->modtaboff, dysymtab->nmodtab);
457 printf (" (endoff: 0x%08lx)\n",
458 dysymtab->modtaboff + dysymtab->nmodtab
459 * (mdata->header.version == 2 ?
460 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
461 printf (" external reference table: off: 0x%08lx num: %-8lu",
462 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
463 printf (" (endoff: 0x%08lx)\n",
464 dysymtab->extrefsymoff
465 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
466 printf (" indirect symbol table: off: 0x%08lx num: %-8lu",
467 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
468 printf (" (endoff: 0x%08lx)\n",
469 dysymtab->indirectsymoff
470 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
471 printf (" external relocation table: off: 0x%08lx num: %-8lu",
472 dysymtab->extreloff, dysymtab->nextrel);
473 printf (" (endoff: 0x%08lx)\n",
474 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
475 printf (" local relocation table: off: 0x%08lx num: %-8lu",
476 dysymtab->locreloff, dysymtab->nlocrel);
477 printf (" (endoff: 0x%08lx)\n",
478 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
479
480 if (!verbose)
481 return;
482
483 if (dysymtab->ntoc > 0
484 || dysymtab->nindirectsyms > 0
485 || dysymtab->nextrefsyms > 0)
486 {
487 /* Try to read the symbols to display the toc or indirect symbols. */
488 bfd_mach_o_read_symtab_symbols (abfd);
489 }
490 else if (dysymtab->nmodtab > 0)
491 {
492 /* Try to read the strtab to display modules name. */
493 bfd_mach_o_read_symtab_strtab (abfd);
494 }
495
496 for (i = 0; i < dysymtab->nmodtab; i++)
497 {
498 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
499 printf (" module %u:\n", i);
500 printf (" name: %lu", module->module_name_idx);
501 if (mdata->symtab && mdata->symtab->strtab)
502 printf (": %s",
503 mdata->symtab->strtab + module->module_name_idx);
504 printf ("\n");
505 printf (" extdefsym: idx: %8lu num: %lu\n",
506 module->iextdefsym, module->nextdefsym);
507 printf (" refsym: idx: %8lu num: %lu\n",
508 module->irefsym, module->nrefsym);
509 printf (" localsym: idx: %8lu num: %lu\n",
510 module->ilocalsym, module->nlocalsym);
511 printf (" extrel: idx: %8lu num: %lu\n",
512 module->iextrel, module->nextrel);
513 printf (" init: idx: %8u num: %u\n",
514 module->iinit, module->ninit);
515 printf (" term: idx: %8u num: %u\n",
516 module->iterm, module->nterm);
517 printf (" objc_module_info: addr: ");
518 printf_vma (module->objc_module_info_addr);
519 printf (" size: %lu\n", module->objc_module_info_size);
520 }
521
522 if (dysymtab->ntoc > 0)
523 {
524 bfd_mach_o_symtab_command *symtab = mdata->symtab;
525
526 printf (" table of content: (symbol/module)\n");
527 for (i = 0; i < dysymtab->ntoc; i++)
528 {
529 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
530
531 printf (" %4u: ", i);
532 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
533 {
534 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
535 printf ("%s (%lu)", name ? name : "*invalid*",
536 toc->symbol_index);
537 }
538 else
539 printf ("%lu", toc->symbol_index);
540
541 printf (" / ");
542 if (symtab && symtab->strtab
543 && toc->module_index < dysymtab->nmodtab)
544 {
545 bfd_mach_o_dylib_module *mod;
546 mod = &dysymtab->dylib_module[toc->module_index];
547 printf ("%s (%lu)",
548 symtab->strtab + mod->module_name_idx,
549 toc->module_index);
550 }
551 else
552 printf ("%lu", toc->module_index);
553
554 printf ("\n");
555 }
556 }
557
558 if (dysymtab->nindirectsyms != 0)
559 {
560 printf (" indirect symbols:\n");
561
562 for (i = 0; i < mdata->nsects; i++)
563 {
564 bfd_mach_o_section *sec = mdata->sections[i];
565 unsigned int j, first, last;
566 bfd_mach_o_symtab_command *symtab = mdata->symtab;
567 bfd_vma addr;
568 bfd_vma entry_size;
569
570 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
571 {
572 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
573 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
574 case BFD_MACH_O_S_SYMBOL_STUBS:
575 first = sec->reserved1;
576 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
577 addr = sec->addr;
578 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
579 printf (" for section %s.%s:\n",
580 sec->segname, sec->sectname);
581 for (j = first; j < last; j++)
582 {
583 unsigned int isym = dysymtab->indirect_syms[j];
584
585 printf (" ");
586 printf_vma (addr);
587 printf (" %5u: 0x%08x", j, isym);
588 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
589 printf (" LOCAL");
590 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
591 printf (" ABSOLUTE");
592 if (symtab && symtab->symbols
593 && isym < symtab->nsyms
594 && symtab->symbols[isym].symbol.name)
595 printf (" %s", symtab->symbols[isym].symbol.name);
596 printf ("\n");
597 addr += entry_size;
598 }
599 break;
600 default:
601 break;
602 }
603 }
604 }
605 if (dysymtab->nextrefsyms > 0)
606 {
607 bfd_mach_o_symtab_command *symtab = mdata->symtab;
608
609 printf (" external reference table: (symbol flags)\n");
610 for (i = 0; i < dysymtab->nextrefsyms; i++)
611 {
612 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
613
614 printf (" %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
615 if (symtab && symtab->symbols
616 && ref->isym < symtab->nsyms
617 && symtab->symbols[ref->isym].symbol.name)
618 printf (" %s", symtab->symbols[ref->isym].symbol.name);
619 printf ("\n");
620 }
621 }
622
623 }
624
625 static void
626 dump_dyld_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
627 {
628 bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
629
630 printf (" rebase: off: 0x%08x size: %-8u\n",
631 info->rebase_off, info->rebase_size);
632 printf (" bind: off: 0x%08x size: %-8u\n",
633 info->bind_off, info->bind_size);
634 printf (" weak bind: off: 0x%08x size: %-8u\n",
635 info->weak_bind_off, info->weak_bind_size);
636 printf (" lazy bind: off: 0x%08x size: %-8u\n",
637 info->lazy_bind_off, info->lazy_bind_size);
638 printf (" export: off: 0x%08x size: %-8u\n",
639 info->export_off, info->export_size);
640 }
641
642 static void
643 dump_thread (bfd *abfd, bfd_mach_o_load_command *cmd)
644 {
645 bfd_mach_o_thread_command *thread = &cmd->command.thread;
646 unsigned int j;
647 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
648 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
649
650 printf (" nflavours: %lu\n", thread->nflavours);
651 for (j = 0; j < thread->nflavours; j++)
652 {
653 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
654 const bfd_mach_o_xlat_name *name_table;
655
656 printf (" %2u: flavour: 0x%08lx", j, flavour->flavour);
657 switch (mdata->header.cputype)
658 {
659 case BFD_MACH_O_CPU_TYPE_I386:
660 case BFD_MACH_O_CPU_TYPE_X86_64:
661 name_table = bfd_mach_o_thread_x86_name;
662 break;
663 default:
664 name_table = NULL;
665 break;
666 }
667 if (name_table != NULL)
668 printf (": %s", bfd_mach_o_get_name (name_table, flavour->flavour));
669 putchar ('\n');
670
671 printf (" offset: 0x%08lx size: 0x%08lx\n",
672 flavour->offset, flavour->size);
673 if (bed->_bfd_mach_o_print_thread)
674 {
675 char *buf = xmalloc (flavour->size);
676
677 if (bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
678 && bfd_bread (buf, flavour->size, abfd) == flavour->size)
679 (*bed->_bfd_mach_o_print_thread)(abfd, flavour, stdout, buf);
680
681 free (buf);
682 }
683 }
684 }
685
686 static const bfd_mach_o_xlat_name bfd_mach_o_cs_magic[] =
687 {
688 { "embedded signature", BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE },
689 { "requirement", BFD_MACH_O_CS_MAGIC_REQUIREMENT },
690 { "requirements", BFD_MACH_O_CS_MAGIC_REQUIREMENTS },
691 { "code directory", BFD_MACH_O_CS_MAGIC_CODEDIRECTORY },
692 { "embedded entitlements", BFD_MACH_O_CS_MAGIC_EMBEDDED_ENTITLEMENTS },
693 { "blob wrapper", BFD_MACH_O_CS_MAGIC_BLOB_WRAPPER },
694 { NULL, 0 }
695 };
696
697 static const bfd_mach_o_xlat_name bfd_mach_o_cs_hash_type[] =
698 {
699 { "no-hash", BFD_MACH_O_CS_NO_HASH },
700 { "sha1", BFD_MACH_O_CS_HASH_SHA1 },
701 { "sha256", BFD_MACH_O_CS_HASH_SHA256 },
702 { "skein 160", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_160x256 },
703 { "skein 256", BFD_MACH_O_CS_HASH_PRESTANDARD_SKEIN_256x512 },
704 { NULL, 0 }
705 };
706
707 static unsigned int
708 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len);
709
710 static void
711 dump_code_signature_superblob (bfd *abfd ATTRIBUTE_UNUSED,
712 const unsigned char *buf, unsigned int len)
713 {
714 unsigned int count;
715 unsigned int i;
716
717 if (len < 12)
718 {
719 printf (_(" [bad block length]\n"));
720 return;
721 }
722 count = bfd_getb32 (buf + 8);
723 printf (_(" %u index entries:\n"), count);
724 if (len < 12 + 8 * count)
725 {
726 printf (_(" [bad block length]\n"));
727 return;
728 }
729 for (i = 0; i < count; i++)
730 {
731 unsigned int type;
732 unsigned int off;
733
734 type = bfd_getb32 (buf + 12 + 8 * i);
735 off = bfd_getb32 (buf + 12 + 8 * i + 4);
736 printf (_(" index entry %u: type: %08x, offset: %08x\n"),
737 i, type, off);
738
739 dump_code_signature_blob (abfd, buf + off, len - off);
740 }
741 }
742
743 static void
744 swap_code_codedirectory_v1_in
745 (const struct mach_o_codesign_codedirectory_external_v1 *src,
746 struct mach_o_codesign_codedirectory_v1 *dst)
747 {
748 dst->version = bfd_getb32 (src->version);
749 dst->flags = bfd_getb32 (src->flags);
750 dst->hash_offset = bfd_getb32 (src->hash_offset);
751 dst->ident_offset = bfd_getb32 (src->ident_offset);
752 dst->nbr_special_slots = bfd_getb32 (src->nbr_special_slots);
753 dst->nbr_code_slots = bfd_getb32 (src->nbr_code_slots);
754 dst->code_limit = bfd_getb32 (src->code_limit);
755 dst->hash_size = src->hash_size[0];
756 dst->hash_type = src->hash_type[0];
757 dst->spare1 = src->spare1[0];
758 dst->page_size = src->page_size[0];
759 dst->spare2 = bfd_getb32 (src->spare2);
760 }
761
762 static void
763 hexdump (unsigned int start, unsigned int len,
764 const unsigned char *buf)
765 {
766 unsigned int i, j;
767
768 for (i = 0; i < len; i += 16)
769 {
770 printf ("%08x:", start + i);
771 for (j = 0; j < 16; j++)
772 {
773 fputc (j == 8 ? '-' : ' ', stdout);
774 if (i + j < len)
775 printf ("%02x", buf[i + j]);
776 else
777 fputs (" ", stdout);
778 }
779 fputc (' ', stdout);
780 for (j = 0; j < 16; j++)
781 {
782 if (i + j < len)
783 fputc (ISPRINT (buf[i + j]) ? buf[i + j] : '.', stdout);
784 else
785 fputc (' ', stdout);
786 }
787 fputc ('\n', stdout);
788 }
789 }
790
791 static void
792 dump_code_signature_codedirectory (bfd *abfd ATTRIBUTE_UNUSED,
793 const unsigned char *buf, unsigned int len)
794 {
795 struct mach_o_codesign_codedirectory_v1 cd;
796 const char *id;
797
798 if (len < sizeof (struct mach_o_codesign_codedirectory_external_v1))
799 {
800 printf (_(" [bad block length]\n"));
801 return;
802 }
803
804 swap_code_codedirectory_v1_in
805 ((const struct mach_o_codesign_codedirectory_external_v1 *) (buf + 8), &cd);
806
807 printf (_(" version: %08x\n"), cd.version);
808 printf (_(" flags: %08x\n"), cd.flags);
809 printf (_(" hash offset: %08x\n"), cd.hash_offset);
810 id = (const char *) buf + cd.ident_offset;
811 printf (_(" ident offset: %08x (- %08x)\n"),
812 cd.ident_offset, cd.ident_offset + (unsigned) strlen (id) + 1);
813 printf (_(" identity: %s\n"), id);
814 printf (_(" nbr special slots: %08x (at offset %08x)\n"),
815 cd.nbr_special_slots,
816 cd.hash_offset - cd.nbr_special_slots * cd.hash_size);
817 printf (_(" nbr code slots: %08x\n"), cd.nbr_code_slots);
818 printf (_(" code limit: %08x\n"), cd.code_limit);
819 printf (_(" hash size: %02x\n"), cd.hash_size);
820 printf (_(" hash type: %02x (%s)\n"),
821 cd.hash_type,
822 bfd_mach_o_get_name (bfd_mach_o_cs_hash_type, cd.hash_type));
823 printf (_(" spare1: %02x\n"), cd.spare1);
824 printf (_(" page size: %02x\n"), cd.page_size);
825 printf (_(" spare2: %08x\n"), cd.spare2);
826 if (cd.version >= 0x20100)
827 printf (_(" scatter offset: %08x\n"),
828 (unsigned) bfd_getb32 (buf + 44));
829 }
830
831 static unsigned int
832 dump_code_signature_blob (bfd *abfd, const unsigned char *buf, unsigned int len)
833 {
834 unsigned int magic;
835 unsigned int length;
836
837 if (len < 8)
838 {
839 printf (_(" [truncated block]\n"));
840 return 0;
841 }
842 magic = bfd_getb32 (buf);
843 length = bfd_getb32 (buf + 4);
844 if (magic == 0 || length == 0)
845 return 0;
846
847 printf (_(" magic : %08x (%s)\n"), magic,
848 bfd_mach_o_get_name (bfd_mach_o_cs_magic, magic));
849 printf (_(" length: %08x\n"), length);
850 if (length > len)
851 {
852 printf (_(" [bad block length]\n"));
853 return 0;
854 }
855
856 switch (magic)
857 {
858 case BFD_MACH_O_CS_MAGIC_EMBEDDED_SIGNATURE:
859 dump_code_signature_superblob (abfd, buf, length);
860 break;
861 case BFD_MACH_O_CS_MAGIC_CODEDIRECTORY:
862 dump_code_signature_codedirectory (abfd, buf, length);
863 break;
864 default:
865 hexdump (0, length - 8, buf + 8);
866 break;
867 }
868 return length;
869 }
870
871 static void
872 dump_code_signature (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
873 {
874 unsigned char *buf = xmalloc (cmd->datasize);
875 unsigned int off;
876
877 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
878 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
879 {
880 non_fatal (_("cannot read code signature data"));
881 free (buf);
882 return;
883 }
884 for (off = 0; off < cmd->datasize;)
885 {
886 unsigned int len;
887
888 len = dump_code_signature_blob (abfd, buf + off, cmd->datasize - off);
889
890 if (len == 0)
891 break;
892 off += len;
893 }
894 free (buf);
895 }
896
897 static void
898 dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
899 {
900 unsigned char *buf = xmalloc (cmd->datasize);
901 unsigned char *p;
902 unsigned int len;
903 bfd_vma addr = 0;
904
905 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
906 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
907 {
908 non_fatal (_("cannot read segment split info"));
909 free (buf);
910 return;
911 }
912 if (buf[cmd->datasize - 1] != 0)
913 {
914 non_fatal (_("segment split info is not nul terminated"));
915 free (buf);
916 return;
917 }
918
919 switch (buf[0])
920 {
921 case 0:
922 printf (_(" 32 bit pointers:\n"));
923 break;
924 case 1:
925 printf (_(" 64 bit pointers:\n"));
926 break;
927 case 2:
928 printf (_(" PPC hi-16:\n"));
929 break;
930 default:
931 printf (_(" Unhandled location type %u\n"), buf[0]);
932 break;
933 }
934 for (p = buf + 1; *p != 0; p += len)
935 {
936 addr += read_unsigned_leb128 (abfd, p, &len);
937 fputs (" ", stdout);
938 bfd_printf_vma (abfd, addr);
939 putchar ('\n');
940 }
941 free (buf);
942 }
943
944 static void
945 dump_function_starts (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
946 {
947 unsigned char *buf = xmalloc (cmd->datasize);
948 unsigned char *end_buf = buf + cmd->datasize;
949 unsigned char *p;
950 bfd_vma addr;
951
952 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
953 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
954 {
955 non_fatal (_("cannot read function starts"));
956 free (buf);
957 return;
958 }
959
960 /* Function starts are delta encoded, starting from the base address. */
961 addr = bfd_mach_o_get_base_address (abfd);
962
963 for (p = buf; ;)
964 {
965 bfd_vma delta = 0;
966 unsigned int shift = 0;
967
968 if (*p == 0 || p == end_buf)
969 break;
970 while (1)
971 {
972 unsigned char b = *p++;
973
974 delta |= (b & 0x7f) << shift;
975 if ((b & 0x80) == 0)
976 break;
977 if (p == end_buf)
978 {
979 fputs (" [truncated]\n", stdout);
980 break;
981 }
982 shift += 7;
983 }
984
985 addr += delta;
986 fputs (" ", stdout);
987 bfd_printf_vma (abfd, addr);
988 putchar ('\n');
989 }
990 free (buf);
991 }
992
993 static const bfd_mach_o_xlat_name data_in_code_kind_name[] =
994 {
995 { "data", BFD_MACH_O_DICE_KIND_DATA },
996 { "1 byte jump table", BFD_MACH_O_DICE_JUMP_TABLES8 },
997 { "2 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES16 },
998 { "4 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES32 },
999 { "4 bytes abs jump table", BFD_MACH_O_DICE_ABS_JUMP_TABLES32 },
1000 { NULL, 0 }
1001 };
1002
1003 static void
1004 dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
1005 {
1006 unsigned char *buf;
1007 unsigned char *p;
1008
1009 if (cmd->datasize == 0)
1010 {
1011 printf (" no data_in_code entries\n");
1012 return;
1013 }
1014
1015 buf = xmalloc (cmd->datasize);
1016 if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
1017 || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
1018 {
1019 non_fatal (_("cannot read data_in_code"));
1020 free (buf);
1021 return;
1022 }
1023
1024 printf (" offset length kind\n");
1025 for (p = buf; p < buf + cmd->datasize; )
1026 {
1027 struct mach_o_data_in_code_entry_external *dice;
1028 unsigned int offset;
1029 unsigned int length;
1030 unsigned int kind;
1031
1032 dice = (struct mach_o_data_in_code_entry_external *) p;
1033
1034 offset = bfd_get_32 (abfd, dice->offset);
1035 length = bfd_get_16 (abfd, dice->length);
1036 kind = bfd_get_16 (abfd, dice->kind);
1037
1038 printf (" 0x%08x 0x%04x 0x%04x %s\n", offset, length, kind,
1039 bfd_mach_o_get_name (data_in_code_kind_name, kind));
1040
1041 p += sizeof (*dice);
1042 }
1043 free (buf);
1044 }
1045
1046 static void
1047 dump_twolevel_hints (bfd *abfd, bfd_mach_o_twolevel_hints_command *cmd)
1048 {
1049 size_t sz = 4 * cmd->nhints;
1050 unsigned char *buf;
1051 unsigned char *p;
1052
1053 buf = xmalloc (sz);
1054 if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
1055 || bfd_bread (buf, sz, abfd) != sz)
1056 {
1057 non_fatal (_("cannot read twolevel hints"));
1058 free (buf);
1059 return;
1060 }
1061
1062 for (p = buf; p < buf + sz; p += 4)
1063 {
1064 unsigned int v;
1065 unsigned int isub_image;
1066 unsigned int itoc;
1067
1068 v = bfd_get_32 (abfd, p);
1069 if (bfd_big_endian (abfd))
1070 {
1071 isub_image = (v >> 24) & 0xff;
1072 itoc = v & 0xffffff;
1073 }
1074 else
1075 {
1076 isub_image = v & 0xff;
1077 itoc = (v >> 8) & 0xffffff;
1078 }
1079
1080 printf (" %3u %8u\n", isub_image, itoc);
1081 }
1082 free (buf);
1083 }
1084
1085 static void
1086 dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
1087 bfd_boolean verbose)
1088 {
1089 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1090 const char *cmd_name;
1091
1092 cmd_name = bfd_mach_o_get_name_or_null
1093 (bfd_mach_o_load_command_name, cmd->type);
1094 printf ("Load command ");
1095 if (cmd_name == NULL)
1096 printf ("0x%02x:", cmd->type);
1097 else
1098 printf ("%s:", cmd_name);
1099
1100 switch (cmd->type)
1101 {
1102 case BFD_MACH_O_LC_SEGMENT:
1103 case BFD_MACH_O_LC_SEGMENT_64:
1104 dump_segment (abfd, cmd);
1105 break;
1106 case BFD_MACH_O_LC_UUID:
1107 {
1108 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
1109 unsigned int j;
1110
1111 for (j = 0; j < sizeof (uuid->uuid); j ++)
1112 printf (" %02x", uuid->uuid[j]);
1113 putchar ('\n');
1114 }
1115 break;
1116 case BFD_MACH_O_LC_LOAD_DYLIB:
1117 case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
1118 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1119 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1120 case BFD_MACH_O_LC_ID_DYLIB:
1121 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
1122 {
1123 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
1124 printf (" %s\n", dylib->name_str);
1125 printf (" time stamp: 0x%08lx\n",
1126 dylib->timestamp);
1127 printf (" current version: 0x%08lx\n",
1128 dylib->current_version);
1129 printf (" comptibility version: 0x%08lx\n",
1130 dylib->compatibility_version);
1131 }
1132 break;
1133 case BFD_MACH_O_LC_LOAD_DYLINKER:
1134 case BFD_MACH_O_LC_ID_DYLINKER:
1135 printf (" %s\n", cmd->command.dylinker.name_str);
1136 break;
1137 case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
1138 putchar ('\n');
1139 printf (" %s\n", cmd->command.dylinker.name_str);
1140 break;
1141 case BFD_MACH_O_LC_SYMTAB:
1142 {
1143 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
1144 printf ("\n"
1145 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
1146 symtab->symoff, symtab->nsyms,
1147 symtab->symoff + symtab->nsyms
1148 * (mdata->header.version == 2
1149 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
1150 printf (" stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
1151 symtab->stroff, symtab->strsize,
1152 symtab->stroff + symtab->strsize);
1153 break;
1154 }
1155 case BFD_MACH_O_LC_DYSYMTAB:
1156 putchar ('\n');
1157 dump_dysymtab (abfd, cmd, verbose);
1158 break;
1159 case BFD_MACH_O_LC_LOADFVMLIB:
1160 case BFD_MACH_O_LC_IDFVMLIB:
1161 {
1162 bfd_mach_o_fvmlib_command *fvmlib = &cmd->command.fvmlib;
1163 printf (" %s\n", fvmlib->name_str);
1164 printf (" minor version: 0x%08x\n", fvmlib->minor_version);
1165 printf (" header address: 0x%08x\n", fvmlib->header_addr);
1166 }
1167 break;
1168 case BFD_MACH_O_LC_CODE_SIGNATURE:
1169 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1170 case BFD_MACH_O_LC_FUNCTION_STARTS:
1171 case BFD_MACH_O_LC_DATA_IN_CODE:
1172 case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
1173 {
1174 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
1175 printf
1176 ("\n"
1177 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
1178 linkedit->dataoff, linkedit->datasize,
1179 linkedit->dataoff + linkedit->datasize);
1180
1181 if (verbose)
1182 switch (cmd->type)
1183 {
1184 case BFD_MACH_O_LC_CODE_SIGNATURE:
1185 dump_code_signature (abfd, linkedit);
1186 break;
1187 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1188 dump_segment_split_info (abfd, linkedit);
1189 break;
1190 case BFD_MACH_O_LC_FUNCTION_STARTS:
1191 dump_function_starts (abfd, linkedit);
1192 break;
1193 case BFD_MACH_O_LC_DATA_IN_CODE:
1194 dump_data_in_code (abfd, linkedit);
1195 break;
1196 default:
1197 break;
1198 }
1199 }
1200 break;
1201 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1202 case BFD_MACH_O_LC_SUB_UMBRELLA:
1203 case BFD_MACH_O_LC_SUB_LIBRARY:
1204 case BFD_MACH_O_LC_SUB_CLIENT:
1205 case BFD_MACH_O_LC_RPATH:
1206 {
1207 bfd_mach_o_str_command *str = &cmd->command.str;
1208 printf (" %s\n", str->str);
1209 break;
1210 }
1211 case BFD_MACH_O_LC_THREAD:
1212 case BFD_MACH_O_LC_UNIXTHREAD:
1213 dump_thread (abfd, cmd);
1214 break;
1215 case BFD_MACH_O_LC_ENCRYPTION_INFO:
1216 {
1217 bfd_mach_o_encryption_info_command *cryp =
1218 &cmd->command.encryption_info;
1219 printf
1220 ("\n"
1221 " cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)"
1222 " cryptid: %u\n",
1223 cryp->cryptoff, cryp->cryptsize,
1224 cryp->cryptoff + cryp->cryptsize,
1225 cryp->cryptid);
1226 }
1227 break;
1228 case BFD_MACH_O_LC_DYLD_INFO:
1229 putchar ('\n');
1230 dump_dyld_info (abfd, cmd);
1231 break;
1232 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
1233 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
1234 {
1235 bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
1236
1237 printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min);
1238 }
1239 break;
1240 case BFD_MACH_O_LC_SOURCE_VERSION:
1241 {
1242 bfd_mach_o_source_version_command *version =
1243 &cmd->command.source_version;
1244 printf ("\n"
1245 " version a.b.c.d.e: %u.%u.%u.%u.%u\n",
1246 version->a, version->b, version->c, version->d, version->e);
1247 break;
1248 }
1249 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1250 {
1251 bfd_mach_o_prebound_dylib_command *pbdy = &cmd->command.prebound_dylib;
1252 unsigned char *lm = pbdy->linked_modules;
1253 unsigned int j;
1254 unsigned int last;
1255
1256 printf (" %s\n", pbdy->name_str);
1257 printf (" nmodules: %u\n", pbdy->nmodules);
1258 printf (" linked modules (at %u): ",
1259 pbdy->linked_modules_offset - cmd->offset);
1260 last = pbdy->nmodules > 32 ? 32 : pbdy->nmodules;
1261 for (j = 0; j < last; j++)
1262 printf ("%u", (lm[j >> 3] >> (j & 7)) & 1);
1263 if (last < pbdy->nmodules)
1264 printf ("...");
1265 putchar ('\n');
1266 break;
1267 }
1268 case BFD_MACH_O_LC_PREBIND_CKSUM:
1269 {
1270 bfd_mach_o_prebind_cksum_command *cksum = &cmd->command.prebind_cksum;
1271 printf (" 0x%08x\n", cksum->cksum);
1272 break;
1273 }
1274 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1275 {
1276 bfd_mach_o_twolevel_hints_command *hints =
1277 &cmd->command.twolevel_hints;
1278
1279 printf ("\n"
1280 " table offset: 0x%08x nbr hints: %u\n",
1281 hints->offset, hints->nhints);
1282 if (verbose)
1283 dump_twolevel_hints (abfd, hints);
1284 break;
1285 }
1286 case BFD_MACH_O_LC_MAIN:
1287 {
1288 bfd_mach_o_main_command *entry = &cmd->command.main;
1289 printf ("\n"
1290 " entry offset: ");
1291 printf_uint64 (entry->entryoff);
1292 printf ("\n"
1293 " stack size: ");
1294 printf_uint64 (entry->stacksize);
1295 printf ("\n");
1296 break;
1297 }
1298 default:
1299 putchar ('\n');
1300 printf (" offset: 0x%08lx\n", (unsigned long)cmd->offset);
1301 printf (" size: 0x%08lx\n", (unsigned long)cmd->len);
1302 break;
1303 }
1304 putchar ('\n');
1305 }
1306
1307 static void
1308 dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64)
1309 {
1310 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1311 unsigned int i;
1312
1313 for (i = 0; i < mdata->header.ncmds; i++)
1314 {
1315 bfd_mach_o_load_command *cmd = &mdata->commands[i];
1316
1317 if (cmd32 == 0)
1318 dump_load_command (abfd, cmd, FALSE);
1319 else if (cmd->type == cmd32 || cmd->type == cmd64)
1320 dump_load_command (abfd, cmd, TRUE);
1321 }
1322 }
1323
1324 static const char * const unwind_x86_64_regs[] =
1325 {"", "rbx", "r12", "r13", "r14", "r15", "rbp", "???" };
1326
1327 static const char * const unwind_x86_regs[] =
1328 {"", "ebx", "ecx", "edx", "edi", "edi", "ebp", "???" };
1329
1330 /* Dump x86 or x86-64 compact unwind encoding. Works for both architecture,
1331 as the encoding is the same (but not register names). */
1332
1333 static void
1334 dump_unwind_encoding_x86 (unsigned int encoding, unsigned int sz,
1335 const char * const regs_name[])
1336 {
1337 unsigned int mode;
1338
1339 mode = encoding & MACH_O_UNWIND_X86_64_MODE_MASK;
1340 switch (mode)
1341 {
1342 case MACH_O_UNWIND_X86_64_MODE_RBP_FRAME:
1343 {
1344 unsigned int regs;
1345 char pfx = sz == 8 ? 'R' : 'E';
1346
1347 regs = encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_REGSITERS;
1348 printf (" %cSP frame", pfx);
1349 if (regs != 0)
1350 {
1351 unsigned int offset;
1352 int i;
1353
1354 offset = (encoding & MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET) >> 16;
1355 printf (" at %cBP-%u:", pfx, offset * sz);
1356 for (i = 0; i < 5; i++)
1357 {
1358 unsigned int reg = (regs >> (i * 3)) & 0x7;
1359 if (reg != MACH_O_UNWIND_X86_64_REG_NONE)
1360 printf (" %s", regs_name[reg]);
1361 }
1362 }
1363 }
1364 break;
1365 case MACH_O_UNWIND_X86_64_MODE_STACK_IMMD:
1366 case MACH_O_UNWIND_X86_64_MODE_STACK_IND:
1367 {
1368 unsigned int stack_size;
1369 unsigned int reg_count;
1370 unsigned int reg_perm;
1371 unsigned int regs[6];
1372 int i, j;
1373
1374 printf (" frameless");
1375 stack_size =
1376 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE) >> 16;
1377 reg_count =
1378 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT) >> 10;
1379 reg_perm = encoding & MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION;
1380
1381 if (mode == MACH_O_UNWIND_X86_64_MODE_STACK_IMMD)
1382 printf (" size: 0x%03x", stack_size * sz);
1383 else
1384 {
1385 unsigned int stack_adj;
1386
1387 stack_adj =
1388 (encoding & MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST) >> 13;
1389 printf (" size at 0x%03x + 0x%02x", stack_size, stack_adj * sz);
1390 }
1391 /* Registers are coded using arithmetic compression: the register
1392 is indexed in range 0-6, the second in range 0-5, the third in
1393 range 0-4, etc. Already used registers are removed in next
1394 ranges. */
1395 #define DO_PERM(R, NUM) R = reg_perm / NUM; reg_perm -= R * NUM
1396 switch (reg_count)
1397 {
1398 case 6:
1399 case 5:
1400 DO_PERM (regs[0], 120);
1401 DO_PERM (regs[1], 24);
1402 DO_PERM (regs[2], 6);
1403 DO_PERM (regs[3], 2);
1404 DO_PERM (regs[4], 1);
1405 regs[5] = 0; /* Not used if reg_count = 5. */
1406 break;
1407 case 4:
1408 DO_PERM (regs[0], 60);
1409 DO_PERM (regs[1], 12);
1410 DO_PERM (regs[2], 3);
1411 DO_PERM (regs[3], 1);
1412 break;
1413 case 3:
1414 DO_PERM (regs[0], 20);
1415 DO_PERM (regs[1], 4);
1416 DO_PERM (regs[2], 1);
1417 break;
1418 case 2:
1419 DO_PERM (regs[0], 5);
1420 DO_PERM (regs[1], 1);
1421 break;
1422 case 1:
1423 DO_PERM (regs[0], 1);
1424 break;
1425 case 0:
1426 break;
1427 default:
1428 printf (" [bad reg count]");
1429 return;
1430 }
1431 #undef DO_PERM
1432 /* Renumber. */
1433 for (i = reg_count - 1; i >= 0; i--)
1434 {
1435 unsigned int inc = 1;
1436 for (j = 0; j < i; j++)
1437 if (regs[i] >= regs[j])
1438 inc++;
1439 regs[i] += inc;
1440 }
1441 /* Display. */
1442 for (i = 0; i < (int) reg_count; i++)
1443 printf (" %s", regs_name[regs[i]]);
1444 }
1445 break;
1446 case MACH_O_UNWIND_X86_64_MODE_DWARF:
1447 printf (" Dwarf offset: 0x%06x",
1448 encoding & MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET);
1449 break;
1450 default:
1451 printf (" [unhandled mode]");
1452 break;
1453 }
1454 }
1455
1456 static void
1457 dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding)
1458 {
1459 printf ("0x%08x", encoding);
1460 if (encoding == 0)
1461 return;
1462
1463 switch (mdata->header.cputype)
1464 {
1465 case BFD_MACH_O_CPU_TYPE_X86_64:
1466 dump_unwind_encoding_x86 (encoding, 8, unwind_x86_64_regs);
1467 break;
1468 case BFD_MACH_O_CPU_TYPE_I386:
1469 dump_unwind_encoding_x86 (encoding, 4, unwind_x86_regs);
1470 break;
1471 default:
1472 printf (" [unhandled cpu]");
1473 break;
1474 }
1475 if (encoding & MACH_O_UNWIND_HAS_LSDA)
1476 printf (" LSDA");
1477 if (encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1478 printf (" PERS(%u)",
1479 ((encoding & MACH_O_UNWIND_PERSONALITY_MASK)
1480 >> MACH_O_UNWIND_PERSONALITY_SHIFT));
1481 }
1482
1483 static void
1484 dump_obj_compact_unwind (bfd *abfd,
1485 const unsigned char *content, bfd_size_type size)
1486 {
1487 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1488 int is_64 = mdata->header.version == 2;
1489 const unsigned char *p;
1490
1491 printf ("Compact unwind info:\n");
1492 printf (" start length personality lsda\n");
1493
1494 if (is_64)
1495 {
1496 struct mach_o_compact_unwind_64 *e =
1497 (struct mach_o_compact_unwind_64 *) content;
1498
1499 for (p = content; p < content + size; p += sizeof (*e))
1500 {
1501 e = (struct mach_o_compact_unwind_64 *) p;
1502
1503 putchar (' ');
1504 printf_uint64 (bfd_get_64 (abfd, e->start));
1505 printf (" %08lx", bfd_get_32 (abfd, e->length));
1506 putchar (' ');
1507 printf_uint64 (bfd_get_64 (abfd, e->personality));
1508 putchar (' ');
1509 printf_uint64 (bfd_get_64 (abfd, e->lsda));
1510 putchar ('\n');
1511
1512 printf (" encoding: ");
1513 dump_unwind_encoding (mdata, bfd_get_32 (abfd, e->encoding));
1514 putchar ('\n');
1515 }
1516 }
1517 else
1518 {
1519 printf ("unhandled\n");
1520 }
1521 }
1522
1523 static void
1524 dump_exe_compact_unwind (bfd *abfd,
1525 const unsigned char *content, bfd_size_type size)
1526 {
1527 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1528 struct mach_o_unwind_info_header *hdr;
1529 unsigned int version;
1530 unsigned int encodings_offset;
1531 unsigned int encodings_count;
1532 unsigned int personality_offset;
1533 unsigned int personality_count;
1534 unsigned int index_offset;
1535 unsigned int index_count;
1536 struct mach_o_unwind_index_entry *index_entry;
1537 unsigned int i;
1538
1539 /* The header. */
1540 printf ("Compact unwind info:\n");
1541
1542 hdr = (struct mach_o_unwind_info_header *) content;
1543 if (size < sizeof (*hdr))
1544 {
1545 printf (" truncated!\n");
1546 return;
1547 }
1548
1549 version = bfd_get_32 (abfd, hdr->version);
1550 if (version != MACH_O_UNWIND_SECTION_VERSION)
1551 {
1552 printf (" unknown version: %u\n", version);
1553 return;
1554 }
1555 encodings_offset = bfd_get_32 (abfd, hdr->encodings_array_offset);
1556 encodings_count = bfd_get_32 (abfd, hdr->encodings_array_count);
1557 personality_offset = bfd_get_32 (abfd, hdr->personality_array_offset);
1558 personality_count = bfd_get_32 (abfd, hdr->personality_array_count);
1559 index_offset = bfd_get_32 (abfd, hdr->index_offset);
1560 index_count = bfd_get_32 (abfd, hdr->index_count);
1561 printf (" %u encodings, %u personalities, %u level-1 indexes:\n",
1562 encodings_count, personality_count, index_count);
1563
1564 /* Personality. */
1565 if (personality_count > 0)
1566 {
1567 const unsigned char *pers = content + personality_offset;
1568
1569 printf (" personalities\n");
1570 for (i = 0; i < personality_count; i++)
1571 printf (" %u: 0x%08x\n", i,
1572 (unsigned) bfd_get_32 (abfd, pers + 4 * i));
1573 }
1574
1575 /* Level-1 index. */
1576 printf (" idx function level2 off lsda off\n");
1577
1578 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
1579 for (i = 0; i < index_count; i++)
1580 {
1581 unsigned int func_offset;
1582 unsigned int level2_offset;
1583 unsigned int lsda_offset;
1584
1585 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
1586 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
1587 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
1588 printf (" %3u 0x%08x 0x%08x 0x%08x\n",
1589 i, func_offset, level2_offset, lsda_offset);
1590 index_entry++;
1591 }
1592
1593 /* Level-1 index. */
1594 index_entry = (struct mach_o_unwind_index_entry *) (content + index_offset);
1595 for (i = 0; i < index_count; i++)
1596 {
1597 unsigned int func_offset;
1598 unsigned int level2_offset;
1599 const unsigned char *level2;
1600 unsigned int kind;
1601
1602 func_offset = bfd_get_32 (abfd, index_entry->function_offset);
1603 level2_offset = bfd_get_32 (abfd, index_entry->second_level_offset);
1604
1605 /* No level-2 for this index (should be the last index). */
1606 if (level2_offset == 0)
1607 continue;
1608
1609 level2 = content + level2_offset;
1610 kind = bfd_get_32 (abfd, level2);
1611 switch (kind)
1612 {
1613 case MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED:
1614 {
1615 struct mach_o_unwind_compressed_second_level_page_header *l2;
1616 unsigned int entry_offset;
1617 unsigned int entry_count;
1618 unsigned int l2_encodings_offset;
1619 unsigned int l2_encodings_count;
1620 const unsigned char *en;
1621 unsigned int j;
1622
1623 l2 = (struct mach_o_unwind_compressed_second_level_page_header *)
1624 level2;
1625 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
1626 entry_count = bfd_get_16 (abfd, l2->entry_count);
1627 l2_encodings_offset = bfd_get_16 (abfd, l2->encodings_offset);
1628 l2_encodings_count = bfd_get_16 (abfd, l2->encodings_count);
1629
1630 printf (" index %2u: compressed second level: "
1631 "%u entries, %u encodings (at 0x%08x)\n",
1632 i, entry_count, l2_encodings_count, l2_encodings_offset);
1633 printf (" # function eidx encoding\n");
1634
1635 en = level2 + entry_offset;
1636 for (j = 0; j < entry_count; j++)
1637 {
1638 unsigned int entry;
1639 unsigned int en_func;
1640 unsigned int enc_idx;
1641 unsigned int encoding;
1642 const unsigned char *enc_addr;
1643
1644 entry = bfd_get_32 (abfd, en);
1645 en_func =
1646 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry);
1647 enc_idx =
1648 MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry);
1649 if (enc_idx < encodings_count)
1650 enc_addr = content + encodings_offset
1651 + 4 * enc_idx;
1652 else
1653 enc_addr = level2 + l2_encodings_offset
1654 + 4 * (enc_idx - encodings_count);
1655 encoding = bfd_get_32 (abfd, enc_addr);
1656
1657 printf (" %4u 0x%08x [%3u] ", j,
1658 func_offset + en_func, enc_idx);
1659 dump_unwind_encoding (mdata, encoding);
1660 putchar ('\n');
1661
1662 en += 4;
1663 }
1664 }
1665 break;
1666
1667 case MACH_O_UNWIND_SECOND_LEVEL_REGULAR:
1668 {
1669 struct mach_o_unwind_regular_second_level_page_header *l2;
1670 struct mach_o_unwind_regular_second_level_entry *en;
1671 unsigned int entry_offset;
1672 unsigned int entry_count;
1673 unsigned int j;
1674
1675 l2 = (struct mach_o_unwind_regular_second_level_page_header *)
1676 level2;
1677
1678 entry_offset = bfd_get_16 (abfd, l2->entry_page_offset);
1679 entry_count = bfd_get_16 (abfd, l2->entry_count);
1680 printf (" index %2u: regular level 2 at 0x%04x, %u entries\n",
1681 i, entry_offset, entry_count);
1682 printf (" # function encoding\n");
1683
1684 en = (struct mach_o_unwind_regular_second_level_entry *)
1685 (level2 + entry_offset);
1686 for (j = 0; j < entry_count; j++)
1687 {
1688 unsigned int en_func;
1689 unsigned int encoding;
1690
1691 en_func = bfd_get_32 (abfd, en->function_offset);
1692 encoding = bfd_get_32 (abfd, en->encoding);
1693 printf (" %-4u 0x%08x ", j, en_func);
1694 dump_unwind_encoding (mdata, encoding);
1695 putchar ('\n');
1696 en++;
1697 }
1698 }
1699 break;
1700
1701 default:
1702 printf (" index %2u: unhandled second level format (%u)\n",
1703 i, kind);
1704 break;
1705 }
1706
1707 {
1708 struct mach_o_unwind_lsda_index_entry *lsda;
1709 unsigned int lsda_offset;
1710 unsigned int next_lsda_offset;
1711 unsigned int nbr_lsda;
1712 unsigned int j;
1713
1714 lsda_offset = bfd_get_32 (abfd, index_entry->lsda_index_offset);
1715 next_lsda_offset = bfd_get_32 (abfd, index_entry[1].lsda_index_offset);
1716 lsda = (struct mach_o_unwind_lsda_index_entry *)
1717 (content + lsda_offset);
1718 nbr_lsda = (next_lsda_offset - lsda_offset) / sizeof (*lsda);
1719 for (j = 0; j < nbr_lsda; j++)
1720 {
1721 printf (" lsda %3u: function 0x%08x lsda 0x%08x\n",
1722 j, (unsigned int) bfd_get_32 (abfd, lsda->function_offset),
1723 (unsigned int) bfd_get_32 (abfd, lsda->lsda_offset));
1724 lsda++;
1725 }
1726 }
1727 index_entry++;
1728 }
1729 }
1730
1731 static void
1732 dump_section_content (bfd *abfd,
1733 const char *segname, const char *sectname,
1734 void (*dump)(bfd*, const unsigned char*, bfd_size_type))
1735 {
1736 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1737 unsigned int i;
1738
1739 for (i = 0; i < mdata->header.ncmds; i++)
1740 {
1741 bfd_mach_o_load_command *cmd = &mdata->commands[i];
1742 if (cmd->type == BFD_MACH_O_LC_SEGMENT
1743 || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
1744 {
1745 bfd_mach_o_segment_command *seg = &cmd->command.segment;
1746 bfd_mach_o_section *sec;
1747 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1748 if (strcmp (sec->segname, segname) == 0
1749 && strcmp (sec->sectname, sectname) == 0)
1750 {
1751 bfd_size_type size;
1752 asection *bfdsec = sec->bfdsection;
1753 unsigned char *content;
1754
1755 size = bfd_get_section_size (bfdsec);
1756 content = (unsigned char *) xmalloc (size);
1757 bfd_get_section_contents (abfd, bfdsec, content, 0, size);
1758
1759 (*dump)(abfd, content, size);
1760
1761 free (content);
1762 }
1763 }
1764 }
1765 }
1766
1767 /* Dump ABFD (according to the options[] array). */
1768
1769 static void
1770 mach_o_dump (bfd *abfd)
1771 {
1772 if (options[OPT_HEADER].selected)
1773 dump_header (abfd);
1774 if (options[OPT_SECTION].selected)
1775 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT, BFD_MACH_O_LC_SEGMENT_64);
1776 if (options[OPT_MAP].selected)
1777 dump_section_map (abfd);
1778 if (options[OPT_LOAD].selected)
1779 dump_load_commands (abfd, 0, 0);
1780 if (options[OPT_DYSYMTAB].selected)
1781 dump_load_commands (abfd, BFD_MACH_O_LC_DYSYMTAB, 0);
1782 if (options[OPT_CODESIGN].selected)
1783 dump_load_commands (abfd, BFD_MACH_O_LC_CODE_SIGNATURE, 0);
1784 if (options[OPT_SEG_SPLIT_INFO].selected)
1785 dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO, 0);
1786 if (options[OPT_FUNCTION_STARTS].selected)
1787 dump_load_commands (abfd, BFD_MACH_O_LC_FUNCTION_STARTS, 0);
1788 if (options[OPT_DATA_IN_CODE].selected)
1789 dump_load_commands (abfd, BFD_MACH_O_LC_DATA_IN_CODE, 0);
1790 if (options[OPT_TWOLEVEL_HINTS].selected)
1791 dump_load_commands (abfd, BFD_MACH_O_LC_TWOLEVEL_HINTS, 0);
1792 if (options[OPT_COMPACT_UNWIND].selected)
1793 {
1794 dump_section_content (abfd, "__LD", "__compact_unwind",
1795 dump_obj_compact_unwind);
1796 dump_section_content (abfd, "__TEXT", "__unwind_info",
1797 dump_exe_compact_unwind);
1798 }
1799 }
1800
1801 /* Vector for Mach-O. */
1802
1803 const struct objdump_private_desc objdump_private_desc_mach_o =
1804 {
1805 mach_o_help,
1806 mach_o_filter,
1807 mach_o_dump,
1808 options
1809 };