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/expr.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/expr.c')
-rw-r--r-- | gas/expr.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/gas/expr.c b/gas/expr.c index 215b2bad7c..f818ad389a 100644 --- a/gas/expr.c +++ b/gas/expr.c @@ -1325,7 +1325,9 @@ operand (expressionS *expressionP, enum expr_mode mode) /* If we have an absolute symbol or a reg, then we know its value now. */ segment = S_GET_SEGMENT (symbolP); - if (mode != expr_defer && segment == absolute_section) + if (mode != expr_defer + && segment == absolute_section + && !S_FORCE_RELOC (symbolP, 0)) { expressionP->X_op = O_constant; expressionP->X_add_number = S_GET_VALUE (symbolP); @@ -1840,7 +1842,9 @@ expr (int rankarg, /* Larger # is higher rank. */ #ifdef md_allow_local_subtract && md_allow_local_subtract (resultP, & right, rightseg) #endif - && (SEG_NORMAL (rightseg) + && ((SEG_NORMAL (rightseg) + && !S_FORCE_RELOC (resultP->X_add_symbol, 0) + && !S_FORCE_RELOC (right.X_add_symbol, 0)) || right.X_add_symbol == resultP->X_add_symbol) && frag_offset_fixed_p (symbol_get_frag (resultP->X_add_symbol), symbol_get_frag (right.X_add_symbol), @@ -1954,7 +1958,10 @@ expr (int rankarg, /* Larger # is higher rank. */ else if (op_left == O_subtract) { resultP->X_add_number -= right.X_add_number; - if (retval == rightseg && SEG_NORMAL (retval)) + if (retval == rightseg + && SEG_NORMAL (retval) + && !S_FORCE_RELOC (resultP->X_add_symbol, 0) + && !S_FORCE_RELOC (right.X_add_symbol, 0)) { retval = absolute_section; rightseg = absolute_section; |