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