https://github.com/windsunil updated https://github.com/llvm/llvm-project/pull/219828
>From 998c7d2e5e621f0160511b303e8285903de8545e Mon Sep 17 00:00:00 2001 From: Sunil Dora <[email protected]> Date: Sun, 30 Aug 2026 20:51:10 +0530 Subject: [PATCH 1/2] [clang][Driver] Link libssp_nonshared.a on musl with stack protector musl does not provide __stack_chk_fail_local, but GCC emits calls to it in PIC/PIE code on some targets (32-bit x86, PowerPC), so linking GCC-built objects with clang on musl fails: ld: undefined reference to `__stack_chk_fail_local' musl distributions (Alpine, OpenEmbedded) ship the symbol in a small libssp_nonshared.a and patch GCC to pass -lssp_nonshared when stack protection is enabled. Do the same here, but only when the library is present in the toolchain library paths, so toolchains without it are not affected. Co-authored-by: Khem Raj <[email protected]> Signed-off-by: Sunil Dora <[email protected]> --- clang/docs/ReleaseNotes.md | 4 +++ clang/lib/Driver/ToolChains/Gnu.cpp | 18 ++++++++++++ .../musl_ssp_tree/usr/lib/libssp_nonshared.a | 0 clang/test/Driver/linux-musl-ssp.c | 28 +++++++++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 clang/test/Driver/Inputs/musl_ssp_tree/usr/lib/libssp_nonshared.a create mode 100644 clang/test/Driver/linux-musl-ssp.c diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index bdbabf2cd98d0..47fb498cd5e3f 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -205,6 +205,10 @@ features cannot lower the translation-unit ABI level; - Clang tools now resolve tool names without a path in compilation databases through `PATH`. +- On musl targets, the driver now links ``libssp_nonshared.a`` when stack + protection is enabled and the library is present in the toolchain library + paths, matching what musl distributions configure GCC to do. + - Clang now allows GNU computed `goto` extension in `constexpr` functions, matching the relaxed `constexpr` function body rules introduced in C++23. diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 04f3b8d2200d6..5285f55897732 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -535,6 +535,24 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nolibc)) CmdArgs.push_back("-lc"); + // musl does not provide __stack_chk_fail_local, but GCC emits calls + // to it in PIC/PIE code on some targets (32-bit x86, PowerPC). musl + // distributions ship the symbol in libssp_nonshared.a and make GCC + // link it when stack protection is on; match that if the library + // exists. + if (ToolChain.getTriple().isMusl()) { + bool WantsSSP = ToolChain.GetDefaultStackProtectorLevel( + /*KernelOrKext=*/false) != LangOptions::SSPOff; + if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, + options::OPT_fstack_protector, + options::OPT_fstack_protector_all, + options::OPT_fstack_protector_strong)) + WantsSSP = !A->getOption().matches(options::OPT_fno_stack_protector); + if (WantsSSP && + ToolChain.GetFilePath("libssp_nonshared.a") != "libssp_nonshared.a") + CmdArgs.push_back("-lssp_nonshared"); + } + // Add IAMCU specific libs, if needed. if (IsIAMCU) CmdArgs.push_back("-lgloss"); diff --git a/clang/test/Driver/Inputs/musl_ssp_tree/usr/lib/libssp_nonshared.a b/clang/test/Driver/Inputs/musl_ssp_tree/usr/lib/libssp_nonshared.a new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/linux-musl-ssp.c b/clang/test/Driver/linux-musl-ssp.c new file mode 100644 index 0000000000000..4e6bc9cc427ce --- /dev/null +++ b/clang/test/Driver/linux-musl-ssp.c @@ -0,0 +1,28 @@ +// Check that on musl the driver links libssp_nonshared.a when stack +// protection is enabled and the sysroot provides the library. + +// RUN: %clang -### --target=i686-unknown-linux-musl \ +// RUN: --sysroot=%S/Inputs/musl_ssp_tree -fstack-protector-strong %s 2>&1 \ +// RUN: | FileCheck --check-prefix=SSP %s +// SSP: "-lc" "-lssp_nonshared" + +// Not with stack protection disabled (last flag wins). +// RUN: %clang -### --target=i686-unknown-linux-musl \ +// RUN: --sysroot=%S/Inputs/musl_ssp_tree -fstack-protector-strong \ +// RUN: -fno-stack-protector %s 2>&1 | FileCheck --check-prefix=NOSSP %s +// NOSSP-NOT: "-lssp_nonshared" + +// Not without any stack protector flag. +// RUN: %clang -### --target=i686-unknown-linux-musl \ +// RUN: --sysroot=%S/Inputs/musl_ssp_tree %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NOSSP %s + +// Not on glibc: libc_nonshared.a is linked via the libc.so linker script. +// RUN: %clang -### --target=i686-unknown-linux-gnu \ +// RUN: --sysroot=%S/Inputs/musl_ssp_tree -fstack-protector-strong %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NOSSP %s + +// Not when the sysroot does not provide the library. +// RUN: %clang -### --target=i686-unknown-linux-musl \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree -fstack-protector-strong %s \ +// RUN: 2>&1 | FileCheck --check-prefix=NOSSP %s >From 5f2fa61ad41778f095d83569bfbee05e405c40f1 Mon Sep 17 00:00:00 2001 From: Sunil Dora <[email protected]> Date: Mon, 31 Aug 2026 11:58:32 +0530 Subject: [PATCH 2/2] Reflow test RUN lines to two lines per command (review feedback) --- clang/test/Driver/linux-musl-ssp.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/clang/test/Driver/linux-musl-ssp.c b/clang/test/Driver/linux-musl-ssp.c index 4e6bc9cc427ce..4e48a20ea52cc 100644 --- a/clang/test/Driver/linux-musl-ssp.c +++ b/clang/test/Driver/linux-musl-ssp.c @@ -1,28 +1,23 @@ // Check that on musl the driver links libssp_nonshared.a when stack // protection is enabled and the sysroot provides the library. -// RUN: %clang -### --target=i686-unknown-linux-musl \ -// RUN: --sysroot=%S/Inputs/musl_ssp_tree -fstack-protector-strong %s 2>&1 \ +// RUN: %clang -### --target=i686-unknown-linux-musl --sysroot=%S/Inputs/musl_ssp_tree -fstack-protector-strong %s 2>&1 \ // RUN: | FileCheck --check-prefix=SSP %s // SSP: "-lc" "-lssp_nonshared" // Not with stack protection disabled (last flag wins). -// RUN: %clang -### --target=i686-unknown-linux-musl \ -// RUN: --sysroot=%S/Inputs/musl_ssp_tree -fstack-protector-strong \ -// RUN: -fno-stack-protector %s 2>&1 | FileCheck --check-prefix=NOSSP %s +// RUN: %clang -### --target=i686-unknown-linux-musl --sysroot=%S/Inputs/musl_ssp_tree -fstack-protector-strong -fno-stack-protector %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NOSSP %s // NOSSP-NOT: "-lssp_nonshared" // Not without any stack protector flag. -// RUN: %clang -### --target=i686-unknown-linux-musl \ -// RUN: --sysroot=%S/Inputs/musl_ssp_tree %s 2>&1 \ +// RUN: %clang -### --target=i686-unknown-linux-musl --sysroot=%S/Inputs/musl_ssp_tree %s 2>&1 \ // RUN: | FileCheck --check-prefix=NOSSP %s // Not on glibc: libc_nonshared.a is linked via the libc.so linker script. -// RUN: %clang -### --target=i686-unknown-linux-gnu \ -// RUN: --sysroot=%S/Inputs/musl_ssp_tree -fstack-protector-strong %s 2>&1 \ +// RUN: %clang -### --target=i686-unknown-linux-gnu --sysroot=%S/Inputs/musl_ssp_tree -fstack-protector-strong %s 2>&1 \ // RUN: | FileCheck --check-prefix=NOSSP %s // Not when the sysroot does not provide the library. -// RUN: %clang -### --target=i686-unknown-linux-musl \ -// RUN: --sysroot=%S/Inputs/basic_linux_tree -fstack-protector-strong %s \ -// RUN: 2>&1 | FileCheck --check-prefix=NOSSP %s +// RUN: %clang -### --target=i686-unknown-linux-musl --sysroot=%S/Inputs/basic_linux_tree -fstack-protector-strong %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NOSSP %s _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
