[PATCH] ld: fix ABSOLUTE for general expressions
Kyrill Tkachov
kyrylo.tkachov@foss.arm.com
Thu Sep 29 13:29:00 GMT 2016
Hi Alan,
On 20/07/16 03:44, Alan Modra wrote:
> Like all changes that affect script expressions there is quite a good
> chance that someone is relying on the old behaviour. For example,
> Jakub called the maxpage3b behaviour a "feature" in
> https://sourceware.org/ml/binutils/2007-01/msg00181.html
> Well, that one seems quite clearly a bug to me. I'm actually more
> worried about "absolute (<number>)" inside output section statements,
> ie. the behaviour that Tristan thinks should be changed. Oh well,
> let's see who screams.
I noticed this patch breaks linking of an arm defconfig Linux kernel.
It fails with:
arm-none-linux-gnueabihf-ld: HYP init code too big or misaligned
This is with a linux-4.7.4 kernel configured with:
make ARCH=arm defconfig
Thanks,
Kyrill
> ---
> Early expression evaluation
>
> Folding a constant expression early can lead to loss of tokens, eg.
> ABSOLUTE, that are significant in ld's horrible context sensitive
> expression evaluation. Also, MAXPAGESIZE and other "constants" may
> not have taken values specified on the command line, leading to the
> wrong value being cached.
>
> * ldexp.c (exp_unop, exp_binop, exp_trinop, exp_nameop): Don't
> fold expression.
> * testsuite/ld-elf/maxpage3b.d: Expect correct maxpagesize.
>
> diff --git a/ld/ldexp.c b/ld/ldexp.c
> index 68c4bc5..a560643 100644
> --- a/ld/ldexp.c
> +++ b/ld/ldexp.c
> @@ -1255,80 +1255,55 @@ exp_fold_tree_no_dot (etree_type *tree)
> etree_type *
> exp_binop (int code, etree_type *lhs, etree_type *rhs)
> {
> - etree_type value, *new_e;
> -
> - value.type.node_code = code;
> - value.type.filename = lhs->type.filename;
> - value.type.lineno = lhs->type.lineno;
> - value.binary.lhs = lhs;
> - value.binary.rhs = rhs;
> - value.type.node_class = etree_binary;
> - exp_fold_tree_no_dot (&value);
> - if (expld.result.valid_p)
> - return exp_intop (expld.result.value);
> -
> - new_e = (etree_type *) stat_alloc (sizeof (new_e->binary));
> - memcpy (new_e, &value, sizeof (new_e->binary));
> + etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->binary));
> +
> + new_e->type.node_code = code;
> + new_e->type.filename = lhs->type.filename;
> + new_e->type.lineno = lhs->type.lineno;
> + new_e->binary.lhs = lhs;
> + new_e->binary.rhs = rhs;
> + new_e->type.node_class = etree_binary;
> return new_e;
> }
>
> etree_type *
> exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
> {
> - etree_type value, *new_e;
> -
> - value.type.node_code = code;
> - value.type.filename = cond->type.filename;
> - value.type.lineno = cond->type.lineno;
> - value.trinary.lhs = lhs;
> - value.trinary.cond = cond;
> - value.trinary.rhs = rhs;
> - value.type.node_class = etree_trinary;
> - exp_fold_tree_no_dot (&value);
> - if (expld.result.valid_p)
> - return exp_intop (expld.result.value);
> -
> - new_e = (etree_type *) stat_alloc (sizeof (new_e->trinary));
> - memcpy (new_e, &value, sizeof (new_e->trinary));
> + etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->trinary));
> +
> + new_e->type.node_code = code;
> + new_e->type.filename = cond->type.filename;
> + new_e->type.lineno = cond->type.lineno;
> + new_e->trinary.lhs = lhs;
> + new_e->trinary.cond = cond;
> + new_e->trinary.rhs = rhs;
> + new_e->type.node_class = etree_trinary;
> return new_e;
> }
>
> etree_type *
> exp_unop (int code, etree_type *child)
> {
> - etree_type value, *new_e;
> -
> - value.unary.type.node_code = code;
> - value.unary.type.filename = child->type.filename;
> - value.unary.type.lineno = child->type.lineno;
> - value.unary.child = child;
> - value.unary.type.node_class = etree_unary;
> - exp_fold_tree_no_dot (&value);
> - if (expld.result.valid_p)
> - return exp_intop (expld.result.value);
> + etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->unary));
>
> - new_e = (etree_type *) stat_alloc (sizeof (new_e->unary));
> - memcpy (new_e, &value, sizeof (new_e->unary));
> + new_e->unary.type.node_code = code;
> + new_e->unary.type.filename = child->type.filename;
> + new_e->unary.type.lineno = child->type.lineno;
> + new_e->unary.child = child;
> + new_e->unary.type.node_class = etree_unary;
> return new_e;
> }
>
> etree_type *
> exp_nameop (int code, const char *name)
> {
> - etree_type value, *new_e;
> -
> - value.name.type.node_code = code;
> - value.name.type.filename = ldlex_filename ();
> - value.name.type.lineno = lineno;
> - value.name.name = name;
> - value.name.type.node_class = etree_name;
> -
> - exp_fold_tree_no_dot (&value);
> - if (expld.result.valid_p)
> - return exp_intop (expld.result.value);
> + etree_type *new_e = (etree_type *) stat_alloc (sizeof (new_e->name));
>
> - new_e = (etree_type *) stat_alloc (sizeof (new_e->name));
> - memcpy (new_e, &value, sizeof (new_e->name));
> + new_e->name.type.node_code = code;
> + new_e->name.type.filename = ldlex_filename ();
> + new_e->name.type.lineno = lineno;
> + new_e->name.name = name;
> + new_e->name.type.node_class = etree_name;
> return new_e;
>
> }
> diff --git a/ld/testsuite/ld-elf/maxpage3b.d b/ld/testsuite/ld-elf/maxpage3b.d
> index 4bee0ec..62b50c9 100644
> --- a/ld/testsuite/ld-elf/maxpage3b.d
> +++ b/ld/testsuite/ld-elf/maxpage3b.d
> @@ -4,7 +4,8 @@
> #target: x86_64-*-linux*
>
> #...
> - \[[ 0-9]+\] \.data[ \t]+PROGBITS[ \t]+0*200000[ \t]+[ \t0-9a-f]+WA?.*
> + \[[ 0-9]+\] \.data[ \t]+PROGBITS[ \t]+0*10000000[ \t]+[ \t0-9a-f]+WA?.*
> #...
> LOAD+.*0x10000000
> + LOAD+.*0x10000000
> #pass
>
More information about the Binutils
mailing list