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