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
  • Loading branch information
Sebastien Bourdeauducq committed May 29, 2012
1 parent 6797c47 commit ddbd2d4
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/clang/Driver/HostInfo.h
Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions lib/Driver/Driver.cpp
Expand Up @@ -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);
Expand Down
54 changes: 54 additions & 0 deletions lib/Driver/HostInfo.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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){
Expand Down
30 changes: 30 additions & 0 deletions lib/Driver/ToolChains.cpp
Expand Up @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions lib/Driver/ToolChains.h
Expand Up @@ -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);
Expand Down
52 changes: 52 additions & 0 deletions lib/Driver/Tools.cpp
Expand Up @@ -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 {
Expand Down
30 changes: 30 additions & 0 deletions lib/Driver/Tools.h
Expand Up @@ -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.
Expand Down

0 comments on commit ddbd2d4

Please sign in to comment.