Arm64: assembling adrp with operand involving .

Nick Clifton nickc@redhat.com
Mon May 9 15:21:29 GMT 2022


Hi Jan,

   [I must admit that I have the lost the original context for this thread...]

> Was it really intented to reference the (equated) symbol
> in the relocations? There's now an inconsistency in that some
> relocations against constants reference the constants (when
> aarch64_get_expression()'s defer_resolution is false) while for the
> ones here and a few others it's the symbol which is referenced. I
> think one or the other ought to be used consistently,

I totally agree - the assembler should behave consistently if at all possible,

> from a purely abstract pov I'd
> say the symbols ought to be used if they're global

(or otherwise visible and alterable outside of the current context, yes ?)

> and constants
> ought to be used when the symbols aren't global, or are e.g. hidden).

Agreed.

> Some of my confusion with the original change is that, rather than
> doing more evaluation of the involved expression, you switched to
> doing less. 

(This was probably due to my being lazy and not really thinking the problem through ...)

> This felt the wrong way round. I've come up with this
> (not cleaned up) alternative, which makes . uses work as expected
> while still taking care of the issue in the original bug report:


> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -604,7 +604,7 @@ aarch64_get_expression (expressionS *  e
>     input_line_pointer = *str;
>     in_aarch64_get_expression = true;
>     if (defer_resolution)
> -    seg = deferred_expression (ep);
> +    seg = /*deferred_*/expression (ep);
>     else
>       seg = expression (ep);
>     in_aarch64_get_expression = false;
> @@ -8824,7 +8824,8 @@ md_apply_fix (fixS * fixP, valueT * valP
>   
>     /* Note whether this will delete the relocation.  */
>   
> -  if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
> +  if (fixP->fx_addsy == 0 && !fixP->fx_pcrel
> +      && aarch64_force_reloc (fixP->fx_r_type) <= 0)
>       fixP->fx_done = 1;
>   
>     /* Process the relocations.  */
> 
> But when using a transitive equate, the intermediate symbol is then
> used, which still doesn't feel quite right. Hence my thought of
> doing yet more evaluation of the expression.

I do not get what you are saying here.  Could you provide a small
example of code that might experience this problem ?

Still, given that this approach appears to be simple, self-contained
and correct, I am inclined to think that it is the best solution...


> If, otoh, the symbol references in the relocs are indeed meant to be
> as they are now,

As a general rule, this is one of those things that the target's assembler
language specification ought to define.  Of course not all targets do have
a well defined assembler language specification, so then we have to do the
best that we can.


> then the only other solution to the problem with .
> that I can see is to introduce yet another expression parsing mode,
> which would resolve . but defer everything else. One problem with
> skipping evaluation of the expression is that in
> 
> 	.text
> 
> 	.set x, 0x12345678
> 	.eqv bar, x
> foo:
> //	adrp	x0, x
> //	add	x0, x0, :lo12:x
> 	adrp	x0, bar
> 	add	x0, x0, :lo12:bar
> 
> 	.set x, 0x98765432
> 	adrp	x0, x
> 	add	x0, x0, :lo12:x
> 	adrp	x0, bar
> 	add	x0, x0, :lo12:bar
> 
> the two pairs of relocations against "bar" necessarily can only
> reflect one value, while "bar" being a forward ref would suggest
> x'es original value to be used in the first pair, but x'es final
> value to be used by the latter one.

Which would definitely confuse the programmer.  So I think that we
should avoid this route unless specifically required by the target's
assembler language specification.  (IE, for the AArch64, I could not
find anything saying that this behaviour is required, so I think that
we should not go down this route...)

Cheers
   Nick



More information about the Binutils mailing list