On Mon, 2 Sep 2024, Evgeny Karpov wrote:
aarch64.cc has been updated to prevent emitting "symbol + offset" for SYMBOL_SMALL_ABSOLUTE for the PECOFF target. "symbol + offset" cannot be used in relocations for aarch64-w64-mingw32 due to relocation requirements.
What relocation requirements are these? COFF for aarch64 does permit symbol+offset references in most relocations.
The IMAGE_REL_ARM64_PAGEBASE_REL21, IMAGE_REL_ARM64_REL21, IMAGE_REL_ARM64_PAGEOFFSET_12A and IMAGE_REL_ARM64_PAGEOFFSET_12L relocations all do support storing a symbol offset in the immediate of the instruction. LLD and MS link.exe support this just fine.
The only case where symbol offsets aren't supported, is the IMAGE_REL_ARM64_BRANCH* relocations. MS link.exe ignores the instruction immediate in those, so within LLVM, we've followed suit, and avoid emitting those as symbol+offset. It would be easy to implement support for it in LLD, but then we'd end up with object files incompatible with MS link.exe.
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.
If GNU ld doesn't support offsets in these relocations yet, I'd recommend implementing support for it there (cross check with LLD or MS link.exe how it behaves) rather than avoiding it in the compiler.
// Martin