On Wed, 4 Sep 2024, Evgeny Karpov wrote:

Monday, September 2, 2024
Martin Storsjö <mar...@martin.st> wrote:

The only non-obvious thing, is that for IMAGE_REL_ARM64_PAGEBASE_REL21,
i.e. "adrp" instructions, the immediate that gets stored in the
instruction, is the byte offset to the symbol.

After linking, when the instruction is interpreted at execution time, the
immediate in an adrp instruction denotes the offset in units of 2^12 bytes
- but in relocatable object files, the unit of the immediate is in single
bytes.

This is exactly the reason why the fix was introduced, and it resolves
the issues detected during testing.
Here is a more detailed explanation.

1. the code without the fix
adrp        x0, symbol + 256
add         x0, x0, symbol + 256

I can attest that there are _no_ problems with using such representation in COFF-ARM64. Whatever issues you are having must be caused by bugs in your assembler, or linker, or both.

Let's consider the following example, when symbol is located at 3072.

1. Example without the fix
compilation time
adrp        x0, (3072 + 256) & ~0xFFF // x0 = 0
add         x0, x0, (3072 + 256) & 0xFFF // x0 = 3328

linking time when symbol is relocated with offset 896
adrp        x0, (0 + 896) & ~0xFFF // x0 = 0

Why did the 3072 suddenly become 0 here?

add         x0, x0, (3328 + 896) & 0xFFF; // x0 = 128

Where did 3328 come from in your example? Wasn't "symbol" supposed to be at address 3072, and we're adding an offset of 896 to it?


In any case - you are misrepresenting how the relocations and immediates work.

If you have this on the assembly level:

    adrp x0, symbol + 896

then the assembler should output an adrp instruction, with the instruction immediate encoding the offset 896, with an IMAGE_REL_ARM64_PAGEBASE_REL21 pointing at "symbol".

When the linker links this object file, it will resolve the virtual address of "symbol", add the offset 896, and use this as the destination address to calculate the final page offset, for the instruction.

I can produce a set of test data to showcase the various corner cases that can be relevant in handling of these relocations, which work with both LLD and MS link.exe, to help you pinpoint your potential bug in your assembler and linker, and potential misunderstandings about how these concepts work. I can hopefully have such a set of examples ready for you tonight.

// Martin

Reply via email to