X-Recipient: archive-cygwin AT delorie DOT com X-Spam-Check-By: sourceware.org Message-ID: <471BB6DC.9000306@t-online.de> Date: Sun, 21 Oct 2007 22:30:20 +0200 From: Christian Franke User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070802 SeaMonkey/1.1.4 MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: [Patch] Convert PE relocatable modules to ELF with objcopy Content-Type: multipart/mixed; boundary="------------030603090308010106090400" X-ID: E3ZF6yZQghmPO8XQcaWIl5uGjcEkkJwz1uFavd-VBfX-F-Lj0uCHLg4gGJ0a2AugEE X-TOI-MSGID: 9eb2b602-9325-411f-b8c7-addd08feaf4d X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com --------------030603090308010106090400 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit objcopy from binutils-20060817-1 cannot convert pe-i396 to elf32-i386. The offsets of the pc-relative relocation entries are not converted properly. (http://sourceware.org/bugzilla/show_bug.cgi?id=970) I recently started a Cygwin port of GRUB2 ([Maybe ITP later]-). (http://lists.gnu.org/archive/html/grub-devel/2007-10/msg00071.html) GRUB2 loadable modules use ELF format, therefore, some PE to ELF conversion is required to build on Cygwin. The first working Cygwin patch for GRUB2 includes a workaround to load the broken ELF modules produced by objcopy. It would be desirable to fix this in objcopy itself. A patch is attached. 2007-10-21 Christian Franke * objcopy.c (fix_relocation): New function to fix pc-relative relocation offset, for PE to ELF only. (copy_section): Call fix_relocation for section data. Christian --------------030603090308010106090400 Content-Type: text/x-patch; name="objcopy-fix-pe-relocation.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="objcopy-fix-pe-relocation.patch" --- binutils-20060817-1.orig/binutils/objcopy.c 2006-08-17 07:01:02.001000000 +0200 +++ binutils-20060817-1/binutils/objcopy.c 2007-10-21 21:51:11.468750000 +0200 @@ -2202,6 +2202,31 @@ loser: status = 1; } + +/* Fix pc-relative relocation. + When converting from PE to ELF, the pc-relative + relocation offset is off by 4. + (http://sourceware.org/bugzilla/show_bug.cgi?id=970) */ + +static void +fix_relocation (bfd *ibfd, arelent **relpp, long relcount, void *data, bfd *obfd) +{ + arelent **p; + long i; + /* For now, handle only the pe-i386 -> elf32-i386 case */ + if (!(!strcmp (ibfd->xvec->name, "pe-i386") && !strcmp (obfd->xvec->name, "elf32-i386"))) + return; + for (i = 0, p = relpp; i < relcount && *p; i++, p++) + { + arelent *q = *p; + if (q->howto->pc_relative && q->howto->size == 2) + /* elf32-i386 does not support addent in relocation info, + apply it to the section data */ + *(long *)((char *)data+q->address) -= 4; + } +} + + /* Copy the data of input section ISECTION of IBFD to an output section with the same name in OBFD. If stripping then don't copy any relocation info. */ @@ -2255,6 +2280,7 @@ copy_section (bfd *ibfd, sec_ptr isectio } } + relpp = 0; relcount = 0; if (relsize == 0) bfd_set_reloc (obfd, osection, NULL, 0); else @@ -2295,6 +2321,9 @@ copy_section (bfd *ibfd, sec_ptr isectio if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size)) RETURN_NONFATAL (bfd_get_filename (ibfd)); + if (relcount > 0) + fix_relocation (ibfd, relpp, relcount, memhunk, obfd); + if (copy_byte >= 0) { /* Keep only every `copy_byte'th byte in MEMHUNK. */ --------------030603090308010106090400 Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --------------030603090308010106090400--