Index: src/llvm2ice.cpp |
diff --git a/src/llvm2ice.cpp b/src/llvm2ice.cpp |
index a28b07f924c61a3b9dd45a17a72f30746014e27c..4caa6b84b250cfd38478c5eeb90b0ae74a53d745 100644 |
--- a/src/llvm2ice.cpp |
+++ b/src/llvm2ice.cpp |
@@ -20,6 +20,7 @@ |
#include "llvm/IR/LLVMContext.h" |
#include "llvm/IRReader/IRReader.h" |
#include "llvm/Support/CommandLine.h" |
+#include "llvm/Support/FileSystem.h" |
#include "llvm/Support/raw_os_ostream.h" |
#include "llvm/Support/SourceMgr.h" |
@@ -173,6 +174,11 @@ static cl::opt<bool> |
static cl::alias UseIas("ias", cl::desc("Alias for -integrated-as"), |
cl::NotHidden, cl::aliasopt(UseIntegratedAssembler)); |
+static cl::opt<bool> |
+ UseELFWriter("elf-writer", |
+ cl::desc("Use ELF writer with the integrated assembler"), |
+ cl::init(false)); |
+ |
static cl::opt<bool> AlwaysExitSuccess( |
"exit-success", cl::desc("Exit with success status, even if errors found"), |
cl::init(false)); |
@@ -200,7 +206,7 @@ static struct { |
// Validates values of build attributes. Prints them to Stream if |
// Stream is non-null. |
-static void ValidateAndGenerateBuildAttributes(raw_os_ostream *Stream) { |
+static void ValidateAndGenerateBuildAttributes(Ice::Ostream *Stream) { |
if (Stream) |
*Stream << TargetArch << "\n"; |
@@ -242,25 +248,20 @@ int main(int argc, char **argv) { |
VMask |= VerboseList[i]; |
} |
- std::ofstream Ofs; |
- if (OutputFilename != "-") { |
- Ofs.open(OutputFilename.c_str(), std::ofstream::out); |
- } |
- raw_os_ostream *Os = |
- new raw_os_ostream(OutputFilename == "-" ? std::cout : Ofs); |
- Os->SetUnbuffered(); |
- |
- ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Os : nullptr); |
- if (GenerateBuildAtts) |
- return GetReturnValue(0); |
- |
std::ofstream Lfs; |
+ std::unique_ptr<Ice::Ostream> Ls; |
if (LogFilename != "-") { |
Lfs.open(LogFilename.c_str(), std::ofstream::out); |
+ Ls.reset(new raw_os_ostream(Lfs)); |
+ } else { |
+ Ls.reset(new raw_os_ostream(std::cout)); |
} |
- raw_os_ostream *Ls = new raw_os_ostream(LogFilename == "-" ? std::cout : Lfs); |
Ls->SetUnbuffered(); |
+ ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Ls.get() : nullptr); |
+ if (GenerateBuildAtts) |
+ return GetReturnValue(0); |
+ |
if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) { |
*Ls << "Error: Build doesn't allow --no-ir-gen when not " |
<< "ALLOW_DISABLE_IR_GEN!\n"; |
@@ -274,6 +275,7 @@ int main(int argc, char **argv) { |
Flags.FunctionSections = FunctionSections; |
Flags.DataSections = DataSections; |
Flags.UseIntegratedAssembler = UseIntegratedAssembler; |
+ Flags.UseELFWriter = UseELFWriter; |
Flags.UseSandboxing = UseSandboxing; |
Flags.PhiEdgeSplit = EnablePhiEdgeSplit; |
Flags.DecorateAsm = DecorateAsm; |
@@ -294,11 +296,45 @@ int main(int argc, char **argv) { |
LLSuffix.length(), LLSuffix) == 0) |
BuildOnRead = false; |
- Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix, |
- Flags); |
+ // With the ELF writer, use a raw_fd_ostream to allow seeking. |
+ // Also don't buffer, otherwise it gets pretty slow. |
+ std::unique_ptr<Ice::Ostream> Os; |
+ std::unique_ptr<Ice::ELFStreamer> ELFStr; |
+ std::ofstream Ofs; |
+ if (UseELFWriter) { |
+ if (OutputFilename == "-") { |
+ *Ls << "Error: writing binary ELF to stdout is unsupported\n"; |
+ return GetReturnValue(1); |
+ } |
+ std::string ErrorInfo; |
+ raw_fd_ostream *FdOs = |
+ new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, sys::fs::F_None); |
+ Os.reset(FdOs); |
+ if (!ErrorInfo.empty()) { |
+ *Ls << "Failed to open output file: " << OutputFilename << ":\n" |
+ << ErrorInfo << "\n"; |
+ return GetReturnValue(1); |
+ } |
+ ELFStr.reset(new Ice::ELFStreamer(*FdOs)); |
+ } else { |
+ if (OutputFilename != "-") { |
+ Ofs.open(OutputFilename.c_str(), std::ofstream::out); |
+ Os.reset(new raw_os_ostream(Ofs)); |
+ } else { |
+ Os.reset(new raw_os_ostream(std::cout)); |
+ } |
+ Os->SetUnbuffered(); |
+ } |
+ |
+ Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TargetArch, |
+ OptLevel, TestPrefix, Flags); |
Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); |
+ if (UseELFWriter) { |
+ Ctx.getObjectWriter()->writeInitialELFHeader(); |
+ } |
+ |
int ErrorStatus = 0; |
if (BuildOnRead) { |
Ice::PNaClTranslator Translator(&Ctx, Flags); |
@@ -324,6 +360,9 @@ int main(int argc, char **argv) { |
<< "--build-on-read=0 not allowed\n"; |
return GetReturnValue(1); |
} |
+ if (UseELFWriter) { |
+ Ctx.getObjectWriter()->writeNonUserSections(); |
+ } |
if (SubzeroTimingEnabled) |
Ctx.dumpTimers(); |
if (TimeEachFunction) { |