aboutsummaryrefslogtreecommitdiff
path: root/gas/write.c
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2010-12-02 13:25:13 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2010-12-02 13:25:13 +0000
commitc969da647374bec1548589cd47406e2a12a7800c (patch)
tree70576c6e17cf11e39b7eb45aac6bf109929e911e /gas/write.c
parent0c98115d15fbd16d6808a5a7718d748072c00dd7 (diff)
downloadgdb-c969da647374bec1548589cd47406e2a12a7800c.zip
gdb-c969da647374bec1548589cd47406e2a12a7800c.tar.gz
gdb-c969da647374bec1548589cd47406e2a12a7800c.tar.bz2
gas/
* symbols.c (S_FORCE_RELOC): Return true for indirect functions even if !strict. * expr.c (operand): Don't convert absolute symbols to constants if S_FORCE_RELOC is true. (expr): Only reduce subtractions between different symbols if S_FORCE_RELOC is false for both of them. * write.c (fixup_segment): Don't remove symbols if S_FORCE_RELOC is true for them, regardless of their segment. gas/testsuite/ * gas/i386/ifunc-2.s, gas/i386/ifunc-2.l: New test. * gas/i386/ifunc-3.s, gas/i386/ifunc-3.d: Likeise. * gas/i386/i386.exp: Run them.
Diffstat (limited to 'gas/write.c')
-rw-r--r--gas/write.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/gas/write.c b/gas/write.c
index 939b80e..018800e 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -932,6 +932,8 @@ fixup_segment (fixS *fixP, segT this_segment)
sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy);
if (fixP->fx_addsy != NULL
&& sub_symbol_segment == add_symbol_segment
+ && !S_FORCE_RELOC (fixP->fx_addsy, 0)
+ && !S_FORCE_RELOC (fixP->fx_subsy, 0)
&& !TC_FORCE_RELOCATION_SUB_SAME (fixP, add_symbol_segment))
{
add_number += S_GET_VALUE (fixP->fx_addsy);
@@ -945,6 +947,7 @@ fixup_segment (fixS *fixP, segT this_segment)
#endif
}
else if (sub_symbol_segment == absolute_section
+ && !S_FORCE_RELOC (fixP->fx_subsy, 0)
&& !TC_FORCE_RELOCATION_SUB_ABS (fixP, add_symbol_segment))
{
add_number -= S_GET_VALUE (fixP->fx_subsy);
@@ -952,6 +955,7 @@ fixup_segment (fixS *fixP, segT this_segment)
fixP->fx_subsy = NULL;
}
else if (sub_symbol_segment == this_segment
+ && !S_FORCE_RELOC (fixP->fx_subsy, 0)
&& !TC_FORCE_RELOCATION_SUB_LOCAL (fixP, add_symbol_segment))
{
add_number -= S_GET_VALUE (fixP->fx_subsy);
@@ -994,6 +998,7 @@ fixup_segment (fixS *fixP, segT this_segment)
if (fixP->fx_addsy)
{
if (add_symbol_segment == this_segment
+ && !S_FORCE_RELOC (fixP->fx_addsy, 0)
&& !TC_FORCE_RELOCATION_LOCAL (fixP))
{
/* This fixup was made when the symbol's segment was
@@ -1007,6 +1012,7 @@ fixup_segment (fixS *fixP, segT this_segment)
fixP->fx_pcrel = 0;
}
else if (add_symbol_segment == absolute_section
+ && !S_FORCE_RELOC (fixP->fx_addsy, 0)
&& !TC_FORCE_RELOCATION_ABS (fixP))
{
add_number += S_GET_VALUE (fixP->fx_addsy);