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