From 1778ad74b30a4873b8288ef88918677d333164e2 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 14 Nov 2012 11:03:27 +0000 Subject: [PATCH] bfd/ 2012-11-14 Tristan Gingold * mach-o.c (bfd_mach_o_read_main) (bfd_mach_o_read_source_version): New functions. (bfd_mach_o_read_command): Handle BFD_MACH_O_LC_DATA_IN_CODE, BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS, BFD_MACH_O_LC_MAIN, BFD_MACH_O_LC_SOURCE_VERSION. * mach-o.h (bfd_mach_o_main_command) (bfd_mach_o_source_version_command): New types. (bfd_mach_o_load_command): Add fields for these new types. binutils/ 2012-11-14 Tristan Gingold * od-macho.c (bfd_mach_o_load_command_name): Add new definitions. (dump_load_command): Handle BFD_MACH_O_LC_SOURCE_VERSION and BFD_MACH_O_LC_MAIN. --- bfd/ChangeLog | 11 ++++++++++ bfd/mach-o.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ bfd/mach-o.h | 21 +++++++++++++++++- binutils/ChangeLog | 6 ++++++ binutils/od-macho.c | 25 ++++++++++++++++++++++ 5 files changed, 114 insertions(+), 1 deletion(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9eb40470507..2f39d1ca70c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2012-11-14 Tristan Gingold + + * mach-o.c (bfd_mach_o_read_main) + (bfd_mach_o_read_source_version): New functions. + (bfd_mach_o_read_command): Handle BFD_MACH_O_LC_DATA_IN_CODE, + BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS, BFD_MACH_O_LC_MAIN, + BFD_MACH_O_LC_SOURCE_VERSION. + * mach-o.h (bfd_mach_o_main_command) + (bfd_mach_o_source_version_command): New types. + (bfd_mach_o_load_command): Add fields for these new types. + 2012-11-14 Tristan Gingold * mach-o.c (bfd_mach_o_canonicalize_one_reloc): Add a special diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 29ebba4a77e..e44cf6d4c58 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -3666,6 +3666,48 @@ bfd_mach_o_read_encryption_info (bfd *abfd, bfd_mach_o_load_command *command) return TRUE; } +static bfd_boolean +bfd_mach_o_read_main (bfd *abfd, bfd_mach_o_load_command *command) +{ + bfd_mach_o_main_command *cmd = &command->command.main; + struct mach_o_entry_point_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 FALSE; + + cmd->entryoff = bfd_get_64 (abfd, raw.entryoff); + cmd->stacksize = bfd_get_64 (abfd, raw.stacksize); + return TRUE; +} + +static bfd_boolean +bfd_mach_o_read_source_version (bfd *abfd, bfd_mach_o_load_command *command) +{ + bfd_mach_o_source_version_command *cmd = &command->command.source_version; + struct mach_o_source_version_command_external raw; + bfd_uint64_t ver; + + if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0 + || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw)) + return FALSE; + + ver = bfd_get_64 (abfd, raw.version); + /* Note: we use a serie of shift to avoid shift > 32 (for which gcc + generates warnings) in case of the host doesn't support 64 bit + integers. */ + cmd->e = ver & 0x3ff; + ver >>= 10; + cmd->d = ver & 0x3ff; + ver >>= 10; + cmd->c = ver & 0x3ff; + ver >>= 10; + cmd->b = ver & 0x3ff; + ver >>= 10; + cmd->a = ver & 0xffffff; + return TRUE; +} + static int bfd_mach_o_read_segment (bfd *abfd, bfd_mach_o_load_command *command, @@ -3842,6 +3884,8 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command) case BFD_MACH_O_LC_CODE_SIGNATURE: case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO: case BFD_MACH_O_LC_FUNCTION_STARTS: + case BFD_MACH_O_LC_DATA_IN_CODE: + case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS: if (bfd_mach_o_read_linkedit (abfd, command) != 0) return -1; break; @@ -3858,6 +3902,14 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command) if (!bfd_mach_o_read_version_min (abfd, command)) return -1; break; + case BFD_MACH_O_LC_MAIN: + if (!bfd_mach_o_read_main (abfd, command)) + return -1; + break; + case BFD_MACH_O_LC_SOURCE_VERSION: + if (!bfd_mach_o_read_source_version (abfd, command)) + return -1; + break; default: (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"), abfd, (unsigned long) command->type); diff --git a/bfd/mach-o.h b/bfd/mach-o.h index f228df048ff..1db86746b9b 100644 --- a/bfd/mach-o.h +++ b/bfd/mach-o.h @@ -467,7 +467,7 @@ bfd_mach_o_fvmlib_command; typedef struct bfd_mach_o_dyld_info_command { /* File offset and size to rebase info. */ - unsigned int rebase_off; + unsigned int rebase_off; unsigned int rebase_size; /* File offset and size of binding info. */ @@ -505,6 +505,23 @@ typedef struct bfd_mach_o_encryption_info_command } bfd_mach_o_encryption_info_command; +typedef struct bfd_mach_o_main_command +{ + bfd_uint64_t entryoff; + bfd_uint64_t stacksize; +} +bfd_mach_o_main_command; + +typedef struct bfd_mach_o_source_version_command +{ + unsigned int a; + unsigned short b; + unsigned short c; + unsigned short d; + unsigned short e; +} +bfd_mach_o_source_version_command; + typedef struct bfd_mach_o_load_command { bfd_mach_o_load_command_type type; @@ -527,6 +544,8 @@ typedef struct bfd_mach_o_load_command bfd_mach_o_version_min_command version_min; bfd_mach_o_encryption_info_command encryption_info; bfd_mach_o_fvmlib_command fvmlib; + bfd_mach_o_main_command main; + bfd_mach_o_source_version_command source_version; } command; } diff --git a/binutils/ChangeLog b/binutils/ChangeLog index c70e4b34d8e..23f84093fc9 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2012-11-14 Tristan Gingold + + * od-macho.c (bfd_mach_o_load_command_name): Add new definitions. + (dump_load_command): Handle BFD_MACH_O_LC_SOURCE_VERSION + and BFD_MACH_O_LC_MAIN. + 2012-11-13 Maciej W. Rozycki * readelf.c (get_machine_flags) : Move diff --git a/binutils/od-macho.c b/binutils/od-macho.c index ca1dba73b4a..e62f137022a 100644 --- a/binutils/od-macho.c +++ b/binutils/od-macho.c @@ -182,6 +182,10 @@ static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] = { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS}, { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS}, { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT}, + { "main", BFD_MACH_O_LC_MAIN}, + { "data_in_code", BFD_MACH_O_LC_DATA_IN_CODE}, + { "source_version", BFD_MACH_O_LC_SOURCE_VERSION}, + { "dylib_code_sign_drs", BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS}, { NULL, 0} }; @@ -1036,6 +1040,27 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd, printf (" %u.%u.%u\n", ver->rel, ver->maj, ver->min); } break; + case BFD_MACH_O_LC_SOURCE_VERSION: + { + bfd_mach_o_source_version_command *version = + &cmd->command.source_version; + printf ("\n" + " version a.b.c.d.e: %u.%u.%u.%u.%u\n", + version->a, version->b, version->c, version->d, version->e); + break; + } + case BFD_MACH_O_LC_MAIN: + { + bfd_mach_o_main_command *entry = &cmd->command.main; + printf ("\n" + " entry offset: "); + printf_vma (entry->entryoff); + printf ("\n" + " stack size: "); + printf_vma (entry->stacksize); + printf ("\n"); + break; + } default: putchar ('\n'); printf (" offset: 0x%08lx\n", (unsigned long)cmd->offset); -- 2.30.2