diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 221c4a4c81..6c0fa83d21 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,21 @@ +2008-12-23 Tristan Gingold + + * mach-o.c (bfd_mach_o_make_bfd_section): Use the standard ELF name + .eh_frame for __TEXT.__eh_frame so that it is recognized by gdb. + Use shorter sections name for well known sections. + (bfd_mach_o_scan_read_dylinker): Only put dylinker name in the + section content. + (bfd_mach_o_scan_read_segment): Use shorter sections name for + well known segments. + (bfd_mach_o_scan_read_command): Ignore some new commands. + (bfd_mach_o_openr_next_archived_file): Use more descriptive names + for members filename. + (bfd_mach_o_fat_extract): New function to easily extract members + of a fat binary. + * mach-o.h (bfd_mach_o_load_command_type): Add new constants. + (bfd_mach_o_dylinker_command): Fix comment and reindent. + (bfd_mach_o_fat_extract): New prototype. + 2008-12-23 Johan Olmutz Nielsen * coffcode.h (coff_write_object_contents): Always initialise diff --git a/bfd/mach-o.c b/bfd/mach-o.c index afad9fdc12..9ae1bba1f7 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -796,6 +796,22 @@ bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section, if (strcmp (section->segname, "__DWARF") == 0 && strncmp (section->sectname, "__", 2) == 0) sprintf (sname, ".%s", section->sectname + 2); + else if (strcmp (section->segname, "__TEXT") == 0) + { + if (strcmp (section->sectname, "__eh_frame") == 0) + strcpy (sname, ".eh_frame"); + else if (section->sectname[0]) + sprintf (sname, "%s.%s", section->segname, section->sectname); + else + strcpy (sname, section->segname); + } + else if (strcmp (section->segname, "__DATA") == 0) + { + if (section->sectname[0]) + sprintf (sname, "%s.%s", section->segname, section->sectname); + else + strcpy (sname, section->segname); + } else sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname); @@ -1210,8 +1226,8 @@ bfd_mach_o_scan_read_dylinker (bfd *abfd, bfdsec->vma = 0; bfdsec->lma = 0; - bfdsec->size = command->len - 8; - bfdsec->filepos = command->offset + 8; + bfdsec->size = command->len - nameoff; + bfdsec->filepos = command->offset + nameoff; bfdsec->alignment_power = 0; cmd->section = bfdsec; @@ -1584,7 +1600,13 @@ bfd_mach_o_scan_read_segment (bfd *abfd, sname = bfd_alloc (abfd, snamelen); if (sname == NULL) return -1; - sprintf (sname, "%s.%s", prefix, seg->segname); + if (strcmp (seg->segname, "__TEXT") == 0 + || strcmp (seg->segname, "__DATA") == 0 + || strcmp (seg->segname, "__IMPORT") == 0 + || strcmp (seg->segname, "__LINKEDIT") == 0) + strcpy (sname, seg->segname); + else + sprintf (sname, "%s.%s", prefix, seg->segname); bfdsec = bfd_make_section_anyway (abfd, sname); if (bfdsec == NULL) @@ -1708,6 +1730,8 @@ bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command) return -1; break; case BFD_MACH_O_LC_CODE_SIGNATURE: + case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO: + case BFD_MACH_O_LC_REEXPORT_DYLIB: break; default: fprintf (stderr, "unable to read unknown load command 0x%lx\n", @@ -2110,10 +2134,8 @@ bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev) mach_o_fat_archentry *entry = NULL; unsigned long i; bfd *nbfd; - const char *arch_name; enum bfd_architecture arch_type; unsigned long arch_subtype; - char *s = NULL; adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data; BFD_ASSERT (adata != NULL); @@ -2153,17 +2175,89 @@ bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev) bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype, &arch_type, &arch_subtype); - arch_name = bfd_printable_arch_mach (arch_type, arch_subtype); - s = bfd_malloc (strlen (arch_name) + 1); - if (s == NULL) - return NULL; - strcpy (s, arch_name); - nbfd->filename = s; + /* Create the member filename. + Use FILENAME:ARCH_NAME. */ + { + char *s = NULL; + const char *arch_name; + size_t arch_file_len = strlen (bfd_get_filename (archive)); + + arch_name = bfd_printable_arch_mach (arch_type, arch_subtype); + s = bfd_malloc (arch_file_len + 1 + strlen (arch_name) + 1); + if (s == NULL) + return NULL; + memcpy (s, bfd_get_filename (archive), arch_file_len); + s[arch_file_len] = ':'; + strcpy (s + arch_file_len + 1, arch_name); + nbfd->filename = s; + } nbfd->iostream = NULL; + bfd_set_arch_mach (nbfd, arch_type, arch_subtype); return nbfd; } +/* If ABFD format is FORMAT and architecture is ARCH, return it. + If ABFD is a fat image containing a member that corresponds to FORMAT + and ARCH, returns it. + In other case, returns NULL. + This function allows transparent uses of fat images. */ +bfd * +bfd_mach_o_fat_extract (bfd *abfd, + bfd_format format, + const bfd_arch_info_type *arch) +{ + bfd *res; + mach_o_fat_data_struct *adata; + unsigned int i; + + if (bfd_check_format (abfd, format)) + { + if (bfd_get_arch_info (abfd) == arch) + return abfd; + return NULL; + } + if (!bfd_check_format (abfd, bfd_archive) + || abfd->xvec != &mach_o_fat_vec) + return NULL; + + /* This is a Mach-O fat image. */ + adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data; + BFD_ASSERT (adata != NULL); + + for (i = 0; i < adata->nfat_arch; i++) + { + struct mach_o_fat_archentry *e = &adata->archentries[i]; + enum bfd_architecture cpu_type; + unsigned long cpu_subtype; + + bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype, + &cpu_type, &cpu_subtype); + if (cpu_type != arch->arch || cpu_subtype != arch->mach) + continue; + + /* The architecture is found. */ + res = _bfd_new_bfd_contained_in (abfd); + if (res == NULL) + return NULL; + + res->origin = e->offset; + + res->filename = strdup (abfd->filename); + res->iostream = NULL; + + if (bfd_check_format (res, format)) + { + BFD_ASSERT (bfd_get_arch_info (res) == arch); + return res; + } + bfd_close (res); + return NULL; + } + + return NULL; +} + int bfd_mach_o_lookup_section (bfd *abfd, asection *section, diff --git a/bfd/mach-o.h b/bfd/mach-o.h index 8ffb1b242e..615a4b3eda 100644 --- a/bfd/mach-o.h +++ b/bfd/mach-o.h @@ -105,7 +105,11 @@ typedef enum bfd_mach_o_load_command_type in a dylib. */ BFD_MACH_O_LC_UUID = 0x1b, /* 128-bit UUID of the executable. */ BFD_MACH_O_LC_RPATH = 0x1c, /* Run path addiions. */ - BFD_MACH_O_LC_CODE_SIGNATURE = 0x1d /* Local of code signature. */ + BFD_MACH_O_LC_CODE_SIGNATURE = 0x1d, /* Local of code signature. */ + 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_load_command_type; @@ -458,10 +462,10 @@ bfd_mach_o_thread_command; typedef struct bfd_mach_o_dylinker_command { - unsigned long cmd; /* LC_ID_DYLIB or LC_LOAD_DYLIB. */ - unsigned long cmdsize; /* Includes pathname string. */ - unsigned long name_offset; /* Offset to library's path name. */ - unsigned long name_len; /* Offset to library's path name. */ + unsigned long cmd; /* LC_ID_DYLINKER or LC_LOAD_DYLINKER. */ + unsigned long cmdsize; /* Includes pathname string. */ + unsigned long name_offset; /* Offset to library's path name. */ + unsigned long name_len; /* Offset to library's path name. */ asection *section; } bfd_mach_o_dylinker_command; @@ -555,6 +559,7 @@ int bfd_mach_o_core_fetch_environment (bfd *, unsigned ch char * bfd_mach_o_core_file_failing_command (bfd *); int bfd_mach_o_core_file_failing_signal (bfd *); bfd_boolean bfd_mach_o_core_file_matches_executable_p (bfd *, bfd *); +bfd *bfd_mach_o_fat_extract (bfd *, bfd_format , const bfd_arch_info_type *); extern const bfd_target mach_o_be_vec; extern const bfd_target mach_o_le_vec;