Relative expressions and ASSERT

Maciej W. Rozycki macro@codesourcery.com
Thu Jan 20 17:18:00 GMT 2011


On Thu, 20 Jan 2011, Alan Modra wrote:

> > I got a linker regression report on symbol subtraction on x86. I am waiting
> > for a testcase.
> 
> I'd like to see the testcase too.
> 
> I have two possible patches.  The first only changes subtraction and
> xor of two symbols so that the result is simply a number, even if the
> symbols are not in the same section.  That I think is the correct
> result and uncontroversial.  However, this patch leaves (x + -y) with
> a section, a result that differs now from (x - y).

 Yes, that I find that natural actually.

 With this program:

$ cat sub.s
foo:
	.long	4
bar:
	.long	bar - foo
	.long	bar + -foo
	.long	bar ^ foo

I get this:

$ mips-linux-gnu-as -o sub.o sub.s
sub.s: Assembler messages:
sub.s:5: Error: invalid section for operation on `foo'
sub.s:6: Error: invalid sections for operation on `bar' and `foo'

so I'm happy with both the unary arithmetic negation and the XOR operator 
to return a result that is different to a binary subtraction (we don't 
have to fail as does GAS, at least on the final link).

 I've been looking through the thread (including the August part), trying 
to understand what the origin of your changes has been.  What has struck 
me is nobody proposed an approach that would be equivalent to what GAS 
(and to some extent C) expression evaluation is.

 My idea is to divide operands and operations into three classes:

1. Plain symbol references, possibly with an offset yield an expression
   relative to the symbol's section.  Examples:

   foo
   foo + 4
   foo - 2 - (3 * 5)
   -7 + foo

2. Plain numbers and any operations made on them plus subtraction of two 
   section-relative expressions (i.e. anything that falls into #1 above) 
   yield a plain number.  Examples:

   0
   3 + 7
   foo - bar
   bar - foo + 2
   (bar + 2) - foo
   (bar - 10) - (foo + (~4 ^ 12))

3. Anything else yields an absolute expression (I would see no problem if 
   it failed altogether on an incremental link, though I understand we 
   may not want to do this for compatibility reasons).  You can make it 
   section-relative again by adding it to a section-relative expression.  
   Examples:

   foo + bar
   -foo + bar
   2 * foo
   foo & 1
   foo ^ bar
   etc., etc...

(note that #1 and #2 are how pointer arithmetics works in C too).  This 
for example implies that:

   foo + foo + foo

and:

   foo + 2 * foo

are relative, but:

   3 * foo

is not.

 Does it make any sense to you or anybody?

 Thanks for your work on this issue.

  Maciej



More information about the Binutils mailing list