Skip to content

[RISCV][Driver] Add support for -m flag to linker job of Baremetal toolchain #134442

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

Open
wants to merge 5 commits into
base: users/quic-garvgupt/sysroot
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/CommonArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs, const JobAction &JA);

const char *getLDMOption(const llvm::Triple &T, const llvm::opt::ArgList &Args);

void addLinkerCompressDebugSectionsOption(const ToolChain &TC,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
Expand Down
68 changes: 56 additions & 12 deletions clang/lib/Driver/ToolChains/BareMetal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,12 +568,24 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const llvm::Triple::ArchType Arch = TC.getArch();
const llvm::Triple &Triple = getToolChain().getEffectiveTriple();

AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));

CmdArgs.push_back("-Bstatic");

if (TC.getTriple().isRISCV() && Args.hasArg(options::OPT_mno_relax))
CmdArgs.push_back("--no-relax");
if (const char *LDMOption = getLDMOption(TC.getTriple(), Args)) {
CmdArgs.push_back("-m");
CmdArgs.push_back(LDMOption);
} else {
D.Diag(diag::err_target_unknown_triple) << Triple.str();
return;
}

if (Triple.isRISCV()) {
CmdArgs.push_back("-X");
if (Args.hasArg(options::OPT_mno_relax))
CmdArgs.push_back("--no-relax");
}

if (Triple.isARM() || Triple.isThumb()) {
bool IsBigEndian = arm::isARMBigEndian(Triple, Args);
Expand All @@ -584,19 +596,48 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");
}

if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
options::OPT_r)) {
CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt0.o")));
bool NeedCRTs =
!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);

const char *CRTBegin, *CRTEnd;
if (NeedCRTs) {
if (!Args.hasArg(options::OPT_r))
CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt0.o")));
if (TC.hasValidGCCInstallation() || detectGCCToolchainAdjacent(D)) {
auto RuntimeLib = TC.GetRuntimeLibType(Args);
switch (RuntimeLib) {
case (ToolChain::RLT_Libgcc): {
CRTBegin = "crtbegin.o";
CRTEnd = "crtend.o";
break;
}
case (ToolChain::RLT_CompilerRT): {
CRTBegin =
TC.getCompilerRTArgString(Args, "crtbegin", ToolChain::FT_Object);
CRTEnd =
TC.getCompilerRTArgString(Args, "crtend", ToolChain::FT_Object);
break;
}
}
CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTBegin)));
}
}

Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
options::OPT_s, options::OPT_t, options::OPT_r});
Args.addAllArgs(CmdArgs,
{options::OPT_L, options::OPT_u, options::OPT_T_Group,
options::OPT_s, options::OPT_t, options::OPT_r});

TC.AddFilePathLibArgs(Args, CmdArgs);

for (const auto &LibPath : TC.getLibraryPaths())
CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-L", LibPath)));

if (D.isUsingLTO())
addLTOOptions(TC, Args, CmdArgs, Output, Inputs,
D.getLTOMode() == LTOK_Thin);

AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);

if (TC.ShouldLinkCXXStdlib(Args)) {
bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
!Args.hasArg(options::OPT_static);
Expand All @@ -609,14 +650,17 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}

if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
CmdArgs.push_back("--start-group");
AddRunTimeLibs(TC, D, CmdArgs, Args);

CmdArgs.push_back("-lc");
if (TC.hasValidGCCInstallation() || detectGCCToolchainAdjacent(D))
CmdArgs.push_back("-lgloss");
CmdArgs.push_back("--end-group");
}

if (D.isUsingLTO())
addLTOOptions(TC, Args, CmdArgs, Output, Inputs,
D.getLTOMode() == LTOK_Thin);
if ((TC.hasValidGCCInstallation() || detectGCCToolchainAdjacent(D)) &&
NeedCRTs)
CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTEnd)));

if (TC.getTriple().isRISCV())
CmdArgs.push_back("-X");
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Driver/ToolChains/BareMetal.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class LLVM_LIBRARY_VISIBILITY BareMetal : public Generic_ELF {
public:
bool initGCCInstallation(const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
bool hasValidGCCInstallation() const { return IsGCCInstallationValid; }
bool isBareMetal() const override { return true; }
bool isCrossCompiling() const override { return true; }
bool HasNativeLLVMSupport() const override { return true; }
Expand All @@ -63,8 +64,6 @@ class LLVM_LIBRARY_VISIBILITY BareMetal : public Generic_ELF {
return ToolChain::CST_Libcxx;
}

const char *getDefaultLinker() const override { return "ld.lld"; }

void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
Expand Down
70 changes: 70 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,76 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
}
}

const char *tools::getLDMOption(const llvm::Triple &T, const ArgList &Args) {
switch (T.getArch()) {
case llvm::Triple::x86:
if (T.isOSIAMCU())
return "elf_iamcu";
return "elf_i386";
case llvm::Triple::aarch64:
return "aarch64linux";
case llvm::Triple::aarch64_be:
return "aarch64linuxb";
case llvm::Triple::arm:
case llvm::Triple::thumb:
case llvm::Triple::armeb:
case llvm::Triple::thumbeb:
return tools::arm::isARMBigEndian(T, Args) ? "armelfb_linux_eabi"
: "armelf_linux_eabi";
case llvm::Triple::m68k:
return "m68kelf";
case llvm::Triple::ppc:
if (T.isOSLinux())
return "elf32ppclinux";
return "elf32ppc";
case llvm::Triple::ppcle:
if (T.isOSLinux())
return "elf32lppclinux";
return "elf32lppc";
case llvm::Triple::ppc64:
return "elf64ppc";
case llvm::Triple::ppc64le:
return "elf64lppc";
case llvm::Triple::riscv32:
return "elf32lriscv";
case llvm::Triple::riscv64:
return "elf64lriscv";
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
return "elf32_sparc";
case llvm::Triple::sparcv9:
return "elf64_sparc";
case llvm::Triple::loongarch32:
return "elf32loongarch";
case llvm::Triple::loongarch64:
return "elf64loongarch";
case llvm::Triple::mips:
return "elf32btsmip";
case llvm::Triple::mipsel:
return "elf32ltsmip";
case llvm::Triple::mips64:
if (tools::mips::hasMipsAbiArg(Args, "n32") || T.isABIN32())
return "elf32btsmipn32";
return "elf64btsmip";
case llvm::Triple::mips64el:
if (tools::mips::hasMipsAbiArg(Args, "n32") || T.isABIN32())
return "elf32ltsmipn32";
return "elf64ltsmip";
case llvm::Triple::systemz:
return "elf64_s390";
case llvm::Triple::x86_64:
if (T.isX32())
return "elf32_x86_64";
return "elf_x86_64";
case llvm::Triple::ve:
return "elf64ve";
case llvm::Triple::csky:
return "cskyelf_linux";
default:
return nullptr;
}
}

void tools::addLinkerCompressDebugSectionsOption(
const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) {
Expand Down
70 changes: 0 additions & 70 deletions clang/lib/Driver/ToolChains/Gnu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,76 +219,6 @@ void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA,
// The types are (hopefully) good enough.
}

static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
switch (T.getArch()) {
case llvm::Triple::x86:
if (T.isOSIAMCU())
return "elf_iamcu";
return "elf_i386";
case llvm::Triple::aarch64:
return "aarch64linux";
case llvm::Triple::aarch64_be:
return "aarch64linuxb";
case llvm::Triple::arm:
case llvm::Triple::thumb:
case llvm::Triple::armeb:
case llvm::Triple::thumbeb:
return tools::arm::isARMBigEndian(T, Args) ? "armelfb_linux_eabi"
: "armelf_linux_eabi";
case llvm::Triple::m68k:
return "m68kelf";
case llvm::Triple::ppc:
if (T.isOSLinux())
return "elf32ppclinux";
return "elf32ppc";
case llvm::Triple::ppcle:
if (T.isOSLinux())
return "elf32lppclinux";
return "elf32lppc";
case llvm::Triple::ppc64:
return "elf64ppc";
case llvm::Triple::ppc64le:
return "elf64lppc";
case llvm::Triple::riscv32:
return "elf32lriscv";
case llvm::Triple::riscv64:
return "elf64lriscv";
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
return "elf32_sparc";
case llvm::Triple::sparcv9:
return "elf64_sparc";
case llvm::Triple::loongarch32:
return "elf32loongarch";
case llvm::Triple::loongarch64:
return "elf64loongarch";
case llvm::Triple::mips:
return "elf32btsmip";
case llvm::Triple::mipsel:
return "elf32ltsmip";
case llvm::Triple::mips64:
if (tools::mips::hasMipsAbiArg(Args, "n32") || T.isABIN32())
return "elf32btsmipn32";
return "elf64btsmip";
case llvm::Triple::mips64el:
if (tools::mips::hasMipsAbiArg(Args, "n32") || T.isABIN32())
return "elf32ltsmipn32";
return "elf64ltsmip";
case llvm::Triple::systemz:
return "elf64_s390";
case llvm::Triple::x86_64:
if (T.isX32())
return "elf32_x86_64";
return "elf_x86_64";
case llvm::Triple::ve:
return "elf64ve";
case llvm::Triple::csky:
return "cskyelf_linux";
default:
return nullptr;
}
}

static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) {
bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
if (HasStaticPIE && Args.hasArg(options::OPT_no_pie)) {
Expand Down
13 changes: 10 additions & 3 deletions clang/test/Driver/aarch64-toolchain-extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,21 @@
// RUN: mkdir -p %t/aarch64-nogcc/bin
// RUN: ln -s %clang %t/aarch64-nogcc/bin/clang
// RUN: ln -s %S/Inputs/basic_aarch64_nogcc_tree/aarch64-none-elf %t/aarch64-nogcc/aarch64-none-elf
// RUN: ln -s %S/Inputs/basic_aarch64_nogcc_tree/bin/aarch64-none-elf-ld %t/aarch64-nogcc/bin/aarch64-none-elf-ld
// RUN: %t/aarch64-nogcc/bin/clang %s -### -no-canonical-prefixes \
// RUN: --gcc-toolchain=%t/aarch64-nogcc/invalid \
// RUN: --target=aarch64-none-elf --rtlib=libgcc -fuse-ld=ld 2>&1 \
// RUN: | FileCheck -check-prefix=C-ARM-BAREMETAL-NOGCC %s
// RUN: | FileCheck -check-prefix=C-AARCH64-BAREMETAL-NOGCC %s

// RUN: %t/aarch64-nogcc/bin/clang %s -### -no-canonical-prefixes \
// RUN: --sysroot=%t/aarch64-nogcc/bin/../aarch64-none-elf \
// RUN: --target=aarch64-none-elf --rtlib=libgcc -fuse-ld=ld 2>&1 \
// RUN: | FileCheck -check-prefix=C-ARM-BAREMETAL-NOGCC %s
// RUN: | FileCheck -check-prefix=C-AARCH64-BAREMETAL-NOGCC %s

// C-ARM-BAREMETAL-NOGCC: "-internal-isystem" "{{.*}}/aarch64-nogcc/bin/../aarch64-none-elf/include"
// C-AARCH64-BAREMETAL-NOGCC: "-internal-isystem" "{{.*}}/aarch64-nogcc/bin/../aarch64-none-elf/include"
// C-AARCH64-BAREMETAL-NOGCC: "{{.*}}/aarch64-nogcc/bin/aarch64-none-elf-ld"
// C-AARCH64-BAREMETAL-NOGCC: "{{.*}}/aarch64-nogcc/bin/../aarch64-none-elf/lib/crt0.o"
// C-AARCH64-BAREMETAL-NOGCC: "{{.*}}/aarch64-nogcc/{{.*}}/aarch64-none-elf/lib/crtbegin.o"
// C-AARCH64-BAREMETAL-NOGCC: "{{.*}}/aarch64-nogcc/bin/../aarch64-none-elf/lib"
// C-AARCH64-BAREMETAL-NOGCC: "{{.*}}.o" "--start-group" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgloss" "--end-group"
// C-AARCH64-BAREMETAL-NOGCC: "{{.*}}/aarch64-nogcc/{{.*}}/aarch64-none-elf/lib/crtend.o"
Loading