X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fgold%2Fgold-plugin.cpp;h=0214c139349b88a3f90144fc6e9c602f8370e1e5;hb=e4f1a9b8a272ff7452759019ee7774e9dbdf1568;hp=c8542b1752019a932ae4108e21a108ae346265b2;hpb=dd76f18f90f3d9934353d852e45271b3be747743;p=oota-llvm.git diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index c8542b17520..0214c139349 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -17,7 +17,7 @@ #include "llvm-c/lto.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/ToolOutputFile.h" #include "llvm/System/Errno.h" #include "llvm/System/Path.h" #include "llvm/System/Program.h" @@ -42,6 +42,7 @@ namespace { ld_plugin_get_symbols get_symbols = NULL; ld_plugin_add_input_file add_input_file = NULL; ld_plugin_add_input_library add_input_library = NULL; + ld_plugin_set_extra_library_path set_extra_library_path = NULL; ld_plugin_message message = discard_message; int api_version = 0; @@ -65,7 +66,11 @@ namespace options { static generate_bc generate_bc_file = BC_NO; static std::string bc_path; static std::string as_path; + static std::vector as_args; static std::vector pass_through; + static std::string extra_library_path; + static std::string triple; + static std::string mcpu; // Additional options to pass into the code generator. // Note: This array will contain all plugin options which are not claimed // as plugin exclusive to pass to the code generator. @@ -81,6 +86,8 @@ namespace options { if (opt == "generate-api-file") { generate_api_file = true; + } else if (opt.startswith("mcpu=")) { + mcpu = opt.substr(strlen("mcpu=")); } else if (opt.startswith("as=")) { if (!as_path.empty()) { (*message)(LDPL_WARNING, "Path to as specified twice. " @@ -88,9 +95,16 @@ namespace options { } else { as_path = opt.substr(strlen("as=")); } + } else if (opt.startswith("as-arg=")) { + llvm::StringRef item = opt.substr(strlen("as-arg=")); + as_args.push_back(item.str()); + } else if (opt.startswith("extra-library-path=")) { + extra_library_path = opt.substr(strlen("extra_library_path=")); } else if (opt.startswith("pass-through=")) { llvm::StringRef item = opt.substr(strlen("pass-through=")); pass_through.push_back(item.str()); + } else if (opt.startswith("mtriple=")) { + triple = opt.substr(strlen("mtriple=")); } else if (opt == "emit-llvm") { generate_bc_file = BC_ONLY; } else if (opt == "also-emit-llvm") { @@ -125,8 +139,6 @@ ld_plugin_status onload(ld_plugin_tv *tv) { // for services. bool registeredClaimFile = false; - bool registeredAllSymbolsRead = false; - bool registeredCleanup = false; for (; tv->tv_tag != LDPT_NULL; ++tv) { switch (tv->tv_tag) { @@ -174,8 +186,6 @@ ld_plugin_status onload(ld_plugin_tv *tv) { if ((*callback)(all_symbols_read_hook) != LDPS_OK) return LDPS_ERR; - - registeredAllSymbolsRead = true; } break; case LDPT_REGISTER_CLEANUP_HOOK: { ld_plugin_register_cleanup callback; @@ -183,8 +193,6 @@ ld_plugin_status onload(ld_plugin_tv *tv) { if ((*callback)(cleanup_hook) != LDPS_OK) return LDPS_ERR; - - registeredCleanup = true; } break; case LDPT_ADD_SYMBOLS: add_symbols = tv->tv_u.tv_add_symbols; @@ -198,6 +206,9 @@ ld_plugin_status onload(ld_plugin_tv *tv) { case LDPT_ADD_INPUT_LIBRARY: add_input_library = tv->tv_u.tv_add_input_file; break; + case LDPT_SET_EXTRA_LIBRARY_PATH: + set_extra_library_path = tv->tv_u.tv_set_extra_library_path; + break; case LDPT_MESSAGE: message = tv->tv_u.tv_message; break; @@ -269,6 +280,10 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, lto_get_error_message()); return LDPS_ERR; } + + if (!options::triple.empty()) + lto_module_set_target_triple(cf.M, options::triple.c_str()); + cf.handle = file->handle; unsigned sym_count = lto_module_get_num_symbols(cf.M); cf.syms.reserve(sym_count); @@ -393,6 +408,17 @@ static ld_plugin_status all_symbols_read_hook(void) { sys::Path p = sys::Program::FindProgramByName(options::as_path); lto_codegen_set_assembler_path(cg, p.c_str()); } + if (!options::as_args.empty()) { + std::vector as_args_p; + for (std::vector::iterator I = options::as_args.begin(), + E = options::as_args.end(); I != E; ++I) { + as_args_p.push_back(I->c_str()); + } + lto_codegen_set_assembler_args(cg, &as_args_p[0], as_args_p.size()); + } + if (!options::mcpu.empty()) + lto_codegen_set_cpu(cg, options::mcpu.c_str()); + // Pass through extra options to the code generator. if (!options::extra.empty()) { for (std::vector::iterator it = options::extra.begin(); @@ -427,29 +453,42 @@ static ld_plugin_status all_symbols_read_hook(void) { (*message)(LDPL_ERROR, "%s", ErrMsg.c_str()); return LDPS_ERR; } - raw_fd_ostream objFile(uniqueObjPath.c_str(), ErrMsg, - raw_fd_ostream::F_Binary); + tool_output_file objFile(uniqueObjPath.c_str(), ErrMsg, + raw_fd_ostream::F_Binary); if (!ErrMsg.empty()) { (*message)(LDPL_ERROR, "%s", ErrMsg.c_str()); return LDPS_ERR; } - objFile.write(buffer, bufsize); - objFile.close(); + objFile.os().write(buffer, bufsize); + objFile.os().close(); + if (objFile.os().has_error()) { + (*message)(LDPL_ERROR, "Error writing output file '%s'", + uniqueObjPath.c_str()); + objFile.os().clear_error(); + return LDPS_ERR; + } + objFile.keep(); lto_codegen_dispose(cg); - if ((*add_input_file)(const_cast(uniqueObjPath.c_str())) != LDPS_OK) { + if ((*add_input_file)(uniqueObjPath.c_str()) != LDPS_OK) { (*message)(LDPL_ERROR, "Unable to add .o file to the link."); (*message)(LDPL_ERROR, "File left behind in: %s", uniqueObjPath.c_str()); return LDPS_ERR; } + if (!options::extra_library_path.empty() && + set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK) { + (*message)(LDPL_ERROR, "Unable to set the extra library path."); + return LDPS_ERR; + } + for (std::vector::iterator i = options::pass_through.begin(), e = options::pass_through.end(); i != e; ++i) { std::string &item = *i; - char *item_p = const_cast(item.c_str()); + const char *item_p = item.c_str(); if (llvm::StringRef(item).startswith("-l")) { if (add_input_library(item_p + 2) != LDPS_OK) { (*message)(LDPL_ERROR, "Unable to add library to the link.");