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