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