From fbeb56a4a5a51d90d26e31dbb602e9f8419c432a Mon Sep 17 00:00:00 2001 From: Dave Korn Date: Mon, 8 Jun 2009 16:06:24 +0000 Subject: 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. --- gas/ChangeLog | 10 ++++++++++ gas/config/tc-i386.c | 26 +++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index 0678a3bdf0..23ba55bcb4 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2009-06-08 Dave Korn + + 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. + 2009-06-04 Alan Modra * dep-in.sed: Don't use \n in replacement part of s command. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 706e924d98..faa638fbbf 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -6955,6 +6955,10 @@ md_estimate_size_before_relax (fragP, segment) || (IS_ELF && (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 ) { @@ -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. */ -- cgit v1.2.1