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