gold-plugin.cpp revision cbb170d057aa6692b19f577b1e09a6c1c7a26969
13e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky//===-- gold-plugin.cpp - Plugin to gold for Link Time Optimization ------===// 23e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// 33e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// The LLVM Compiler Infrastructure 43e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// 53e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// This file is distributed under the University of Illinois Open Source 63e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// License. See LICENSE.TXT for details. 73e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// 83e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky//===----------------------------------------------------------------------===// 93e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// 103e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// This is a gold plugin for LLVM. It provides an LLVM implementation of the 113e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// interface described in http://gcc.gnu.org/wiki/whopr/driver . 123e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky// 133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky//===----------------------------------------------------------------------===// 143e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1509b5d90429258f92f5e5ac98411a71460bcd9230Duncan Sands#include "llvm/Config/config.h" 163e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include "plugin-api.h" 173e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 183e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include "llvm-c/lto.h" 193e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 203e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include "llvm/Support/raw_ostream.h" 21ed1c0ffe0b2287deaee7cba7506c93aa34c6d4b7Jeffrey Yasskin#include "llvm/System/Errno.h" 223e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include "llvm/System/Path.h" 2342de34f013ee15377dd78aa0d827100166cb66c9Rafael Espindola#include "llvm/System/Program.h" 243e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 256cbbdfd2e900164beeb34513a25d88cc58e582b0Torok Edwin#include <cerrno> 263e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <cstdlib> 273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <cstring> 28ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky#include <fstream> 293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <list> 303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <vector> 313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyusing namespace llvm; 333e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckynamespace { 353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_status discard_message(int level, const char *format, ...) { 363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // Die loudly. Recent versions of Gold pass ld_plugin_message as the first 373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // callback in the transfer vector. This should never be called. 383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky abort(); 393e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_add_symbols add_symbols = NULL; 423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_get_symbols get_symbols = NULL; 433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_add_input_file add_input_file = NULL; 44dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola ld_plugin_add_input_library add_input_library = NULL; 4511f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola ld_plugin_set_extra_library_path set_extra_library_path = NULL; 463e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_message message = discard_message; 473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int api_version = 0; 493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int gold_version = 0; 503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky struct claimed_file { 523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_module_t M; 533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky void *handle; 543e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::vector<ld_plugin_symbol> syms; 553e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky }; 563e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_model output_type = LTO_CODEGEN_PIC_MODEL_STATIC; 58c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola std::string output_name = ""; 593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::list<claimed_file> Modules; 603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::vector<sys::Path> Cleanup; 613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 635c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzovnamespace options { 64c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola enum generate_bc { BC_NO, BC_ALSO, BC_ONLY }; 65f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman static bool generate_api_file = false; 66c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola static generate_bc generate_bc_file = BC_NO; 6762bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola static std::string bc_path; 686c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola static std::string as_path; 69dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola static std::vector<std::string> pass_through; 7011f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola static std::string extra_library_path; 71cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola static std::string triple; 725c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Additional options to pass into the code generator. 73fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky // Note: This array will contain all plugin options which are not claimed 745c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // as plugin exclusive to pass to the code generator. 75fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky // For example, "generate-api-file" and "as"options are for the plugin 765c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // use only and will not be passed. 77f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman static std::vector<std::string> extra; 785c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 796c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola static void process_plugin_option(const char* opt_) 805c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov { 816c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola if (opt_ == NULL) 825c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov return; 836c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola llvm::StringRef opt = opt_; 845c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 856c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola if (opt == "generate-api-file") { 865c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov generate_api_file = true; 876c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola } else if (opt.startswith("as=")) { 886c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola if (!as_path.empty()) { 895c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov (*message)(LDPL_WARNING, "Path to as specified twice. " 906c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola "Discarding %s", opt_); 915c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } else { 926c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola as_path = opt.substr(strlen("as=")); 935c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 9411f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola } else if (opt.startswith("extra-library-path=")) { 9511f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola extra_library_path = opt.substr(strlen("extra_library_path=")); 96dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola } else if (opt.startswith("pass-through=")) { 97dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola llvm::StringRef item = opt.substr(strlen("pass-through=")); 98dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola pass_through.push_back(item.str()); 99cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola } else if (opt == "mtriple=") { 100cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola triple = opt.substr(strlen("mtriple=")); 1016c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola } else if (opt == "emit-llvm") { 102c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola generate_bc_file = BC_ONLY; 1036c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola } else if (opt == "also-emit-llvm") { 104c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola generate_bc_file = BC_ALSO; 1056c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola } else if (opt.startswith("also-emit-llvm=")) { 1066c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola llvm::StringRef path = opt.substr(strlen("also-emit-llvm=")); 107c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola generate_bc_file = BC_ALSO; 108662f738ec3f9f4c77052b5a593cb30c28069713eNick Lewycky if (!bc_path.empty()) { 10962bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola (*message)(LDPL_WARNING, "Path to the output IL file specified twice. " 1106c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola "Discarding %s", opt_); 11162bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } else { 11262bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola bc_path = path; 11362bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } 1145c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } else { 1155c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Save this option to pass to the code generator. 1166c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola extra.push_back(opt); 1175c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 1185c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 1195c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov} 1205c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 121f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, 122f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman int *claimed); 123f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status all_symbols_read_hook(void); 124f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status cleanup_hook(void); 1253e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1263e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyextern "C" ld_plugin_status onload(ld_plugin_tv *tv); 1273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyld_plugin_status onload(ld_plugin_tv *tv) { 1283e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // We're given a pointer to the first transfer vector. We read through them 1293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // until we find one where tv_tag == LDPT_NULL. The REGISTER_* tagged values 1303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // contain pointers to functions that we need to call to register our own 1313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // hooks. The others are addresses of functions we can use to call into gold 1323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // for services. 1333e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky bool registeredClaimFile = false; 1353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (; tv->tv_tag != LDPT_NULL; ++tv) { 1373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (tv->tv_tag) { 1383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_API_VERSION: 1393e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky api_version = tv->tv_u.tv_val; 1403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_GOLD_VERSION: // major * 100 + minor 1423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky gold_version = tv->tv_u.tv_val; 1433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 144c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola case LDPT_OUTPUT_NAME: 145c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola output_name = tv->tv_u.tv_string; 146c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola break; 1473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_LINKER_OUTPUT: 1483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (tv->tv_u.tv_val) { 1493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_REL: // .o 1503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_DYN: // .so 1513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC; 1523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_EXEC: // .exe 1543e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky output_type = LTO_CODEGEN_PIC_MODEL_STATIC; 1553e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1563e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 1573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unknown output file type %d", 1583e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky tv->tv_u.tv_val); 1593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 1613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // TODO: add an option to disable PIC. 1623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky //output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC; 1633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_OPTION: 1655c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov options::process_plugin_option(tv->tv_u.tv_string); 1663e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1673e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_CLAIM_FILE_HOOK: { 1683e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_claim_file callback; 1693e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_claim_file; 1703e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1713e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*callback)(claim_file_hook) != LDPS_OK) 1723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1733e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1743e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky registeredClaimFile = true; 1753e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1763e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK: { 1773e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_all_symbols_read callback; 1783e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_all_symbols_read; 1793e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*callback)(all_symbols_read_hook) != LDPS_OK) 1813e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1823e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1833e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_CLEANUP_HOOK: { 1843e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_cleanup callback; 1853e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_cleanup; 1863e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1873e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*callback)(cleanup_hook) != LDPS_OK) 1883e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1893e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1903e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_ADD_SYMBOLS: 1913e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky add_symbols = tv->tv_u.tv_add_symbols; 1923e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1933e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_GET_SYMBOLS: 1943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky get_symbols = tv->tv_u.tv_get_symbols; 1953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1963e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_ADD_INPUT_FILE: 1973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky add_input_file = tv->tv_u.tv_add_input_file; 1983e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 199dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola case LDPT_ADD_INPUT_LIBRARY: 200dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola add_input_library = tv->tv_u.tv_add_input_file; 201dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola break; 20211f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola case LDPT_SET_EXTRA_LIBRARY_PATH: 20311f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola set_extra_library_path = tv->tv_u.tv_set_extra_library_path; 20411f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola break; 2053e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_MESSAGE: 2063e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky message = tv->tv_u.tv_message; 2073e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2083e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 2093e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2103e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 2113e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 2123e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 21398c507ed5c2883bc8ef487d952e851da37f8b32fRafael Espindola if (!registeredClaimFile) { 2146210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola (*message)(LDPL_ERROR, "register_claim_file not passed to LLVMgold."); 2156210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola return LDPS_ERR; 2166210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola } 21798c507ed5c2883bc8ef487d952e851da37f8b32fRafael Espindola if (!add_symbols) { 2186210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola (*message)(LDPL_ERROR, "add_symbols not passed to LLVMgold."); 2196210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola return LDPS_ERR; 2206210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola } 2213e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2223e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 2233e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 2243e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2253e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// claim_file_hook - called by gold to see whether this file is one that 2263e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// our plugin can handle. We'll try to open it and register all the symbols 2273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// with add_symbol if possible. 228f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, 229f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman int *claimed) { 2303e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin void *buf = NULL; 2313e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin if (file->offset) { 232c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky // Gold has found what might be IR part-way inside of a file, such as 233c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky // an .a archive. 2343e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin if (lseek(file->fd, file->offset, SEEK_SET) == -1) { 2350df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky (*message)(LDPL_ERROR, 236fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky "Failed to seek to archive member of %s at offset %d: %s\n", 2373e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin file->name, 238ed1c0ffe0b2287deaee7cba7506c93aa34c6d4b7Jeffrey Yasskin file->offset, sys::StrError(errno).c_str()); 2393e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin return LDPS_ERR; 2403e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin } 2413e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin buf = malloc(file->filesize); 2423e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin if (!buf) { 2430df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky (*message)(LDPL_ERROR, 244fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky "Failed to allocate buffer for archive member of size: %d\n", 2453e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin file->filesize); 2463e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin return LDPS_ERR; 2473e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin } 2483e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin if (read(file->fd, buf, file->filesize) != file->filesize) { 2490df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky (*message)(LDPL_ERROR, 2500df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky "Failed to read archive member of %s at offset %d: %s\n", 2513e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin file->name, 2520df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky file->offset, 253ed1c0ffe0b2287deaee7cba7506c93aa34c6d4b7Jeffrey Yasskin sys::StrError(errno).c_str()); 2540df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky free(buf); 2553e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin return LDPS_ERR; 2563e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin } 2570df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky if (!lto_module_is_object_file_in_memory(buf, file->filesize)) { 2580df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky free(buf); 2593e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin return LDPS_OK; 2600df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky } 2613e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin } else if (!lto_module_is_object_file(file->name)) 2623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 2633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky *claimed = 1; 2653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky Modules.resize(Modules.size() + 1); 2663e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky claimed_file &cf = Modules.back(); 2673e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 268c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky cf.M = buf ? lto_module_create_from_memory(buf, file->filesize) : 269c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky lto_module_create(file->name); 270ea97aa6129fc89292e215d01fa66504195f1a969Nick Lewycky free(buf); 2713e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (!cf.M) { 2723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Failed to create LLVM module: %s", 2733e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_get_error_message()); 2743e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 2753e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 276cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola 277cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola if (!options::triple.empty()) 278cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola lto_module_set_target_triple(cf.M, options::triple.c_str()); 279cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola 2803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.handle = file->handle; 2813e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky unsigned sym_count = lto_module_get_num_symbols(cf.M); 2823e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.reserve(sym_count); 2833e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2843e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (unsigned i = 0; i != sym_count; ++i) { 2853e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_symbol_attributes attrs = lto_module_get_symbol_attribute(cf.M, i); 2863e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((attrs & LTO_SYMBOL_SCOPE_MASK) == LTO_SYMBOL_SCOPE_INTERNAL) 2873e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky continue; 2883e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2893e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.push_back(ld_plugin_symbol()); 2903e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_symbol &sym = cf.syms.back(); 2913e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.name = const_cast<char *>(lto_module_get_symbol_name(cf.M, i)); 2923e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.version = NULL; 2933e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int scope = attrs & LTO_SYMBOL_SCOPE_MASK; 2953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (scope) { 2963e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_SCOPE_HIDDEN: 2973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_HIDDEN; 2983e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2993e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_SCOPE_PROTECTED: 3003e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_PROTECTED; 3013e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3023e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case 0: // extern 3033e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_SCOPE_DEFAULT: 3043e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_DEFAULT; 3053e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3063e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 3073e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unknown scope attribute: %d", scope); 3083e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 3093e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3103e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3113e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int definition = attrs & LTO_SYMBOL_DEFINITION_MASK; 3123e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (definition) { 3133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_REGULAR: 3143e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_DEF; 3153e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3163e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_UNDEFINED: 3173e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_UNDEF; 3183e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3193e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_TENTATIVE: 3203e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_COMMON; 3213e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3223e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_WEAK: 3233e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_WEAKDEF; 3243e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3257431af050f287011fd52e64034ede6dd98193febRafael Espindola case LTO_SYMBOL_DEFINITION_WEAKUNDEF: 3267431af050f287011fd52e64034ede6dd98193febRafael Espindola sym.def = LDPK_WEAKUNDEF; 3277431af050f287011fd52e64034ede6dd98193febRafael Espindola break; 3283e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 3293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unknown definition attribute: %d", definition); 3303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 3313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3333e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // LLVM never emits COMDAT. 3343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.size = 0; 3353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.comdat_key = NULL; 3363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.resolution = LDPR_UNKNOWN; 3383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3393e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.reserve(cf.syms.size()); 3413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (!cf.syms.empty()) { 3433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*add_symbols)(cf.handle, cf.syms.size(), &cf.syms[0]) != LDPS_OK) { 3443e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unable to add symbols!"); 3453e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 3463e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 3503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 3513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// all_symbols_read_hook - gold informs us that all symbols have been read. 3533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// At this point, we use get_symbols to see if any of our definitions have 3543e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// been overridden by a native object file. Then, perform optimization and 3553e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// codegen. 356f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status all_symbols_read_hook(void) { 3573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_code_gen_t cg = lto_codegen_create(); 3583e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (std::list<claimed_file>::iterator I = Modules.begin(), 3603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky E = Modules.end(); I != E; ++I) 3613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_add_module(cg, I->M); 3623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 363ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky std::ofstream api_file; 3645c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (options::generate_api_file) { 365ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky api_file.open("apifile.txt", std::ofstream::out | std::ofstream::trunc); 366ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky if (!api_file.is_open()) { 367ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky (*message)(LDPL_FATAL, "Unable to open apifile.txt for writing."); 368ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky abort(); 369ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky } 370ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky } 371ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky 3723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // If we don't preserve any symbols, libLTO will assume that all symbols are 3733e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // needed. Keep all symbols unless we're producing a final executable. 374c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola bool anySymbolsPreserved = false; 375c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola for (std::list<claimed_file>::iterator I = Modules.begin(), 3763e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky E = Modules.end(); I != E; ++I) { 377c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola (*get_symbols)(I->handle, I->syms.size(), &I->syms[0]); 378c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola for (unsigned i = 0, e = I->syms.size(); i != e; i++) { 379c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola if (I->syms[i].resolution == LDPR_PREVAILING_DEF) { 380c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola lto_codegen_add_must_preserve_symbol(cg, I->syms[i].name); 381c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola anySymbolsPreserved = true; 382c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola 383c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola if (options::generate_api_file) 384c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola api_file << I->syms[i].name << "\n"; 3853e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3863e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 38738a979bf95db020094769194651b91291ca0220cRafael Espindola } 3883e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 38938a979bf95db020094769194651b91291ca0220cRafael Espindola if (options::generate_api_file) 39038a979bf95db020094769194651b91291ca0220cRafael Espindola api_file.close(); 391ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky 39238a979bf95db020094769194651b91291ca0220cRafael Espindola if (!anySymbolsPreserved) { 39338a979bf95db020094769194651b91291ca0220cRafael Espindola // All of the IL is unnecessary! 39438a979bf95db020094769194651b91291ca0220cRafael Espindola lto_codegen_dispose(cg); 39538a979bf95db020094769194651b91291ca0220cRafael Espindola return LDPS_OK; 3963e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3983e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_set_pic_model(cg, output_type); 3993e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_set_debug_model(cg, LTO_DEBUG_MODEL_DWARF); 4006c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola if (!options::as_path.empty()) { 4015c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov sys::Path p = sys::Program::FindProgramByName(options::as_path); 40242de34f013ee15377dd78aa0d827100166cb66c9Rafael Espindola lto_codegen_set_assembler_path(cg, p.c_str()); 40342de34f013ee15377dd78aa0d827100166cb66c9Rafael Espindola } 4045c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Pass through extra options to the code generator. 4055c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (!options::extra.empty()) { 4065c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov for (std::vector<std::string>::iterator it = options::extra.begin(); 4075c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov it != options::extra.end(); ++it) { 4085c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov lto_codegen_debug_options(cg, (*it).c_str()); 4095c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 4105c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 4113e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 412c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola 413c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola if (options::generate_bc_file != options::BC_NO) { 414c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola std::string path; 415c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola if (options::generate_bc_file == options::BC_ONLY) 416c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola path = output_name; 417c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola else if (!options::bc_path.empty()) 418c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola path = options::bc_path; 419c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola else 420c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola path = output_name + ".bc"; 421c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola bool err = lto_codegen_write_merged_modules(cg, path.c_str()); 42262bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola if (err) 42362bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola (*message)(LDPL_FATAL, "Failed to write the output file."); 424c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola if (options::generate_bc_file == options::BC_ONLY) 425c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola exit(0); 42662bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } 4273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky size_t bufsize = 0; 4283e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky const char *buffer = static_cast<const char *>(lto_codegen_compile(cg, 4293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky &bufsize)); 4303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::string ErrMsg; 4323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4333e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sys::Path uniqueObjPath("/tmp/llvmgold.o"); 4343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (uniqueObjPath.createTemporaryFileOnDisk(true, &ErrMsg)) { 4353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "%s", ErrMsg.c_str()); 4363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 4373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 438221aec60a7feb5fa14e7c2539617909855623ac1Nick Lewycky raw_fd_ostream objFile(uniqueObjPath.c_str(), ErrMsg, 439221aec60a7feb5fa14e7c2539617909855623ac1Nick Lewycky raw_fd_ostream::F_Binary); 4403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (!ErrMsg.empty()) { 4413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "%s", ErrMsg.c_str()); 4423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 4433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4443e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 445221aec60a7feb5fa14e7c2539617909855623ac1Nick Lewycky objFile.write(buffer, bufsize); 446221aec60a7feb5fa14e7c2539617909855623ac1Nick Lewycky objFile.close(); 4473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_dispose(cg); 4493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 450bebb640b6b495b89f37dde7921f88f24deaf00beRafael Espindola if ((*add_input_file)(uniqueObjPath.c_str()) != LDPS_OK) { 4513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unable to add .o file to the link."); 4523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "File left behind in: %s", uniqueObjPath.c_str()); 4533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 4543e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4553e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 45611f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola if (!options::extra_library_path.empty() && 45711f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK) { 45811f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola (*message)(LDPL_ERROR, "Unable to set the extra library path."); 45911f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola return LDPS_ERR; 46011f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola } 46111f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola 462dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola for (std::vector<std::string>::iterator i = options::pass_through.begin(), 463dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola e = options::pass_through.end(); 464dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola i != e; ++i) { 465dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola std::string &item = *i; 466bebb640b6b495b89f37dde7921f88f24deaf00beRafael Espindola const char *item_p = item.c_str(); 467dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola if (llvm::StringRef(item).startswith("-l")) { 468dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola if (add_input_library(item_p + 2) != LDPS_OK) { 469dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola (*message)(LDPL_ERROR, "Unable to add library to the link."); 470dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola return LDPS_ERR; 471dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola } 472dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola } else { 473dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola if (add_input_file(item_p) != LDPS_OK) { 474dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola (*message)(LDPL_ERROR, "Unable to add .o file to the link."); 475dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola return LDPS_ERR; 476dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola } 477dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola } 478dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola } 479dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola 4803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky Cleanup.push_back(uniqueObjPath); 4813e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4823e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 4833e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 4843e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 485f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status cleanup_hook(void) { 4863e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::string ErrMsg; 4873e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4883e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (int i = 0, e = Cleanup.size(); i != e; ++i) 4893e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (Cleanup[i].eraseFromDisk(false, &ErrMsg)) 4903e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Failed to delete '%s': %s", Cleanup[i].c_str(), 4913e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ErrMsg.c_str()); 4923e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4933e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 4943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 495