Skip to content

Commit

Permalink
Bare metal 'ELF' toolchain that runs as and ld directly
Browse files Browse the repository at this point in the history
Sebastien Bourdeauducq committed May 29, 2012
1 parent 6797c47 commit ddbd2d4
Showing 7 changed files with 179 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/clang/Driver/HostInfo.h
Original file line number Diff line number Diff line change
@@ -65,6 +65,8 @@ class HostInfo {

const HostInfo *createAuroraUXHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createBareMetalHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createDarwinHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createOpenBSDHostInfo(const Driver &D,
3 changes: 3 additions & 0 deletions lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
@@ -1574,6 +1574,9 @@ const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
llvm::PrettyStackTraceString CrashInfo("Constructing host");
llvm::Triple Triple(llvm::Triple::normalize(TripleStr).c_str());

if (Triple.getEnvironment() == llvm::Triple::ELF)
return createBareMetalHostInfo(*this, Triple);

// TCE is an osless target
if (Triple.getArchName() == "tce")
return createTCEHostInfo(*this, Triple);
54 changes: 54 additions & 0 deletions lib/Driver/HostInfo.cpp
Original file line number Diff line number Diff line change
@@ -34,6 +34,54 @@ HostInfo::~HostInfo() {

namespace {

// Bare metal Host Info

/// BareMetalHostInfo - Bare metal host information implementation.
class BareMetalHostInfo : public HostInfo {
/// Cache of tool chains we have created.
mutable llvm::StringMap<ToolChain*> ToolChains;

public:
BareMetalHostInfo(const Driver &D, const llvm::Triple& Triple)
: HostInfo(D, Triple) {}
~BareMetalHostInfo();

virtual bool useDriverDriver() const;

virtual ToolChain *CreateToolChain(const ArgList &Args,
const char *ArchName) const;
};

BareMetalHostInfo::~BareMetalHostInfo() {
for (llvm::StringMap<ToolChain*>::iterator
it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it){
delete it->second;
}
}

bool BareMetalHostInfo::useDriverDriver() const {
return false;
}

ToolChain *BareMetalHostInfo::CreateToolChain(const ArgList &Args,
const char *ArchName) const {
assert(!ArchName &&
"Unexpected arch name on platform without driver driver support.");

std::string Arch = getArchName();
ArchName = Arch.c_str();

ToolChain *&TC = ToolChains[ArchName];
if (!TC) {
llvm::Triple TCTriple(getTriple());
TCTriple.setArchName(ArchName);

TC = new toolchains::BareMetal(*this, TCTriple);
}

return TC;
}

// Darwin Host Info

/// DarwinHostInfo - Darwin host information implementation.
@@ -669,6 +717,12 @@ clang::driver::createAuroraUXHostInfo(const Driver &D,
return new AuroraUXHostInfo(D, Triple);
}

const HostInfo *
clang::driver::createBareMetalHostInfo(const Driver &D,
const llvm::Triple& Triple) {
return new BareMetalHostInfo(D, Triple);
}

const HostInfo *
clang::driver::createDarwinHostInfo(const Driver &D,
const llvm::Triple& Triple){
30 changes: 30 additions & 0 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
@@ -1406,6 +1406,36 @@ const char *Generic_GCC::GetDefaultRelocationModel() const {
const char *Generic_GCC::GetForcedPicModel() const {
return 0;
}

/// BareMetal - Bare metal tool chain which can call as(1) and ld(1) directly.

BareMetal::BareMetal(const HostInfo &Host, const llvm::Triple& Triple)
: Generic_ELF(Host, Triple) {
}

Tool &BareMetal::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
Action::ActionClass Key;
if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Key = Action::AnalyzeJobClass;
else
Key = JA.getKind();

Tool *&T = Tools[Key];
if (!T) {
switch (Key) {
case Action::AssembleJobClass:
T = new tools::baremetal::Assemble(*this); break;
case Action::LinkJobClass:
T = new tools::baremetal::Link(*this); break;
default:
T = &Generic_GCC::SelectTool(C, JA, Inputs);
}
}

return *T;
}

/// Hexagon Toolchain

Hexagon_TC::Hexagon_TC(const HostInfo &Host, const llvm::Triple& Triple)
8 changes: 8 additions & 0 deletions lib/Driver/ToolChains.h
Original file line number Diff line number Diff line change
@@ -442,6 +442,14 @@ class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC {
const ActionList &Inputs) const;
};

class LLVM_LIBRARY_VISIBILITY BareMetal : public Generic_ELF {
public:
BareMetal(const HostInfo &Host, const llvm::Triple& Triple);

virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const;
};

class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF {
public:
OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
52 changes: 52 additions & 0 deletions lib/Driver/Tools.cpp
Original file line number Diff line number Diff line change
@@ -2659,6 +2659,58 @@ void gcc::Link::RenderExtraToolArgs(const JobAction &JA,
// The types are (hopefully) good enough.
}

/// Bare metal Tools

void baremetal::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
ArgStringList CmdArgs;

Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
options::OPT_Xassembler);

CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());

for (InputInfoList::const_iterator
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
const InputInfo &II = *it;
CmdArgs.push_back(II.getFilename());
}

const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("as"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}

void baremetal::Link::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
ArgStringList CmdArgs;

if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
} else {
assert(Output.isNothing() && "Invalid output.");
}

Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_e);

AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);

addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());

const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
}

// Hexagon tools start.
void hexagon::Assemble::RenderExtraToolArgs(const JobAction &JA,
ArgStringList &CmdArgs) const {
30 changes: 30 additions & 0 deletions lib/Driver/Tools.h
Original file line number Diff line number Diff line change
@@ -153,6 +153,36 @@ namespace gcc {
};
} // end namespace gcc

/// baremetal -- Directly call GNU Binutils assembler and linker
namespace baremetal {
class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
public:
Assemble(const ToolChain &TC) : Tool("baremetal::Assemble", "assembler",
TC) {}

virtual bool hasIntegratedCPP() const { return false; }

virtual void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &TCArgs,
const char *LinkingOutput) const;
};
class LLVM_LIBRARY_VISIBILITY Link : public Tool {
public:
Link(const ToolChain &TC) : Tool("baremetal::Link", "linker", TC) {}

virtual bool hasIntegratedCPP() const { return false; }

virtual void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &TCArgs,
const char *LinkingOutput) const;
};
} // end namespace baremetal


namespace hexagon {
// For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile and Compile.
// We simply use "clang -cc1" for those actions.

0 comments on commit ddbd2d4

Please sign in to comment.