This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] ld: fix ABSOLUTE for general expressions


On Tue, Jul 19, 2016 at 12:05:08PM +0200, Tristan Gingold wrote:
> 
> > On 19 Jul 2016, at 10:39, Alan Modra <amodra@gmail.com> wrote:
> > 
> > On Tue, Jul 19, 2016 at 09:06:49AM +0200, Tristan Gingold wrote:
> >> 
> >>> On 19 Jul 2016, at 03:02, Alan Modra <amodra@gmail.com> wrote:
> >>> 
> >>> On Mon, Jul 18, 2016 at 05:34:06PM +0200, Tristan Gingold wrote:
> >>>> Hello,
> >>>> 
> >>>> it appears that ABSOLUTE(x) doesn't generate an absolute value when X is not a symbol, it looks like it works only for symbols.
> >>>> See the testcase for an example.
> >>> [snip]
> >>>> +SECTIONS
> >>>> +{
> >>>> +  .text 0x100 :
> >>>> +  {
> >>>> +    *(.text)
> >>>> +   _stack_start = ABSOLUTE(0x0800);
> >>>> +  }
> >>>> +}
> >>> 
> >>> I think what you're missing is that a plain number inside an output
> >>> section statement is section relative, if the number is used as an
> >>> address.
> >> 
> >> But, this is not what the doc says:
> >> 
> >> ABSOLUTE(exp)
> >> Return the absolute (non-relocatable, as opposed to non-negative) value of the expression exp. Primarily useful to assign an absolute value to a symbol within a section definition, where symbol values are normally section relative.
> >> 
> >> I think the doc is clear, and according to it:
> >> 
> >> SECTIONS
> >> {
> >> .text 0x100 :
> >> {
> >>   *(.text)
> >>  _stack_start = ABSOLUTE(0x0800);
> >> }
> >> }
> >> 
> >> should set _stack_start to the value 0x800 (and not 0x900).
> > 
> > So how would you expect the following to behave?
> > 
> > SECTIONS
> > {
> >  .text 0x100 :
> >  {
> >    *(.text)
> >    x = 0x800;
> >    y = absolute (x);
> >    z = absolute (0x800);
> >  }
> > }
> > 
> > I would have thought that x, y and z should have the same value in an
> > executable, and they do as shown by nm.
> > 
> > 0000000000000900 T x
> > 0000000000000900 A y
> > 0000000000000900 T z
> 
> I agree with that for x and y, but not for z.
> 
> > There *is* a bug in the section of z.  Somehow it manages to be
> > section relative!  Hmm, no doubt due to premature folding of the
> > expression, in exp_unop.
> 
> Yes, and that is what my patch changes.
> 
> >> I am not against allowing only symbols for operand of ABSOLUTE.  I think this would be much clearer and still backward compatible in practice.
> >> 
> >> The rule you gave 'a plain number inside an output section statement is section relative' is not well defined.
> >> For example, how to apply it to:
> >>  x = 0x80 + 4;
> >> I know how ld would understand it: this is section_vma + 0x84.  But this is not exactly your rule!
> > 
> > In this case we have a section relative 0x80 added to a section
> > relative 4, which by the odd rules regarding operations on two values
> > in the same section, comes to a section relative 0x84.
> 
> I fail to draw a conclusion from your mail.  Do you agree there is a bug ?
> 
> Do you think we need to fix it (by changing the code) or do you think we need to change to doc (and only allow ABSOLUTE on symbols) ?

I believe exp_unop should not be calling exp_fold_tree, which would
leave the "absolute" token in the tree.  Similarly for the other
functions creating expression trees.  Interestingly, this causes
FAIL: ld-elf/maxpage3b but on examination it looks like the test was
added without properly checking the result.  So this fixes a bug in
evaluation of CONSTANT, and it also happens to give you the value you
want for your _stack_start testcase.  I'm going to play with it a bit
before committing, and of course fix the testsuite failure.

diff --git a/ld/ldexp.c b/ld/ldexp.c
index 68c4bc5..e72c13f 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -1263,9 +1263,6 @@ exp_binop (int code, etree_type *lhs, etree_type *rhs)
   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));
@@ -1284,9 +1281,6 @@ exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
   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));
@@ -1303,9 +1297,6 @@ exp_unop (int code, etree_type *child)
   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);
 
   new_e = (etree_type *) stat_alloc (sizeof (new_e->unary));
   memcpy (new_e, &value, sizeof (new_e->unary));
@@ -1323,10 +1314,6 @@ exp_nameop (int code, const char *name)
   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);
-
   new_e = (etree_type *) stat_alloc (sizeof (new_e->name));
   memcpy (new_e, &value, sizeof (new_e->name));
   return new_e;

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]