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