[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