ld expression section
authorAlan Modra <amodra@gmail.com>
Tue, 4 Oct 2016 00:13:50 +0000 (10:43 +1030)
committerAlan Modra <amodra@gmail.com>
Tue, 4 Oct 2016 00:13:50 +0000 (10:43 +1030)
Changes the result of ld expressions that were previously plain
numbers to be an absolute address, in the same circumstances where
numbers are treated as absolute addresses.

* ld.texinfo (Expression Section): Update result of arithmetic
expressions.
* ldexp.c (arith_result_section): New function.
(fold_binary): Use it.

ld/ChangeLog
ld/ld.texinfo
ld/ldexp.c

index 8b22c50a1f31f2aa4ad0def90e767eb619b392fc..dd202295e5c0c5c38cd340a177de5338594ba41b 100644 (file)
@@ -1,3 +1,10 @@
+2016-10-04  Alan Modra  <amodra@gmail.com>
+
+       * ld.texinfo (Expression Section): Update result of arithmetic
+       expressions.
+       * ldexp.c (arith_result_section): New function.
+       (fold_binary): Use it.
+
 2016-10-04  Alan Modra  <amodra@gmail.com>
 
        * ldexp.c (exp_value_fold): New function.
index 1303a0e5361d65bef57da6fa5ce73cd1575bf410..6528b6a8f5f659621ad3eb5233c34e2fdedf143a 100644 (file)
@@ -6032,7 +6032,9 @@ The result of comparisons, @samp{&&} and @samp{||} is also a number.
 @item
 The result of other binary arithmetic and logical operations on two
 relative addresses in the same section or two absolute addresses
-(after above conversions) is also a number.
+(after above conversions) is also a number when
+@code{LD_FEATURE ("SANE_EXPR")} or inside an output section definition
+but an absolute address otherwise.
 @item
 The result of other operations on relative addresses or one
 relative address and a number, is a relative address in the same
index 9f88144b67819df658b5abbcaf3217f28a0f1422..a5931fdb2df6764472e2381f3b3df5421450ba0f 100644 (file)
@@ -417,6 +417,32 @@ fold_unary (etree_type *tree)
     }
 }
 
+/* Arithmetic operators, bitwise AND, bitwise OR and XOR keep the
+   section of one of their operands only when the other operand is a
+   plain number.  Losing the section when operating on two symbols,
+   ie. a result of a plain number, is required for subtraction and
+   XOR.  It's justifiable for the other operations on the grounds that
+   adding, multiplying etc. two section relative values does not
+   really make sense unless they are just treated as numbers.
+   The same argument could be made for many expressions involving one
+   symbol and a number.  For example, "1 << x" and "100 / x" probably
+   should not be given the section of x.  The trouble is that if we
+   fuss about such things the rules become complex and it is onerous
+   to document ld expression evaluation.  */
+static void
+arith_result_section (const etree_value_type *lhs)
+{
+  if (expld.result.section == lhs->section)
+    {
+      if (expld.section == bfd_abs_section_ptr
+         && !config.sane_expr)
+       /* Duplicate the insanity in exp_fold_tree_1 case etree_value.  */
+       expld.result.section = bfd_abs_section_ptr;
+      else
+       expld.result.section = NULL;
+    }
+}
+
 static void
 fold_binary (etree_type *tree)
 {
@@ -483,26 +509,10 @@ fold_binary (etree_type *tree)
 
       switch (tree->type.node_code)
        {
-         /* Arithmetic operators, bitwise AND, bitwise OR and XOR
-            keep the section of one of their operands only when the
-            other operand is a plain number.  Losing the section when
-            operating on two symbols, ie. a result of a plain number,
-            is required for subtraction and XOR.  It's justifiable
-            for the other operations on the grounds that adding,
-            multiplying etc. two section relative values does not
-            really make sense unless they are just treated as
-            numbers.
-            The same argument could be made for many expressions
-            involving one symbol and a number.  For example,
-            "1 << x" and "100 / x" probably should not be given the
-            section of x.  The trouble is that if we fuss about such
-            things the rules become complex and it is onerous to
-            document ld expression evaluation.  */
 #define BOP(x, y) \
        case x:                                                 \
          expld.result.value = lhs.value y expld.result.value;  \
-         if (expld.result.section == lhs.section)              \
-           expld.result.section = NULL;                        \
+         arith_result_section (&lhs);                          \
          break;
 
          /* Comparison operators, logical AND, and logical OR always
@@ -536,8 +546,7 @@ fold_binary (etree_type *tree)
                                  % (bfd_signed_vma) expld.result.value);
          else if (expld.phase != lang_mark_phase_enum)
            einfo (_("%F%S %% by zero\n"), tree->binary.rhs);
-         if (expld.result.section == lhs.section)
-           expld.result.section = NULL;
+         arith_result_section (&lhs);
          break;
 
        case '/':
@@ -546,8 +555,7 @@ fold_binary (etree_type *tree)
                                  / (bfd_signed_vma) expld.result.value);
          else if (expld.phase != lang_mark_phase_enum)
            einfo (_("%F%S / by zero\n"), tree->binary.rhs);
-         if (expld.result.section == lhs.section)
-           expld.result.section = NULL;
+         arith_result_section (&lhs);
          break;
 
        case MAX_K: