This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Relative expressions and ASSERT
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