summaryrefslogtreecommitdiff
path: root/gas/expr.c
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@nildram.co.uk>2010-12-02 13:25:12 +0000
committerRichard Sandiford <rsandifo@nildram.co.uk>2010-12-02 13:25:12 +0000
commit0d1ec319642e4ffaf690b45c7956b2f69677f7b1 (patch)
tree3fa8c9ac99137e5f204d58d45b835ad63f7f8cd0 /gas/expr.c
parentb30a98ba0b3ba0e37e67acf53fcd3da3037dff56 (diff)
downloadbinutils-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.c13
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;