gold-plugin.cpp revision c4b55610d8cdd58e09b570c33c7484a60e500389
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; 443e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_message message = discard_message; 453e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 463e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int api_version = 0; 473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int gold_version = 0; 483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky struct claimed_file { 503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_module_t M; 513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky void *handle; 523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::vector<ld_plugin_symbol> syms; 533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky }; 543e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 553e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_model output_type = LTO_CODEGEN_PIC_MODEL_STATIC; 56c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola std::string output_name = ""; 573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::list<claimed_file> Modules; 583e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::vector<sys::Path> Cleanup; 593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 615c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzovnamespace options { 62c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola enum generate_bc { BC_NO, BC_ALSO, BC_ONLY }; 63f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman static bool generate_api_file = false; 64c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola static generate_bc generate_bc_file = BC_NO; 6562bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola static std::string bc_path; 66f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman static const char *as_path = NULL; 675c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Additional options to pass into the code generator. 68fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky // Note: This array will contain all plugin options which are not claimed 695c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // as plugin exclusive to pass to the code generator. 70fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky // For example, "generate-api-file" and "as"options are for the plugin 715c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // use only and will not be passed. 72f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman static std::vector<std::string> extra; 735c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 74f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman static void process_plugin_option(const char* opt) 755c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov { 765c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (opt == NULL) 775c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov return; 785c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 795c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (strcmp("generate-api-file", opt) == 0) { 805c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov generate_api_file = true; 815c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } else if (strncmp("as=", opt, 3) == 0) { 825c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (as_path) { 835c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov (*message)(LDPL_WARNING, "Path to as specified twice. " 845c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov "Discarding %s", opt); 855c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } else { 865c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov as_path = strdup(opt + 3); 875c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 88c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola } else if (strcmp("emit-llvm", opt) == 0) { 89c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola generate_bc_file = BC_ONLY; 90c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola } else if (strcmp("also-emit-llvm", opt) == 0) { 91c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola generate_bc_file = BC_ALSO; 92fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky } else if (llvm::StringRef(opt).startswith("also-emit-llvm=")) { 9362bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola const char *path = opt + strlen("also-emit-llvm="); 94c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola generate_bc_file = BC_ALSO; 95662f738ec3f9f4c77052b5a593cb30c28069713eNick Lewycky if (!bc_path.empty()) { 9662bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola (*message)(LDPL_WARNING, "Path to the output IL file specified twice. " 9762bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola "Discarding %s", opt); 9862bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } else { 9962bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola bc_path = path; 10062bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } 1015c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } else { 1025c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Save this option to pass to the code generator. 1035c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov extra.push_back(std::string(opt)); 1045c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 1055c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 1065c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov} 1075c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 108f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, 109f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman int *claimed); 110f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status all_symbols_read_hook(void); 111f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status cleanup_hook(void); 1123e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyextern "C" ld_plugin_status onload(ld_plugin_tv *tv); 1143e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyld_plugin_status onload(ld_plugin_tv *tv) { 1153e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // We're given a pointer to the first transfer vector. We read through them 1163e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // until we find one where tv_tag == LDPT_NULL. The REGISTER_* tagged values 1173e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // contain pointers to functions that we need to call to register our own 1183e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // hooks. The others are addresses of functions we can use to call into gold 1193e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // for services. 1203e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1213e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky bool registeredClaimFile = false; 1223e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky bool registeredAllSymbolsRead = false; 1233e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky bool registeredCleanup = false; 1243e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1253e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (; tv->tv_tag != LDPT_NULL; ++tv) { 1263e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (tv->tv_tag) { 1273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_API_VERSION: 1283e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky api_version = tv->tv_u.tv_val; 1293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_GOLD_VERSION: // major * 100 + minor 1313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky gold_version = tv->tv_u.tv_val; 1323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 133c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola case LDPT_OUTPUT_NAME: 134c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola output_name = tv->tv_u.tv_string; 135c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola break; 1363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_LINKER_OUTPUT: 1373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (tv->tv_u.tv_val) { 1383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_REL: // .o 1393e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_DYN: // .so 1403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC; 1413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_EXEC: // .exe 1433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky output_type = LTO_CODEGEN_PIC_MODEL_STATIC; 1443e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1453e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 1463e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unknown output file type %d", 1473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky tv->tv_u.tv_val); 1483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 1503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // TODO: add an option to disable PIC. 1513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky //output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC; 1523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_OPTION: 1545c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov options::process_plugin_option(tv->tv_u.tv_string); 1553e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1563e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_CLAIM_FILE_HOOK: { 1573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_claim_file callback; 1583e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_claim_file; 1593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*callback)(claim_file_hook) != LDPS_OK) 1613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky registeredClaimFile = true; 1643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK: { 1663e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_all_symbols_read callback; 1673e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_all_symbols_read; 1683e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1693e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*callback)(all_symbols_read_hook) != LDPS_OK) 1703e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1713e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky registeredAllSymbolsRead = true; 1733e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1743e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_CLEANUP_HOOK: { 1753e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_cleanup callback; 1763e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_cleanup; 1773e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1783e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*callback)(cleanup_hook) != LDPS_OK) 1793e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1813e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky registeredCleanup = true; 1823e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1833e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_ADD_SYMBOLS: 1843e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky add_symbols = tv->tv_u.tv_add_symbols; 1853e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1863e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_GET_SYMBOLS: 1873e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky get_symbols = tv->tv_u.tv_get_symbols; 1883e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1893e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_ADD_INPUT_FILE: 1903e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky add_input_file = tv->tv_u.tv_add_input_file; 1913e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1923e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_MESSAGE: 1933e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky message = tv->tv_u.tv_message; 1943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 1963e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 1983e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 1993e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 20098c507ed5c2883bc8ef487d952e851da37f8b32fRafael Espindola if (!registeredClaimFile) { 2016210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola (*message)(LDPL_ERROR, "register_claim_file not passed to LLVMgold."); 2026210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola return LDPS_ERR; 2036210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola } 20498c507ed5c2883bc8ef487d952e851da37f8b32fRafael Espindola if (!add_symbols) { 2056210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola (*message)(LDPL_ERROR, "add_symbols not passed to LLVMgold."); 2066210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola return LDPS_ERR; 2076210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola } 2083e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2093e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 2103e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 2113e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2123e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// claim_file_hook - called by gold to see whether this file is one that 2133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// our plugin can handle. We'll try to open it and register all the symbols 2143e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// with add_symbol if possible. 215f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, 216f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman int *claimed) { 2173e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin void *buf = NULL; 2183e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin if (file->offset) { 219c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky // Gold has found what might be IR part-way inside of a file, such as 220c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky // an .a archive. 2213e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin if (lseek(file->fd, file->offset, SEEK_SET) == -1) { 2220df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky (*message)(LDPL_ERROR, 223fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky "Failed to seek to archive member of %s at offset %d: %s\n", 2243e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin file->name, 225ed1c0ffe0b2287deaee7cba7506c93aa34c6d4b7Jeffrey Yasskin file->offset, sys::StrError(errno).c_str()); 2263e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin return LDPS_ERR; 2273e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin } 2283e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin buf = malloc(file->filesize); 2293e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin if (!buf) { 2300df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky (*message)(LDPL_ERROR, 231fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky "Failed to allocate buffer for archive member of size: %d\n", 2323e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin file->filesize); 2333e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin return LDPS_ERR; 2343e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin } 2353e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin if (read(file->fd, buf, file->filesize) != file->filesize) { 2360df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky (*message)(LDPL_ERROR, 2370df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky "Failed to read archive member of %s at offset %d: %s\n", 2383e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin file->name, 2390df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky file->offset, 240ed1c0ffe0b2287deaee7cba7506c93aa34c6d4b7Jeffrey Yasskin sys::StrError(errno).c_str()); 2410df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky free(buf); 2423e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin return LDPS_ERR; 2433e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin } 2440df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky if (!lto_module_is_object_file_in_memory(buf, file->filesize)) { 2450df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky free(buf); 2463e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin return LDPS_OK; 2470df91b2c8677f3f8fd25b46953051c9d95c1c1aeNick Lewycky } 2483e5a0d8b0b848d1b0deb8976924703787b221e31Torok Edwin } else if (!lto_module_is_object_file(file->name)) 2493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 2503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky *claimed = 1; 2523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky Modules.resize(Modules.size() + 1); 2533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky claimed_file &cf = Modules.back(); 2543e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 255c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky cf.M = buf ? lto_module_create_from_memory(buf, file->filesize) : 256c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky lto_module_create(file->name); 257ea97aa6129fc89292e215d01fa66504195f1a969Nick Lewycky free(buf); 2583e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (!cf.M) { 2593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Failed to create LLVM module: %s", 2603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_get_error_message()); 2613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 2623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 2633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.handle = file->handle; 2643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky unsigned sym_count = lto_module_get_num_symbols(cf.M); 2653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.reserve(sym_count); 2663e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2673e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (unsigned i = 0; i != sym_count; ++i) { 2683e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_symbol_attributes attrs = lto_module_get_symbol_attribute(cf.M, i); 2693e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((attrs & LTO_SYMBOL_SCOPE_MASK) == LTO_SYMBOL_SCOPE_INTERNAL) 2703e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky continue; 2713e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.push_back(ld_plugin_symbol()); 2733e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_symbol &sym = cf.syms.back(); 2743e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.name = const_cast<char *>(lto_module_get_symbol_name(cf.M, i)); 2753e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.version = NULL; 2763e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2773e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int scope = attrs & LTO_SYMBOL_SCOPE_MASK; 2783e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (scope) { 2793e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_SCOPE_HIDDEN: 2803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_HIDDEN; 2813e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2823e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_SCOPE_PROTECTED: 2833e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_PROTECTED; 2843e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2853e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case 0: // extern 2863e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_SCOPE_DEFAULT: 2873e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_DEFAULT; 2883e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2893e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 2903e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unknown scope attribute: %d", scope); 2913e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 2923e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 2933e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int definition = attrs & LTO_SYMBOL_DEFINITION_MASK; 2953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (definition) { 2963e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_REGULAR: 2973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_DEF; 2983e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2993e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_UNDEFINED: 3003e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_UNDEF; 3013e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3023e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_TENTATIVE: 3033e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_COMMON; 3043e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3053e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_WEAK: 3063e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_WEAKDEF; 3073e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3087431af050f287011fd52e64034ede6dd98193febRafael Espindola case LTO_SYMBOL_DEFINITION_WEAKUNDEF: 3097431af050f287011fd52e64034ede6dd98193febRafael Espindola sym.def = LDPK_WEAKUNDEF; 3107431af050f287011fd52e64034ede6dd98193febRafael Espindola break; 3113e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 3123e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unknown definition attribute: %d", definition); 3133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 3143e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3153e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3163e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // LLVM never emits COMDAT. 3173e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.size = 0; 3183e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.comdat_key = NULL; 3193e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3203e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.resolution = LDPR_UNKNOWN; 3213e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3223e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3233e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.reserve(cf.syms.size()); 3243e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3253e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (!cf.syms.empty()) { 3263e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*add_symbols)(cf.handle, cf.syms.size(), &cf.syms[0]) != LDPS_OK) { 3273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unable to add symbols!"); 3283e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 3293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 3333e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 3343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// all_symbols_read_hook - gold informs us that all symbols have been read. 3363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// At this point, we use get_symbols to see if any of our definitions have 3373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// been overridden by a native object file. Then, perform optimization and 3383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// codegen. 339f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status all_symbols_read_hook(void) { 3403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_code_gen_t cg = lto_codegen_create(); 3413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (std::list<claimed_file>::iterator I = Modules.begin(), 3433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky E = Modules.end(); I != E; ++I) 3443e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_add_module(cg, I->M); 3453e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 346ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky std::ofstream api_file; 3475c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (options::generate_api_file) { 348ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky api_file.open("apifile.txt", std::ofstream::out | std::ofstream::trunc); 349ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky if (!api_file.is_open()) { 350ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky (*message)(LDPL_FATAL, "Unable to open apifile.txt for writing."); 351ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky abort(); 352ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky } 353ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky } 354ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky 3553e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // If we don't preserve any symbols, libLTO will assume that all symbols are 3563e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // needed. Keep all symbols unless we're producing a final executable. 357c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola bool anySymbolsPreserved = false; 358c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola for (std::list<claimed_file>::iterator I = Modules.begin(), 3593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky E = Modules.end(); I != E; ++I) { 360c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola (*get_symbols)(I->handle, I->syms.size(), &I->syms[0]); 361c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola for (unsigned i = 0, e = I->syms.size(); i != e; i++) { 362c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola if (I->syms[i].resolution == LDPR_PREVAILING_DEF) { 363c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola lto_codegen_add_must_preserve_symbol(cg, I->syms[i].name); 364c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola anySymbolsPreserved = true; 365c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola 366c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola if (options::generate_api_file) 367c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola api_file << I->syms[i].name << "\n"; 3683e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3693e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3703e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3715c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (options::generate_api_file) 372ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky api_file.close(); 373ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky 3743e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (!anySymbolsPreserved) { 3753e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // This entire file is unnecessary! 3763e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_dispose(cg); 3773e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 3783e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3793e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3813e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_set_pic_model(cg, output_type); 3823e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_set_debug_model(cg, LTO_DEBUG_MODEL_DWARF); 3835c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (options::as_path) { 3845c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov sys::Path p = sys::Program::FindProgramByName(options::as_path); 38542de34f013ee15377dd78aa0d827100166cb66c9Rafael Espindola lto_codegen_set_assembler_path(cg, p.c_str()); 38642de34f013ee15377dd78aa0d827100166cb66c9Rafael Espindola } 3875c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Pass through extra options to the code generator. 3885c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (!options::extra.empty()) { 3895c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov for (std::vector<std::string>::iterator it = options::extra.begin(); 3905c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov it != options::extra.end(); ++it) { 3915c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov lto_codegen_debug_options(cg, (*it).c_str()); 3925c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 3935c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 3943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 395c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola 396c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola if (options::generate_bc_file != options::BC_NO) { 397c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola std::string path; 398c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola if (options::generate_bc_file == options::BC_ONLY) 399c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola path = output_name; 400c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola else if (!options::bc_path.empty()) 401c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola path = options::bc_path; 402c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola else 403c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola path = output_name + ".bc"; 404c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola bool err = lto_codegen_write_merged_modules(cg, path.c_str()); 40562bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola if (err) 40662bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola (*message)(LDPL_FATAL, "Failed to write the output file."); 407c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola if (options::generate_bc_file == options::BC_ONLY) 408c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola exit(0); 40962bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } 4103e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky size_t bufsize = 0; 4113e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky const char *buffer = static_cast<const char *>(lto_codegen_compile(cg, 4123e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky &bufsize)); 4133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4143e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::string ErrMsg; 4153e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4163e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sys::Path uniqueObjPath("/tmp/llvmgold.o"); 4173e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (uniqueObjPath.createTemporaryFileOnDisk(true, &ErrMsg)) { 4183e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "%s", ErrMsg.c_str()); 4193e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 4203e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4214b67bc1e80a94ccceebda899e889e15c6c6c45baNick Lewycky raw_fd_ostream *objFile = 42217e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner new raw_fd_ostream(uniqueObjPath.c_str(), ErrMsg, 423baa26395ccf17fc988bb9cf62d6659ca8415ece9Dan Gohman raw_fd_ostream::F_Binary); 4243e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (!ErrMsg.empty()) { 4253e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky delete objFile; 4263e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "%s", ErrMsg.c_str()); 4273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 4283e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky objFile->write(buffer, bufsize); 4313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky objFile->close(); 4323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4333e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_dispose(cg); 4343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*add_input_file)(const_cast<char*>(uniqueObjPath.c_str())) != LDPS_OK) { 4363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unable to add .o file to the link."); 4373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "File left behind in: %s", uniqueObjPath.c_str()); 4383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 4393e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky Cleanup.push_back(uniqueObjPath); 4423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 4443e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 4453e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 446f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status cleanup_hook(void) { 4473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::string ErrMsg; 4483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (int i = 0, e = Cleanup.size(); i != e; ++i) 4503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (Cleanup[i].eraseFromDisk(false, &ErrMsg)) 4513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Failed to delete '%s': %s", Cleanup[i].c_str(), 4523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ErrMsg.c_str()); 4533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4543e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 4553e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 456