This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Revised patch for using PE object files under non-PE platforms
- To: binutils at sourceware dot cygnus dot com
- Subject: Revised patch for using PE object files under non-PE platforms
- From: "H . J . Lu" <hjl at valinux dot com>
- Date: Sun, 18 Jun 2000 09:49:39 -0700
This is a revised patch to link PE object files with non-PE object
files to generate a non-PE executable. It works with my testcase
of PE/ELF and COFF/ELF using DISP32 and dir32 relocations. My testcase
needs a PE assembler, a COFF assembler, an ELF/PE linker and an
ELF/COFF linker. I can provide it if anyone is interested. In theory,
my patch shouldn't affect normal COFF nor native PE. But I don't have
native PE to test. I'd like to get some feedbacks on native PE.
Thanks.
--
H.J. Lu (hjl@gnu.org)
----
2000-06-18 H.J. Lu <hjl@gnu.org>
* coff-i386.c (coff_i386_reloc): Don't return in case of
output_bfd == (bfd *) NULL if COFF_WITH_PE is defined.
Compensate PE relocations when linking with non-PE object
files to generate a non-PE executable.
Index: coff-i386.c
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/coff-i386.c,v
retrieving revision 1.1.1.8
retrieving revision 1.7
diff -u -p -r1.1.1.8 -r1.7
--- coff-i386.c 2000/01/28 16:32:55 1.1.1.8
+++ coff-i386.c 2000/06/18 00:26:34 1.7
@@ -73,8 +73,10 @@ coff_i386_reloc (abfd, reloc_entry, symb
{
symvalue diff;
+#ifndef COFF_WITH_PE
if (output_bfd == (bfd *) NULL)
return bfd_reloc_continue;
+#endif
if (bfd_is_com_section (symbol->section))
{
@@ -102,7 +104,26 @@ coff_i386_reloc (abfd, reloc_entry, symb
ignores the addend for a COFF target when producing
relocateable output. This seems to be always wrong for 386
COFF, so we handle the addend here instead. */
- diff = reloc_entry->addend;
+#ifdef COFF_WITH_PE
+ if (output_bfd == (bfd *) NULL)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+
+ /* Although PC relative relocations are very similar between
+ PE and non-PE formats, but they are off by 1 << howto->size
+ bytes. For the external relocation, PE is very different
+ from others. See md_apply_fix3 () in gas/config/tc-i386.c.
+ When we link PE and non-PE object files together to
+ generate a non-PE executable, we have to compensate it
+ here. */
+ if (howto->pc_relative == true && howto->pcrel_offset == true)
+ diff = -(1 << howto->size);
+ else
+ diff = -reloc_entry->addend;
+ }
+ else
+#endif
+ diff = reloc_entry->addend;
}
#ifdef COFF_WITH_PE