diff options
author | Richard Sandiford <rsandifo@nildram.co.uk> | 2010-12-02 13:25:12 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@nildram.co.uk> | 2010-12-02 13:25:12 +0000 |
commit | 0d1ec319642e4ffaf690b45c7956b2f69677f7b1 (patch) | |
tree | 3fa8c9ac99137e5f204d58d45b835ad63f7f8cd0 /gas/write.c | |
parent | b30a98ba0b3ba0e37e67acf53fcd3da3037dff56 (diff) | |
download | binutils-redhat-0d1ec319642e4ffaf690b45c7956b2f69677f7b1.tar.gz |
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.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/gas/write.c b/gas/write.c index 939b80e520..018800e075 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); |