diff options
author | Tristan Gingold <tristan.gingold@adacore.com> | 2014-03-26 15:01:53 +0100 |
---|---|---|
committer | Tristan Gingold <tristan.gingold@adacore.com> | 2014-04-02 15:03:51 +0200 |
commit | 7a79c51466c30188d49d03d3e3593c87e5a3345e (patch) | |
tree | ba47b17425271ba5074065034c29bd37f8055c02 /bfd/mach-o.c | |
parent | 5979d6b69b20a8355ea94b75fad97415fce4788c (diff) | |
download | gdb-7a79c51466c30188d49d03d3e3593c87e5a3345e.zip gdb-7a79c51466c30188d49d03d3e3593c87e5a3345e.tar.gz gdb-7a79c51466c30188d49d03d3e3593c87e5a3345e.tar.bz2 |
mach-o: read and dump: prebound_dylib, prebind_cksum, twolevel_hints.
include/mach-o:
* external.h (mach_o_prebound_dylib_command_external)
(mach_o_prebind_cksum_command_external)
(mach_o_twolevel_hints_command_external): New types.
bfd/
* mach-o.h (bfd_mach_o_twolevel_hints_command)
(bfd_mach_o_prebind_cksum_command): New types.
(bfd_mach_o_prebound_dylib_command): Rewrite.
(bfd_mach_o_load_command): Add prebind_cksum and twolevel_hints
fields.
* mach-o.c (bfd_mach_o_read_prebound_dylib): Read and decode the
command.
(bfd_mach_o_read_prebind_cksum): New function.
(bfd_mach_o_read_twolevel_hints): Ditto.
(bfd_mach_o_read_command): Handle prebind cksum and twolevel hints
commands.
binutils/
* od-macho.c (OPT_TWOLEVEL_HINTS): New macro.
(options): Add entry for twolevel_hints.
(dump_data_in_code): Fix error message.
(dump_twolevel_hints): New function.
(dump_load_command): Handle prebound dylib, prebind cksum
and twolevel hints.
(mach_o_dump): Handle twolevel hints.
Diffstat (limited to 'bfd/mach-o.c')
-rw-r--r-- | bfd/mach-o.c | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/bfd/mach-o.c b/bfd/mach-o.c index e33c01f..525607e 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -3207,12 +3207,69 @@ bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command) } static int -bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED, - bfd_mach_o_load_command *command ATTRIBUTE_UNUSED) +bfd_mach_o_read_prebound_dylib (bfd *abfd, + bfd_mach_o_load_command *command) { - /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */ + bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; + struct mach_o_prebound_dylib_command_external raw; + unsigned int nameoff; + unsigned int modoff; + unsigned int str_len; + unsigned char *str; + + if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0 + || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw)) + return -1; + + nameoff = bfd_h_get_32 (abfd, raw.name); + modoff = bfd_h_get_32 (abfd, raw.linked_modules); + if (nameoff > command->len || modoff > command->len) + return -1; + + str_len = command->len - sizeof (raw); + str = bfd_alloc (abfd, str_len); + if (str == NULL) + return -1; + if (bfd_bread (str, str_len, abfd) != str_len) + return -1; + + cmd->name_offset = command->offset + nameoff; + cmd->nmodules = bfd_h_get_32 (abfd, raw.nmodules); + cmd->linked_modules_offset = command->offset + modoff; + + cmd->name_str = (char *)str + nameoff - (sizeof (raw) + BFD_MACH_O_LC_SIZE); + cmd->linked_modules = str + modoff - (sizeof (raw) + BFD_MACH_O_LC_SIZE); + return 0; +} + +static int +bfd_mach_o_read_prebind_cksum (bfd *abfd, + bfd_mach_o_load_command *command) +{ + bfd_mach_o_prebind_cksum_command *cmd = &command->command.prebind_cksum; + struct mach_o_prebind_cksum_command_external raw; - BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB); + if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0 + || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw)) + return -1; + + cmd->cksum = bfd_get_32 (abfd, raw.cksum); + return 0; +} + +static int +bfd_mach_o_read_twolevel_hints (bfd *abfd, + bfd_mach_o_load_command *command) +{ + bfd_mach_o_twolevel_hints_command *cmd = &command->command.twolevel_hints; + struct mach_o_twolevel_hints_command_external raw; + + if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0 + || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw)) + return -1; + + cmd->offset = bfd_get_32 (abfd, raw.offset); + cmd->nhints = bfd_get_32 (abfd, raw.nhints); return 0; } @@ -3881,8 +3938,13 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command) if (bfd_mach_o_read_dysymtab (abfd, command) != 0) return -1; break; - case BFD_MACH_O_LC_TWOLEVEL_HINTS: case BFD_MACH_O_LC_PREBIND_CKSUM: + if (bfd_mach_o_read_prebind_cksum (abfd, command) != 0) + return -1; + break; + case BFD_MACH_O_LC_TWOLEVEL_HINTS: + if (bfd_mach_o_read_twolevel_hints (abfd, command) != 0) + return -1; break; case BFD_MACH_O_LC_UUID: if (bfd_mach_o_read_uuid (abfd, command) != 0) |