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