X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=binutils%2Fod-macho.c;h=f5d2cf5cde03c8eee3027e47f1ce726c9163967d;hb=0cf082277804ba3747be70a4013019f68b92bb84;hp=92d6a73322f49a3f5607b8e9c92284e9dea8aff7;hpb=47f8a1070c0619bf7698e6584f7196f06e529da0;p=binutils-gdb.git diff --git a/binutils/od-macho.c b/binutils/od-macho.c index 92d6a73322f..f5d2cf5cde0 100644 --- a/binutils/od-macho.c +++ b/binutils/od-macho.c @@ -1,5 +1,5 @@ /* od-macho.c -- dump information about an Mach-O object file. - Copyright (C) 2011-2014 Free Software Foundation, Inc. + Copyright (C) 2011-2017 Free Software Foundation, Inc. Written by Tristan Gingold, Adacore. This file is part of GNU Binutils. @@ -26,8 +26,8 @@ #include "bfd.h" #include "objdump.h" #include "bucomm.h" +#include "dwarf.h" #include "bfdlink.h" -#include "libbfd.h" #include "mach-o.h" #include "mach-o/external.h" #include "mach-o/codesign.h" @@ -45,6 +45,7 @@ #define OPT_FUNCTION_STARTS 8 #define OPT_DATA_IN_CODE 9 #define OPT_TWOLEVEL_HINTS 10 +#define OPT_DYLD_INFO 11 /* List of actions. */ static struct objdump_private_option options[] = @@ -60,6 +61,7 @@ static struct objdump_private_option options[] = { "function_starts", 0 }, { "data_in_code", 0 }, { "twolevel_hints", 0 }, + { "dyld_info", 0 }, { NULL, 0 } }; @@ -81,6 +83,7 @@ For Mach-O files:\n\ function_starts Display start address of functions\n\ data_in_code Display data in code entries\n\ twolevel_hints Display the two-level namespace lookup hints table\n\ + dyld_info Display dyld information\n\ ")); } @@ -152,6 +155,10 @@ static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] = { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE }, { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS }, { "pie", BFD_MACH_O_MH_PIE }, + { "dead_strippable_dylib", BFD_MACH_O_MH_DEAD_STRIPPABLE_DYLIB }, + { "has_tlv", BFD_MACH_O_MH_HAS_TLV_DESCRIPTORS }, + { "no_heap_execution", BFD_MACH_O_MH_NO_HEAP_EXECUTION }, + { "app_extension_safe", BFD_MACH_O_MH_APP_EXTENSION_SAFE }, { NULL, 0} }; @@ -200,6 +207,9 @@ static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] = { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE}, { "source_version", BFD_MACH_O_LC_SOURCE_VERSION}, { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS}, + { "encryption_info_64", BFD_MACH_O_LC_ENCRYPTION_INFO_64}, + { "linker_options", BFD_MACH_O_LC_LINKER_OPTIONS}, + { "linker_optimization_hint", BFD_MACH_O_LC_LINKER_OPTIMIZATION_HINT}, { NULL, 0} }; @@ -249,7 +259,7 @@ bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table, printf ("-"); } -/* Print a bfd_uint64_t, using a platform independant style. */ +/* Print a bfd_uint64_t, using a platform independent style. */ static void printf_uint64 (bfd_uint64_t v) @@ -314,22 +324,22 @@ static void dump_section_map (bfd *abfd) { bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); - unsigned int i; + bfd_mach_o_load_command *cmd; unsigned int sec_nbr = 0; fputs (_("Segments and Sections:\n"), stdout); fputs (_(" #: Segment name Section name Address\n"), stdout); - for (i = 0; i < mdata->header.ncmds; i++) + for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next) { bfd_mach_o_segment_command *seg; bfd_mach_o_section *sec; - if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT - && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64) + if (cmd->type != BFD_MACH_O_LC_SEGMENT + && cmd->type != BFD_MACH_O_LC_SEGMENT_64) continue; - seg = &mdata->commands[i].command.segment; + seg = &cmd->command.segment; printf ("[Segment %-16s ", seg->segname); printf_vma (seg->vmaddr); @@ -622,26 +632,365 @@ dump_dysymtab (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose) } +static bfd_boolean +load_and_dump (bfd *abfd, ufile_ptr off, unsigned int len, + void (*dump)(bfd *abfd, unsigned char *buf, unsigned int len, + ufile_ptr off)) +{ + unsigned char *buf; + + if (len == 0) + return TRUE; + + buf = xmalloc (len); + + if (bfd_seek (abfd, off, SEEK_SET) == 0 + && bfd_bread (buf, len, abfd) == len) + dump (abfd, buf, len, off); + else + return FALSE; + + free (buf); + return TRUE; +} + +static const bfd_mach_o_xlat_name bfd_mach_o_dyld_rebase_type_name[] = +{ + { "pointer", BFD_MACH_O_REBASE_TYPE_POINTER }, + { "text_abs32", BFD_MACH_O_REBASE_TYPE_TEXT_ABSOLUTE32 }, + { "text_pcrel32", BFD_MACH_O_REBASE_TYPE_TEXT_PCREL32 }, + { NULL, 0 } +}; + +static void +dump_dyld_info_rebase (bfd *abfd, unsigned char *buf, unsigned int len, + ufile_ptr off ATTRIBUTE_UNUSED) +{ + unsigned int i; + bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); + unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4; + + for (i = 0; i < len; ) + { + unsigned char b = buf[i++]; + unsigned char imm = b & BFD_MACH_O_REBASE_IMMEDIATE_MASK; + bfd_vma leb; + unsigned int leblen; + + printf (" [0x%04x] 0x%02x: ", i, b); + switch (b & BFD_MACH_O_REBASE_OPCODE_MASK) + { + case BFD_MACH_O_REBASE_OPCODE_DONE: + printf ("done\n"); + return; + case BFD_MACH_O_REBASE_OPCODE_SET_TYPE_IMM: + printf ("set_type %s\n", + bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm)); + break; + case BFD_MACH_O_REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("set segment: %u and offset: 0x%08x\n", + imm, (unsigned) leb); + i += leblen; + break; + case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_ULEB: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("add addr uleb: 0x%08x\n", (unsigned) leb); + i += leblen; + break; + case BFD_MACH_O_REBASE_OPCODE_ADD_ADDR_IMM_SCALED: + printf ("add addr imm scaled: %u\n", imm * ptrsize); + break; + case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_IMM_TIMES: + printf ("rebase imm times: %u\n", imm); + break; + case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("rebase uleb times: %u\n", (unsigned) leb); + i += leblen; + break; + case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("rebase add addr uleb: %u\n", (unsigned) leb); + i += leblen; + break; + case BFD_MACH_O_REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("rebase uleb times (%u)", (unsigned) leb); + i += leblen; + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf (" skipping uleb (%u)\n", (unsigned) leb); + i += leblen; + break; + default: + printf ("unknown\n"); + return; + } + } + printf (" rebase commands without end!\n"); +} + +static void +dump_dyld_info_bind (bfd *abfd, unsigned char *buf, unsigned int len, + ufile_ptr off ATTRIBUTE_UNUSED) +{ + unsigned int i; + bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); + unsigned int ptrsize = mdata->header.version == 2 ? 8 : 4; + + for (i = 0; i < len; ) + { + unsigned char b = buf[i++]; + unsigned char imm = b & BFD_MACH_O_BIND_IMMEDIATE_MASK; + bfd_vma leb; + unsigned int leblen; + + printf (" [0x%04x] 0x%02x: ", i, b); + switch (b & BFD_MACH_O_BIND_OPCODE_MASK) + { + case BFD_MACH_O_BIND_OPCODE_DONE: + printf ("done\n"); + return; + case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: + printf ("set dylib ordinal imm: %u\n", imm); + break; + case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("set dylib ordinal uleb: %u\n", imm); + i += leblen; + break; + case BFD_MACH_O_BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: + imm = (imm != 0) ? imm | BFD_MACH_O_BIND_OPCODE_MASK : imm; + printf ("set dylib special imm: %d\n", imm); + break; + case BFD_MACH_O_BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: + printf ("set symbol trailing flags imm: 0x%02x, ", imm); + for (; i < len && buf[i] != 0; i++) + putchar (buf[i] >= ' ' && buf[i] < 0x7f ? buf[i] : '?'); + putchar ('\n'); + i++; + break; + case BFD_MACH_O_BIND_OPCODE_SET_TYPE_IMM: + /* Kludge: use the same table as rebase type. */ + printf ("set_type %s\n", + bfd_mach_o_get_name (bfd_mach_o_dyld_rebase_type_name, imm)); + break; + case BFD_MACH_O_BIND_OPCODE_SET_ADDEND_SLEB: + { + bfd_signed_vma svma; + svma = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("set addend sleb: 0x%08x\n", (unsigned) svma); + i += leblen; + } + break; + case BFD_MACH_O_BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("set segment: %u and offset: 0x%08x\n", + imm, (unsigned) leb); + i += leblen; + break; + case BFD_MACH_O_BIND_OPCODE_ADD_ADDR_ULEB: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("add addr uleb: 0x%08x\n", (unsigned) leb); + i += leblen; + break; + case BFD_MACH_O_BIND_OPCODE_DO_BIND: + printf ("do bind\n"); + break; + case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("do bind add addr uleb: 0x%08x\n", (unsigned) leb); + i += leblen; + break; + case BFD_MACH_O_BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: + printf ("do bind add addr imm scaled: %u\n", imm * ptrsize); + break; + case BFD_MACH_O_BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf ("do bind uleb times (%u)", (unsigned) leb); + i += leblen; + leb = read_leb128 (buf + i, &leblen, 0, buf + len); + printf (" skipping uleb (%u)\n", (unsigned) leb); + i += leblen; + break; + default: + printf ("unknown\n"); + return; + } + } + printf (" bind commands without end!\n"); +} + +struct export_info_data +{ + const unsigned char *name; + struct export_info_data *next; +}; + static void -dump_dyld_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd) +dump_dyld_info_export_1 (bfd *abfd, unsigned char *buf, unsigned int len, + unsigned int off, struct export_info_data *parent, + struct export_info_data *base) { - bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info; + bfd_vma size; + unsigned int leblen; + unsigned int child_count; + unsigned int i; + + size = read_leb128 (buf + off, &leblen, 0, buf + len); + off += leblen; + + if (size != 0) + { + bfd_vma flags; + struct export_info_data *d; + + flags = read_leb128 (buf + off, &leblen, 0, buf + len); + off += leblen; + + fputs (" ", stdout); + switch (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_MASK) + { + case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_REGULAR: + putchar ('-'); + break; + case BFD_MACH_O_EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL: + putchar ('T'); + break; + default: + putchar ('?'); + break; + } + putchar ((flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION) ? + 'W' : '-'); + + if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_REEXPORT) + { + bfd_vma lib; + + lib = read_leb128 (buf + off, &leblen, 0, buf + len); + off += leblen; + + fputs (" [reexport] ", stdout); + for (d = base; d != NULL; d = d->next) + printf ("%s", d->name); + + fputs (" (", stdout); + if (buf[off] != 0) + { + fputs ((const char *)buf + off, stdout); + putchar (' '); + off += strlen ((const char *)buf + off); + } + printf ("from dylib %u)\n", (unsigned) lib); + off++; + } + else + { + bfd_vma offset; + bfd_vma resolv = 0; + + offset = read_leb128 (buf + off, &leblen, 0, buf + len); + off += leblen; + + if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) + { + resolv = read_leb128 (buf + off, &leblen, 0, buf + len); + off += leblen; + } + + printf (" 0x%08x ", (unsigned) offset); + for (d = base; d != NULL; d = d->next) + printf ("%s", d->name); + if (flags & BFD_MACH_O_EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) + printf (" [resolv: 0x%08x]", (unsigned) resolv); + printf ("\n"); + } + } + + child_count = read_leb128 (buf + off, &leblen, 0, buf + len); + off += leblen; + + for (i = 0; i < child_count; i++) + { + struct export_info_data sub_data; + bfd_vma sub_off; + + sub_data.name = buf + off; + sub_data.next = NULL; + parent->next = &sub_data; + + off += strlen ((const char *)buf + off) + 1; + + sub_off = read_leb128 (buf + off, &leblen, 0, buf + len); + off += leblen; + + dump_dyld_info_export_1 (abfd, buf, len, sub_off, &sub_data, base); + } +} + +static void +dump_dyld_info_export (bfd *abfd, unsigned char *buf, unsigned int len, + ufile_ptr off ATTRIBUTE_UNUSED) +{ + struct export_info_data data; + + data.name = (const unsigned char *) ""; + data.next = NULL; + + printf (" fl offset sym (Flags: Tls Weak)\n"); + dump_dyld_info_export_1 (abfd, buf, len, 0, &data, &data); +} + +static void +dump_dyld_info (bfd *abfd, bfd_mach_o_load_command *cmd, + bfd_boolean verbose) +{ + bfd_mach_o_dyld_info_command *dinfo = &cmd->command.dyld_info; printf (" rebase: off: 0x%08x size: %-8u (endoff: 0x%08x)\n", - info->rebase_off, info->rebase_size, - info->rebase_off + info->rebase_size); + dinfo->rebase_off, dinfo->rebase_size, + dinfo->rebase_off + dinfo->rebase_size); printf (" bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n", - info->bind_off, info->bind_size, - info->bind_off + info->bind_size); + dinfo->bind_off, dinfo->bind_size, + dinfo->bind_off + dinfo->bind_size); printf (" weak bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n", - info->weak_bind_off, info->weak_bind_size, - info->weak_bind_off + info->weak_bind_size); + dinfo->weak_bind_off, dinfo->weak_bind_size, + dinfo->weak_bind_off + dinfo->weak_bind_size); printf (" lazy bind: off: 0x%08x size: %-8u (endoff: 0x%08x)\n", - info->lazy_bind_off, info->lazy_bind_size, - info->lazy_bind_off + info->lazy_bind_size); + dinfo->lazy_bind_off, dinfo->lazy_bind_size, + dinfo->lazy_bind_off + dinfo->lazy_bind_size); printf (" export: off: 0x%08x size: %-8u (endoff: 0x%08x)\n", - info->export_off, info->export_size, - info->export_off + info->export_size); + dinfo->export_off, dinfo->export_size, + dinfo->export_off + dinfo->export_size); + + if (!verbose) + return; + + printf (" rebase:\n"); + if (!load_and_dump (abfd, dinfo->rebase_off, dinfo->rebase_size, + dump_dyld_info_rebase)) + non_fatal (_("cannot read rebase dyld info")); + + printf (" bind:\n"); + if (!load_and_dump (abfd, dinfo->bind_off, dinfo->bind_size, + dump_dyld_info_bind)) + non_fatal (_("cannot read bind dyld info")); + + printf (" weak bind:\n"); + if (!load_and_dump (abfd, dinfo->weak_bind_off, dinfo->weak_bind_size, + dump_dyld_info_bind)) + non_fatal (_("cannot read weak bind dyld info")); + + printf (" lazy bind:\n"); + if (!load_and_dump (abfd, dinfo->lazy_bind_off, dinfo->lazy_bind_size, + dump_dyld_info_bind)) + non_fatal (_("cannot read lazy bind dyld info")); + + printf (" exported symbols:\n"); + if (!load_and_dump (abfd, dinfo->export_off, dinfo->export_size, + dump_dyld_info_export)) + non_fatal (_("cannot read export symbols dyld info")); } static void @@ -938,7 +1287,7 @@ dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd) } for (p = buf + 1; *p != 0; p += len) { - addr += read_unsigned_leb128 (abfd, p, &len); + addr += read_leb128 (p, &len, 0, buf + cmd->datasize); fputs (" ", stdout); bfd_printf_vma (abfd, addr); putchar ('\n'); @@ -1207,8 +1556,8 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd, case BFD_MACH_O_LC_SUB_CLIENT: case BFD_MACH_O_LC_RPATH: { - bfd_mach_o_str_command *str = &cmd->command.str; - printf (" %s\n", str->str); + bfd_mach_o_str_command *strc = &cmd->command.str; + printf (" %s\n", strc->str); break; } case BFD_MACH_O_LC_THREAD: @@ -1219,16 +1568,15 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd, { bfd_mach_o_encryption_info_command *cryp = &cmd->command.encryption_info; - printf - (" cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)" - " cryptid: %u\n", - cryp->cryptoff, cryp->cryptsize, - cryp->cryptoff + cryp->cryptsize, - cryp->cryptid); + printf (" cryptoff: 0x%08x cryptsize: 0x%08x (endoff 0x%08x)" + " cryptid: %u\n", + cryp->cryptoff, cryp->cryptsize, + cryp->cryptoff + cryp->cryptsize, + cryp->cryptid); } break; case BFD_MACH_O_LC_DYLD_INFO: - dump_dyld_info (abfd, cmd); + dump_dyld_info (abfd, cmd, verbose); break; case BFD_MACH_O_LC_VERSION_MIN_MACOSX: case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS: @@ -1303,12 +1651,11 @@ static void dump_load_commands (bfd *abfd, unsigned int cmd32, unsigned int cmd64) { bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); + bfd_mach_o_load_command *cmd; unsigned int i; - for (i = 0; i < mdata->header.ncmds; i++) + for (cmd = mdata->first_command, i = 0; cmd != NULL; cmd = cmd->next, i++) { - bfd_mach_o_load_command *cmd = &mdata->commands[i]; - if (cmd32 == 0) dump_load_command (abfd, cmd, i, FALSE); else if (cmd->type == cmd32 || cmd->type == cmd64) @@ -1448,6 +1795,62 @@ dump_unwind_encoding_x86 (unsigned int encoding, unsigned int sz, } } +/* Dump arm64 compact unwind entries. */ + +static void +dump_unwind_encoding_arm64 (unsigned int encoding) +{ + switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK) + { + case MACH_O_UNWIND_ARM64_MODE_FRAMELESS: + printf (" frameless"); + break; + case MACH_O_UNWIND_ARM64_MODE_DWARF: + printf (" Dwarf offset: 0x%06x", + encoding & MACH_O_UNWIND_ARM64_DWARF_SECTION_OFFSET); + return; + case MACH_O_UNWIND_ARM64_MODE_FRAME: + printf (" frame"); + break; + default: + printf (" [unhandled mode]"); + return; + } + switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK) + { + case MACH_O_UNWIND_ARM64_MODE_FRAMELESS: + case MACH_O_UNWIND_ARM64_MODE_FRAME: + if (encoding & MACH_O_UNWIND_ARM64_FRAME_X19_X20_PAIR) + printf (" x19-x20"); + if (encoding & MACH_O_UNWIND_ARM64_FRAME_X21_X22_PAIR) + printf (" x21-x22"); + if (encoding & MACH_O_UNWIND_ARM64_FRAME_X23_X24_PAIR) + printf (" x23-x24"); + if (encoding & MACH_O_UNWIND_ARM64_FRAME_X25_X26_PAIR) + printf (" x25-x26"); + if (encoding & MACH_O_UNWIND_ARM64_FRAME_X27_X28_PAIR) + printf (" x27-x28"); + break; + } + switch (encoding & MACH_O_UNWIND_ARM64_MODE_MASK) + { + case MACH_O_UNWIND_ARM64_MODE_FRAME: + if (encoding & MACH_O_UNWIND_ARM64_FRAME_D8_D9_PAIR) + printf (" d8-d9"); + if (encoding & MACH_O_UNWIND_ARM64_FRAME_D10_D11_PAIR) + printf (" d10-d11"); + if (encoding & MACH_O_UNWIND_ARM64_FRAME_D12_D13_PAIR) + printf (" d12-d13"); + if (encoding & MACH_O_UNWIND_ARM64_FRAME_D14_D15_PAIR) + printf (" d14-d15"); + break; + case MACH_O_UNWIND_ARM64_MODE_FRAMELESS: + printf (" size: %u", + (encoding & MACH_O_UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK) >> 8); + break; + } +} + static void dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding) { @@ -1463,6 +1866,9 @@ dump_unwind_encoding (bfd_mach_o_data_struct *mdata, unsigned int encoding) case BFD_MACH_O_CPU_TYPE_I386: dump_unwind_encoding_x86 (encoding, 4, unwind_x86_regs); break; + case BFD_MACH_O_CPU_TYPE_ARM64: + dump_unwind_encoding_arm64 (encoding); + break; default: printf (" [unhandled cpu]"); break; @@ -1729,11 +2135,10 @@ dump_section_content (bfd *abfd, void (*dump)(bfd*, const unsigned char*, bfd_size_type)) { bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); - unsigned int i; + bfd_mach_o_load_command *cmd; - for (i = 0; i < mdata->header.ncmds; i++) + for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next) { - bfd_mach_o_load_command *cmd = &mdata->commands[i]; if (cmd->type == BFD_MACH_O_LC_SEGMENT || cmd->type == BFD_MACH_O_LC_SEGMENT_64) { @@ -1791,6 +2196,8 @@ mach_o_dump (bfd *abfd) dump_section_content (abfd, "__TEXT", "__unwind_info", dump_exe_compact_unwind); } + if (options[OPT_DYLD_INFO].selected) + dump_load_commands (abfd, BFD_MACH_O_LC_DYLD_INFO, 0); } /* Vector for Mach-O. */