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