blob: 648469e4cec5135fdd6a69fdba7034ac49674f14 [file] [log] [blame]
David L. Jonesf561aba2017-03-08 01:02:16 +00001//===--- DragonFly.cpp - DragonFly ToolChain Implementations ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "DragonFly.h"
11#include "CommonArgs.h"
12#include "clang/Driver/Compilation.h"
13#include "clang/Driver/Driver.h"
14#include "clang/Driver/Options.h"
15#include "llvm/Option/ArgList.h"
16
17using namespace clang::driver;
18using namespace clang::driver::tools;
19using namespace clang::driver::toolchains;
20using namespace clang;
21using namespace llvm::opt;
22
23/// DragonFly Tools
24
25// For now, DragonFly Assemble does just about the same as for
26// FreeBSD, but this may change soon.
27void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
28 const InputInfo &Output,
29 const InputInfoList &Inputs,
30 const ArgList &Args,
31 const char *LinkingOutput) const {
32 claimNoWarnArgs(Args);
33 ArgStringList CmdArgs;
34
35 // When building 32-bit code on DragonFly/pc64, we have to explicitly
36 // instruct as in the base system to assemble 32-bit code.
37 if (getToolChain().getArch() == llvm::Triple::x86)
38 CmdArgs.push_back("--32");
39
40 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
41
42 CmdArgs.push_back("-o");
43 CmdArgs.push_back(Output.getFilename());
44
45 for (const auto &II : Inputs)
46 CmdArgs.push_back(II.getFilename());
47
48 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
49 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
50}
51
52void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
53 const InputInfo &Output,
54 const InputInfoList &Inputs,
55 const ArgList &Args,
56 const char *LinkingOutput) const {
57 const Driver &D = getToolChain().getDriver();
58 ArgStringList CmdArgs;
59
60 if (!D.SysRoot.empty())
61 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
62
63 CmdArgs.push_back("--eh-frame-hdr");
64 if (Args.hasArg(options::OPT_static)) {
65 CmdArgs.push_back("-Bstatic");
66 } else {
67 if (Args.hasArg(options::OPT_rdynamic))
68 CmdArgs.push_back("-export-dynamic");
69 if (Args.hasArg(options::OPT_shared))
70 CmdArgs.push_back("-Bshareable");
71 else {
72 CmdArgs.push_back("-dynamic-linker");
73 CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
74 }
75 CmdArgs.push_back("--hash-style=gnu");
76 CmdArgs.push_back("--enable-new-dtags");
77 }
78
79 // When building 32-bit code on DragonFly/pc64, we have to explicitly
80 // instruct ld in the base system to link 32-bit code.
81 if (getToolChain().getArch() == llvm::Triple::x86) {
82 CmdArgs.push_back("-m");
83 CmdArgs.push_back("elf_i386");
84 }
85
86 if (Output.isFilename()) {
87 CmdArgs.push_back("-o");
88 CmdArgs.push_back(Output.getFilename());
89 } else {
90 assert(Output.isNothing() && "Invalid output.");
91 }
92
93 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
94 if (!Args.hasArg(options::OPT_shared)) {
95 if (Args.hasArg(options::OPT_pg))
96 CmdArgs.push_back(
97 Args.MakeArgString(getToolChain().GetFilePath("gcrt1.o")));
98 else {
99 if (Args.hasArg(options::OPT_pie))
100 CmdArgs.push_back(
101 Args.MakeArgString(getToolChain().GetFilePath("Scrt1.o")));
102 else
103 CmdArgs.push_back(
104 Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
105 }
106 }
107 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
108 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
109 CmdArgs.push_back(
110 Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
111 else
112 CmdArgs.push_back(
113 Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
114 }
115
116 Args.AddAllArgs(CmdArgs,
117 {options::OPT_L, options::OPT_T_Group, options::OPT_e});
118
119 AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
120
121 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
122 CmdArgs.push_back("-L/usr/lib/gcc50");
123
124 if (!Args.hasArg(options::OPT_static)) {
125 CmdArgs.push_back("-rpath");
126 CmdArgs.push_back("/usr/lib/gcc50");
127 }
128
129 if (D.CCCIsCXX()) {
Nico Weber0ee47d92017-07-25 18:02:57 +0000130 if (getToolChain().ShouldLinkCXXStdlib(Args))
131 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
David L. Jonesf561aba2017-03-08 01:02:16 +0000132 CmdArgs.push_back("-lm");
133 }
134
135 if (Args.hasArg(options::OPT_pthread))
136 CmdArgs.push_back("-lpthread");
137
138 if (!Args.hasArg(options::OPT_nolibc)) {
139 CmdArgs.push_back("-lc");
140 }
141
142 if (Args.hasArg(options::OPT_static) ||
143 Args.hasArg(options::OPT_static_libgcc)) {
144 CmdArgs.push_back("-lgcc");
145 CmdArgs.push_back("-lgcc_eh");
146 } else {
147 if (Args.hasArg(options::OPT_shared_libgcc)) {
148 CmdArgs.push_back("-lgcc_pic");
149 if (!Args.hasArg(options::OPT_shared))
150 CmdArgs.push_back("-lgcc");
151 } else {
152 CmdArgs.push_back("-lgcc");
153 CmdArgs.push_back("--as-needed");
154 CmdArgs.push_back("-lgcc_pic");
155 CmdArgs.push_back("--no-as-needed");
156 }
157 }
158 }
159
160 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
161 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
162 CmdArgs.push_back(
163 Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
164 else
165 CmdArgs.push_back(
166 Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
167 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
168 }
169
170 getToolChain().addProfileRTLibs(Args, CmdArgs);
171
172 const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
173 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
174}
175
176/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
177
178DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
179 const ArgList &Args)
180 : Generic_ELF(D, Triple, Args) {
181
182 // Path mangling to find libexec
183 getProgramPaths().push_back(getDriver().getInstalledDir());
184 if (getDriver().getInstalledDir() != getDriver().Dir)
185 getProgramPaths().push_back(getDriver().Dir);
186
187 getFilePaths().push_back(getDriver().Dir + "/../lib");
188 getFilePaths().push_back("/usr/lib");
189 getFilePaths().push_back("/usr/lib/gcc50");
190}
191
192Tool *DragonFly::buildAssembler() const {
193 return new tools::dragonfly::Assembler(*this);
194}
195
196Tool *DragonFly::buildLinker() const {
197 return new tools::dragonfly::Linker(*this);
198}