Patch: mach-o improvments (Ping)
Tristan Gingold
gingold@adacore.com
Thu Dec 11 13:13:00 GMT 2008
Hi,
ping for this patch.
Tristan.
On Dec 5, 2008, at 2:24 PM, Tristan Gingold wrote:
> Hi,
>
> this patch add a few features to the mach-o bfd back-end.
>
> The function bfd_mach_o_fat_extract makes easier (and faster) to
> extract
> a member of a fat binary. Also if the bfd input is a thin one, and
> corresponds
> to the architecture requested, it is returned. So this function can
> be
> used to transparently handle fat binaries. Will be used in gdb.
>
> Some well known sections and segments names are made shorter (no
> LC_SEGMENT.
> prefix). Made the output of objdump -h more readable.
> The section that correspond to ".eh_frame" is now named ".eh_frame"
> so that
> it is recognized by gdb.
>
> A few new mach-o load commands are now ignored (instead of
> generating a
> warning).
>
> Tested by using gdb.
>
> Tristan.
>
> bfd/
> 2008-12-05 Tristan Gingold <gingold@adacore.com>
>
> * 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.
>
> *** bfd/mach-o.c 6 Nov 2008 13:03:43 -0000 1.30
> --- bfd/mach-o.c 5 Dec 2008 13:17:58 -0000
> *************** bfd_mach_o_make_bfd_section (bfd *abfd,
> *** 796,801 ****
> --- 796,817 ----
> 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);
>
> *************** bfd_mach_o_scan_read_dylinker (bfd *abfd
> *** 1210,1217 ****
>
> bfdsec->vma = 0;
> bfdsec->lma = 0;
> ! bfdsec->size = command->len - 8;
> ! bfdsec->filepos = command->offset + 8;
> bfdsec->alignment_power = 0;
>
> cmd->section = bfdsec;
> --- 1226,1233 ----
>
> bfdsec->vma = 0;
> bfdsec->lma = 0;
> ! bfdsec->size = command->len - nameoff;
> ! bfdsec->filepos = command->offset + nameoff;
> bfdsec->alignment_power = 0;
>
> cmd->section = bfdsec;
> *************** bfd_mach_o_scan_read_segment (bfd *abfd,
> *** 1584,1590 ****
> sname = bfd_alloc (abfd, snamelen);
> if (sname == NULL)
> return -1;
> ! sprintf (sname, "%s.%s", prefix, seg->segname);
>
> bfdsec = bfd_make_section_anyway (abfd, sname);
> if (bfdsec == NULL)
> --- 1600,1612 ----
> sname = bfd_alloc (abfd, snamelen);
> if (sname == NULL)
> return -1;
> ! 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)
> *************** bfd_mach_o_scan_read_command (bfd *abfd,
> *** 1708,1713 ****
> --- 1730,1737 ----
> 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",
> *************** bfd_mach_o_openr_next_archived_file (bfd
> *** 2110,2119 ****
> 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);
> --- 2134,2141 ----
> *************** bfd_mach_o_openr_next_archived_file (bfd
> *** 2153,2169 ****
>
> 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;
> nbfd->iostream = NULL;
>
> return nbfd;
> }
>
> int
> bfd_mach_o_lookup_section (bfd *abfd,
> asection *section,
> --- 2175,2264 ----
>
> bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
> &arch_type, &arch_subtype);
> ! /* Create the member filename.
> ! Use FILENAME:ARCH_NAME. */
> ! {
> ! char *s = NULL;
> ! const char *archive_name = lbasename (bfd_get_filename
> (archive));
> ! size_t archive_name_len = strlen (archive_name);
> ! const char *arch_name;
> !
> ! arch_name = bfd_printable_arch_mach (arch_type, arch_subtype);
> ! s = bfd_malloc (archive_name_len + 1 + strlen (arch_name) + 1);
> ! if (s == NULL)
> ! return NULL;
> ! memcpy (s, archive_name, archive_name_len);
> ! s[archive_name_len] = ':';
> ! strcpy (s + archive_name_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,
> Index: bfd/mach-o.h
> ===================================================================
> RCS file: /cvs/src/src/bfd/mach-o.h,v
> retrieving revision 1.11
> diff -c -p -r1.11 mach-o.h
> *** bfd/mach-o.h 6 Nov 2008 13:03:43 -0000 1.11
> --- bfd/mach-o.h 5 Dec 2008 13:17:58 -0000
> *************** typedef enum bfd_mach_o_load_command_typ
> *** 105,111 ****
> 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_load_command_type;
>
> --- 105,115 ----
> 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_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;
>
> *************** bfd_mach_o_thread_command;
> *** 458,467 ****
>
> 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. */
> asection *section;
> }
> bfd_mach_o_dylinker_command;
> --- 462,471 ----
>
> typedef struct bfd_mach_o_dylinker_command
> {
> ! 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;
> *************** int bfd_mach_o_core_fetch
> *** 555,560 ****
> --- 559,565 ----
> 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;
>
More information about the Binutils
mailing list