diff options
author | Tristan Gingold <tristan.gingold@adacore.com> | 2014-03-26 10:41:16 +0100 |
---|---|---|
committer | Tristan Gingold <tristan.gingold@adacore.com> | 2014-04-01 12:39:28 +0200 |
commit | c275b681a57c50a6ed5d7cb5192be588fd451427 (patch) | |
tree | 2adde5f1fdc9164afb3a7eba459067a016455a93 /binutils/od-macho.c | |
parent | a41f2563d040d86954ccda7faa4a8ad7bdbcae88 (diff) | |
download | gdb-c275b681a57c50a6ed5d7cb5192be588fd451427.zip gdb-c275b681a57c50a6ed5d7cb5192be588fd451427.tar.gz gdb-c275b681a57c50a6ed5d7cb5192be588fd451427.tar.bz2 |
mach-o: display data_in_code.
binutils/
* od-macho.c (OPT_DATA_IN_CODE): New macro.
(options): Add entry for data in code.
(mach_o_help): Ditto.
(data_in_code_kind_name): New array.
(dump_data_in_code): New function.
(dump_load_command): Handle data in code.
(mach_o_dump): Ditto.
(dump_header): Display a terminal newline.
Diffstat (limited to 'binutils/od-macho.c')
-rw-r--r-- | binutils/od-macho.c | 85 |
1 files changed, 78 insertions, 7 deletions
diff --git a/binutils/od-macho.c b/binutils/od-macho.c index 80bf5c2..31cce9d 100644 --- a/binutils/od-macho.c +++ b/binutils/od-macho.c @@ -43,6 +43,7 @@ #define OPT_SEG_SPLIT_INFO 6 #define OPT_COMPACT_UNWIND 7 #define OPT_FUNCTION_STARTS 8 +#define OPT_DATA_IN_CODE 9 /* List of actions. */ static struct objdump_private_option options[] = @@ -56,6 +57,7 @@ static struct objdump_private_option options[] = { "seg_split_info", 0 }, { "compact_unwind", 0 }, { "function_starts", 0 }, + { "data_in_code", 0 }, { NULL, 0 } }; @@ -75,6 +77,7 @@ For Mach-O files:\n\ seg_split_info Display segment split info\n\ compact_unwind Display compact unwinding info\n\ function_starts Display start address of functions\n\ + data_in_code Display data in code entries\n\ ")); } @@ -284,6 +287,7 @@ dump_header (bfd *abfd) bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags); fputs (_(")\n"), stdout); printf (_(" reserved : %08x\n"), h->reserved); + putchar ('\n'); } static void @@ -974,6 +978,59 @@ dump_function_starts (bfd *abfd, bfd_mach_o_linkedit_command *cmd) free (buf); } +static const bfd_mach_o_xlat_name data_in_code_kind_name[] = +{ + { "data", BFD_MACH_O_DICE_KIND_DATA }, + { "1 byte jump table", BFD_MACH_O_DICE_JUMP_TABLES8 }, + { "2 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES16 }, + { "4 bytes jump table", BFD_MACH_O_DICE_JUMP_TABLES32 }, + { "4 bytes abs jump table", BFD_MACH_O_DICE_ABS_JUMP_TABLES32 }, + { NULL, 0 } +}; + +static void +dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd) +{ + unsigned char *buf; + unsigned char *p; + + if (cmd->datasize == 0) + { + printf (" no data_in_code entries\n"); + return; + } + + buf = xmalloc (cmd->datasize); + if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0 + || bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize) + { + non_fatal (_("cannot read function starts")); + free (buf); + return; + } + + printf (" offset length kind\n"); + for (p = buf; p < buf + cmd->datasize; ) + { + struct mach_o_data_in_code_entry_external *dice; + unsigned int offset; + unsigned int length; + unsigned int kind; + + dice = (struct mach_o_data_in_code_entry_external *) p; + + offset = bfd_get_32 (abfd, dice->offset); + length = bfd_get_16 (abfd, dice->length); + kind = bfd_get_16 (abfd, dice->kind); + + printf (" 0x%08x 0x%04x 0x%04x %s\n", offset, length, kind, + bfd_mach_o_get_name (data_in_code_kind_name, kind)); + + p += sizeof (*dice); + } + free (buf); +} + static void dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd, bfd_boolean verbose) @@ -1070,14 +1127,26 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd, linkedit->dataoff, linkedit->datasize, linkedit->dataoff + linkedit->datasize); - if (verbose && cmd->type == BFD_MACH_O_LC_CODE_SIGNATURE) - dump_code_signature (abfd, linkedit); - else if (verbose && cmd->type == BFD_MACH_O_LC_SEGMENT_SPLIT_INFO) - dump_segment_split_info (abfd, linkedit); - else if (verbose && cmd->type == BFD_MACH_O_LC_FUNCTION_STARTS) - dump_function_starts (abfd, linkedit); - break; + if (verbose) + switch (cmd->type) + { + case BFD_MACH_O_LC_CODE_SIGNATURE: + dump_code_signature (abfd, linkedit); + break; + case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO: + dump_segment_split_info (abfd, linkedit); + break; + case BFD_MACH_O_LC_FUNCTION_STARTS: + dump_function_starts (abfd, linkedit); + break; + case BFD_MACH_O_LC_DATA_IN_CODE: + dump_data_in_code (abfd, linkedit); + break; + default: + break; + } } + break; case BFD_MACH_O_LC_SUB_FRAMEWORK: case BFD_MACH_O_LC_SUB_UMBRELLA: case BFD_MACH_O_LC_SUB_LIBRARY: @@ -1617,6 +1686,8 @@ mach_o_dump (bfd *abfd) dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO, 0); if (options[OPT_FUNCTION_STARTS].selected) dump_load_commands (abfd, BFD_MACH_O_LC_FUNCTION_STARTS, 0); + if (options[OPT_DATA_IN_CODE].selected) + dump_load_commands (abfd, BFD_MACH_O_LC_DATA_IN_CODE, 0); if (options[OPT_COMPACT_UNWIND].selected) { dump_section_content (abfd, "__LD", "__compact_unwind", |