cc-wrapper: enable tlsdesc on i686, x86_64 linux
TLSDESC is a more performant way of doing TLS, since it has a custom calling convention that does not require the caller (of what's usually __tls_get_addr) to spill clobbered registers and assumes that the callee preserves all registers. This adds corresponding plumbing in the machineFlags in the cc-wrapper that includes version gates for compilers. TLSDESC needs to be supported by the bintools and libc, so I've only enabled it for architectures that our packaged glibc, musl, GNU binutils support (x86, x86_64). We package a lot of LLVM versions and support for -mtls-dialect in the Clang driver has only landed in LLVM 19, so a version check is added there too. Ideally we'd set the default at GCC build-time, but LLVM lacks such an option, so we'd have to keep it in the compiler wrapper for now. Gentoo is already building with it by default [1], as is Fedora [2]. In glibc < 2.40 [3] there existed a bug with not all registers being preserved, but it has since been resolved. x86 support has existed since basically forever with LLVM adding support in LLVM >= 19.1. LoongArch support has been added recently too, but it's only available since musl 1.2.6 while we are stuck at 1.2.5 for now, so I haven't dug deeper. Aarch64 uses TLSDESC by default already. The support status on non-Linux is a bit unclear, so these defaults are scoped only to linux targets. Sadly RISC-V support is still cooking apparently [4]. See: https://maskray.me/blog/2021-02-14-all-about-thread-local-storage See: https://groups.google.com/g/x86-64-abi/c/0tjmaQx6nZ0 [1]: https://github.com/gentoo/gentoo/commit/46191b478ebcb6bc6831627526da44f04dfcd1be [2]: https://src.fedoraproject.org/rpms/gcc/c/8f8d2ea9c326784bce044ff86547107611dda338?branch=rawhide [3]: https://sourceware.org/bugzilla/show_bug.cgi?id=31372 [4]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/494
This commit is contained in:
@@ -316,6 +316,17 @@ let
|
||||
tune =
|
||||
if targetPlatform ? gcc.tune then findBestTuneApproximation targetPlatform.gcc.tune else null;
|
||||
|
||||
tlsDialect =
|
||||
if
|
||||
# Support status on non-Linux systems is a bit unclear.
|
||||
targetPlatform.isLinux
|
||||
# Support added in https://github.com/llvm/llvm-project/commit/36b4a9ccd9f7e04010476e6b2a311f2052a4ac20 (19.1.0)
|
||||
&& (isClang -> versionAtLeast ccVersion "19.1")
|
||||
then
|
||||
(if targetPlatform.isx86 then "gnu2" else null)
|
||||
else
|
||||
null;
|
||||
|
||||
# Machine flags. These are necessary to support
|
||||
|
||||
# TODO: We should make a way to support miscellaneous machine
|
||||
@@ -353,7 +364,13 @@ let
|
||||
# TODO: clang on powerpcspe also needs a condition: https://github.com/llvm/llvm-project/issues/71356
|
||||
# https://releases.llvm.org/18.1.6/tools/clang/docs/ReleaseNotes.html#loongarch-support
|
||||
((targetPlatform.isLoongArch64 && isClang) -> versionAtLeast ccVersion "18.1")
|
||||
) "-mcmodel=${targetPlatform.gcc.cmodel}";
|
||||
) "-mcmodel=${targetPlatform.gcc.cmodel}"
|
||||
# Enable TLSDESC. This needs to be supported by the libc and bintools.
|
||||
# See: https://maskray.me/blog/2021-02-14-all-about-thread-local-storage
|
||||
# Aarch64 uses TLSDESC by default and the option is completely ignored (at least on LLVM).
|
||||
# TODO: Enable by default in GCC via --with-tls since https://gcc.gnu.org/cgit/gcc/commit/?id=96a291c4bb0b8a00b0a125e6a60f60072ffe53a7 (GCC 16).
|
||||
# No equivalent build-time option for LLVM yet.
|
||||
++ optional (tlsDialect != null) "-mtls-dialect=${tlsDialect}";
|
||||
|
||||
defaultHardeningFlags = bintools.defaultHardeningFlags or [ ];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user