ld expression section
Kyrill Tkachov
kyrylo.tkachov@foss.arm.com
Tue Oct 4 15:06:00 GMT 2016
On 04/10/16 01:24, Alan Modra wrote:
> 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.
Thanks Alan, I have no problems building the kernel after these two patches.
Kyrill
> 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:
>
More information about the Binutils
mailing list