mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-04-12 14:33:06 +08:00
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.
This commit is contained in:
parent
5979d6b69b
commit
7a79c51466
@ -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.
|
||||
|
72
bfd/mach-o.c
72
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
|
32
bfd/mach-o.h
32
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;
|
||||
|
@ -1,3 +1,13 @@
|
||||
2014-04-02 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2014-04-01 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* od-macho.c (OPT_DATA_IN_CODE): New macro.
|
||||
|
@ -44,6 +44,7 @@
|
||||
#define OPT_COMPACT_UNWIND 7
|
||||
#define OPT_FUNCTION_STARTS 8
|
||||
#define OPT_DATA_IN_CODE 9
|
||||
#define OPT_TWOLEVEL_HINTS 10
|
||||
|
||||
/* List of actions. */
|
||||
static struct objdump_private_option options[] =
|
||||
@ -58,6 +59,7 @@ static struct objdump_private_option options[] =
|
||||
{ "compact_unwind", 0 },
|
||||
{ "function_starts", 0 },
|
||||
{ "data_in_code", 0 },
|
||||
{ "twolevel_hints", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
@ -78,6 +80,7 @@ For Mach-O files:\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\
|
||||
twolevel_hints Display the two-level namespace lookup hints table\n\
|
||||
"));
|
||||
}
|
||||
|
||||
@ -1004,7 +1007,7 @@ dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
|
||||
if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
|
||||
|| bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
|
||||
{
|
||||
non_fatal (_("cannot read function starts"));
|
||||
non_fatal (_("cannot read data_in_code"));
|
||||
free (buf);
|
||||
return;
|
||||
}
|
||||
@ -1031,6 +1034,45 @@ dump_data_in_code (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
|
||||
free (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_twolevel_hints (bfd *abfd, bfd_mach_o_twolevel_hints_command *cmd)
|
||||
{
|
||||
size_t sz = 4 * cmd->nhints;
|
||||
unsigned char *buf;
|
||||
unsigned char *p;
|
||||
|
||||
buf = xmalloc (sz);
|
||||
if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
|
||||
|| bfd_bread (buf, sz, abfd) != sz)
|
||||
{
|
||||
non_fatal (_("cannot read twolevel hints"));
|
||||
free (buf);
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = buf; p < buf + sz; p += 4)
|
||||
{
|
||||
unsigned int v;
|
||||
unsigned int isub_image;
|
||||
unsigned int itoc;
|
||||
|
||||
v = bfd_get_32 (abfd, p);
|
||||
if (bfd_big_endian (abfd))
|
||||
{
|
||||
isub_image = (v >> 24) & 0xff;
|
||||
itoc = v & 0xffffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
isub_image = v & 0xff;
|
||||
itoc = (v >> 8) & 0xffffff;
|
||||
}
|
||||
|
||||
printf (" %3u %8u\n", isub_image, itoc);
|
||||
}
|
||||
free (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
|
||||
bfd_boolean verbose)
|
||||
@ -1195,6 +1237,43 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
|
||||
version->a, version->b, version->c, version->d, version->e);
|
||||
break;
|
||||
}
|
||||
case BFD_MACH_O_LC_PREBOUND_DYLIB:
|
||||
{
|
||||
bfd_mach_o_prebound_dylib_command *pbdy = &cmd->command.prebound_dylib;
|
||||
unsigned char *lm = pbdy->linked_modules;
|
||||
unsigned int j;
|
||||
unsigned int last;
|
||||
|
||||
printf (" %s\n", pbdy->name_str);
|
||||
printf (" nmodules: %u\n", pbdy->nmodules);
|
||||
printf (" linked modules (at %u): ",
|
||||
pbdy->linked_modules_offset - cmd->offset);
|
||||
last = pbdy->nmodules > 32 ? 32 : pbdy->nmodules;
|
||||
for (j = 0; j < last; j++)
|
||||
printf ("%u", (lm[j >> 3] >> (j & 7)) & 1);
|
||||
if (last < pbdy->nmodules)
|
||||
printf ("...");
|
||||
putchar ('\n');
|
||||
break;
|
||||
}
|
||||
case BFD_MACH_O_LC_PREBIND_CKSUM:
|
||||
{
|
||||
bfd_mach_o_prebind_cksum_command *cksum = &cmd->command.prebind_cksum;
|
||||
printf (" 0x%08x\n", cksum->cksum);
|
||||
break;
|
||||
}
|
||||
case BFD_MACH_O_LC_TWOLEVEL_HINTS:
|
||||
{
|
||||
bfd_mach_o_twolevel_hints_command *hints =
|
||||
&cmd->command.twolevel_hints;
|
||||
|
||||
printf ("\n"
|
||||
" table offset: 0x%08x nbr hints: %u\n",
|
||||
hints->offset, hints->nhints);
|
||||
if (verbose)
|
||||
dump_twolevel_hints (abfd, hints);
|
||||
break;
|
||||
}
|
||||
case BFD_MACH_O_LC_MAIN:
|
||||
{
|
||||
bfd_mach_o_main_command *entry = &cmd->command.main;
|
||||
@ -1688,6 +1767,8 @@ mach_o_dump (bfd *abfd)
|
||||
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_TWOLEVEL_HINTS].selected)
|
||||
dump_load_commands (abfd, BFD_MACH_O_LC_TWOLEVEL_HINTS, 0);
|
||||
if (options[OPT_COMPACT_UNWIND].selected)
|
||||
{
|
||||
dump_section_content (abfd, "__LD", "__compact_unwind",
|
||||
|
@ -1,3 +1,9 @@
|
||||
2014-04-02 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* external.h (mach_o_prebound_dylib_command_external)
|
||||
(mach_o_prebind_cksum_command_external)
|
||||
(mach_o_twolevel_hints_command_external): New types.
|
||||
|
||||
2014-03-26 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* loader.h (bfd_mach_o_cpu_type): Add BFD_MACH_O_CPU_TYPE_ARM64.
|
||||
|
@ -287,6 +287,24 @@ struct mach_o_dyld_info_command_external
|
||||
unsigned char export_size[4];
|
||||
};
|
||||
|
||||
struct mach_o_prebound_dylib_command_external
|
||||
{
|
||||
unsigned char name[4];
|
||||
unsigned char nmodules[4];
|
||||
unsigned char linked_modules[4];
|
||||
};
|
||||
|
||||
struct mach_o_prebind_cksum_command_external
|
||||
{
|
||||
unsigned char cksum[4];
|
||||
};
|
||||
|
||||
struct mach_o_twolevel_hints_command_external
|
||||
{
|
||||
unsigned char offset[4];
|
||||
unsigned char nhints[4];
|
||||
};
|
||||
|
||||
struct mach_o_version_min_command_external
|
||||
{
|
||||
unsigned char version[4];
|
||||
|
Loading…
x
Reference in New Issue
Block a user