fixup_aarch64_movw support for COFF AArch64

Hi Everyone,

I'm working Chromium targeting Windows on ARM64 platform. As a part of this work I ran into an issue related to llvm in Swiftshader.

Currently fixup_aarch64_movw relocation type is not supported for COFF ARM64 (AArch64WinCOFFObjectWriter). As far as I see, Microsoft hasn't defined indicator for this relocation type. I haven't seen documented anywhere.

For AArch32 mova/movt indicators were implemented, I'm not sure but maybe we need to have something similar for AArch64?

Could someone give me some pointers how I could handle/fix this?

Many thanks,

Regards,

Adam

I'm working Chromium targeting Windows on ARM64 platform. As a part of this work I ran into an issue related to llvm in Swiftshader.

Currently fixup_aarch64_movw relocation type is not supported for COFF ARM64 (AArch64WinCOFFObjectWriter). As far as I see, Microsoft hasn't defined indicator for this relocation type. I haven't seen documented anywhere.

For AArch32 mova/movt indicators were implemented, I'm not sure but maybe we need to have something similar for AArch64?

The AArch32 movw/movt relocation was for a true relocation, where the target of the relocation is a symbol that is unknown at the assembly stage. But for AArch64 there is no such relocation defined for COFF.

Could someone give me some pointers how I could handle/fix this?

I'm not entirely sure, but it seems like this fixup type is only used for absolute values that are resolved before the object file is written - from AArch64AsmBackend.cpp, adjustFixupValue:

   case AArch64::fixup_aarch64_movw:
     [...]
     if (!IsResolved) {
       // FIXME: Figure out when this can actually happen, and verify our
       // behavior.
       Ctx.reportError(Fixup.getLoc(), "unresolved movw fixup not yet "
                                       "implemented");
       return Value;
     }

Despite this, it seems like AArch64ELFObjectWriter::getRelocType does return some ELF/AArch64 specific relocation types for this (but which never end up emitted to object files).

I tried adding an error in AArch64AsmBackend.cpp for this fixup type and running the tests in llvm/test/MC (I didn't check other parts of the testsuite), and it broke two tests, MC/AArch64/fixup-absolute.s and MC/AArch64/fixup-absolute-signed.s. And these two produce ELF object files without relocations.

So I would aim at making these two testcases work for COFF files, which shouldn't require making up any new COFF relocation types, at least not ones that would end up visible outside of the lib/Target/AArch64 internals.

// Martin

Martin,

Thanks for your suggestion.

I look at these tests, try to make them work for COFF.

Adam

Hi Adam,

SwiftShader calls LLVM to do JIT for ARM64. LLVM set CodeModel::Large for ARM64 in JIT mode [1] because it assumes a pointer could reach any place in 64-bit address space. The causes LLVM generating 4 MOV instructions to load 64-bit address/constant with each MOV loads 16-bit to the target. Windows ARM64 limited branch range (probably +/- 4GB which is reachable by ADRP/ADD instruction pair) so it doesn't support relocating the previous long branch (4 MOVs), both at compile/link time and load time. There are vary places in LLVM which checks CodeModel::Large and generate code accordingly [2].

Introduce new relocation types to COFF will cause interop issue with MSVC. You probably could change CodeModel for JIT and see how far SwiftShader can go.

[1]: https://github.com/llvm-mirror/llvm/blob/6e45beba86221def2571af2b4e3f00ea8b8f5643/lib/Target/AArch64/AArch64TargetMachine.cpp#L251
[2]: https://github.com/llvm-mirror/llvm/blob/6e45beba86221def2571af2b4e3f00ea8b8f5643/lib/Target/AArch64/AArch64InstrInfo.cpp#L1525

-Tom

Hi Tom,

Thanks for your comments and sorry for the delayed response.

I've tried out to use CodeModel::Small, it seems it works, at least LLVM doesn't generate mov instructions. I think it is a good starting point. Since finally the execution reaches the linker part of JIT. By the way could it be valid if for example the CodeModel::Small is used for JIT on Windows on ARM?

However the COFF ARM64 support for MC-JIT runtime dynamic linker is missing. So I started to work on that. First of all I would like to understand better how that work.

Adam

If it’s just for JIT, you might want to try to tell it to use ELF format as the target triple. (That’s how we do it for the JuliaLang JIT, since the RTDyld support for COFF is less mature. But I’ve only tried it on x86 and amd64.)