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