1//===--- Ananas.cpp - Ananas ToolChain Implementations ------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "Ananas.h" 10#include "CommonArgs.h" 11#include "clang/Driver/Compilation.h" 12#include "clang/Driver/Driver.h" 13#include "clang/Driver/InputInfo.h" 14#include "clang/Driver/Options.h" 15#include "llvm/ADT/SmallString.h" 16#include "llvm/Option/ArgList.h" 17#include "llvm/Support/Path.h" 18 19using namespace clang::driver; 20using namespace clang::driver::tools; 21using namespace clang::driver::toolchains; 22using namespace clang; 23using namespace llvm::opt; 24 25void ananas::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 26 const InputInfo &Output, 27 const InputInfoList &Inputs, 28 const ArgList &Args, 29 const char *LinkingOutput) const { 30 claimNoWarnArgs(Args); 31 ArgStringList CmdArgs; 32 33 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 34 35 CmdArgs.push_back("-o"); 36 CmdArgs.push_back(Output.getFilename()); 37 38 for (const auto &II : Inputs) 39 CmdArgs.push_back(II.getFilename()); 40 41 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); 42 C.addCommand(std::make_unique<Command>(JA, *this, 43 ResponseFileSupport::AtFileCurCP(), 44 Exec, CmdArgs, Inputs, Output)); 45} 46 47void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA, 48 const InputInfo &Output, 49 const InputInfoList &Inputs, 50 const ArgList &Args, 51 const char *LinkingOutput) const { 52 const ToolChain &ToolChain = getToolChain(); 53 const Driver &D = ToolChain.getDriver(); 54 ArgStringList CmdArgs; 55 56 // Silence warning for "clang -g foo.o -o foo" 57 Args.ClaimAllArgs(options::OPT_g_Group); 58 // and "clang -emit-llvm foo.o -o foo" 59 Args.ClaimAllArgs(options::OPT_emit_llvm); 60 // and for "clang -w foo.o -o foo". Other warning options are already 61 // handled somewhere else. 62 Args.ClaimAllArgs(options::OPT_w); 63 64 if (!D.SysRoot.empty()) 65 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 66 67 if (Args.hasArg(options::OPT_static)) { 68 CmdArgs.push_back("-Bstatic"); 69 } else { 70 if (Args.hasArg(options::OPT_rdynamic)) 71 CmdArgs.push_back("-export-dynamic"); 72 if (Args.hasArg(options::OPT_shared)) { 73 CmdArgs.push_back("-Bshareable"); 74 } else if (!Args.hasArg(options::OPT_r)) { 75 Args.AddAllArgs(CmdArgs, options::OPT_pie); 76 CmdArgs.push_back("-dynamic-linker"); 77 CmdArgs.push_back("/lib/ld-ananas.so"); 78 } 79 } 80 81 if (Output.isFilename()) { 82 CmdArgs.push_back("-o"); 83 CmdArgs.push_back(Output.getFilename()); 84 } else { 85 assert(Output.isNothing() && "Invalid output."); 86 } 87 88 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, 89 options::OPT_r)) { 90 if (!Args.hasArg(options::OPT_shared)) { 91 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); 92 } 93 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); 94 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) { 95 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o"))); 96 } else { 97 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); 98 } 99 } 100 101 Args.AddAllArgs(CmdArgs, options::OPT_L); 102 ToolChain.AddFilePathLibArgs(Args, CmdArgs); 103 Args.AddAllArgs(CmdArgs, 104 {options::OPT_T_Group, options::OPT_e, options::OPT_s, 105 options::OPT_t, options::OPT_Z_Flag, options::OPT_r}); 106 107 if (D.isUsingLTO()) { 108 assert(!Inputs.empty() && "Must have at least one input."); 109 addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0], 110 D.getLTOMode() == LTOK_Thin); 111 } 112 113 AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); 114 115 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, 116 options::OPT_r)) { 117 if (ToolChain.ShouldLinkCXXStdlib(Args)) 118 ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 119 CmdArgs.push_back("-lc"); 120 } 121 122 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, 123 options::OPT_r)) { 124 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 125 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o"))); 126 else 127 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); 128 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); 129 } 130 131 const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); 132 C.addCommand(std::make_unique<Command>(JA, *this, 133 ResponseFileSupport::AtFileCurCP(), 134 Exec, CmdArgs, Inputs, Output)); 135} 136 137// Ananas - Ananas tool chain which can call as(1) and ld(1) directly. 138 139Ananas::Ananas(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 140 : Generic_ELF(D, Triple, Args) { 141 getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); 142} 143 144Tool *Ananas::buildAssembler() const { 145 return new tools::ananas::Assembler(*this); 146} 147 148Tool *Ananas::buildLinker() const { return new tools::ananas::Linker(*this); } 149