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 | |
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')
-rw-r--r-- | bfd/ChangeLog | 14 | ||||
-rw-r--r-- | bfd/mach-o.c | 72 | ||||
-rw-r--r-- | bfd/mach-o.h | 32 |
3 files changed, 110 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5c7b2b3..d2fb972 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,17 @@ +2014-04-02 Tristan Gingold <gingold@adacore.com> + + * 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. + 2014-04-02 Alan Modra <amodra@gmail.com> * elfcode.h (bfd_from_remote_memory): Add "size" parameter. 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) diff --git a/bfd/mach-o.h b/bfd/mach-o.h index 4418b92..629459b 100644 --- a/bfd/mach-o.h +++ b/bfd/mach-o.h @@ -375,6 +375,27 @@ bfd_mach_o_dysymtab_command; #define BFD_MACH_O_INDIRECT_SYMBOL_ABS 0x40000000 #define BFD_MACH_O_INDIRECT_SYMBOL_SIZE 4 +/* For LC_TWOLEVEL_HINTS. */ + +typedef struct bfd_mach_o_twolevel_hints_command +{ + /* Offset to the hint table. */ + unsigned int offset; + + /* Number of entries in the table. */ + unsigned int nhints; +} +bfd_mach_o_twolevel_hints_command; + +/* For LC_PREBIND_CKSUM. */ + +typedef struct bfd_mach_o_prebind_cksum_command +{ + /* Checksum or zero. */ + unsigned int cksum; +} +bfd_mach_o_prebind_cksum_command; + /* For LC_THREAD or LC_UNIXTHREAD. */ typedef struct bfd_mach_o_thread_flavour @@ -421,9 +442,12 @@ bfd_mach_o_dylib_command; typedef struct bfd_mach_o_prebound_dylib_command { - unsigned long name; /* Library's path name. */ - unsigned long nmodules; /* Number of modules in library. */ - unsigned long linked_modules; /* Bit vector of linked modules. */ + unsigned int name_offset; /* Library's path name. */ + unsigned int nmodules; /* Number of modules in library. */ + unsigned int linked_modules_offset; /* Bit vector of linked modules. */ + + char *name_str; + unsigned char *linked_modules; } bfd_mach_o_prebound_dylib_command; @@ -535,6 +559,8 @@ typedef struct bfd_mach_o_load_command bfd_mach_o_dylib_command dylib; bfd_mach_o_dylinker_command dylinker; bfd_mach_o_prebound_dylib_command prebound_dylib; + bfd_mach_o_prebind_cksum_command prebind_cksum; + bfd_mach_o_twolevel_hints_command twolevel_hints; bfd_mach_o_uuid_command uuid; bfd_mach_o_linkedit_command linkedit; bfd_mach_o_str_command str; |