diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9fd34c2e8e..39ee6fd19a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2009-09-09 Tristan Gingold + + Handle DYLD_INFO introduced by Darwin10. + * mach-o.h (bfd_mach_o_load_command_type): Add + BFD_MACH_O_LC_DYLD_INFO. + (bfd_mach_o_dyld_info_command): New type. + (bfd_mach_o_load_command): Add dyld_info field. + * mach-o.c (bfd_mach_o_scan_read_str): Reduce size of buf. + (bfd_mach_o_scan_read_dyld_info): New function. + (bfd_mach_o_scan_read_command): Handle BFD_MACH_O_LC_DYLD_INFO. + (bfd_mach_o_bfd_print_private_bfd_data): Ditto. + (bfd_mach_o_load_command_name): AddB FD_MACH_O_LC_DYLD_INFO. + (bfd_mach_o_print_dyld_info): New function. + + 2009-09-09 M R Swami Reddy * elf32-cr16.c (elf32_cr16_relocate_section): Add code to discard the diff --git a/bfd/mach-o.c b/bfd/mach-o.c index d1d6e70f15..5cf531ea06 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -2195,7 +2195,7 @@ static int bfd_mach_o_scan_read_str (bfd *abfd, bfd_mach_o_load_command *command) { bfd_mach_o_str_command *cmd = &command->command.str; - char buf[8]; + char buf[4]; unsigned long off; if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0 @@ -2214,6 +2214,29 @@ bfd_mach_o_scan_read_str (bfd *abfd, bfd_mach_o_load_command *command) return 0; } +static int +bfd_mach_o_scan_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command) +{ + bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info; + char buf[40]; + + if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0 + || bfd_bread ((PTR) buf, sizeof (buf), abfd) != sizeof (buf)) + return -1; + + cmd->rebase_off = bfd_get_32 (abfd, buf + 0); + cmd->rebase_size = bfd_get_32 (abfd, buf + 4); + cmd->bind_off = bfd_get_32 (abfd, buf + 8); + cmd->bind_size = bfd_get_32 (abfd, buf + 12); + cmd->weak_bind_off = bfd_get_32 (abfd, buf + 16); + cmd->weak_bind_size = bfd_get_32 (abfd, buf + 20); + cmd->lazy_bind_off = bfd_get_32 (abfd, buf + 24); + cmd->lazy_bind_size = bfd_get_32 (abfd, buf + 28); + cmd->export_off = bfd_get_32 (abfd, buf + 32); + cmd->export_size = bfd_get_32 (abfd, buf + 36); + return 0; +} + static int bfd_mach_o_scan_read_segment (bfd *abfd, bfd_mach_o_load_command *command, @@ -2384,6 +2407,10 @@ bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command) if (bfd_mach_o_scan_read_linkedit (abfd, command) != 0) return -1; break; + case BFD_MACH_O_LC_DYLD_INFO: + if (bfd_mach_o_scan_read_dyld_info (abfd, command) != 0) + return -1; + break; default: fprintf (stderr, "unable to read unknown load command 0x%lx\n", (unsigned long) command->type); @@ -3183,6 +3210,7 @@ static bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] = { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB}, { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB}, { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO}, + { "dyld_info", BFD_MACH_O_LC_DYLD_INFO}, { NULL, 0} }; @@ -3538,6 +3566,24 @@ bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED, } +static void +bfd_mach_o_print_dyld_info (bfd *abfd ATTRIBUTE_UNUSED, + bfd_mach_o_load_command *cmd, FILE *file) +{ + bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info; + + fprintf (file, " rebase: off: 0x%08x size: %-8u\n", + info->rebase_off, info->rebase_size); + fprintf (file, " bind: off: 0x%08x size: %-8u\n", + info->bind_off, info->bind_size); + fprintf (file, " weak bind: off: 0x%08x size: %-8u\n", + info->weak_bind_off, info->weak_bind_size); + fprintf (file, " lazy bind: off: 0x%08x size: %-8u\n", + info->lazy_bind_off, info->lazy_bind_size); + fprintf (file, " export: off: 0x%08x size: %-8u\n", + info->export_off, info->export_size); +} + bfd_boolean bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, PTR ptr) { @@ -3660,6 +3706,10 @@ bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, PTR ptr) } break; } + case BFD_MACH_O_LC_DYLD_INFO: + fprintf (file, "\n"); + bfd_mach_o_print_dyld_info (abfd, cmd, file); + break; default: fprintf (file, "\n"); break; diff --git a/bfd/mach-o.h b/bfd/mach-o.h index 0f48324f52..c1831e4bc1 100644 --- a/bfd/mach-o.h +++ b/bfd/mach-o.h @@ -132,7 +132,8 @@ typedef enum bfd_mach_o_load_command_type BFD_MACH_O_LC_SEGMENT_SPLIT_INFO = 0x1e, /* Local of info to split seg. */ BFD_MACH_O_LC_REEXPORT_DYLIB = 0x1f, /* Load and re-export lib. */ BFD_MACH_O_LC_LAZY_LOAD_DYLIB = 0x20, /* Delay load of lib until use. */ - BFD_MACH_O_LC_ENCRYPTION_INFO = 0x21 /* Encrypted segment info. */ + BFD_MACH_O_LC_ENCRYPTION_INFO = 0x21, /* Encrypted segment info. */ + BFD_MACH_O_LC_DYLD_INFO = 0x22 /* Compressed dyld information. */ } bfd_mach_o_load_command_type; @@ -768,6 +769,30 @@ typedef struct bfd_mach_o_str_command } bfd_mach_o_str_command; +typedef struct bfd_mach_o_dyld_info_command +{ + /* File offset and size to rebase info. */ + unsigned int rebase_off; + unsigned int rebase_size; + + /* File offset and size of binding info. */ + unsigned int bind_off; + unsigned int bind_size; + + /* File offset and size of weak binding info. */ + unsigned int weak_bind_off; + unsigned int weak_bind_size; + + /* File offset and size of lazy binding info. */ + unsigned int lazy_bind_off; + unsigned int lazy_bind_size; + + /* File offset and size of export info. */ + unsigned int export_off; + unsigned int export_size; +} +bfd_mach_o_dyld_info_command; + typedef struct bfd_mach_o_load_command { bfd_mach_o_load_command_type type; @@ -786,6 +811,7 @@ typedef struct bfd_mach_o_load_command bfd_mach_o_uuid_command uuid; bfd_mach_o_linkedit_command linkedit; bfd_mach_o_str_command str; + bfd_mach_o_dyld_info_command dyld_info; } command; }