summaryrefslogtreecommitdiffstats
path: root/bfd/coff-i386.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2000-06-18 23:48:21 +0000
committerH.J. Lu <hjl.tools@gmail.com>2000-06-18 23:48:21 +0000
commit689be7170418e0cf6400f76f3a00a111925a3f3d (patch)
treee2cfc67d1482985ed88f618c9e4e7032be9dcda0 /bfd/coff-i386.c
parent119caedd35addc4bb75f02d2d47dd7d1047934bd (diff)
downloadppe42-binutils-689be7170418e0cf6400f76f3a00a111925a3f3d.tar.gz
ppe42-binutils-689be7170418e0cf6400f76f3a00a111925a3f3d.zip
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.
Diffstat (limited to 'bfd/coff-i386.c')
-rw-r--r--bfd/coff-i386.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
index 84d4d145c7..c7aa659c0e 100644
--- a/bfd/coff-i386.c
+++ b/bfd/coff-i386.c
@@ -73,8 +73,10 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
{
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, symbol, data, input_section, output_bfd,
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
OpenPOWER on IntegriCloud