This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: Prevent mn10300 assembler from relaxing calls to weak symbols
- From: Nick Clifton <nickc at redhat dot com>
- To: Binutils <binutils at sourceware dot org>
- Date: Mon, 18 Feb 2008 10:03:04 +0000
- Subject: PATCH: Prevent mn10300 assembler from relaxing calls to weak symbols
Hi Guys,
I am going to apply the attached patch which fixes a bug in the
mn10300 assembler. Prior to the patch the mn10300 assembler relaxation
code would decide to relax a call to a defined, weak symbol. This is a
bad idea since of course the symbol can be overridden during linking,
possibly invalidating the relaxation.
Cheers
Nick
gas/ChangeLog
2008-02-18 Nick Clifton <nickc@redhat.com>
* config/tc-mn10300.c (has_known_symbol_location): New function.
Do not regard weak symbols as having a known location.
(md_estimate_size_before_relax): Use new function.
(md_pcrel_from): Do not compute a pcrel against a weak symbol.
Index: gas/config/tc-mn10300.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mn10300.c,v
retrieving revision 1.66
diff -c -3 -p -r1.66 tc-mn10300.c
*************** tc_gen_reloc (asection *seg ATTRIBUTE_UN
*** 2262,2285 ****
return relocs;
}
int
md_estimate_size_before_relax (fragS *fragp, asection *seg)
{
if (fragp->fr_subtype == 6
! && (!S_IS_DEFINED (fragp->fr_symbol)
! || seg != S_GET_SEGMENT (fragp->fr_symbol)))
fragp->fr_subtype = 7;
else if (fragp->fr_subtype == 8
! && (!S_IS_DEFINED (fragp->fr_symbol)
! || seg != S_GET_SEGMENT (fragp->fr_symbol)))
fragp->fr_subtype = 9;
else if (fragp->fr_subtype == 10
! && (!S_IS_DEFINED (fragp->fr_symbol)
! || seg != S_GET_SEGMENT (fragp->fr_symbol)))
fragp->fr_subtype = 12;
if (fragp->fr_subtype == 13)
return 3;
if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
abort ();
--- 2268,2303 ----
return relocs;
}
+ /* Returns true iff the symbol attached to the frag is at a known location
+ in the given section, (and hence the relocation to it can be relaxed by
+ the assembler). */
+ static inline bfd_boolean
+ has_known_symbol_location (fragS * fragp, asection * sec)
+ {
+ symbolS * sym = fragp->fr_symbol;
+
+ return sym != NULL
+ && S_IS_DEFINED (sym)
+ && ! S_IS_WEAK (sym)
+ && S_GET_SEGMENT (sym) == sec;
+ }
+
int
md_estimate_size_before_relax (fragS *fragp, asection *seg)
{
if (fragp->fr_subtype == 6
! && ! has_known_symbol_location (fragp, seg))
fragp->fr_subtype = 7;
else if (fragp->fr_subtype == 8
! && ! has_known_symbol_location (fragp, seg))
fragp->fr_subtype = 9;
else if (fragp->fr_subtype == 10
! && ! has_known_symbol_location (fragp, seg))
fragp->fr_subtype = 12;
if (fragp->fr_subtype == 13)
return 3;
+
if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
abort ();
*************** md_estimate_size_before_relax (fragS *fr
*** 2289,2299 ****
long
md_pcrel_from (fixS *fixp)
{
! if (fixp->fx_addsy != NULL && !S_IS_DEFINED (fixp->fx_addsy))
! {
! /* The symbol is undefined. Let the linker figure it out. */
! return 0;
! }
return fixp->fx_frag->fr_address + fixp->fx_where;
}
--- 2307,2317 ----
long
md_pcrel_from (fixS *fixp)
{
! if (fixp->fx_addsy != (symbolS *) NULL
! && (!S_IS_DEFINED (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)))
! /* The symbol is undefined or weak. Let the linker figure it out. */
! return 0;
!
return fixp->fx_frag->fr_address + fixp->fx_where;
}