[PATCH 2/4] GAS: Make new fake labels when cloning a symbol
Richard Sandiford
rdsandiford@googlemail.com
Sat Jul 31 08:59:00 GMT 2010
"Maciej W. Rozycki" <macro@codesourcery.com> writes:
> Equated symbols (defined with .eqv) aka forward references are defined to
> reevaluate the expression they are defined to whenever they are referred
> to. This does not happen for the special "dot" symbol -- the value
> calculated the first time the equated symbol has been used is then used
> over and over again.
>
> The reason is each time a reference to the "dot" symbol is made a special
> fake label is created. This label is then recorded in the chain of
> symbols the equated symbol is defined to and never reevaluated. The
> solution is to create a new fake label each time the equated symbol is
> used.
>
> Additionally symbol_clone_if_forward_ref() would only be called
> recursively for internal symbols referring to the special expression
> section. It should happen for all symbols.
>
> Overall with symbol definitions like this:
>
> .data
> .eqv fnord, .
> .eqv foobar, fnord + 4
> .eqv foobaz, foobar - 16
> .word 0
> .word fnord
> .word fnord
> .word foobaz
> .word foobaz
>
> the "dot" symbol would only be calculated once, with the second .word
> directive, i.e. both the second and the third word emitted would have the
> same value (address of the second word).
>
> This would also cause "foobaz" to be calculated (as a forward reference)
> with the third .eqv directive and then cloned each time when used with
> .word. Howeved "foobar" would only be calculated with the second and the
> third .eqv directive, but not with the .word directives, thus fixed at
> the value of the first rather than each use.
>
> In the end data emitted would be:
>
> 0, 0, 0, -12, -12
>
> as if .set was used, rather than:
>
> 0, 4, 8, 0, 4
>
> as expected.
Unfortunately, keying off FAKE_LABEL_NAME isn't enough to prove that
that the symbol is ".". FAKE_LABEL_NAME is also used in the DWARF
machinery, and to hold the result of nested expressions. It's a bit
of a convoluted example, but after the patch:
.set noreorder
.eqv foo,(x+bar)-frob
.set bar,0
.set frob,0
x:
nop
b foo
nop
nop
b foo
nop
gives:
00000000 <x>:
0: 00000000 nop
4: 1000ffff b 4 <x+0x4>
8: 00000000 nop
c: 00000000 nop
10: 1000ffff b 10 <x+0x10>
14: 00000000 nop
Also, as far as:
- if (symbolP->bsym->section == expr_section && !symbolP->sy_resolving)
+ if (!symbolP->sy_resolving)
goes, I'm not sure that we really should be walking through other
_non-eqv_ symbol definitions. E.g. after the patch:
.set noreorder
.eqv foo,bar
.eqv baz,.
.set bar,baz
x:
nop
b foo
nop
.set bar,baz
nop
b foo
nop
assembles as:
00000000 <baz>:
0: 00000000 nop
4: 1000ffff b 4 <baz+0x4>
8: 00000000 nop
0000000c <bar>:
c: 00000000 nop
10: 1000ffff b 10 <bar+0x4>
14: 00000000 nop
whereas the branches should be to 0x0 and 0xc respectively.
I'm not saying the current code's right, of course. I agree that:
.set noreorder
.eqv foo,bar
.eqv bar,baz
.set baz,.
nop
b foo
nop
.set baz,.
nop
b foo
nop
ought to be the same as the previous example, and at the moment it isn't.
I just think the recursiveness should be limited to expressions and
forward references. It might help if we split the problem into two:
fixing the chained-.eqv evaluation, and fixing "." references.
Richard
More information about the Binutils
mailing list