aboutsummaryrefslogtreecommitdiff
path: root/bfd/mach-o.c
diff options
context:
space:
mode:
authorTristan Gingold <tristan.gingold@adacore.com>2014-03-26 15:01:53 +0100
committerTristan Gingold <tristan.gingold@adacore.com>2014-04-02 15:03:51 +0200
commit7a79c51466c30188d49d03d3e3593c87e5a3345e (patch)
treeba47b17425271ba5074065034c29bd37f8055c02 /bfd/mach-o.c
parent5979d6b69b20a8355ea94b75fad97415fce4788c (diff)
downloadgdb-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.c72
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)