Skip to content

Commit 085b257

Browse files
committed
[clang] Add managarm OS target
1 parent 9d681fd commit 085b257

File tree

7 files changed

+325
-0
lines changed

7 files changed

+325
-0
lines changed

clang/lib/Basic/Targets.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
159159
return std::make_unique<OHOSTargetInfo<AArch64leTargetInfo>>(Triple,
160160
Opts);
161161
}
162+
case llvm::Triple::Managarm:
163+
return std::make_unique<ManagarmTargetInfo<AArch64leTargetInfo>>(Triple,
164+
Opts);
162165
case llvm::Triple::NetBSD:
163166
return std::make_unique<NetBSDTargetInfo<AArch64leTargetInfo>>(Triple,
164167
Opts);
@@ -637,6 +640,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
637640
return std::make_unique<PS5OSTargetInfo<X86_64TargetInfo>>(Triple, Opts);
638641
case llvm::Triple::Hurd:
639642
return std::make_unique<HurdTargetInfo<X86_64TargetInfo>>(Triple, Opts);
643+
case llvm::Triple::Managarm:
644+
return std::make_unique<ManagarmTargetInfo<X86_64TargetInfo>>(Triple,
645+
Opts);
640646
default:
641647
return std::make_unique<X86_64TargetInfo>(Triple, Opts);
642648
}

clang/lib/Basic/Targets/OSTargets.h

+30
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,36 @@ class LLVM_LIBRARY_VISIBILITY LinuxTargetInfo : public OSTargetInfo<Target> {
373373
}
374374
};
375375

376+
// Managarm Target
377+
template <typename Target>
378+
class LLVM_LIBRARY_VISIBILITY ManagarmTargetInfo : public OSTargetInfo<Target> {
379+
protected:
380+
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
381+
MacroBuilder &Builder) const override {
382+
DefineStd(Builder, "unix", Opts);
383+
Builder.defineMacro("__managarm__");
384+
if (Opts.POSIXThreads)
385+
Builder.defineMacro("_REENTRANT");
386+
if (Opts.CPlusPlus)
387+
Builder.defineMacro("_GNU_SOURCE");
388+
if (this->HasFloat128)
389+
Builder.defineMacro("__FLOAT128__");
390+
}
391+
392+
public:
393+
ManagarmTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
394+
: OSTargetInfo<Target>(Triple, Opts) {
395+
switch (Triple.getArch()) {
396+
default:
397+
break;
398+
case llvm::Triple::x86:
399+
case llvm::Triple::x86_64:
400+
this->HasFloat128 = true;
401+
break;
402+
}
403+
}
404+
};
405+
376406
// NetBSD Target
377407
template <typename Target>
378408
class LLVM_LIBRARY_VISIBILITY NetBSDTargetInfo : public OSTargetInfo<Target> {

clang/lib/Driver/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ add_clang_library(clangDriver
6565
ToolChains/HLSL.cpp
6666
ToolChains/Hurd.cpp
6767
ToolChains/Linux.cpp
68+
ToolChains/Managarm.cpp
6869
ToolChains/MipsLinux.cpp
6970
ToolChains/MinGW.cpp
7071
ToolChains/MSP430.cpp

clang/lib/Driver/Driver.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "ToolChains/Linux.h"
3333
#include "ToolChains/MSP430.h"
3434
#include "ToolChains/MSVC.h"
35+
#include "ToolChains/Managarm.h"
3536
#include "ToolChains/MinGW.h"
3637
#include "ToolChains/MipsLinux.h"
3738
#include "ToolChains/NaCl.h"
@@ -6437,6 +6438,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
64376438
case llvm::Triple::Fuchsia:
64386439
TC = std::make_unique<toolchains::Fuchsia>(*this, Target, Args);
64396440
break;
6441+
case llvm::Triple::Managarm:
6442+
TC = std::make_unique<toolchains::Managarm>(*this, Target, Args);
6443+
break;
64406444
case llvm::Triple::Solaris:
64416445
TC = std::make_unique<toolchains::Solaris>(*this, Target, Args);
64426446
break;

clang/lib/Driver/ToolChains/Gnu.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
228228
return "elf_iamcu";
229229
return "elf_i386";
230230
case llvm::Triple::aarch64:
231+
if (T.isOSManagarm())
232+
return "aarch64managarm";
231233
return "aarch64linux";
232234
case llvm::Triple::aarch64_be:
233235
return "aarch64linuxb";
+227
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
//===--- Managarm.h - Managarm 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 "Managarm.h"
11+
#include "Arch/ARM.h"
12+
#include "Arch/RISCV.h"
13+
#include "CommonArgs.h"
14+
#include "clang/Config/config.h"
15+
#include "clang/Driver/Driver.h"
16+
#include "clang/Driver/Options.h"
17+
#include "clang/Driver/SanitizerArgs.h"
18+
#include "llvm/Option/ArgList.h"
19+
#include "llvm/Support/Path.h"
20+
21+
using namespace clang::driver;
22+
using namespace clang::driver::toolchains;
23+
using namespace clang;
24+
using namespace llvm::opt;
25+
26+
using tools::addPathIfExists;
27+
28+
std::string Managarm::getMultiarchTriple(const Driver &D,
29+
const llvm::Triple &TargetTriple,
30+
StringRef SysRoot) const {
31+
// For most architectures, just use whatever we have rather than trying to be
32+
// clever.
33+
switch (TargetTriple.getArch()) {
34+
default:
35+
break;
36+
37+
case llvm::Triple::x86_64:
38+
// We don't want this for x32, otherwise it will match x86_64 libs
39+
return "x86_64-managarm-" + TargetTriple.getEnvironmentName().str();
40+
case llvm::Triple::aarch64:
41+
return "aarch64-managarm-" + TargetTriple.getEnvironmentName().str();
42+
case llvm::Triple::riscv64:
43+
return "riscv64-managarm-" + TargetTriple.getEnvironmentName().str();
44+
}
45+
return TargetTriple.str();
46+
}
47+
48+
static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
49+
// It happens that only x86, PPC and SPARC use the 'lib32' variant of
50+
// oslibdir, and using that variant while targeting other architectures causes
51+
// problems because the libraries are laid out in shared system roots that
52+
// can't cope with a 'lib32' library search path being considered. So we only
53+
// enable them when we know we may need it.
54+
//
55+
// FIXME: This is a bit of a hack. We should really unify this code for
56+
// reasoning about oslibdir spellings with the lib dir spellings in the
57+
// GCCInstallationDetector, but that is a more significant refactoring.
58+
if (Triple.getArch() == llvm::Triple::x86 || Triple.isPPC32() ||
59+
Triple.getArch() == llvm::Triple::sparc)
60+
return "lib32";
61+
62+
if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32())
63+
return "libx32";
64+
65+
if (Triple.getArch() == llvm::Triple::riscv32)
66+
return "lib32";
67+
68+
return Triple.isArch32Bit() ? "lib" : "lib64";
69+
}
70+
71+
Managarm::Managarm(const Driver &D, const llvm::Triple &Triple,
72+
const ArgList &Args)
73+
: Generic_ELF(D, Triple, Args) {
74+
GCCInstallation.init(Triple, Args);
75+
Multilibs = GCCInstallation.getMultilibs();
76+
SelectedMultilibs.assign({GCCInstallation.getMultilib()});
77+
std::string SysRoot = computeSysRoot();
78+
79+
ToolChain::path_list &PPaths = getProgramPaths();
80+
81+
Generic_GCC::PushPPaths(PPaths);
82+
83+
#ifdef ENABLE_LINKER_BUILD_ID
84+
ExtraOpts.push_back("--build-id");
85+
#endif
86+
87+
// The selection of paths to try here is designed to match the patterns which
88+
// the GCC driver itself uses, as this is part of the GCC-compatible driver.
89+
// This was determined by running GCC in a fake filesystem, creating all
90+
// possible permutations of these directories, and seeing which ones it added
91+
// to the link paths.
92+
path_list &Paths = getFilePaths();
93+
94+
const std::string OSLibDir = std::string(getOSLibDir(Triple, Args));
95+
const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
96+
97+
Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths);
98+
99+
addPathIfExists(D, concat(SysRoot, "/lib", MultiarchTriple), Paths);
100+
addPathIfExists(D, concat(SysRoot, "/lib/..", OSLibDir), Paths);
101+
addPathIfExists(D, concat(SysRoot, "/usr/lib/", MultiarchTriple), Paths);
102+
addPathIfExists(D, concat(SysRoot, "/usr/lib/../", OSLibDir), Paths);
103+
104+
Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths);
105+
106+
addPathIfExists(D, SysRoot + "/lib", Paths);
107+
addPathIfExists(D, SysRoot + "/usr/lib", Paths);
108+
}
109+
110+
bool Managarm::HasNativeLLVMSupport() const { return true; }
111+
112+
Tool *Managarm::buildLinker() const {
113+
return new tools::gnutools::Linker(*this);
114+
}
115+
116+
Tool *Managarm::buildAssembler() const {
117+
return new tools::gnutools::Assembler(*this);
118+
}
119+
120+
std::string Managarm::computeSysRoot() const {
121+
if (!getDriver().SysRoot.empty())
122+
return getDriver().SysRoot;
123+
return std::string();
124+
}
125+
126+
std::string Managarm::getDynamicLinker(const ArgList &Args) const {
127+
switch (getTriple().getArch()) {
128+
case llvm::Triple::aarch64:
129+
return "/lib/aarch64-managarm/ld.so";
130+
case llvm::Triple::riscv64: {
131+
StringRef ABIName = tools::riscv::getRISCVABI(Args, getTriple());
132+
return ("/lib/riscv64-managarm/ld-riscv64-" + ABIName + ".so").str();
133+
}
134+
case llvm::Triple::x86_64:
135+
return "/lib/x86_64-managarm/ld.so";
136+
default:
137+
llvm_unreachable("unsupported architecture");
138+
}
139+
}
140+
141+
void Managarm::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
142+
ArgStringList &CC1Args) const {
143+
const Driver &D = getDriver();
144+
std::string SysRoot = computeSysRoot();
145+
146+
if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
147+
return;
148+
149+
if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
150+
addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
151+
152+
// Add 'include' in the resource directory, which is similar to
153+
// GCC_INCLUDE_DIR (private headers) in GCC.
154+
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
155+
SmallString<128> ResourceDirInclude(D.ResourceDir);
156+
llvm::sys::path::append(ResourceDirInclude, "include");
157+
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
158+
}
159+
160+
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
161+
return;
162+
163+
// TOOL_INCLUDE_DIR
164+
AddMultilibIncludeArgs(DriverArgs, CC1Args);
165+
166+
// Check for configure-time C include directories.
167+
StringRef CIncludeDirs(C_INCLUDE_DIRS);
168+
if (CIncludeDirs != "") {
169+
SmallVector<StringRef, 5> dirs;
170+
CIncludeDirs.split(dirs, ":");
171+
for (StringRef dir : dirs) {
172+
StringRef Prefix =
173+
llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
174+
addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
175+
}
176+
return;
177+
}
178+
179+
// On systems using multiarch, add /usr/include/$triple before
180+
// /usr/include.
181+
std::string MultiarchIncludeDir = getMultiarchTriple(D, getTriple(), SysRoot);
182+
if (!MultiarchIncludeDir.empty())
183+
addExternCSystemInclude(
184+
DriverArgs, CC1Args,
185+
concat(SysRoot, "/usr/include", MultiarchIncludeDir));
186+
187+
// Add an include of '/include' directly. This isn't provided by default by
188+
// system GCCs, but is often used with cross-compiling GCCs, and harmless to
189+
// add even when Clang is acting as-if it were a system compiler.
190+
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include"));
191+
192+
addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include"));
193+
}
194+
195+
void Managarm::addLibStdCxxIncludePaths(
196+
const llvm::opt::ArgList &DriverArgs,
197+
llvm::opt::ArgStringList &CC1Args) const {
198+
// We need a detected GCC installation on Managarm to provide libstdc++'s
199+
// headers.
200+
if (!GCCInstallation.isValid())
201+
return;
202+
203+
StringRef TripleStr = GCCInstallation.getTriple().str();
204+
205+
// Try generic GCC detection.
206+
Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, TripleStr);
207+
}
208+
209+
SanitizerMask Managarm::getSupportedSanitizers() const {
210+
const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
211+
const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
212+
SanitizerMask Res = ToolChain::getSupportedSanitizers();
213+
Res |= SanitizerKind::PointerCompare;
214+
Res |= SanitizerKind::PointerSubtract;
215+
Res |= SanitizerKind::KernelAddress;
216+
Res |= SanitizerKind::Vptr;
217+
if (IsX86_64)
218+
Res |= SanitizerKind::KernelMemory;
219+
if (IsX86 || IsX86_64)
220+
Res |= SanitizerKind::Function;
221+
return Res;
222+
}
223+
224+
void Managarm::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {
225+
for (const auto &Opt : ExtraOpts)
226+
CmdArgs.push_back(Opt.c_str());
227+
}
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===--- Managarm.h - Managarm 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+
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MANAGARM_H
11+
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MANAGARM_H
12+
13+
#include "Gnu.h"
14+
#include "clang/Driver/ToolChain.h"
15+
16+
namespace clang {
17+
namespace driver {
18+
namespace toolchains {
19+
20+
class LLVM_LIBRARY_VISIBILITY Managarm : public Generic_ELF {
21+
public:
22+
Managarm(const Driver &D, const llvm::Triple &Triple,
23+
const llvm::opt::ArgList &Args);
24+
25+
bool HasNativeLLVMSupport() const override;
26+
27+
std::string getMultiarchTriple(const Driver &D,
28+
const llvm::Triple &TargetTriple,
29+
StringRef SysRoot) const override;
30+
31+
void
32+
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
33+
llvm::opt::ArgStringList &CC1Args) const override;
34+
void
35+
addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
36+
llvm::opt::ArgStringList &CC1Args) const override;
37+
SanitizerMask getSupportedSanitizers() const override;
38+
std::string computeSysRoot() const override;
39+
40+
std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override;
41+
42+
void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override;
43+
44+
std::vector<std::string> ExtraOpts;
45+
46+
protected:
47+
Tool *buildAssembler() const override;
48+
Tool *buildLinker() const override;
49+
};
50+
51+
} // end namespace toolchains
52+
} // end namespace driver
53+
} // end namespace clang
54+
55+
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MANAGARM_H

0 commit comments

Comments
 (0)