aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-i386.c
diff options
context:
space:
mode:
authorDave Korn <dave.korn@artimi.com>2009-06-08 16:06:24 +0000
committerDave Korn <dave.korn@artimi.com>2009-06-08 16:06:24 +0000
commitfbeb56a4a5a51d90d26e31dbb602e9f8419c432a (patch)
tree1927a4b0abbb76831f2efbe87294200b75b815b7 /gas/config/tc-i386.c
parent7681d515c36554427defeb13acf2ab435fc2e475 (diff)
downloadgdb-fbeb56a4a5a51d90d26e31dbb602e9f8419c432a.zip
gdb-fbeb56a4a5a51d90d26e31dbb602e9f8419c432a.tar.gz
gdb-fbeb56a4a5a51d90d26e31dbb602e9f8419c432a.tar.bz2
PR gas/977
* config/tc-i386.c (md_estimate_size_before_relax): Don't relax branches to weak symbols. (md_apply_fix): Don't convert fixes against weak symbols to section-relative offsets, but save addend for later reloc emission. (tc_gen_reloc): When emitting reloc against weak symbol, adjust addend to pre-compensate for bfd_install_relocation.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r--gas/config/tc-i386.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 706e924..faa638f 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -6956,6 +6956,10 @@ md_estimate_size_before_relax (fragP, segment)
&& (S_IS_EXTERNAL (fragP->fr_symbol)
|| S_IS_WEAK (fragP->fr_symbol)))
#endif
+#if defined (OBJ_COFF) && defined (TE_PE)
+ || (OUTPUT_FLAVOR == bfd_target_coff_flavour
+ && S_IS_WEAK (fragP->fr_symbol))
+#endif
)
{
/* Symbol is undefined in this segment, or we need to keep a
@@ -7249,6 +7253,12 @@ md_apply_fix (fixP, valP, seg)
value += md_pcrel_from (fixP);
#endif
}
+#if defined (OBJ_COFF) && defined (TE_PE)
+ if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
+ {
+ value -= S_GET_VALUE (fixP->fx_addsy);
+ }
+#endif
/* Fix a few things - the dynamic linker expects certain values here,
and we must not disappoint it. */
@@ -7312,6 +7322,16 @@ md_apply_fix (fixP, valP, seg)
/* Are we finished with this relocation now? */
if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
+#if defined (OBJ_COFF) && defined (TE_PE)
+ else if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
+ {
+ fixP->fx_done = 0;
+ /* Remember value for tc_gen_reloc. */
+ fixP->fx_addnumber = value;
+ /* Clear out the frag for now. */
+ value = 0;
+ }
+#endif
else if (use_rela_relocations)
{
fixP->fx_no_overflow = 1;
@@ -8214,7 +8234,11 @@ tc_gen_reloc (section, fixp)
vtable entry to be used in the relocation's section offset. */
if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
rel->address = fixp->fx_offset;
-
+#if defined (OBJ_COFF) && defined (TE_PE)
+ else if (fixp->fx_addsy && S_IS_WEAK (fixp->fx_addsy))
+ rel->addend = fixp->fx_addnumber - (S_GET_VALUE (fixp->fx_addsy) * 2);
+ else
+#endif
rel->addend = 0;
}
/* Use the rela in 64bit mode. */