-
Notifications
You must be signed in to change notification settings - Fork 15
lld: arm64 big-endian: ld.lld: error: unknown emulation: aarch64linuxb #1288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
We probably need https://git.kernel.org/linus/28187dc8ebd938d574edfc6d9e0f9c51c21ff3f4 for arm64 as well. LLD does not support big-endian ARM: #380 |
I don't think that's the case actually: I can link a big-endian arm64 user space executable with ld.lld, it sounds more like something in the way we call ld on arm64 is slightly different between ld.bfd and ld.lld. |
Both big-endian arm and aarch64 are unsupported. See https://reviews.llvm.org/D58655#1410282 for aarch64be (@smithp35) The unclear things are what relocation types need |
Should lld refuse to link big-endian binaries then, instead of producing invalid output? FWIW, I found that I only needed a small patch to actually get the big-endian kernel to build with both linkers:
This avoids the two build failures i see with lld, and the resulting kernel still boots when built with ld.bfd, but is silently broken with lld, and that seems worse than an error message rejecting the '-EB' command line flag to the linker. |
I agree that an explicit error message is preferable to silently not working. It may be worth approaching TCWG in Linaro if BE support is important enough to work on. This is my memory of what we'd need to do to get BE support working. AArch64 support in LLD shouldn't be too far away. Instructions in AArch64 are always LE so we'd have to look through the code for any if BE do this based on the template parameters and force LE instead. I expect that it is mostly a matter of going through the source and making changes then do a lot of testing. I'd expect that getting applications to work on top of a bfd linked kernel first will be easier than getting the kernel to boot though. Arm support in LLD needs more work.
The endian reversal of instructions isn't a huge amount of work but it is messy. The mapping symbols $a $t and $d give the range of Arm, Thumb and Data. The linker (after relocation) needs to endian reverse a word at a time for $a (4-byte instructions), a halfword at a time for $t (2-byte instructions) and leave $d alone. |
I tried various combinations of clang/gcc, ld.bfd/ld.lld and big-endian/little-endian to understand what the behavior is today. This is what I found:
I don't have a big-endian user space, so I was unable to try running user space executables. It should be possible to test them using qemu-user though, with libc as the only required dependency. |
Patch sent to disable the config for |
Similar to commit 28187dc ("ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN depends on !LD_IS_LLD"), ld.lld does not support aarch64 big endian, leading to the following build error when CONFIG_CPU_BIG_ENDIAN is selected: ld.lld: error: unknown emulation: aarch64linuxb There are not currently plans to implement big endian support for aarch64 in ld.lld but if it should be supported in the future, this symbol can depend on the version that first supports it. In the meantime, prevent this symbol from being selected to avoid these type of build errors. While we are here, the indentation of this symbol used spaces since its introduction in commit a872013 ("arm64: kconfig: allow CPU_BIG_ENDIAN to be selected"). Change it to tabs to be consistent with kernel coding style. Link: ClangBuiltLinux#380 Link: ClangBuiltLinux#1288 Reported-by: Arnd Bergmann <[email protected]> Signed-off-by: Nathan Chancellor <[email protected]>
Thalheim kindly shared with me an aarch64_be rootfs. With You may change the LD_IS_LLD patch to check |
@MaskRay thanks a lot! I can confirm that D96188 works with https://github.com/nathanchance/boot-utils/commits/b8883fd4d8cc28f45cd43d9905084b2f0c8c6de3. There is still one other issue that prevents
For the sake of testing this, I did: diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
index 61dbb4c838ef..12cdb72a37c6 100644
--- a/arch/arm64/kernel/vdso/vdso.lds.S
+++ b/arch/arm64/kernel/vdso/vdso.lds.S
@@ -12,7 +12,7 @@
#include <asm/page.h>
#include <asm/vdso.h>
-OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", "elf64-littleaarch64")
+OUTPUT_FORMAT("elf64-bigaarch64")
OUTPUT_ARCH(aarch64)
SECTIONS |
This patch adds * Big-endian values for `R_AARCH64_{ABS,PREL}{16,32,64}` and `R_AARCH64_PLT32` * aarch64elfb & aarch64linuxb BFD emulations * elf64-bigaarch64 output format (bfdname) Link: ClangBuiltLinux/linux#1288 Differential Revision: https://reviews.llvm.org/D96188
Thanks @MaskRay ! Do we want to cherry pick the LLVM fix to 12.x branch, or let this ride the 13.x train? We probably need to amend the kernel patch to check the specific LLD version. |
Supporting aarch64_be is a new feature, and we lack testing on goodness, so I think it is not suitable for 12.x.
|
That is fine with me, I will send that patch along this afternoon. |
Should mark #380 a dup of this. |
Kernel side patch accepted: https://git.kernel.org/arm64/c/e9c6deee00e9 |
Similar to commit 28187dc ("ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN depends on !LD_IS_LLD"), ld.lld prior to 13.0.0 does not properly support aarch64 big endian, leading to the following build error when CONFIG_CPU_BIG_ENDIAN is selected: ld.lld: error: unknown emulation: aarch64linuxb This has been resolved in LLVM 13. To avoid errors like this, only allow CONFIG_CPU_BIG_ENDIAN to be selected if using ld.bfd or ld.lld 13.0.0 and newer. While we are here, the indentation of this symbol used spaces since its introduction in commit a872013 ("arm64: kconfig: allow CPU_BIG_ENDIAN to be selected"). Change it to tabs to be consistent with kernel coding style. Link: ClangBuiltLinux/linux#380 Link: ClangBuiltLinux/linux#1288 Link: llvm/llvm-project@7605a9a Link: llvm/llvm-project@eea34aa Reported-by: Arnd Bergmann <[email protected]> Signed-off-by: Nathan Chancellor <[email protected]> Reviewed-by: Nick Desaulniers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
Link: ClangBuiltLinux/linux#1288 Signed-off-by: Nathan Chancellor <[email protected]>
Link: ClangBuiltLinux/linux#1288 Signed-off-by: Nathan Chancellor <[email protected]>
Link: ClangBuiltLinux/linux#1288 Signed-off-by: Nathan Chancellor <[email protected]>
Merged into mainline: https://git.kernel.org/torvalds/c/e9c6deee00e9 |
commit e9c6dee upstream Similar to commit 28187dc ("ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN depends on !LD_IS_LLD"), ld.lld prior to 13.0.0 does not properly support aarch64 big endian, leading to the following build error when CONFIG_CPU_BIG_ENDIAN is selected: ld.lld: error: unknown emulation: aarch64linuxb This has been resolved in LLVM 13. To avoid errors like this, only allow CONFIG_CPU_BIG_ENDIAN to be selected if using ld.bfd or ld.lld 13.0.0 and newer. While we are here, the indentation of this symbol used spaces since its introduction in commit a872013 ("arm64: kconfig: allow CPU_BIG_ENDIAN to be selected"). Change it to tabs to be consistent with kernel coding style. Link: ClangBuiltLinux/linux#380 Link: ClangBuiltLinux/linux#1288 Link: llvm/llvm-project@7605a9a Link: llvm/llvm-project@eea34aa Reported-by: Arnd Bergmann <[email protected]> Signed-off-by: Nathan Chancellor <[email protected]> Reviewed-by: Nick Desaulniers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Sudip Mukherjee <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
commit e9c6dee upstream Similar to commit 28187dc ("ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN depends on !LD_IS_LLD"), ld.lld prior to 13.0.0 does not properly support aarch64 big endian, leading to the following build error when CONFIG_CPU_BIG_ENDIAN is selected: ld.lld: error: unknown emulation: aarch64linuxb This has been resolved in LLVM 13. To avoid errors like this, only allow CONFIG_CPU_BIG_ENDIAN to be selected if using ld.bfd or ld.lld 13.0.0 and newer. While we are here, the indentation of this symbol used spaces since its introduction in commit a872013 ("arm64: kconfig: allow CPU_BIG_ENDIAN to be selected"). Change it to tabs to be consistent with kernel coding style. Link: ClangBuiltLinux/linux#380 Link: ClangBuiltLinux/linux#1288 Link: llvm/llvm-project@7605a9a Link: llvm/llvm-project@eea34aa Reported-by: Arnd Bergmann <[email protected]> Signed-off-by: Nathan Chancellor <[email protected]> Reviewed-by: Nick Desaulniers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Sudip Mukherjee <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
stable inclusion from stable-5.10.23 commit 7215d7742daf4c036567f03c647738e269d6a943 bugzilla: 50838 -------------------------------- commit e9c6dee upstream Similar to commit 28187dc ("ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN depends on !LD_IS_LLD"), ld.lld prior to 13.0.0 does not properly support aarch64 big endian, leading to the following build error when CONFIG_CPU_BIG_ENDIAN is selected: ld.lld: error: unknown emulation: aarch64linuxb This has been resolved in LLVM 13. To avoid errors like this, only allow CONFIG_CPU_BIG_ENDIAN to be selected if using ld.bfd or ld.lld 13.0.0 and newer. While we are here, the indentation of this symbol used spaces since its introduction in commit a872013 ("arm64: kconfig: allow CPU_BIG_ENDIAN to be selected"). Change it to tabs to be consistent with kernel coding style. Link: ClangBuiltLinux/linux#380 Link: ClangBuiltLinux/linux#1288 Link: llvm/llvm-project@7605a9a Link: llvm/llvm-project@eea34aa Reported-by: Arnd Bergmann <[email protected]> Signed-off-by: Nathan Chancellor <[email protected]> Reviewed-by: Nick Desaulniers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Sudip Mukherjee <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Chen Jun <[email protected]> Acked-by: Weilong Chen <[email protected]> Signed-off-by: Zheng Zengkai <[email protected]>
This patch adds * Big-endian values for `R_AARCH64_{ABS,PREL}{16,32,64}` and `R_AARCH64_PLT32` * aarch64elfb & aarch64linuxb BFD emulations * elf64-bigaarch64 output format (bfdname) Link: ClangBuiltLinux/linux#1288 Differential Revision: https://reviews.llvm.org/D96188
stable inclusion from stable-v5.10.23 commit 7215d7742daf4c036567f03c647738e269d6a943 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9R4L4 CVE: CVE-2023-52750 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7215d7742daf4c036567f03c647738e269d6a943 -------------------------------- commit e9c6dee upstream Similar to commit 28187dc ("ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN depends on !LD_IS_LLD"), ld.lld prior to 13.0.0 does not properly support aarch64 big endian, leading to the following build error when CONFIG_CPU_BIG_ENDIAN is selected: ld.lld: error: unknown emulation: aarch64linuxb This has been resolved in LLVM 13. To avoid errors like this, only allow CONFIG_CPU_BIG_ENDIAN to be selected if using ld.bfd or ld.lld 13.0.0 and newer. While we are here, the indentation of this symbol used spaces since its introduction in commit a872013 ("arm64: kconfig: allow CPU_BIG_ENDIAN to be selected"). Change it to tabs to be consistent with kernel coding style. Link: ClangBuiltLinux/linux#380 Link: ClangBuiltLinux/linux#1288 Link: llvm/llvm-project@7605a9a Link: llvm/llvm-project@eea34aa Reported-by: Arnd Bergmann <[email protected]> Signed-off-by: Nathan Chancellor <[email protected]> Reviewed-by: Nick Desaulniers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Sudip Mukherjee <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Conflicts: arch/arm64/Kconfig [lhb: adjust context] Signed-off-by: Hongbo Li <[email protected]>
This is what I get when building an arm64 big-endian kernel:
ld.lld: error: unknown emulation: aarch64linuxb
make[4]: *** [/git/arm-soc/arch/arm64/kernel/vdso/Makefile:56: arch/arm64/kernel/vdso/vdso.so.dbg] Error 1
I suspect this trivial to workaround, as lld seems to support big-endian in principle, but I could not figure out what the actual problem is.
The text was updated successfully, but these errors were encountered: