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 1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/ADT/DenseSet.h" 177e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola#include "llvm/ADT/StringSet.h" 18ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Analysis/TargetLibraryInfo.h" 19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Analysis/TargetTransformInfo.h" 2037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Bitcode/ReaderWriter.h" 2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/CodeGen/Analysis.h" 22c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/CodeGen/CommandFlags.h" 23ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/AutoUpgrade.h" 2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/IR/Constants.h" 25ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DiagnosticInfo.h" 26ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DiagnosticPrinter.h" 2737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/IR/LLVMContext.h" 28ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LegacyPassManager.h" 2937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/IR/Module.h" 3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/IR/Verifier.h" 3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Linker/Linker.h" 3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/MC/SubtargetFeature.h" 3337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Object/IRObjectFile.h" 342c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Host.h" 36ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/ManagedStatic.h" 37f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/MemoryBuffer.h" 3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/TargetRegistry.h" 39c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/TargetSelect.h" 4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/IPO.h" 4137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/IPO/PassManagerBuilder.h" 4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/Utils/GlobalStatus.h" 4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/Utils/ModuleUtils.h" 4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Transforms/Utils/ValueMapper.h" 453e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <list> 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <plugin-api.h> 47c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error> 483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky#include <vector> 493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifndef LDPO_PIE 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// FIXME: remove this declaration when we stop maintaining Ubuntu Quantal and 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Precise and Debian Wheezy (binutils 2.23 is required) 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines# define LDPO_PIE 3 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 563e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyusing namespace llvm; 573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 583e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckynamespace { 59c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstruct claimed_file { 60c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines void *handle; 61c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::vector<ld_plugin_symbol> syms; 62c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}; 63c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 65c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic ld_plugin_status discard_message(int level, const char *format, ...) { 66c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Die loudly. Recent versions of Gold pass ld_plugin_message as the first 67c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // callback in the transfer vector. This should never be called. 68c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines abort(); 693e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 703e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ld_plugin_get_input_file get_input_file = nullptr; 7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ld_plugin_release_input_file release_input_file = nullptr; 7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ld_plugin_add_symbols add_symbols = nullptr; 7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ld_plugin_get_symbols get_symbols = nullptr; 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ld_plugin_add_input_file add_input_file = nullptr; 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ld_plugin_set_extra_library_path set_extra_library_path = nullptr; 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ld_plugin_get_view get_view = nullptr; 78c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic ld_plugin_message message = discard_message; 7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic Reloc::Model RelocationModel = Reloc::Default; 80c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic std::string output_name = ""; 81c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic std::list<claimed_file> Modules; 82c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic std::vector<std::string> Cleanup; 83c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic llvm::TargetOptions TargetOpts; 84c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 855c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzovnamespace options { 86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines enum OutputType { 87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OT_NORMAL, 88ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OT_DISABLE, 89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OT_BC_ONLY, 90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OT_SAVE_TEMPS 91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines }; 92f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman static bool generate_api_file = false; 93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static OutputType TheOutputType = OT_NORMAL; 944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar static unsigned OptLevel = 2; 95cfaa636a1d31f2db71df627e4882e9d5c066c419Shuxin Yang static std::string obj_path; 9611f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola static std::string extra_library_path; 97cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola static std::string triple; 982d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola static std::string mcpu; 995c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Additional options to pass into the code generator. 100fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky // Note: This array will contain all plugin options which are not claimed 1015c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // as plugin exclusive to pass to the code generator. 102fc55defb308aa994fae446f66ebc5a197263b81eNick Lewycky // For example, "generate-api-file" and "as"options are for the plugin 1035c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // use only and will not be passed. 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static std::vector<const char *> extra; 1055c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 1066c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola static void process_plugin_option(const char* opt_) 1075c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov { 10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (opt_ == nullptr) 1095c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov return; 1106c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola llvm::StringRef opt = opt_; 1115c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 1126c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola if (opt == "generate-api-file") { 1135c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov generate_api_file = true; 1142d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola } else if (opt.startswith("mcpu=")) { 1152d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola mcpu = opt.substr(strlen("mcpu=")); 11611f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola } else if (opt.startswith("extra-library-path=")) { 11711f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola extra_library_path = opt.substr(strlen("extra_library_path=")); 11815af387bffbf8e1fbab720fd0b92291bb68c023bRafael Espindola } else if (opt.startswith("mtriple=")) { 119cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola triple = opt.substr(strlen("mtriple=")); 120cfaa636a1d31f2db71df627e4882e9d5c066c419Shuxin Yang } else if (opt.startswith("obj-path=")) { 121cfaa636a1d31f2db71df627e4882e9d5c066c419Shuxin Yang obj_path = opt.substr(strlen("obj-path=")); 1226c8099243a0d8ff710e8f657628a8bea99b5dd07Rafael Espindola } else if (opt == "emit-llvm") { 123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheOutputType = OT_BC_ONLY; 12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else if (opt == "save-temps") { 125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheOutputType = OT_SAVE_TEMPS; 126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else if (opt == "disable-output") { 127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TheOutputType = OT_DISABLE; 1284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } else if (opt.size() == 2 && opt[0] == 'O') { 1294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (opt[1] < '0' || opt[1] > '3') 1304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar report_fatal_error("Optimization level must be between 0 and 3"); 1314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OptLevel = opt[1] - '0'; 1325c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } else { 1335c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov // Save this option to pass to the code generator. 13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // ParseCommandLineOptions() expects argv[0] to be program name. Lazily 13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // add that. 13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (extra.empty()) 13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines extra.push_back("LLVMgold"); 13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines extra.push_back(opt_); 1405c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 1415c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov } 1425c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov} 1435c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov 144f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, 145f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman int *claimed); 146f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status all_symbols_read_hook(void); 147f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status cleanup_hook(void); 1483e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1493e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyextern "C" ld_plugin_status onload(ld_plugin_tv *tv); 1503e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewyckyld_plugin_status onload(ld_plugin_tv *tv) { 151c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines InitializeAllTargetInfos(); 152c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines InitializeAllTargets(); 153c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines InitializeAllTargetMCs(); 154c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines InitializeAllAsmParsers(); 155c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines InitializeAllAsmPrinters(); 156c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // We're given a pointer to the first transfer vector. We read through them 1583e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // until we find one where tv_tag == LDPT_NULL. The REGISTER_* tagged values 1593e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // contain pointers to functions that we need to call to register our own 1603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // hooks. The others are addresses of functions we can use to call into gold 1613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky // for services. 1623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky bool registeredClaimFile = false; 164c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines bool RegisteredAllSymbolsRead = false; 1653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1663e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky for (; tv->tv_tag != LDPT_NULL; ++tv) { 1673e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (tv->tv_tag) { 168c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola case LDPT_OUTPUT_NAME: 169c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola output_name = tv->tv_u.tv_string; 170c4b55610d8cdd58e09b570c33c7484a60e500389Rafael Espindola break; 1713e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_LINKER_OUTPUT: 1723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky switch (tv->tv_u.tv_val) { 1733e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_REL: // .o 1743e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_DYN: // .so 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case LDPO_PIE: // position independent executable 17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RelocationModel = Reloc::PIC_; 1773e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1783e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPO_EXEC: // .exe 17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RelocationModel = Reloc::Static; 1803e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1813e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, "Unknown output file type %d", tv->tv_u.tv_val); 1833e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1843e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 1853e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1863e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_OPTION: 1875c00b4af61bb6abff2fb28ddd904808623a7db23Viktor Kutuzov options::process_plugin_option(tv->tv_u.tv_string); 1883e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 1893e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_CLAIM_FILE_HOOK: { 1903e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_claim_file callback; 1913e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_claim_file; 1923e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (callback(claim_file_hook) != LDPS_OK) 1943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 1953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 1963e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky registeredClaimFile = true; 1973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 1983e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK: { 1993e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_all_symbols_read callback; 2003e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_all_symbols_read; 2013e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (callback(all_symbols_read_hook) != LDPS_OK) 2033e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 2048e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola 205c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines RegisteredAllSymbolsRead = true; 2063e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 2073e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_REGISTER_CLEANUP_HOOK: { 2083e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_register_cleanup callback; 2093e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky callback = tv->tv_u.tv_register_cleanup; 2103e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 21137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (callback(cleanup_hook) != LDPS_OK) 2123e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 2133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } break; 21437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPT_GET_INPUT_FILE: 21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines get_input_file = tv->tv_u.tv_get_input_file; 21637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPT_RELEASE_INPUT_FILE: 21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines release_input_file = tv->tv_u.tv_release_input_file; 21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 2203e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_ADD_SYMBOLS: 2213e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky add_symbols = tv->tv_u.tv_add_symbols; 2223e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 223438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7Rafael Espindola case LDPT_GET_SYMBOLS_V2: 2243e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky get_symbols = tv->tv_u.tv_get_symbols; 2253e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2263e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_ADD_INPUT_FILE: 2273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky add_input_file = tv->tv_u.tv_add_input_file; 2283e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 22911f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola case LDPT_SET_EXTRA_LIBRARY_PATH: 23011f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola set_extra_library_path = tv->tv_u.tv_set_extra_library_path; 23111f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola break; 232e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola case LDPT_GET_VIEW: 233e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola get_view = tv->tv_u.tv_get_view; 234e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola break; 2353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky case LDPT_MESSAGE: 2363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky message = tv->tv_u.tv_message; 2373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2383e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky default: 2393e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 2403e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 2413e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 2423e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 24398c507ed5c2883bc8ef487d952e851da37f8b32fRafael Espindola if (!registeredClaimFile) { 24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, "register_claim_file not passed to LLVMgold."); 2456210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola return LDPS_ERR; 2466210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola } 24798c507ed5c2883bc8ef487d952e851da37f8b32fRafael Espindola if (!add_symbols) { 24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, "add_symbols not passed to LLVMgold."); 2496210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola return LDPS_ERR; 2506210a9493a25a9f97f4f0ec62a3ed8ca00f72423Rafael Espindola } 2513e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 252c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!RegisteredAllSymbolsRead) 253c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines return LDPS_OK; 254c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!get_input_file) { 25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, "get_input_file not passed to LLVMgold."); 25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return LDPS_ERR; 258c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!release_input_file) { 26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, "relesase_input_file not passed to LLVMgold."); 26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return LDPS_ERR; 262c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 263c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 2643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 2653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 2663e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const GlobalObject *getBaseObject(const GlobalValue &GV) { 26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (auto *GA = dyn_cast<GlobalAlias>(&GV)) 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return GA->getBaseObject(); 27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return cast<GlobalObject>(&GV); 27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic bool shouldSkip(uint32_t Symflags) { 274ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!(Symflags & object::BasicSymbolRef::SF_Global)) 275ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Symflags & object::BasicSymbolRef::SF_FormatSpecific) 277ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 279ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 280ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 281ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { 282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (const auto *BDI = dyn_cast<BitcodeDiagnosticInfo>(&DI)) { 283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::error_code EC = BDI->getError(); 284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (EC == BitcodeError::InvalidBitcodeSignature) 285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string ErrStorage; 289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines { 290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines raw_string_ostream OS(ErrStorage); 291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DiagnosticPrinterRawOStream DP(OS); 292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DI.print(DP); 293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ld_plugin_level Level; 295ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (DI.getSeverity()) { 296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case DS_Error: 297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s", 298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ErrStorage.c_str()); 299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines llvm_unreachable("Fatal doesn't return."); 300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case DS_Warning: 301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Level = LDPL_WARNING; 302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case DS_Note: 3044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case DS_Remark: 305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Level = LDPL_INFO; 306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines message(Level, "LLVM gold plugin: %s", ErrStorage.c_str()); 309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 311c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// Called by gold to see whether this file is one that our plugin can handle. 312c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// We'll try to open it and register all the symbols with add_symbol if 313c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// possible. 314f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, 315f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohman int *claimed) { 31637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LLVMContext Context; 31737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MemoryBufferRef BufferRef; 31837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<MemoryBuffer> Buffer; 319e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola if (get_view) { 32037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const void *view; 321e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola if (get_view(file->handle, &view) != LDPS_OK) { 32237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, "Failed to get a view of %s", file->name); 323e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola return LDPS_ERR; 324e578252c27a85f3e63eb749006def6d0ce5ef1e1Rafael Espindola } 32537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines BufferRef = MemoryBufferRef(StringRef((const char *)view, file->filesize), ""); 326ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin } else { 32771280b55a3406c7dd4215449bf4a3ab216e78ffdIvan Krasin int64_t offset = 0; 328c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky // Gold has found what might be IR part-way inside of a file, such as 329c1da8864a9a47329af6255567097f01d352eb311Nick Lewycky // an .a archive. 330ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin if (file->offset) { 331ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin offset = file->offset; 332ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin } 333c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 334c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MemoryBuffer::getOpenFileSlice(file->fd, file->name, file->filesize, 335c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines offset); 336c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (std::error_code EC = BufferOrErr.getError()) { 33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, EC.message().c_str()); 338ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin return LDPS_ERR; 339ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin } 34037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Buffer = std::move(BufferOrErr.get()); 34137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines BufferRef = Buffer->getMemBufferRef(); 342b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola } 343ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin 344ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Context.setDiagnosticHandler(diagnosticHandler); 34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr = 346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines object::IRObjectFile::create(BufferRef, Context); 34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::error_code EC = ObjOrErr.getError(); 348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (EC == object::object_error::invalid_file_type || 34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EC == object::object_error::bitcode_section_not_found) 350ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin return LDPS_OK; 351ccb7c906d1a2237c6dca4f4e8fbc4d7dca89979aIvan Krasin 35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *claimed = 1; 35337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (EC) { 35537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, "LLVM gold plugin has failed to create LTO module: %s", 35637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EC.message().c_str()); 35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return LDPS_ERR; 358c170f5f31cd697818bf470b57b72c11a1da78010Ivan Krasin } 35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<object::IRObjectFile> Obj = std::move(*ObjOrErr); 3603e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3613e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky Modules.resize(Modules.size() + 1); 3623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky claimed_file &cf = Modules.back(); 363cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola 3643e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.handle = file->handle; 3653e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &Sym : Obj->symbols()) { 36737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint32_t Symflags = Sym.getFlags(); 368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (shouldSkip(Symflags)) 3693e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky continue; 3703e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 3713e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky cf.syms.push_back(ld_plugin_symbol()); 3723e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky ld_plugin_symbol &sym = cf.syms.back(); 37337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.version = nullptr; 37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 37537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<64> Name; 37637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines { 37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines raw_svector_ostream OS(Name); 37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Sym.printName(OS); 37937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 38037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.name = strdup(Name.c_str()); 38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 38237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl()); 38337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 38437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.visibility = LDPV_DEFAULT; 38537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GV) { 38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (GV->getVisibility()) { 38737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case GlobalValue::DefaultVisibility: 38837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.visibility = LDPV_DEFAULT; 38937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 39037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case GlobalValue::HiddenVisibility: 3913e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_HIDDEN; 3923e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 39337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case GlobalValue::ProtectedVisibility: 3943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.visibility = LDPV_PROTECTED; 3953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky break; 39637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 3973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 3983e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 39937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Symflags & object::BasicSymbolRef::SF_Undefined) { 40037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.def = LDPK_UNDEF; 40137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GV && GV->hasExternalWeakLinkage()) 4027431af050f287011fd52e64034ede6dd98193febRafael Espindola sym.def = LDPK_WEAKUNDEF; 40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 40437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.def = LDPK_DEF; 40537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GV) { 40637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(!GV->hasExternalWeakLinkage() && 40737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines !GV->hasAvailableExternallyLinkage() && "Not a declaration!"); 40837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GV->hasCommonLinkage()) 40937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.def = LDPK_COMMON; 41037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (GV->isWeakForLinker()) 41137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.def = LDPK_WEAKDEF; 41237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 4133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4143e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4153e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.size = 0; 41637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.comdat_key = nullptr; 41737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GV) { 41837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const GlobalObject *Base = getBaseObject(*GV); 41937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Base) 42037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Unable to determine comdat of alias!"); 42137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const Comdat *C = Base->getComdat(); 42237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (C) 42337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.comdat_key = strdup(C->getName().str().c_str()); 42437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (Base->hasWeakLinkage() || Base->hasLinkOnceLinkage()) 42537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sym.comdat_key = strdup(sym.name); 42637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 4273e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4283e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky sym.resolution = LDPR_UNKNOWN; 4293e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 4313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky if (!cf.syms.empty()) { 43237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (add_symbols(cf.handle, cf.syms.size(), &cf.syms[0]) != LDPS_OK) { 43337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, "Unable to add symbols!"); 4343e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_ERR; 4353e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4363e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 4373e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 43837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return LDPS_OK; 43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 44037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 44137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void keepGlobalValue(GlobalValue &GV, 44237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::vector<GlobalAlias *> &KeptAliases) { 44337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(!GV.hasLocalLinkage()); 44437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 44537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (auto *GA = dyn_cast<GlobalAlias>(&GV)) 44637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines KeptAliases.push_back(GA); 44737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 44837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (GV.getLinkage()) { 44937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines default: 45037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 45137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case GlobalValue::LinkOnceAnyLinkage: 45237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GV.setLinkage(GlobalValue::WeakAnyLinkage); 45337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 45437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case GlobalValue::LinkOnceODRLinkage: 45537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GV.setLinkage(GlobalValue::WeakODRLinkage); 45637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 4572d8a1d677c81c8e05d1dbc7832e1ced10cfc629aRafael Espindola } 4588e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola 45937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(!GV.isDiscardableIfUnused()); 46037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 4618e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola 46237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void internalize(GlobalValue &GV) { 46337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GV.isDeclarationForLinker()) 46437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; // We get here if there is a matching asm definition. 46537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!GV.hasLocalLinkage()) 46637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GV.setLinkage(GlobalValue::InternalLinkage); 4673e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 4683e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 46937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void drop(GlobalValue &GV) { 47037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (auto *F = dyn_cast<Function>(&GV)) { 47137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines F->deleteBody(); 47237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines F->setComdat(nullptr); // Should deleteBody do this? 47337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 47437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 47537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 47637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (auto *Var = dyn_cast<GlobalVariable>(&GV)) { 47737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Var->setInitializer(nullptr); 47837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Var->setLinkage( 47937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalValue::ExternalLinkage); // Should setInitializer do this? 48037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Var->setComdat(nullptr); // and this? 48137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 48237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 48337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 48437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto &Alias = cast<GlobalAlias>(GV); 48537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Module &M = *Alias.getParent(); 48637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PointerType &Ty = *cast<PointerType>(Alias.getType()); 48737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalValue::LinkageTypes L = Alias.getLinkage(); 48837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *Var = 48937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines new GlobalVariable(M, Ty.getElementType(), /*isConstant*/ false, L, 49037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /*Initializer*/ nullptr); 49137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Var->takeName(&Alias); 49237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Alias.replaceAllUsesWith(Var); 49337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Alias.eraseFromParent(); 4947e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola} 4957e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola 49637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const char *getResolutionName(ld_plugin_symbol_resolution R) { 49737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (R) { 49837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_UNKNOWN: 49937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "UNKNOWN"; 50037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_UNDEF: 50137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "UNDEF"; 50237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREVAILING_DEF: 50337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "PREVAILING_DEF"; 50437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREVAILING_DEF_IRONLY: 50537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "PREVAILING_DEF_IRONLY"; 50637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREEMPTED_REG: 50737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "PREEMPTED_REG"; 50837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREEMPTED_IR: 50937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "PREEMPTED_IR"; 51037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_RESOLVED_IR: 51137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "RESOLVED_IR"; 51237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_RESOLVED_EXEC: 51337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "RESOLVED_EXEC"; 51437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_RESOLVED_DYN: 51537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "RESOLVED_DYN"; 51637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREVAILING_DEF_IRONLY_EXP: 51737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return "PREVAILING_DEF_IRONLY_EXP"; 51837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 51937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("Unknown resolution"); 52037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 521c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 52237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace { 52337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass LocalValueMaterializer : public ValueMaterializer { 52437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DenseSet<GlobalValue *> &Dropped; 525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DenseMap<GlobalObject *, GlobalObject *> LocalVersions; 52637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 52737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic: 52837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocalValueMaterializer(DenseSet<GlobalValue *> &Dropped) : Dropped(Dropped) {} 52937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Value *materializeValueFor(Value *V) override; 53037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 53137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 53237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 53337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesValue *LocalValueMaterializer::materializeValueFor(Value *V) { 534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *GO = dyn_cast<GlobalObject>(V); 535ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!GO) 53637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 537ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto I = LocalVersions.find(GO); 539ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (I != LocalVersions.end()) 540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return I->second; 541ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 542ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Dropped.count(GO)) 54337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 544ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Module &M = *GO->getParent(); 546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GlobalValue::LinkageTypes L = GO->getLinkage(); 547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GlobalObject *Declaration; 548ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto *F = dyn_cast<Function>(GO)) { 549ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Declaration = Function::Create(F->getFunctionType(), L, "", &M); 550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *Var = cast<GlobalVariable>(GO); 552ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Declaration = new GlobalVariable(M, Var->getType()->getElementType(), 553ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Var->isConstant(), L, 554ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /*Initializer*/ nullptr); 555ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 556ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Declaration->takeName(GO); 557ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Declaration->copyAttributesFrom(GO); 558ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 559ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GO->setLinkage(GlobalValue::InternalLinkage); 560ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GO->setName(Declaration->getName()); 561ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Dropped.erase(GO); 562ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GO->replaceAllUsesWith(Declaration); 563ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 564ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LocalVersions[Declaration] = GO; 565ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 566ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return GO; 56737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 56837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 56937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic Constant *mapConstantToLocalCopy(Constant *C, ValueToValueMapTy &VM, 57037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocalValueMaterializer *Materializer) { 57137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return MapValue(C, VM, RF_IgnoreMissingEntries, nullptr, Materializer); 57237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 57337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 574ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void freeSymName(ld_plugin_symbol &Sym) { 575ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines free(Sym.name); 576ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines free(Sym.comdat_key); 577ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Sym.name = nullptr; 578ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Sym.comdat_key = nullptr; 579ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 580ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 58137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic std::unique_ptr<Module> 582ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesgetModuleForFile(LLVMContext &Context, claimed_file &F, 583ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ld_plugin_input_file &Info, raw_fd_ostream *ApiFile, 58437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringSet<> &Internalize, StringSet<> &Maybe) { 58537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 58637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (get_symbols(F.handle, F.syms.size(), &F.syms[0]) != LDPS_OK) 58737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Failed to get symbol information"); 588ca4286295f7db200724cb488a04ad15441a8ba99Nick Lewycky 58937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const void *View; 59037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (get_view(F.handle, &View) != LDPS_OK) 59137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Failed to get a view of file"); 59237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 593ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MemoryBufferRef BufferRef(StringRef((const char *)View, Info.filesize), 594ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Info.name); 595ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr = 596ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines object::IRObjectFile::create(BufferRef, Context); 597ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 598ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (std::error_code EC = ObjOrErr.getError()) 59937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Could not read bitcode from file : %s", 60037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EC.message().c_str()); 60137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 602ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines object::IRObjectFile &Obj = **ObjOrErr; 60337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 604ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Module &M = Obj.getModule(); 60537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 6064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar M.materializeMetadata(); 607ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines UpgradeDebugInfo(M); 60837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 60937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallPtrSet<GlobalValue *, 8> Used; 610ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); 61137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 61237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DenseSet<GlobalValue *> Drop; 61337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::vector<GlobalAlias *> KeptAliases; 614ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 615ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned SymNum = 0; 616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto &ObjSym : Obj.symbols()) { 617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (shouldSkip(ObjSym.getFlags())) 618ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 619ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ld_plugin_symbol &Sym = F.syms[SymNum]; 620ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ++SymNum; 621ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 62237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ld_plugin_symbol_resolution Resolution = 62337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines (ld_plugin_symbol_resolution)Sym.resolution; 62437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 62537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (options::generate_api_file) 62637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *ApiFile << Sym.name << ' ' << getResolutionName(Resolution) << '\n'; 62737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GlobalValue *GV = Obj.getSymbolGV(ObjSym.getRawDataRefImpl()); 629ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!GV) { 630ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines freeSymName(Sym); 63137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; // Asm symbol. 632ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 63337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 63437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Resolution != LDPR_PREVAILING_DEF_IRONLY && GV->hasCommonLinkage()) { 63537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Common linkage is special. There is no single symbol that wins the 63637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // resolution. Instead we have to collect the maximum alignment and size. 63737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // The IR linker does that for us if we just pass it every common GV. 63837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We still have to keep track of LDPR_PREVAILING_DEF_IRONLY so we 63937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // internalize once the IR linker has done its job. 640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines freeSymName(Sym); 6415e0ac58bef2632a804358ec42a6ba5c6be42c450Nick Lewycky continue; 64237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 643c72f8e9f9d5b7a9c1717428f02ba30ad3f401799Rafael Espindola 64437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (Resolution) { 64537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_UNKNOWN: 64637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("Unexpected resolution"); 64737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 64837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_RESOLVED_IR: 64937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_RESOLVED_EXEC: 65037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_RESOLVED_DYN: 65137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(GV->isDeclarationForLinker()); 65237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 65337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case LDPR_UNDEF: 655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!GV->isDeclarationForLinker()) { 656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(GV->hasComdat()); 657ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Drop.insert(GV); 658ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 659ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 660ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 66137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREVAILING_DEF_IRONLY: { 66237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines keepGlobalValue(*GV, KeptAliases); 66337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Used.count(GV)) { 66437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Since we use the regular lib/Linker, we cannot just internalize GV 66537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // now or it will not be copied to the merged module. Instead we force 66637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // it to be copied and then internalize it. 667ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Internalize.insert(GV->getName()); 6683e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 66937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 67037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 67137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 67237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREVAILING_DEF: 67337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines keepGlobalValue(*GV, KeptAliases); 67437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 67537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 67637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREEMPTED_IR: 67737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Gold might have selected a linkonce_odr and preempted a weak_odr. 67837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // In that case we have to make sure we don't end up internalizing it. 67937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!GV->isDiscardableIfUnused()) 680ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Maybe.erase(GV->getName()); 68137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 68237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // fall-through 68337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREEMPTED_REG: 68437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Drop.insert(GV); 68537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 68637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 68737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LDPR_PREVAILING_DEF_IRONLY_EXP: { 68837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We can only check for address uses after we merge the modules. The 68937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // reason is that this GV might have a copy in another module 69037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // and in that module the address might be significant, but that 69137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // copy will be LDPR_PREEMPTED_IR. 69237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GV->hasLinkOnceODRLinkage()) 693ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Maybe.insert(GV->getName()); 69437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines keepGlobalValue(*GV, KeptAliases); 69537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 69637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 6973e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 69837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 699ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines freeSymName(Sym); 70038a979bf95db020094769194651b91291ca0220cRafael Espindola } 7013e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 70237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ValueToValueMapTy VM; 70337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LocalValueMaterializer Materializer(Drop); 70437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (GlobalAlias *GA : KeptAliases) { 70537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Gold told us to keep GA. It is possible that a GV usied in the aliasee 70637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // expression is being dropped. If that is the case, that GV must be copied. 70737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constant *Aliasee = GA->getAliasee(); 70837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Constant *Replacement = mapConstantToLocalCopy(Aliasee, VM, &Materializer); 709ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GA->setAliasee(Replacement); 71037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 7113e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 71237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto *GV : Drop) 71337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines drop(*GV); 71437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 715ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Obj.takeModule(); 71637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 71737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 71837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void runLTOPasses(Module &M, TargetMachine &TM) { 719ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (const DataLayout *DL = TM.getDataLayout()) 7204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar M.setDataLayout(*DL); 721ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 722ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines legacy::PassManager passes; 723ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines passes.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis())); 724ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 72537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PassManagerBuilder PMB; 726ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple())); 72737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PMB.Inliner = createFunctionInliningPass(); 72837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PMB.VerifyInput = true; 72937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PMB.VerifyOutput = true; 73037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PMB.LoopVectorize = true; 73137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PMB.SLPVectorize = true; 7324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PMB.OptLevel = options::OptLevel; 733ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PMB.populateLTOPassManager(passes); 73437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines passes.run(M); 73537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 73637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 73737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void saveBCFile(StringRef Path, Module &M) { 73837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::error_code EC; 73937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None); 74037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (EC) 74137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Failed to write the output file."); 7422c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true); 74337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 74437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 74537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void codegen(Module &M) { 74637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const std::string &TripleStr = M.getTargetTriple(); 74737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Triple TheTriple(TripleStr); 74837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 74937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string ErrMsg; 75037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg); 75137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!TheTarget) 75237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Target not found: %s", ErrMsg.c_str()); 75337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 75437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (unsigned NumOpts = options::extra.size()) 75537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::ParseCommandLineOptions(NumOpts, &options::extra[0]); 75637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 75737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SubtargetFeatures Features; 75837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Features.getDefaultSubtargetFeatures(TheTriple); 75937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const std::string &A : MAttrs) 76037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Features.AddFeature(A); 76137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 76237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 7634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CodeGenOpt::Level CGOptLevel; 7644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar switch (options::OptLevel) { 7654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case 0: 7664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CGOptLevel = CodeGenOpt::None; 7674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 7684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case 1: 7694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CGOptLevel = CodeGenOpt::Less; 7704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 7714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case 2: 7724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CGOptLevel = CodeGenOpt::Default; 7734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 7744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case 3: 7754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CGOptLevel = CodeGenOpt::Aggressive; 7764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 7774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 77837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine( 77937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TripleStr, options::mcpu, Features.getString(), Options, RelocationModel, 7804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CodeModel::Default, CGOptLevel)); 78137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 78237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines runLTOPasses(M, *TM); 78337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 784ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (options::TheOutputType == options::OT_SAVE_TEMPS) 78537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines saveBCFile(output_name + ".opt.bc", M); 78637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 787ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines legacy::PassManager CodeGenPasses; 78837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 78937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<128> Filename; 79037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int FD; 79137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (options::obj_path.empty()) { 79237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::error_code EC = 79337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); 79437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (EC) 79537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Could not create temporary file: %s", 79637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EC.message().c_str()); 79737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 79837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Filename = options::obj_path; 79937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::error_code EC = 80037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sys::fs::openFileForWrite(Filename.c_str(), FD, sys::fs::F_None); 80137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (EC) 80237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Could not open file: %s", EC.message().c_str()); 80362bacd69c2a21d55c308fb3e94e550559762b32cRafael Espindola } 804648a2e6714885e9b3d2a4f380434fe44ef2c4b5bRafael Espindola 805648a2e6714885e9b3d2a4f380434fe44ef2c4b5bRafael Espindola { 80637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines raw_fd_ostream OS(FD, true); 80737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 8082c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar if (TM->addPassesToEmitFile(CodeGenPasses, OS, 80937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines TargetMachine::CGFT_ObjectFile)) 81037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Failed to setup codegen"); 81137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CodeGenPasses.run(M); 812f29140106f74d15ba357aa0a7f109adc939c3104Dan Gohman } 8133e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 81437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (add_input_file(Filename.c_str()) != LDPS_OK) 81537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, 81637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Unable to add .o file to the link. File left behind in: %s", 81737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Filename.c_str()); 81837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 81937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (options::obj_path.empty()) 82037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Cleanup.push_back(Filename.c_str()); 82137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 82237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 82337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// gold informs us that all symbols have been read. At this point, we use 82437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// get_symbols to see if any of our definitions have been overridden by a 82537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// native object file. Then, perform optimization and codegen. 82637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { 82737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Modules.empty()) 82837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return LDPS_OK; 82937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 83037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LLVMContext Context; 8314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Context.setDiagnosticHandler(diagnosticHandler, nullptr, true); 832ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 83337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context)); 83437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Linker L(Combined.get()); 83537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 83637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string DefaultTriple = sys::getDefaultTargetTriple(); 83737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 83837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringSet<> Internalize; 83937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringSet<> Maybe; 84037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (claimed_file &F : Modules) { 841ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ld_plugin_input_file File; 842ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (get_input_file(F.handle, &File) != LDPS_OK) 843ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines message(LDPL_FATAL, "Failed to get file information"); 84437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<Module> M = 845ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe); 84637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!options::triple.empty()) 84737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M->setTargetTriple(options::triple.c_str()); 84837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else if (M->getTargetTriple().empty()) { 84937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M->setTargetTriple(DefaultTriple); 8508e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola } 85137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 85237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (L.linkInModule(M.get())) 85337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Failed to link module"); 854ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (release_input_file(F.handle) != LDPS_OK) 855ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines message(LDPL_FATAL, "Failed to release file information"); 8568e04fc3adf3419eeb9466b66cbaf9b027dcc2cabRafael Espindola } 8573e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 85837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &Name : Internalize) { 85937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalValue *GV = Combined->getNamedValue(Name.first()); 86037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (GV) 86137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines internalize(*GV); 8623e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky } 8633e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 86437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &Name : Maybe) { 86537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GlobalValue *GV = Combined->getNamedValue(Name.first()); 86637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!GV) 86737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 86837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GV->setLinkage(GlobalValue::LinkOnceODRLinkage); 86937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (canBeOmittedFromSymbolTable(GV)) 87037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines internalize(*GV); 87111f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola } 87211f403cf2be4d562f731571aee90bc25bd2d38aeRafael Espindola 873ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (options::TheOutputType == options::OT_DISABLE) 874ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return LDPS_OK; 875ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 876ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (options::TheOutputType != options::OT_NORMAL) { 87737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string path; 878ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (options::TheOutputType == options::OT_BC_ONLY) 87937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines path = output_name; 88037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 88137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines path = output_name + ".bc"; 88237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines saveBCFile(path, *L.getModule()); 883ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (options::TheOutputType == options::OT_BC_ONLY) 88437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return LDPS_OK; 88537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 88637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 88737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines codegen(*L.getModule()); 88837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 88937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!options::extra_library_path.empty() && 89037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK) 89137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Unable to set the extra library path."); 892cfaa636a1d31f2db71df627e4882e9d5c066c419Shuxin Yang 8933e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 8943e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 8953e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 89637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic ld_plugin_status all_symbols_read_hook(void) { 89737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ld_plugin_status Ret; 89837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!options::generate_api_file) { 89937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ret = allSymbolsReadHook(nullptr); 90037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } else { 90137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::error_code EC; 90237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines raw_fd_ostream ApiFile("apifile.txt", EC, sys::fs::F_None); 90337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (EC) 90437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_FATAL, "Unable to open apifile.txt for writing: %s", 90537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EC.message().c_str()); 90637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Ret = allSymbolsReadHook(&ApiFile); 90737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 90837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 909ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines llvm_shutdown(); 910ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 911ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (options::TheOutputType == options::OT_BC_ONLY || 912ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines options::TheOutputType == options::OT_DISABLE) { 913ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (options::TheOutputType == options::OT_DISABLE) 914ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Remove the output file here since ld.bfd creates the output file 915ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // early. 916ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines sys::fs::remove(output_name); 91737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines exit(0); 918ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 91937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 92037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Ret; 92137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 92237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 923f6920033e0ad2cd1e18d52dd56d0e8a3384faf72Dan Gohmanstatic ld_plugin_status cleanup_hook(void) { 92437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (std::string &Name : Cleanup) { 92537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::error_code EC = sys::fs::remove(Name); 926b33941107080129a912632573e5a53f950c3610aRafael Espindola if (EC) 92737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines message(LDPL_ERROR, "Failed to delete '%s': %s", Name.c_str(), 92837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EC.message().c_str()); 929b33941107080129a912632573e5a53f950c3610aRafael Espindola } 9303e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky 9313e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky return LDPS_OK; 9323e62b2dc93dae6904f0717612782ab6ebf413e1dNick Lewycky} 933