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 2. the code with the fix adrp x0, symbol add x0, x0, symbol add x0, x0, 256 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 add x0, x0, (3328 + 896) & 0xFFF; // x0 = 128 which is wrong. it should be x0 = 3072 + 896 + 256 = 4224 2. Example with the fix compilation time adrp x0, 3072 & ~0xFFF // x0 = 0 add x0, x0, 3072 & 0xFFF // x0 = 3072 add x0, x0, 256 // x0 = 3328 linking time when symbol is relocated with offset 896 adrp x0, (0 + 896) & ~0xFFF // x0 = 0 add x0, x0, (3072 + 896) & 0xFFF // x0 = 3968 add x0, x0, 256 // x0 = 4224 x0 contains expected result. Theoretically, the issue can be solved by changing the alignment of segments to 4096. It might require further investigation and a follow-up patch if it works. Even if it works, it has a downside as it increases the segment sizes. Regards, Evgeny