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