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