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