This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: mach-o improvments (Ping)


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;



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]