@@ -154,6 +154,8 @@ BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple,
154154 : Generic_ELF(D, Triple, Args) {
155155 GCCInstallation.init (Triple, Args);
156156 SysRoot = computeSysRoot ();
157+ UseLD =
158+ Args.getLastArgValue (options::OPT_fuse_ld_EQ).equals_insensitive (" ld" );
157159 if (GCCInstallation.isValid ()) {
158160 Multilibs = GCCInstallation.getMultilibs ();
159161 SelectedMultilibs.assign ({GCCInstallation.getMultilib ()});
@@ -331,6 +333,32 @@ BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs() const {
331333 return llvm::reverse (Default);
332334}
333335
336+ ToolChain::CXXStdlibType BareMetal::GetDefaultCXXStdlibType () const {
337+ if (getTriple ().isRISCV () && GCCInstallation.isValid ())
338+ return ToolChain::CST_Libstdcxx;
339+ return ToolChain::CST_Libcxx;
340+ }
341+
342+ ToolChain::RuntimeLibType BareMetal::GetDefaultRuntimeLibType () const {
343+ if (getTriple ().isRISCV () && GCCInstallation.isValid ())
344+ return ToolChain::RLT_Libgcc;
345+ return ToolChain::RLT_CompilerRT;
346+ }
347+
348+ ToolChain::UnwindLibType
349+ BareMetal::GetUnwindLibType (const llvm::opt::ArgList &Args) const {
350+ if (getTriple ().isRISCV ())
351+ return ToolChain::UNW_None;
352+
353+ return ToolChain::GetUnwindLibType (Args);
354+ }
355+
356+ const char *BareMetal::getDefaultLinker () const {
357+ if (isUsingLD ())
358+ return " ld" ;
359+ return " ld.lld" ;
360+ }
361+
334362void BareMetal::AddClangSystemIncludeArgs (const ArgList &DriverArgs,
335363 ArgStringList &CC1Args) const {
336364 if (DriverArgs.hasArg (options::OPT_nostdinc))
@@ -524,12 +552,21 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
524552 const llvm::Triple::ArchType Arch = TC.getArch ();
525553 const llvm::Triple &Triple = getToolChain ().getEffectiveTriple ();
526554
527- AddLinkerInputs (TC, Inputs, Args, CmdArgs, JA);
555+ if (!D.SysRoot .empty ())
556+ CmdArgs.push_back (Args.MakeArgString (" --sysroot=" + D.SysRoot ));
528557
529558 CmdArgs.push_back (" -Bstatic" );
530559
531- if (TC.getTriple ().isRISCV () && Args.hasArg (options::OPT_mno_relax))
532- CmdArgs.push_back (" --no-relax" );
560+ if (Triple.isRISCV ()) {
561+ if (Args.hasArg (options::OPT_mno_relax))
562+ CmdArgs.push_back (" --no-relax" );
563+ if (TC.isUsingLD ()) {
564+ CmdArgs.push_back (" -m" );
565+ CmdArgs.push_back (Arch == llvm::Triple::riscv64 ? " elf64lriscv"
566+ : " elf32lriscv" );
567+ }
568+ CmdArgs.push_back (" -X" );
569+ }
533570
534571 if (Triple.isARM () || Triple.isThumb ()) {
535572 bool IsBigEndian = arm::isARMBigEndian (Triple, Args);
@@ -540,19 +577,54 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
540577 CmdArgs.push_back (Arch == llvm::Triple::aarch64_be ? " -EB" : " -EL" );
541578 }
542579
543- if (!Args.hasArg (options::OPT_nostdlib, options::OPT_nostartfiles,
544- options::OPT_r)) {
545- CmdArgs.push_back (Args.MakeArgString (TC.GetFilePath (" crt0.o" )));
580+ bool WantCRTs =
581+ !Args.hasArg (options::OPT_nostdlib, options::OPT_nostartfiles);
582+
583+ const char *crtbegin, *crtend;
584+ if (WantCRTs) {
585+ if (!Args.hasArg (options::OPT_r))
586+ CmdArgs.push_back (Args.MakeArgString (TC.GetFilePath (" crt0.o" )));
587+ if (TC.isUsingLD ()) {
588+ auto RuntimeLib = TC.GetRuntimeLibType (Args);
589+ if (RuntimeLib == ToolChain::RLT_Libgcc) {
590+ crtbegin = " crtbegin.o" ;
591+ crtend = " crtend.o" ;
592+ } else {
593+ assert (RuntimeLib == ToolChain::RLT_CompilerRT);
594+ crtbegin =
595+ TC.getCompilerRTArgString (Args, " crtbegin" , ToolChain::FT_Object);
596+ crtend =
597+ TC.getCompilerRTArgString (Args, " crtend" , ToolChain::FT_Object);
598+ }
599+ CmdArgs.push_back (Args.MakeArgString (TC.GetFilePath (crtbegin)));
600+ }
546601 }
547602
548- Args.addAllArgs (CmdArgs, {options::OPT_L, options::OPT_T_Group,
549- options::OPT_s, options::OPT_t, options::OPT_r});
603+ Args.addAllArgs (CmdArgs,
604+ {options::OPT_L, options::OPT_u, options::OPT_T_Group,
605+ options::OPT_s, options::OPT_t, options::OPT_r});
550606
551607 TC.AddFilePathLibArgs (Args, CmdArgs);
552608
553609 for (const auto &LibPath : TC.getLibraryPaths ())
554610 CmdArgs.push_back (Args.MakeArgString (llvm::Twine (" -L" , LibPath)));
555611
612+ if (D.isUsingLTO ()) {
613+ assert (!Inputs.empty () && " Must have at least one input." );
614+ // Find the first filename InputInfo object.
615+ auto Input = llvm::find_if (
616+ Inputs, [](const InputInfo &II) -> bool { return II.isFilename (); });
617+ if (Input == Inputs.end ())
618+ // For a very rare case, all of the inputs to the linker are
619+ // InputArg. If that happens, just use the first InputInfo.
620+ Input = Inputs.begin ();
621+
622+ addLTOOptions (TC, Args, CmdArgs, Output, *Input,
623+ D.getLTOMode () == LTOK_Thin);
624+ }
625+
626+ AddLinkerInputs (TC, Inputs, Args, CmdArgs, JA);
627+
556628 if (TC.ShouldLinkCXXStdlib (Args)) {
557629 bool OnlyLibstdcxxStatic = Args.hasArg (options::OPT_static_libstdcxx) &&
558630 !Args.hasArg (options::OPT_static);
@@ -565,26 +637,16 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
565637 }
566638
567639 if (!Args.hasArg (options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
640+ CmdArgs.push_back (" --start-group" );
568641 AddRunTimeLibs (TC, D, CmdArgs, Args);
569-
570642 CmdArgs.push_back (" -lc" );
643+ if (TC.isUsingLD ())
644+ CmdArgs.push_back (" -lgloss" );
645+ CmdArgs.push_back (" --end-group" );
571646 }
572647
573- if (D.isUsingLTO ()) {
574- assert (!Inputs.empty () && " Must have at least one input." );
575- // Find the first filename InputInfo object.
576- auto Input = llvm::find_if (
577- Inputs, [](const InputInfo &II) -> bool { return II.isFilename (); });
578- if (Input == Inputs.end ())
579- // For a very rare case, all of the inputs to the linker are
580- // InputArg. If that happens, just use the first InputInfo.
581- Input = Inputs.begin ();
582-
583- addLTOOptions (TC, Args, CmdArgs, Output, *Input,
584- D.getLTOMode () == LTOK_Thin);
585- }
586- if (TC.getTriple ().isRISCV ())
587- CmdArgs.push_back (" -X" );
648+ if (TC.isUsingLD () && WantCRTs)
649+ CmdArgs.push_back (Args.MakeArgString (TC.GetFilePath (crtend)));
588650
589651 // The R_ARM_TARGET2 relocation must be treated as R_ARM_REL32 on arm*-*-elf
590652 // and arm*-*-eabi (the default is R_ARM_GOT_PREL, used on arm*-*-linux and
0 commit comments