Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: src/IceBrowserCompileServer.cpp

Issue 1903553004: Subzero: Allow overriding command-line args from the browser. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Code review changes Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceBrowserCompileServer.h ('k') | src/IceClFlags.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceBrowserCompileServer.cpp - Browser compile server ---===// 1 //===- subzero/src/IceBrowserCompileServer.cpp - Browser compile server ---===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
11 /// \brief Defines the browser-based compile server. 11 /// \brief Defines the browser-based compile server.
12 /// 12 ///
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 // Can only compile this with the NaCl compiler (needs irt.h, and the 15 // Can only compile this with the NaCl compiler (needs irt.h, and the
16 // unsandboxed LLVM build using the trusted compiler does not have irt.h). 16 // unsandboxed LLVM build using the trusted compiler does not have irt.h).
17 #include "IceBrowserCompileServer.h" 17 #include "IceBrowserCompileServer.h"
18 #include "IceRangeSpec.h"
18 19
19 #if PNACL_BROWSER_TRANSLATOR 20 #if PNACL_BROWSER_TRANSLATOR
20 21
21 // Headers which are not properly part of the SDK are included by their path in 22 // Headers which are not properly part of the SDK are included by their path in
22 // the NaCl tree. 23 // the NaCl tree.
23 #ifdef __pnacl__ 24 #ifdef __pnacl__
24 #include "native_client/src/untrusted/nacl/pnacl.h" 25 #include "native_client/src/untrusted/nacl/pnacl.h"
25 #endif // __pnacl__ 26 #endif // __pnacl__
26 27
27 #include "llvm/Support/QueueStreamer.h" 28 #include "llvm/Support/QueueStreamer.h"
28 29
29 #include <cstring> 30 #include <cstring>
31 #include <fstream>
30 #include <irt.h> 32 #include <irt.h>
31 #include <irt_dev.h> 33 #include <irt_dev.h>
32 #include <pthread.h> 34 #include <pthread.h>
33 #include <thread> 35 #include <thread>
34 36
35 namespace Ice { 37 namespace Ice {
36 38
37 // Create C wrappers around callback handlers for the IRT interface. 39 // Create C wrappers around callback handlers for the IRT interface.
38 namespace { 40 namespace {
39 41
40 BrowserCompileServer *gCompileServer; 42 BrowserCompileServer *gCompileServer;
41 struct nacl_irt_private_pnacl_translator_compile gIRTFuncs; 43 struct nacl_irt_private_pnacl_translator_compile gIRTFuncs;
42 44
43 void getIRTInterfaces() { 45 void getIRTInterfaces() {
44 size_t QueryResult = 46 size_t QueryResult =
45 nacl_interface_query(NACL_IRT_PRIVATE_PNACL_TRANSLATOR_COMPILE_v0_1, 47 nacl_interface_query(NACL_IRT_PRIVATE_PNACL_TRANSLATOR_COMPILE_v0_1,
46 &gIRTFuncs, sizeof(gIRTFuncs)); 48 &gIRTFuncs, sizeof(gIRTFuncs));
47 if (QueryResult != sizeof(gIRTFuncs)) 49 if (QueryResult != sizeof(gIRTFuncs))
48 llvm::report_fatal_error("Failed to get translator compile IRT interface"); 50 llvm::report_fatal_error("Failed to get translator compile IRT interface");
49 } 51 }
50 52
53 // Allow pnacl-sz arguments to be supplied externally, instead of coming from
54 // the browser. This is meant to be used for debugging.
55 //
56 // If the SZARGFILE environment variable is set to a file name, arguments are
57 // read from that file, one argument per line. This requires setting 3
58 // environment variables before starting the browser:
59 //
60 // NACL_ENV_PASSTHROUGH=NACL_DANGEROUS_ENABLE_FILE_ACCESS,NACLENV_SZARGFILE
61 // NACL_DANGEROUS_ENABLE_FILE_ACCESS=1
62 // NACLENV_SZARGFILE=/path/to/myargs.txt
63 //
64 // In addition, Chrome needs to be launched with the "--no-sandbox" argument.
65 //
66 // If the SZARGLIST environment variable is set, arguments are extracted from
67 // that variable's value, separated by the '|' character (being careful to
68 // escape/quote special shell characters). This requires setting 2 environment
69 // variables before starting the browser:
70 //
71 // NACL_ENV_PASSTHROUGH=NACLENV_SZARGLIST
72 // NACLENV_SZARGLIST=arg
73 //
74 // This does not require the "--no-sandbox" argument, and is therefore much
75 // safer, but does require restarting the browser to change the arguments.
76 //
77 // If external arguments are supplied, the browser's NumThreads specification is
78 // ignored, to allow -threads to be specified as an external argument. Note
79 // that the browser normally supplies the "-O2" argument, so externally supplied
80 // arguments might want to provide an explicit -O argument.
81 std::vector<std::string> getExternalArgs() {
82 std::vector<std::string> ExternalArgs;
83 if (BuildDefs::minimal())
84 return ExternalArgs;
85 char ArgsFileVar[] = "SZARGFILE";
86 char ArgsListVar[] = "SZARGLIST";
87 if (const char *ArgsFilename = getenv(ArgsFileVar)) {
88 std::ifstream ArgsStream(ArgsFilename);
89 std::string Arg;
90 while (ArgsStream >> std::ws, std::getline(ArgsStream, Arg)) {
91 if (!Arg.empty() && Arg[0] == '#')
92 continue;
93 ExternalArgs.emplace_back(Arg);
94 }
95 if (ExternalArgs.empty()) {
96 llvm::report_fatal_error("Failed to read arguments from file '" +
97 std::string(ArgsFilename) + "'");
98 }
99 } else if (const char *ArgsList = getenv(ArgsListVar)) {
100 // Leverage the RangeSpec tokenizer.
101 auto Args = RangeSpec::tokenize(ArgsList, '|');
102 ExternalArgs.insert(ExternalArgs.end(), Args.begin(), Args.end());
103 }
104 return ExternalArgs;
105 }
106
51 char *onInitCallback(uint32_t NumThreads, int *ObjFileFDs, 107 char *onInitCallback(uint32_t NumThreads, int *ObjFileFDs,
52 size_t ObjFileFDCount, char **CLArgs, size_t CLArgsLen) { 108 size_t ObjFileFDCount, char **CLArgs, size_t CLArgsLen) {
53 if (ObjFileFDCount < 1) { 109 if (ObjFileFDCount < 1) {
54 std::string Buffer; 110 std::string Buffer;
55 llvm::raw_string_ostream StrBuf(Buffer); 111 llvm::raw_string_ostream StrBuf(Buffer);
56 StrBuf << "Invalid number of FDs for onInitCallback " << ObjFileFDCount 112 StrBuf << "Invalid number of FDs for onInitCallback " << ObjFileFDCount
57 << "\n"; 113 << "\n";
58 return strdup(StrBuf.str().c_str()); 114 return strdup(StrBuf.str().c_str());
59 } 115 }
60 int ObjFileFD = ObjFileFDs[0]; 116 int ObjFileFD = ObjFileFDs[0];
61 if (ObjFileFD < 0) { 117 if (ObjFileFD < 0) {
62 std::string Buffer; 118 std::string Buffer;
63 llvm::raw_string_ostream StrBuf(Buffer); 119 llvm::raw_string_ostream StrBuf(Buffer);
64 StrBuf << "Invalid FD given for onInitCallback " << ObjFileFD << "\n"; 120 StrBuf << "Invalid FD given for onInitCallback " << ObjFileFD << "\n";
65 return strdup(StrBuf.str().c_str()); 121 return strdup(StrBuf.str().c_str());
66 } 122 }
67 // CLArgs is almost an "argv", but is missing the argv[0] program name. 123 // CLArgs is almost an "argv", but is missing the argv[0] program name.
68 std::vector<char *> Argv; 124 std::vector<const char *> Argv;
69 char ProgramName[] = "pnacl-sz.nexe"; 125 constexpr static char ProgramName[] = "pnacl-sz.nexe";
70 Argv.reserve(CLArgsLen + 1); 126 Argv.reserve(CLArgsLen + 1);
71 Argv.push_back(ProgramName); 127 Argv.push_back(ProgramName);
72 for (size_t i = 0; i < CLArgsLen; ++i) { 128
73 Argv.push_back(CLArgs[i]); 129 bool UseNumThreadsFromBrowser = true;
130 auto ExternalArgs = getExternalArgs();
131 if (ExternalArgs.empty()) {
132 for (size_t i = 0; i < CLArgsLen; ++i) {
133 Argv.push_back(CLArgs[i]);
134 }
135 } else {
136 for (auto &Arg : ExternalArgs) {
137 Argv.emplace_back(Arg.c_str());
138 }
139 UseNumThreadsFromBrowser = false;
74 } 140 }
75 // NOTE: strings pointed to by argv are owned by the caller, but we parse 141 // NOTE: strings pointed to by argv are owned by the caller, but we parse
76 // here before returning and don't store them. 142 // here before returning and don't store them.
77 gCompileServer->getParsedFlags(NumThreads, Argv.size(), Argv.data()); 143 gCompileServer->getParsedFlags(UseNumThreadsFromBrowser, NumThreads,
144 Argv.size(), Argv.data());
78 gCompileServer->startCompileThread(ObjFileFD); 145 gCompileServer->startCompileThread(ObjFileFD);
79 return nullptr; 146 return nullptr;
80 } 147 }
81 148
82 int onDataCallback(const void *Data, size_t NumBytes) { 149 int onDataCallback(const void *Data, size_t NumBytes) {
83 return gCompileServer->pushInputBytes(Data, NumBytes) ? 1 : 0; 150 return gCompileServer->pushInputBytes(Data, NumBytes) ? 1 : 0;
84 } 151 }
85 152
86 char *onEndCallback() { 153 char *onEndCallback() {
87 gCompileServer->endInputStream(); 154 gCompileServer->endInputStream();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 } // end of anonymous namespace 222 } // end of anonymous namespace
156 223
157 BrowserCompileServer::~BrowserCompileServer() = default; 224 BrowserCompileServer::~BrowserCompileServer() = default;
158 225
159 void BrowserCompileServer::run() { 226 void BrowserCompileServer::run() {
160 gCompileServer = this; 227 gCompileServer = this;
161 getIRTInterfaces(); 228 getIRTInterfaces();
162 gIRTFuncs.serve_translate_request(&SubzeroCallbacks); 229 gIRTFuncs.serve_translate_request(&SubzeroCallbacks);
163 } 230 }
164 231
165 void BrowserCompileServer::getParsedFlags(uint32_t NumThreads, int argc, 232 void BrowserCompileServer::getParsedFlags(bool UseNumThreadsFromBrowser,
166 char **argv) { 233 uint32_t NumThreads, int argc,
234 const char *const *argv) {
167 ClFlags::parseFlags(argc, argv); 235 ClFlags::parseFlags(argc, argv);
168 ClFlags::getParsedClFlags(ClFlags::Flags); 236 ClFlags::getParsedClFlags(ClFlags::Flags);
169 // Set some defaults which aren't specified via the argv string. 237 // Set some defaults which aren't specified via the argv string.
170 ClFlags::Flags.setNumTranslationThreads(NumThreads); 238 if (UseNumThreadsFromBrowser)
239 ClFlags::Flags.setNumTranslationThreads(NumThreads);
171 ClFlags::Flags.setUseSandboxing(true); 240 ClFlags::Flags.setUseSandboxing(true);
172 ClFlags::Flags.setOutFileType(FT_Elf); 241 ClFlags::Flags.setOutFileType(FT_Elf);
173 ClFlags::Flags.setTargetArch(getTargetArch()); 242 ClFlags::Flags.setTargetArch(getTargetArch());
174 ClFlags::Flags.setInputFileFormat(llvm::PNaClFormat); 243 ClFlags::Flags.setInputFileFormat(llvm::PNaClFormat);
175 } 244 }
176 245
177 bool BrowserCompileServer::pushInputBytes(const void *Data, size_t NumBytes) { 246 bool BrowserCompileServer::pushInputBytes(const void *Data, size_t NumBytes) {
178 // If there was an earlier error, do not attempt to push bytes to the 247 // If there was an earlier error, do not attempt to push bytes to the
179 // QueueStreamer. Otherwise the thread could become blocked. 248 // QueueStreamer. Otherwise the thread could become blocked.
180 if (HadError.load()) 249 if (HadError.load())
(...skipping 18 matching lines...) Expand all
199 // some error category. 268 // some error category.
200 LastError.assign(EC_Translation); 269 LastError.assign(EC_Translation);
201 } 270 }
202 return LastError; 271 return LastError;
203 } 272 }
204 273
205 void BrowserCompileServer::endInputStream() { InputStream->SetDone(); } 274 void BrowserCompileServer::endInputStream() { InputStream->SetDone(); }
206 275
207 void BrowserCompileServer::startCompileThread(int ObjFD) { 276 void BrowserCompileServer::startCompileThread(int ObjFD) {
208 InputStream = new llvm::QueueStreamer(); 277 InputStream = new llvm::QueueStreamer();
209 LogStream = getOutputStream(STDOUT_FILENO); 278 bool LogStreamFailure = false;
279 int LogFD = STDOUT_FILENO;
280 if (getFlags().getLogFilename() == "/dev/stderr") {
281 LogFD = STDERR_FILENO;
282 } else {
283 LogStreamFailure = true;
284 }
285 LogStream = getOutputStream(LogFD);
210 LogStream->SetUnbuffered(); 286 LogStream->SetUnbuffered();
287 if (LogStreamFailure) {
288 *LogStream
289 << "Warning: Log file name must be either '-' or '/dev/stderr'\n";
290 }
211 EmitStream = getOutputStream(ObjFD); 291 EmitStream = getOutputStream(ObjFD);
212 EmitStream->SetBufferSize(1 << 14); 292 EmitStream->SetBufferSize(1 << 14);
213 std::unique_ptr<StringStream> ErrStrm(new StringStream()); 293 std::unique_ptr<StringStream> ErrStrm(new StringStream());
214 ErrorStream = std::move(ErrStrm); 294 ErrorStream = std::move(ErrStrm);
215 ELFStream.reset(new ELFStreamer(*EmitStream.get())); 295 ELFStream.reset(new ELFStreamer(*EmitStream.get()));
216 Ctx.reset(new GlobalContext(LogStream.get(), EmitStream.get(), 296 Ctx.reset(new GlobalContext(LogStream.get(), EmitStream.get(),
217 &ErrorStream->getStream(), ELFStream.get())); 297 &ErrorStream->getStream(), ELFStream.get()));
218 CompileThread = std::thread([this]() { 298 CompileThread = std::thread([this]() {
219 llvm::install_fatal_error_handler(fatalErrorHandler, this); 299 llvm::install_fatal_error_handler(fatalErrorHandler, this);
220 Ctx->initParserThread(); 300 Ctx->initParserThread();
(...skipping 18 matching lines...) Expand all
239 llvm::report_fatal_error("no browser hookups"); 319 llvm::report_fatal_error("no browser hookups");
240 } 320 }
241 321
242 ErrorCode &BrowserCompileServer::getErrorCode() { 322 ErrorCode &BrowserCompileServer::getErrorCode() {
243 llvm::report_fatal_error("no browser hookups"); 323 llvm::report_fatal_error("no browser hookups");
244 } 324 }
245 325
246 } // end of namespace Ice 326 } // end of namespace Ice
247 327
248 #endif // PNACL_BROWSER_TRANSLATOR 328 #endif // PNACL_BROWSER_TRANSLATOR
OLDNEW
« no previous file with comments | « src/IceBrowserCompileServer.h ('k') | src/IceClFlags.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698