Mercurial > projects > ldc
comparison gen/toobj.cpp @ 849:ba390e5e9150
Remove unportable env-sanitizing code. If it is really needed, it needs to be
rethought. Closes #131.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sun, 14 Dec 2008 16:30:06 +0100 |
parents | b972fec8a5f5 |
children | c1aeb2d0b559 |
comparison
equal
deleted
inserted
replaced
846:bc982f1ad106 | 849:ba390e5e9150 |
---|---|
58 // in gen/optimize.cpp | 58 // in gen/optimize.cpp |
59 void ldc_optimize_module(llvm::Module* m, char lvl, bool doinline); | 59 void ldc_optimize_module(llvm::Module* m, char lvl, bool doinline); |
60 | 60 |
61 // fwd decl | 61 // fwd decl |
62 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out); | 62 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out); |
63 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath, char** envp); | 63 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath); |
64 | 64 |
65 ////////////////////////////////////////////////////////////////////////////////////////// | 65 ////////////////////////////////////////////////////////////////////////////////////////// |
66 | 66 |
67 void Module::genobjfile(int multiobj, char** envp) | 67 void Module::genobjfile(int multiobj) |
68 { | 68 { |
69 bool logenabled = Logger::enabled(); | 69 bool logenabled = Logger::enabled(); |
70 if (llvmForceLogging && !logenabled) | 70 if (llvmForceLogging && !logenabled) |
71 { | 71 { |
72 Logger::enable(); | 72 Logger::enable(); |
259 } | 259 } |
260 | 260 |
261 // call gcc to convert assembly to object file | 261 // call gcc to convert assembly to object file |
262 if (global.params.output_o) { | 262 if (global.params.output_o) { |
263 LLPath objpath = LLPath(objfile->name->toChars()); | 263 LLPath objpath = LLPath(objfile->name->toChars()); |
264 assemble(spath, objpath, envp); | 264 assemble(spath, objpath); |
265 } | 265 } |
266 | 266 |
267 if (!global.params.output_s) { | 267 if (!global.params.output_s) { |
268 spath.eraseFromDisk(); | 268 spath.eraseFromDisk(); |
269 } | 269 } |
318 assert(rmod); | 318 assert(rmod); |
319 } | 319 } |
320 | 320 |
321 /* ================================================================== */ | 321 /* ================================================================== */ |
322 | 322 |
323 // helper functions for gcc call to assemble | |
324 // based on llvm-ld code, University of Illinois Open Source License | |
325 | |
326 /// CopyEnv - This function takes an array of environment variables and makes a | |
327 /// copy of it. This copy can then be manipulated any way the caller likes | |
328 /// without affecting the process's real environment. | |
329 /// | |
330 /// Inputs: | |
331 /// envp - An array of C strings containing an environment. | |
332 /// | |
333 /// Return value: | |
334 /// NULL - An error occurred. | |
335 /// | |
336 /// Otherwise, a pointer to a new array of C strings is returned. Every string | |
337 /// in the array is a duplicate of the one in the original array (i.e. we do | |
338 /// not copy the char *'s from one array to another). | |
339 /// | |
340 static char ** CopyEnv(char ** const envp) { | |
341 // Count the number of entries in the old list; | |
342 unsigned entries; // The number of entries in the old environment list | |
343 for (entries = 0; envp[entries] != NULL; entries++) | |
344 /*empty*/; | |
345 | |
346 // Add one more entry for the NULL pointer that ends the list. | |
347 ++entries; | |
348 | |
349 // If there are no entries at all, just return NULL. | |
350 if (entries == 0) | |
351 return NULL; | |
352 | |
353 // Allocate a new environment list. | |
354 char **newenv = new char* [entries]; | |
355 if ((newenv = new char* [entries]) == NULL) | |
356 return NULL; | |
357 | |
358 // Make a copy of the list. Don't forget the NULL that ends the list. | |
359 entries = 0; | |
360 while (envp[entries] != NULL) { | |
361 newenv[entries] = new char[strlen (envp[entries]) + 1]; | |
362 strcpy (newenv[entries], envp[entries]); | |
363 ++entries; | |
364 } | |
365 newenv[entries] = NULL; | |
366 | |
367 return newenv; | |
368 } | |
369 | |
370 // based on llvm-ld code, University of Illinois Open Source License | |
371 | |
372 /// RemoveEnv - Remove the specified environment variable from the environment | |
373 /// array. | |
374 /// | |
375 /// Inputs: | |
376 /// name - The name of the variable to remove. It cannot be NULL. | |
377 /// envp - The array of environment variables. It cannot be NULL. | |
378 /// | |
379 /// Notes: | |
380 /// This is mainly done because functions to remove items from the environment | |
381 /// are not available across all platforms. In particular, Solaris does not | |
382 /// seem to have an unsetenv() function or a setenv() function (or they are | |
383 /// undocumented if they do exist). | |
384 /// | |
385 static void RemoveEnv(const char * name, char ** const envp) { | |
386 for (unsigned index=0; envp[index] != NULL; index++) { | |
387 // Find the first equals sign in the array and make it an EOS character. | |
388 char *p = strchr (envp[index], '='); | |
389 if (p == NULL) | |
390 continue; | |
391 else | |
392 *p = '\0'; | |
393 | |
394 // Compare the two strings. If they are equal, zap this string. | |
395 // Otherwise, restore it. | |
396 if (!strcmp(name, envp[index])) | |
397 *envp[index] = '\0'; | |
398 else | |
399 *p = '='; | |
400 } | |
401 | |
402 return; | |
403 } | |
404 | |
405 // uses gcc to make an obj out of an assembly file | 323 // uses gcc to make an obj out of an assembly file |
406 // based on llvm-ld code, University of Illinois Open Source License | 324 // based on llvm-ld code, University of Illinois Open Source License |
407 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath, char** envp) | 325 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath) |
408 { | 326 { |
409 using namespace llvm; | 327 using namespace llvm; |
410 | 328 |
411 sys::Path gcc = llvm::sys::Program::FindProgramByName("gcc"); | 329 sys::Path gcc = llvm::sys::Program::FindProgramByName("gcc"); |
412 if (gcc.empty()) | 330 if (gcc.empty()) |
413 { | 331 { |
414 error("failed to locate gcc"); | 332 error("failed to locate gcc"); |
415 fatal(); | 333 fatal(); |
416 } | 334 } |
417 | |
418 // Remove these environment variables from the environment of the | |
419 // programs that we will execute. It appears that GCC sets these | |
420 // environment variables so that the programs it uses can configure | |
421 // themselves identically. | |
422 // | |
423 // However, when we invoke GCC below, we want it to use its normal | |
424 // configuration. Hence, we must sanitize its environment. | |
425 char ** clean_env = CopyEnv(envp); | |
426 if (clean_env == NULL) | |
427 return; | |
428 RemoveEnv("LIBRARY_PATH", clean_env); | |
429 RemoveEnv("COLLECT_GCC_OPTIONS", clean_env); | |
430 RemoveEnv("GCC_EXEC_PREFIX", clean_env); | |
431 RemoveEnv("COMPILER_PATH", clean_env); | |
432 RemoveEnv("COLLECT_GCC", clean_env); | |
433 | |
434 | 335 |
435 // Run GCC to assemble and link the program into native code. | 336 // Run GCC to assemble and link the program into native code. |
436 // | 337 // |
437 // Note: | 338 // Note: |
438 // We can't just assemble and link the file with the system assembler | 339 // We can't just assemble and link the file with the system assembler |
468 logstr << "\n" << std::flush; | 369 logstr << "\n" << std::flush; |
469 | 370 |
470 // Run the compiler to assembly the program. | 371 // Run the compiler to assembly the program. |
471 std::string ErrMsg; | 372 std::string ErrMsg; |
472 int R = sys::Program::ExecuteAndWait( | 373 int R = sys::Program::ExecuteAndWait( |
473 gcc, &Args[0], (const char**)clean_env, 0, 0, 0, &ErrMsg); | 374 gcc, &Args[0], 0, 0, 0, 0, &ErrMsg); |
474 if (R) | 375 if (R) |
475 { | 376 { |
476 error("failed to invoke gcc"); | 377 error("failed to invoke gcc"); |
477 fatal(); | 378 fatal(); |
478 } | 379 } |