This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ld expression section
- From: Alan Modra <amodra at gmail dot com>
- To: Kyrill Tkachov <kyrylo dot tkachov at foss dot arm dot com>
- Cc: Tristan Gingold <gingold at adacore dot com>, binutils <binutils at sourceware dot org>
- Date: Tue, 4 Oct 2016 10:54:25 +1030
- Subject: ld expression section
- Authentication-results: sourceware.org; auth=none
- References: <F8E6EE0B-49F3-4986-B48E-45AD57BD0D7C@adacore.com> <20160719010211.GT1256@bubble.grove.modra.org> <DE7B211B-4922-4F8A-AF0D-E11B2ECBB5EC@adacore.com> <20160719083907.GV1256@bubble.grove.modra.org> <D2BAEB3D-9819-47B0-AA16-8F3A9527C890@adacore.com> <20160719113807.GW1256@bubble.grove.modra.org> <20160720024436.GA1256@bubble.grove.modra.org> <57ED173A.6000207@foss.arm.com> <20160930163422.GN4877@bubble.grove.modra.org> <20161004001942.GP4877@bubble.grove.modra.org>
This patch is the real fix for the problem exposed by the arm linux
kernel. There's quite a chance this will break some other script,
which is why I committed the work-around patch too.
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.
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 1303a0e..6528b6a 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -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
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 9f88144..a5931fd 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -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:
--
Alan Modra
Australia Development Lab, IBM