From c324c938becdbb963b34895cc12ffccb261bf167 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 16 Jun 2022 23:33:48 -0700 Subject: [PATCH] [Driver] Pass -X to ld for riscv*-{elf,freebsd,linux} GNU ld has a hack that defaults to -X (--discard-locals) in the emulation file `riscvelf.em`. The recommended way, as gcc/config/arm does, is to let the compiler driver pass -X to ld. (The motivation is likely to discard a plethora of `.L` symbols due to linker relaxation.) lld default to --discard-none. To make clang+lld match GNU ld's behavior, pass -X to ld. Note: GNU ld has a special rule to treat ld -r -s as ld -r -S -x. With -X, driver `-r -Wl,-s` will behave as ld `-r -S -X`. This removes fewer symbols than `-r -S -x` but is safe. Differential Revision: https://reviews.llvm.org/D127826 --- clang/lib/Driver/ToolChains/FreeBSD.cpp | 2 ++ clang/lib/Driver/ToolChains/Gnu.cpp | 2 ++ clang/lib/Driver/ToolChains/RISCVToolchain.cpp | 1 + clang/test/Driver/riscv32-toolchain.c | 3 ++- clang/test/Driver/riscv64-toolchain.c | 3 ++- 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp index 05c58a8..79e3c5c 100644 --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -223,10 +223,12 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, case llvm::Triple::riscv32: CmdArgs.push_back("-m"); CmdArgs.push_back("elf32lriscv"); + CmdArgs.push_back("-X"); break; case llvm::Triple::riscv64: CmdArgs.push_back("-m"); CmdArgs.push_back("elf64lriscv"); + CmdArgs.push_back("-X"); break; default: break; diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index f4caa5e..9a9ac60 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -465,6 +465,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(diag::err_target_unknown_triple) << Triple.str(); return; } + if (Triple.isRISCV()) + CmdArgs.push_back("-X"); if (Args.hasArg(options::OPT_shared)) CmdArgs.push_back("-shared"); diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp index a63ada0..a048765 100644 --- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -163,6 +163,7 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA, } else { CmdArgs.push_back("elf32lriscv"); } + CmdArgs.push_back("-X"); std::string Linker = getToolChain().GetLinkerPath(); diff --git a/clang/test/Driver/riscv32-toolchain.c b/clang/test/Driver/riscv32-toolchain.c index 1682e12..40d45fa 100644 --- a/clang/test/Driver/riscv32-toolchain.c +++ b/clang/test/Driver/riscv32-toolchain.c @@ -23,6 +23,7 @@ // C-RV32-BAREMETAL-ILP32: "{{.*}}Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}riscv32-unknown-elf-ld" // C-RV32-BAREMETAL-ILP32: "--sysroot={{.*}}/Inputs/basic_riscv32_tree/riscv32-unknown-elf" +// C-RV64-BAREMETAL-LP64-SAME: "-X" // C-RV32-BAREMETAL-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/riscv32-unknown-elf/lib{{/|\\\\}}crt0.o" // C-RV32-BAREMETAL-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o" // C-RV32-BAREMETAL-ILP32: "-L{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1" @@ -83,7 +84,7 @@ // C-RV32-LINUX-MULTI-ILP32: "{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/../../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-linux-gnu/bin{{/|\\\\}}ld" // C-RV32-LINUX-MULTI-ILP32: "--sysroot={{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot" -// C-RV32-LINUX-MULTI-ILP32: "-m" "elf32lriscv" +// C-RV32-LINUX-MULTI-ILP32: "-m" "elf32lriscv" "-X" // C-RV32-LINUX-MULTI-ILP32: "-dynamic-linker" "/lib/ld-linux-riscv32-ilp32.so.1" // C-RV32-LINUX-MULTI-ILP32: "{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/lib32/ilp32{{/|\\\\}}crtbegin.o" // C-RV32-LINUX-MULTI-ILP32: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/lib32/ilp32" diff --git a/clang/test/Driver/riscv64-toolchain.c b/clang/test/Driver/riscv64-toolchain.c index 78ce26c..79f0747 100644 --- a/clang/test/Driver/riscv64-toolchain.c +++ b/clang/test/Driver/riscv64-toolchain.c @@ -23,6 +23,7 @@ // C-RV64-BAREMETAL-LP64: "{{.*}}Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}riscv64-unknown-elf-ld" // C-RV64-BAREMETAL-LP64: "--sysroot={{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf" +// C-RV64-BAREMETAL-LP64-SAME: "-X" // C-RV64-BAREMETAL-LP64: "{{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib{{/|\\\\}}crt0.o" // C-RV64-BAREMETAL-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o" // C-RV64-BAREMETAL-LP64: "-L{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1" @@ -83,7 +84,7 @@ // C-RV64-LINUX-MULTI-LP64: "{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/../../..{{/|\\\\}}..{{/|\\\\}}riscv64-unknown-linux-gnu/bin{{/|\\\\}}ld" // C-RV64-LINUX-MULTI-LP64: "--sysroot={{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot" -// C-RV64-LINUX-MULTI-LP64: "-m" "elf64lriscv" +// C-RV64-LINUX-MULTI-LP64: "-m" "elf64lriscv" "-X" // C-RV64-LINUX-MULTI-LP64: "-dynamic-linker" "/lib/ld-linux-riscv64-lp64.so.1" // C-RV64-LINUX-MULTI-LP64: "{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/lib64/lp64{{/|\\\\}}crtbegin.o" // C-RV64-LINUX-MULTI-LP64: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/lib64/lp64" -- 2.7.4