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 159421406aada374f79ce2f8e576824463f7830981Dylan Noblesmith#include "llvm/Config/config.h" // plugin-api.h requires HAVE_STDINT_H 163e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include "plugin-api.h" 173e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 183e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include "llvm-c/lto.h" 193e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 20ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin#include "llvm/ADT/OwningPtr.h" 21ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin#include "llvm/Support/system_error.h" 22ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin#include "llvm/Support/MemoryBuffer.h" 23e4f1a9b8a272ff7452759019ee7774e9dbdf1568Dan Gohman#include "llvm/Support/ToolOutputFile.h" 243cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Errno.h" 253cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Path.h" 263cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Program.h" 273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 286cbbdfd2e900164beeb34513a25d88cc58e582b0Torok Edwin#include <cerrno> 293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <cstdlib> 303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <cstring> 31ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky#include <fstream> 323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <list> 333e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <vector> 343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 358b1659e8bf957f09da5cf912ad2702b3366e4c08Michael J. Spencer// Support Windows/MinGW crazyness. 368b1659e8bf957f09da5cf912ad2702b3366e4c08Michael J. Spencer#ifdef _WIN32 378b1659e8bf957f09da5cf912ad2702b3366e4c08Michael J. Spencer# include <io.h> 388b1659e8bf957f09da5cf912ad2702b3366e4c08Michael J. Spencer# define lseek _lseek 398b1659e8bf957f09da5cf912ad2702b3366e4c08Michael J. Spencer# define read _read 408b1659e8bf957f09da5cf912ad2702b3366e4c08Michael J. Spencer#endif 418b1659e8bf957f09da5cf912ad2702b3366e4c08Michael J. Spencer 423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyusing namespace llvm; 433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 443e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckynamespace { 453e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_status discard_message(int level, const char *format, ...) { 463e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // Die loudly. Recent versions of Gold pass ld_plugin_message as the first 473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // callback in the transfer vector. This should never be called. 483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky abort(); 493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_add_symbols add_symbols = NULL; 523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_get_symbols get_symbols = NULL; 533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_add_input_file add_input_file = NULL; 54dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola ld_plugin_add_input_library add_input_library = NULL; 5511f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola ld_plugin_set_extra_library_path set_extra_library_path = NULL; 56e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola ld_plugin_get_view get_view = NULL; 573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_message message = discard_message; 583e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int api_version = 0; 603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int gold_version = 0; 613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky struct claimed_file { 633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky void *handle; 643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::vector<ld_plugin_symbol> syms; 653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky }; 663e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 673e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky lto_codegen_model output_type = LTO_CODEGEN_PIC_MODEL_STATIC; 68c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola std::string output_name = ""; 693e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::list<claimed_file> Modules; 703e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::vector<sys::Path> Cleanup; 718e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola lto_code_gen_t code_gen = NULL; 723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 733e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 745c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzovnamespace options { 75c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola enum generate_bc { BC_NO, BC_ALSO, BC_ONLY }; 76f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman static bool generate_api_file = false; 77c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola static generate_bc generate_bc_file = BC_NO; 7862bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola static std::string bc_path; 795a287d7a03ebf56c85de05968548aa2826a5886bRafael Espindola static std::string obj_path; 8011f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola static std::string extra_library_path; 81cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola static std::string triple; 822d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola static std::string mcpu; 835c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Additional options to pass into the code generator. 84fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky // Note: This array will contain all plugin options which are not claimed 855c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // as plugin exclusive to pass to the code generator. 86fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky // For example, "generate-api-file" and "as"options are for the plugin 875c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // use only and will not be passed. 88f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman static std::vector<std::string> extra; 895c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 906c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola static void process_plugin_option(const char* opt_) 915c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov { 926c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola if (opt_ == NULL) 935c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov return; 946c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola llvm::StringRef opt = opt_; 955c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 966c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola if (opt == "generate-api-file") { 975c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov generate_api_file = true; 982d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola } else if (opt.startswith("mcpu=")) { 992d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola mcpu = opt.substr(strlen("mcpu=")); 10011f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola } else if (opt.startswith("extra-library-path=")) { 10111f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola extra_library_path = opt.substr(strlen("extra_library_path=")); 10215af387bffbf8e1fbab720fd0b92291bb68c023bRafael Espindola } else if (opt.startswith("mtriple=")) { 103cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola triple = opt.substr(strlen("mtriple=")); 1045a287d7a03ebf56c85de05968548aa2826a5886bRafael Espindola } else if (opt.startswith("obj-path=")) { 1055a287d7a03ebf56c85de05968548aa2826a5886bRafael Espindola obj_path = opt.substr(strlen("obj-path=")); 1066c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola } else if (opt == "emit-llvm") { 107c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola generate_bc_file = BC_ONLY; 1086c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola } else if (opt == "also-emit-llvm") { 109c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola generate_bc_file = BC_ALSO; 1106c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola } else if (opt.startswith("also-emit-llvm=")) { 1116c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola llvm::StringRef path = opt.substr(strlen("also-emit-llvm=")); 112c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola generate_bc_file = BC_ALSO; 113662f738ec3f9f4c77052b5a593cb30c28069713eNick Lewycky if (!bc_path.empty()) { 11462bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola (*message)(LDPL_WARNING, "Path to the output IL file specified twice. " 1156c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola "Discarding %s", opt_); 11662bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } else { 11762bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola bc_path = path; 11862bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } 1195c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } else { 1205c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Save this option to pass to the code generator. 1216c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola extra.push_back(opt); 1225c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 1235c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 1245c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov} 1255c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 126f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, 127f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman int *claimed); 128f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status all_symbols_read_hook(void); 129f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status cleanup_hook(void); 1303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyextern "C" ld_plugin_status onload(ld_plugin_tv *tv); 1323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyld_plugin_status onload(ld_plugin_tv *tv) { 1333e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // We're given a pointer to the first transfer vector. We read through them 1343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // until we find one where tv_tag == LDPT_NULL. The REGISTER_* tagged values 1353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // contain pointers to functions that we need to call to register our own 1363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // hooks. The others are addresses of functions we can use to call into gold 1373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // for services. 1383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1393e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky bool registeredClaimFile = false; 1403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (; tv->tv_tag != LDPT_NULL; ++tv) { 1423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (tv->tv_tag) { 1433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_API_VERSION: 1443e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky api_version = tv->tv_u.tv_val; 1453e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1463e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_GOLD_VERSION: // major * 100 + minor 1473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky gold_version = tv->tv_u.tv_val; 1483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 149c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola case LDPT_OUTPUT_NAME: 150c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola output_name = tv->tv_u.tv_string; 151c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola break; 1523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_LINKER_OUTPUT: 1533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (tv->tv_u.tv_val) { 1543e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_REL: // .o 1553e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_DYN: // .so 1563e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC; 1573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1583e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_EXEC: // .exe 1593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky output_type = LTO_CODEGEN_PIC_MODEL_STATIC; 1603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 1623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unknown output file type %d", 1633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky tv->tv_u.tv_val); 1643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 1663e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // TODO: add an option to disable PIC. 1673e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky //output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC; 1683e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1693e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_OPTION: 1705c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov options::process_plugin_option(tv->tv_u.tv_string); 1713e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_CLAIM_FILE_HOOK: { 1733e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_claim_file callback; 1743e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_claim_file; 1753e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1763e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*callback)(claim_file_hook) != LDPS_OK) 1773e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1783e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1793e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky registeredClaimFile = true; 1803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1813e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK: { 1823e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_all_symbols_read callback; 1833e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_all_symbols_read; 1843e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1853e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*callback)(all_symbols_read_hook) != LDPS_OK) 1863e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1878e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola 1888e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola code_gen = lto_codegen_create(); 1893e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1903e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_CLEANUP_HOOK: { 1913e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_cleanup callback; 1923e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_cleanup; 1933e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*callback)(cleanup_hook) != LDPS_OK) 1953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1963e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_ADD_SYMBOLS: 1983e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky add_symbols = tv->tv_u.tv_add_symbols; 1993e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2003e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_GET_SYMBOLS: 2013e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky get_symbols = tv->tv_u.tv_get_symbols; 2023e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2033e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_ADD_INPUT_FILE: 2043e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky add_input_file = tv->tv_u.tv_add_input_file; 2053e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 206dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola case LDPT_ADD_INPUT_LIBRARY: 207dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola add_input_library = tv->tv_u.tv_add_input_file; 208dd76f18f90f3d9934353d852e45271b3be747743Rafael Espindola break; 20911f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola case LDPT_SET_EXTRA_LIBRARY_PATH: 21011f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola set_extra_library_path = tv->tv_u.tv_set_extra_library_path; 21111f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola break; 212e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola case LDPT_GET_VIEW: 213e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola get_view = tv->tv_u.tv_get_view; 214e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola break; 2153e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_MESSAGE: 2163e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky message = tv->tv_u.tv_message; 2173e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2183e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 2193e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2203e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 2213e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 2223e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 22398c507ed5c2883bc8ef487d952e851da37f8b32fRafael Espindola if (!registeredClaimFile) { 2246210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola (*message)(LDPL_ERROR, "register_claim_file not passed to LLVMgold."); 2256210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola return LDPS_ERR; 2266210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola } 22798c507ed5c2883bc8ef487d952e851da37f8b32fRafael Espindola if (!add_symbols) { 2286210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola (*message)(LDPL_ERROR, "add_symbols not passed to LLVMgold."); 2296210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola return LDPS_ERR; 2306210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola } 2313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 2333e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 2343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// claim_file_hook - called by gold to see whether this file is one that 2363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// our plugin can handle. We'll try to open it and register all the symbols 2373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// with add_symbol if possible. 238f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, 239f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman int *claimed) { 240b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola lto_module_t M; 241ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin const void *view; 242ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin OwningPtr<MemoryBuffer> buffer; 243e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola if (get_view) { 244e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola if (get_view(file->handle, &view) != LDPS_OK) { 245e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola (*message)(LDPL_ERROR, "Failed to get a view of %s", file->name); 246e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola return LDPS_ERR; 247e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola } 248ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin } else { 24971280b55a3406c7dd4215449bf4a3ab216e78ffdIvan Krasin int64_t offset = 0; 250c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky // Gold has found what might be IR part-way inside of a file, such as 251c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky // an .a archive. 252ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin if (file->offset) { 253ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin offset = file->offset; 254ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin } 255ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin if (error_code ec = 256ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin MemoryBuffer::getOpenFile(file->fd, file->name, buffer, file->filesize, 257ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin -1, offset, false)) { 258ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin (*message)(LDPL_ERROR, ec.message().c_str()); 259ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin return LDPS_ERR; 260ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin } 261ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin view = buffer->getBufferStart(); 262b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola } 263ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin 264ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin if (!lto_module_is_object_file_in_memory(view, file->filesize)) 265ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin return LDPS_OK; 266ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin 267ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin M = lto_module_create_from_memory(view, file->filesize); 268c170f5f31cd697818bf470b57b72c11a1da78010Ivan Krasin if (!M) { 269c170f5f31cd697818bf470b57b72c11a1da78010Ivan Krasin if (const char* msg = lto_get_error_message()) { 270ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin (*message)(LDPL_ERROR, 271ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin "LLVM gold plugin has failed to create LTO module: %s", 272ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin msg); 273c170f5f31cd697818bf470b57b72c11a1da78010Ivan Krasin return LDPS_ERR; 274c170f5f31cd697818bf470b57b72c11a1da78010Ivan Krasin } 275f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola return LDPS_OK; 276c170f5f31cd697818bf470b57b72c11a1da78010Ivan Krasin } 2773e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2783e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky *claimed = 1; 2793e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky Modules.resize(Modules.size() + 1); 2803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky claimed_file &cf = Modules.back(); 281cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola 282cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola if (!options::triple.empty()) 28337d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola lto_module_set_target_triple(M, options::triple.c_str()); 284cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola 2853e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.handle = file->handle; 28637d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola unsigned sym_count = lto_module_get_num_symbols(M); 2873e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.reserve(sym_count); 2883e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2893e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (unsigned i = 0; i != sym_count; ++i) { 29037d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola lto_symbol_attributes attrs = lto_module_get_symbol_attribute(M, i); 2913e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((attrs & LTO_SYMBOL_SCOPE_MASK) == LTO_SYMBOL_SCOPE_INTERNAL) 2923e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky continue; 2933e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 2943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.push_back(ld_plugin_symbol()); 2953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_symbol &sym = cf.syms.back(); 29637d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola sym.name = const_cast<char *>(lto_module_get_symbol_name(M, i)); 2978e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola sym.name = strdup(sym.name); 2983e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.version = NULL; 2993e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3003e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int scope = attrs & LTO_SYMBOL_SCOPE_MASK; 3013e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (scope) { 3023e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_SCOPE_HIDDEN: 3033e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_HIDDEN; 3043e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3053e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_SCOPE_PROTECTED: 3063e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_PROTECTED; 3073e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3083e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case 0: // extern 3093e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_SCOPE_DEFAULT: 3103e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_DEFAULT; 3113e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3123e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 3133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unknown scope attribute: %d", scope); 3143e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 3153e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3163e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3173e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky int definition = attrs & LTO_SYMBOL_DEFINITION_MASK; 3185d618ef7f1ad005fc6912f3e9a08c044b082e47fRafael Espindola sym.comdat_key = NULL; 3193e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (definition) { 3203e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_REGULAR: 3213e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_DEF; 3223e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3233e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_UNDEFINED: 3243e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_UNDEF; 3253e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3263e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_TENTATIVE: 3273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_COMMON; 3283e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LTO_SYMBOL_DEFINITION_WEAK: 3305d618ef7f1ad005fc6912f3e9a08c044b082e47fRafael Espindola sym.comdat_key = sym.name; 3313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.def = LDPK_WEAKDEF; 3323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 3337431af050f287011fd52e64034ede6dd98193febRafael Espindola case LTO_SYMBOL_DEFINITION_WEAKUNDEF: 3347431af050f287011fd52e64034ede6dd98193febRafael Espindola sym.def = LDPK_WEAKUNDEF; 3357431af050f287011fd52e64034ede6dd98193febRafael Espindola break; 3363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 3373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unknown definition attribute: %d", definition); 3383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 3393e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.size = 0; 3423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3433e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.resolution = LDPR_UNKNOWN; 3443e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3453e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3463e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.reserve(cf.syms.size()); 3473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (!cf.syms.empty()) { 3493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if ((*add_symbols)(cf.handle, cf.syms.size(), &cf.syms[0]) != LDPS_OK) { 3503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unable to add symbols!"); 3513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 3523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3543e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3558e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola if (code_gen) 3568e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola lto_codegen_add_module(code_gen, M); 3578e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola 3588e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola lto_module_dispose(M); 3598e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola 3603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 3613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 3623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// all_symbols_read_hook - gold informs us that all symbols have been read. 3643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// At this point, we use get_symbols to see if any of our definitions have 3653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// been overridden by a native object file. Then, perform optimization and 3663e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky/// codegen. 367f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status all_symbols_read_hook(void) { 368ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky std::ofstream api_file; 3698e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola assert(code_gen); 3708e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola 3715c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (options::generate_api_file) { 372ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky api_file.open("apifile.txt", std::ofstream::out | std::ofstream::trunc); 373ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky if (!api_file.is_open()) { 374ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky (*message)(LDPL_FATAL, "Unable to open apifile.txt for writing."); 375ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky abort(); 376ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky } 377ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky } 378ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky 3793e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // If we don't preserve any symbols, libLTO will assume that all symbols are 3803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // needed. Keep all symbols unless we're producing a final executable. 381c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola bool anySymbolsPreserved = false; 382c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola for (std::list<claimed_file>::iterator I = Modules.begin(), 3833e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky E = Modules.end(); I != E; ++I) { 3845e0ac58bef2632a804358ec42a6ba5c6be42c450Nick Lewycky if (I->syms.empty()) 3855e0ac58bef2632a804358ec42a6ba5c6be42c450Nick Lewycky continue; 386c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola (*get_symbols)(I->handle, I->syms.size(), &I->syms[0]); 387c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola for (unsigned i = 0, e = I->syms.size(); i != e; i++) { 388c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola if (I->syms[i].resolution == LDPR_PREVAILING_DEF) { 38937d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola lto_codegen_add_must_preserve_symbol(code_gen, I->syms[i].name); 390c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola anySymbolsPreserved = true; 391c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola 392c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola if (options::generate_api_file) 393c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola api_file << I->syms[i].name << "\n"; 3943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 39638a979bf95db020094769194651b91291ca0220cRafael Espindola } 3973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 39838a979bf95db020094769194651b91291ca0220cRafael Espindola if (options::generate_api_file) 39938a979bf95db020094769194651b91291ca0220cRafael Espindola api_file.close(); 400ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky 40138a979bf95db020094769194651b91291ca0220cRafael Espindola if (!anySymbolsPreserved) { 40238a979bf95db020094769194651b91291ca0220cRafael Espindola // All of the IL is unnecessary! 40337d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola lto_codegen_dispose(code_gen); 40438a979bf95db020094769194651b91291ca0220cRafael Espindola return LDPS_OK; 4053e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4063e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 40737d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola lto_codegen_set_pic_model(code_gen, output_type); 40837d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola lto_codegen_set_debug_model(code_gen, LTO_DEBUG_MODEL_DWARF); 4092d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola if (!options::mcpu.empty()) 41037d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola lto_codegen_set_cpu(code_gen, options::mcpu.c_str()); 4112d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola 4125c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Pass through extra options to the code generator. 4135c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov if (!options::extra.empty()) { 4145c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov for (std::vector<std::string>::iterator it = options::extra.begin(); 4155c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov it != options::extra.end(); ++it) { 41637d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola lto_codegen_debug_options(code_gen, (*it).c_str()); 4175c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 4185c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 4193e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 420c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola if (options::generate_bc_file != options::BC_NO) { 421c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola std::string path; 422c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola if (options::generate_bc_file == options::BC_ONLY) 423c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola path = output_name; 424c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola else if (!options::bc_path.empty()) 425c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola path = options::bc_path; 426c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola else 427c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola path = output_name + ".bc"; 42837d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola bool err = lto_codegen_write_merged_modules(code_gen, path.c_str()); 42962bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola if (err) 43062bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola (*message)(LDPL_FATAL, "Failed to write the output file."); 431c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola if (options::generate_bc_file == options::BC_ONLY) 432c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola exit(0); 43362bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } 4345a287d7a03ebf56c85de05968548aa2826a5886bRafael Espindola const char *objPath; 4356421a8815e14189121a5e20731fd005ea08793e1Rafael Espindola if (lto_codegen_compile_to_file(code_gen, &objPath)) { 4366421a8815e14189121a5e20731fd005ea08793e1Rafael Espindola (*message)(LDPL_ERROR, "Could not produce a combined object file\n"); 437f29140106f74d15ba357aa0a7f109adc939c3104Dan Gohman } 4383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 43937d42f8a5072bfd216445b8c1f983686dea0ea1cRafael Espindola lto_codegen_dispose(code_gen); 4408e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola for (std::list<claimed_file>::iterator I = Modules.begin(), 4418e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola E = Modules.end(); I != E; ++I) { 4428e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola for (unsigned i = 0; i != I->syms.size(); ++i) { 4438e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola ld_plugin_symbol &sym = I->syms[i]; 4448e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola free(sym.name); 4458e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola } 4468e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola } 4473e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4485a287d7a03ebf56c85de05968548aa2826a5886bRafael Espindola if ((*add_input_file)(objPath) != LDPS_OK) { 4493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Unable to add .o file to the link."); 4505a287d7a03ebf56c85de05968548aa2826a5886bRafael Espindola (*message)(LDPL_ERROR, "File left behind in: %s", objPath); 4513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 4523e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4533e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 45411f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola if (!options::extra_library_path.empty() && 45511f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK) { 45611f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola (*message)(LDPL_ERROR, "Unable to set the extra library path."); 45711f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola return LDPS_ERR; 45811f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola } 45911f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola 4605a287d7a03ebf56c85de05968548aa2826a5886bRafael Espindola if (options::obj_path.empty()) 4615a287d7a03ebf56c85de05968548aa2826a5886bRafael Espindola Cleanup.push_back(sys::Path(objPath)); 4623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 4643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 4653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 466f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status cleanup_hook(void) { 4673e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky std::string ErrMsg; 4683e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4693e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (int i = 0, e = Cleanup.size(); i != e; ++i) 4703e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (Cleanup[i].eraseFromDisk(false, &ErrMsg)) 4713e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky (*message)(LDPL_ERROR, "Failed to delete '%s': %s", Cleanup[i].c_str(), 4723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ErrMsg.c_str()); 4733e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4743e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 4753e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 476