blob: 144a8eb90da601118930018185b829a7b76286d6 [file] [log] [blame]
Nick Lewyckyfb643e42009-02-03 07:13:24 +00001//===-- gold-plugin.cpp - Plugin to gold for Link Time Optimization ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This is a gold plugin for LLVM. It provides an LLVM implementation of the
11// interface described in http://gcc.gnu.org/wiki/whopr/driver .
12//
13//===----------------------------------------------------------------------===//
14
Rafael Espindola33466a72014-08-21 20:28:55 +000015#include "llvm/Bitcode/ReaderWriter.h"
Rafael Espindola6b244b12014-06-19 21:14:13 +000016#include "llvm/CodeGen/CommandFlags.h"
Mehdi Aminib550cb12016-04-18 09:17:29 +000017#include "llvm/Config/config.h" // plugin-api.h requires HAVE_STDINT_H
Rafael Espindola890db272014-09-09 20:08:22 +000018#include "llvm/IR/Constants.h"
Rafael Espindolad0b23be2015-01-10 00:07:30 +000019#include "llvm/IR/DiagnosticPrinter.h"
Teresa Johnson683abe72016-05-26 01:46:41 +000020#include "llvm/LTO/LTO.h"
Teresa Johnson9ba95f92016-08-11 14:58:12 +000021#include "llvm/Support/CommandLine.h"
Rafael Espindola947bdb62014-11-25 20:52:49 +000022#include "llvm/Support/ManagedStatic.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000023#include "llvm/Support/MemoryBuffer.h"
Teresa Johnsonbbd10b42016-05-17 14:45:30 +000024#include "llvm/Support/Path.h"
Rafael Espindola6b244b12014-06-19 21:14:13 +000025#include "llvm/Support/TargetSelect.h"
Teresa Johnsonb13dbd62015-12-09 19:45:55 +000026#include "llvm/Support/raw_ostream.h"
Nick Lewyckyfb643e42009-02-03 07:13:24 +000027#include <list>
Teresa Johnson9ba95f92016-08-11 14:58:12 +000028#include <map>
Chandler Carruth07baed52014-01-13 08:04:33 +000029#include <plugin-api.h>
Teresa Johnson9ba95f92016-08-11 14:58:12 +000030#include <string>
Rafael Espindolaa6e9c3e2014-06-12 17:38:55 +000031#include <system_error>
Benjamin Kramer82de7d32016-05-27 14:27:24 +000032#include <utility>
Nick Lewyckyfb643e42009-02-03 07:13:24 +000033#include <vector>
34
Sylvestre Ledru53999792014-02-11 17:30:18 +000035// FIXME: remove this declaration when we stop maintaining Ubuntu Quantal and
36// Precise and Debian Wheezy (binutils 2.23 is required)
Evgeniy Stepanov330c5a62016-03-04 00:23:29 +000037#define LDPO_PIE 3
38
39#define LDPT_GET_SYMBOLS_V3 28
Sylvestre Ledru53999792014-02-11 17:30:18 +000040
Nick Lewyckyfb643e42009-02-03 07:13:24 +000041using namespace llvm;
Teresa Johnson9ba95f92016-08-11 14:58:12 +000042using namespace lto;
Nick Lewyckyfb643e42009-02-03 07:13:24 +000043
Teresa Johnsoncb15b732015-12-16 16:34:06 +000044static ld_plugin_status discard_message(int level, const char *format, ...) {
45 // Die loudly. Recent versions of Gold pass ld_plugin_message as the first
46 // callback in the transfer vector. This should never be called.
47 abort();
48}
49
50static ld_plugin_release_input_file release_input_file = nullptr;
51static ld_plugin_get_input_file get_input_file = nullptr;
52static ld_plugin_message message = discard_message;
53
Nick Lewyckyfb643e42009-02-03 07:13:24 +000054namespace {
Rafael Espindolabfb8b912014-06-20 01:37:35 +000055struct claimed_file {
56 void *handle;
Teresa Johnson683abe72016-05-26 01:46:41 +000057 void *leader_handle;
Rafael Espindolabfb8b912014-06-20 01:37:35 +000058 std::vector<ld_plugin_symbol> syms;
Teresa Johnson683abe72016-05-26 01:46:41 +000059 off_t filesize;
60 std::string name;
Rafael Espindolabfb8b912014-06-20 01:37:35 +000061};
Rafael Espindolacaabe222015-12-10 14:19:35 +000062
Teresa Johnsoncb15b732015-12-16 16:34:06 +000063/// RAII wrapper to manage opening and releasing of a ld_plugin_input_file.
64struct PluginInputFile {
Teresa Johnson031bed22015-12-16 21:37:48 +000065 void *Handle;
Teresa Johnson7cffaf32016-03-04 17:06:02 +000066 std::unique_ptr<ld_plugin_input_file> File;
Teresa Johnsoncb15b732015-12-16 16:34:06 +000067
Teresa Johnson031bed22015-12-16 21:37:48 +000068 PluginInputFile(void *Handle) : Handle(Handle) {
Teresa Johnson7cffaf32016-03-04 17:06:02 +000069 File = llvm::make_unique<ld_plugin_input_file>();
70 if (get_input_file(Handle, File.get()) != LDPS_OK)
Teresa Johnsoncb15b732015-12-16 16:34:06 +000071 message(LDPL_FATAL, "Failed to get file information");
72 }
73 ~PluginInputFile() {
Teresa Johnson7cffaf32016-03-04 17:06:02 +000074 // File would have been reset to nullptr if we moved this object
75 // to a new owner.
76 if (File)
77 if (release_input_file(Handle) != LDPS_OK)
78 message(LDPL_FATAL, "Failed to release file information");
Teresa Johnsoncb15b732015-12-16 16:34:06 +000079 }
Teresa Johnson7cffaf32016-03-04 17:06:02 +000080
81 ld_plugin_input_file &file() { return *File; }
82
83 PluginInputFile(PluginInputFile &&RHS) = default;
84 PluginInputFile &operator=(PluginInputFile &&RHS) = default;
Teresa Johnsoncb15b732015-12-16 16:34:06 +000085};
86
Rafael Espindolacaabe222015-12-10 14:19:35 +000087struct ResolutionInfo {
Teresa Johnson9ba95f92016-08-11 14:58:12 +000088 bool CanOmitFromDynSym = true;
89 bool DefaultVisibility = true;
Rafael Espindolacaabe222015-12-10 14:19:35 +000090};
Teresa Johnson7cffaf32016-03-04 17:06:02 +000091
Teresa Johnson9ba95f92016-08-11 14:58:12 +000092struct CommonResolution {
93 bool Prevailing = false;
94 bool VisibleToRegularObj = false;
95 uint64_t Size = 0;
96 unsigned Align = 0;
Teresa Johnsoncbf684e2016-08-11 13:03:56 +000097};
Teresa Johnson9ba95f92016-08-11 14:58:12 +000098
Nick Lewyckyfb643e42009-02-03 07:13:24 +000099}
Rafael Espindolabfb8b912014-06-20 01:37:35 +0000100
Rafael Espindola176e6642014-07-29 21:46:05 +0000101static ld_plugin_add_symbols add_symbols = nullptr;
102static ld_plugin_get_symbols get_symbols = nullptr;
103static ld_plugin_add_input_file add_input_file = nullptr;
104static ld_plugin_set_extra_library_path set_extra_library_path = nullptr;
105static ld_plugin_get_view get_view = nullptr;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000106static bool IsExecutable = false;
Rafael Espindola8c34dd82016-05-18 22:04:49 +0000107static Optional<Reloc::Model> RelocationModel;
Rafael Espindolabfb8b912014-06-20 01:37:35 +0000108static std::string output_name = "";
109static std::list<claimed_file> Modules;
Teresa Johnson683abe72016-05-26 01:46:41 +0000110static DenseMap<int, void *> FDToLeaderHandle;
Rafael Espindolacaabe222015-12-10 14:19:35 +0000111static StringMap<ResolutionInfo> ResInfo;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000112static std::map<std::string, CommonResolution> Commons;
Rafael Espindolabfb8b912014-06-20 01:37:35 +0000113static std::vector<std::string> Cleanup;
Rafael Espindola6b244b12014-06-19 21:14:13 +0000114static llvm::TargetOptions TargetOpts;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000115static size_t MaxTasks;
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000116
Viktor Kutuzovfd7ddd92009-10-28 18:55:55 +0000117namespace options {
Rafael Espindola6953a3a2014-11-24 21:18:14 +0000118 enum OutputType {
119 OT_NORMAL,
120 OT_DISABLE,
121 OT_BC_ONLY,
122 OT_SAVE_TEMPS
123 };
Rafael Espindola6953a3a2014-11-24 21:18:14 +0000124 static OutputType TheOutputType = OT_NORMAL;
Peter Collingbourne070843d2015-03-19 22:01:00 +0000125 static unsigned OptLevel = 2;
Teresa Johnsona9f65552016-03-04 16:36:06 +0000126 // Default parallelism of 0 used to indicate that user did not specify.
127 // Actual parallelism default value depends on implementation.
Teresa Johnson7cffaf32016-03-04 17:06:02 +0000128 // Currently, code generation defaults to no parallelism, whereas
129 // ThinLTO uses the hardware_concurrency as the default.
Teresa Johnsona9f65552016-03-04 16:36:06 +0000130 static unsigned Parallelism = 0;
Teresa Johnson8c8fe5a2015-09-16 18:06:45 +0000131#ifdef NDEBUG
132 static bool DisableVerify = true;
133#else
134 static bool DisableVerify = false;
135#endif
Shuxin Yang1826ae22013-08-12 21:07:31 +0000136 static std::string obj_path;
Rafael Espindolaef498152010-06-23 20:20:59 +0000137 static std::string extra_library_path;
Rafael Espindola4ef89f52010-08-09 21:09:46 +0000138 static std::string triple;
Rafael Espindolaccab1dd2010-08-11 00:15:13 +0000139 static std::string mcpu;
Teresa Johnson403a7872015-10-04 14:33:43 +0000140 // When the thinlto plugin option is specified, only read the function
141 // the information from intermediate files and write a combined
142 // global index for the ThinLTO backends.
143 static bool thinlto = false;
Teresa Johnson7cffaf32016-03-04 17:06:02 +0000144 // If false, all ThinLTO backend compilations through code gen are performed
145 // using multiple threads in the gold-plugin, before handing control back to
Teresa Johnson84174c32016-05-10 13:48:23 +0000146 // gold. If true, write individual backend index files which reflect
147 // the import decisions, and exit afterwards. The assumption is
Teresa Johnson7cffaf32016-03-04 17:06:02 +0000148 // that the build system will launch the backend processes.
149 static bool thinlto_index_only = false;
Teresa Johnson1e2708c2016-07-22 18:20:22 +0000150 // If non-empty, holds the name of a file in which to write the list of
151 // oject files gold selected for inclusion in the link after symbol
152 // resolution (i.e. they had selected symbols). This will only be non-empty
153 // in the thinlto_index_only case. It is used to identify files, which may
154 // have originally been within archive libraries specified via
155 // --start-lib/--end-lib pairs, that should be included in the final
156 // native link process (since intervening function importing and inlining
157 // may change the symbol resolution detected in the final link and which
158 // files to include out of --start-lib/--end-lib libraries as a result).
159 static std::string thinlto_linked_objects_file;
Teresa Johnson8570fe42016-05-10 15:54:09 +0000160 // If true, when generating individual index files for distributed backends,
161 // also generate a "${bitcodefile}.imports" file at the same location for each
162 // bitcode file, listing the files it imports from in plain text. This is to
163 // support distributed build file staging.
164 static bool thinlto_emit_imports_files = false;
Teresa Johnsonbbd10b42016-05-17 14:45:30 +0000165 // Option to control where files for a distributed backend (the individual
166 // index files and optional imports files) are created.
167 // If specified, expects a string of the form "oldprefix:newprefix", and
168 // instead of generating these files in the same directory path as the
169 // corresponding bitcode file, will use a path formed by replacing the
170 // bitcode file's path prefix matching oldprefix with newprefix.
171 static std::string thinlto_prefix_replace;
Viktor Kutuzovfd7ddd92009-10-28 18:55:55 +0000172 // Additional options to pass into the code generator.
Nick Lewycky0ac5e222010-06-03 17:10:17 +0000173 // Note: This array will contain all plugin options which are not claimed
Viktor Kutuzovfd7ddd92009-10-28 18:55:55 +0000174 // as plugin exclusive to pass to the code generator.
Rafael Espindola125b9242014-07-29 19:17:44 +0000175 static std::vector<const char *> extra;
Viktor Kutuzovfd7ddd92009-10-28 18:55:55 +0000176
Nick Lewycky7282dd72015-08-05 21:16:02 +0000177 static void process_plugin_option(const char *opt_)
Viktor Kutuzovfd7ddd92009-10-28 18:55:55 +0000178 {
Rafael Espindola176e6642014-07-29 21:46:05 +0000179 if (opt_ == nullptr)
Viktor Kutuzovfd7ddd92009-10-28 18:55:55 +0000180 return;
Rafael Espindolac4dca3a2010-06-07 16:45:22 +0000181 llvm::StringRef opt = opt_;
Viktor Kutuzovfd7ddd92009-10-28 18:55:55 +0000182
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000183 if (opt.startswith("mcpu=")) {
Rafael Espindolaccab1dd2010-08-11 00:15:13 +0000184 mcpu = opt.substr(strlen("mcpu="));
Rafael Espindolaef498152010-06-23 20:20:59 +0000185 } else if (opt.startswith("extra-library-path=")) {
186 extra_library_path = opt.substr(strlen("extra_library_path="));
Rafael Espindola148c3282010-08-10 16:32:15 +0000187 } else if (opt.startswith("mtriple=")) {
Rafael Espindola4ef89f52010-08-09 21:09:46 +0000188 triple = opt.substr(strlen("mtriple="));
Shuxin Yang1826ae22013-08-12 21:07:31 +0000189 } else if (opt.startswith("obj-path=")) {
190 obj_path = opt.substr(strlen("obj-path="));
Rafael Espindolac4dca3a2010-06-07 16:45:22 +0000191 } else if (opt == "emit-llvm") {
Rafael Espindola6953a3a2014-11-24 21:18:14 +0000192 TheOutputType = OT_BC_ONLY;
Rafael Espindola4a3b6cf2014-10-29 23:54:45 +0000193 } else if (opt == "save-temps") {
Rafael Espindola6953a3a2014-11-24 21:18:14 +0000194 TheOutputType = OT_SAVE_TEMPS;
195 } else if (opt == "disable-output") {
196 TheOutputType = OT_DISABLE;
Teresa Johnson403a7872015-10-04 14:33:43 +0000197 } else if (opt == "thinlto") {
198 thinlto = true;
Teresa Johnson7cffaf32016-03-04 17:06:02 +0000199 } else if (opt == "thinlto-index-only") {
200 thinlto_index_only = true;
Teresa Johnson1e2708c2016-07-22 18:20:22 +0000201 } else if (opt.startswith("thinlto-index-only=")) {
202 thinlto_index_only = true;
203 thinlto_linked_objects_file = opt.substr(strlen("thinlto-index-only="));
Teresa Johnson8570fe42016-05-10 15:54:09 +0000204 } else if (opt == "thinlto-emit-imports-files") {
205 thinlto_emit_imports_files = true;
Teresa Johnsonbbd10b42016-05-17 14:45:30 +0000206 } else if (opt.startswith("thinlto-prefix-replace=")) {
207 thinlto_prefix_replace = opt.substr(strlen("thinlto-prefix-replace="));
Reid Kleckner8e96c3e2016-05-17 18:43:22 +0000208 if (thinlto_prefix_replace.find(";") == std::string::npos)
209 message(LDPL_FATAL, "thinlto-prefix-replace expects 'old;new' format");
Peter Collingbourne070843d2015-03-19 22:01:00 +0000210 } else if (opt.size() == 2 && opt[0] == 'O') {
211 if (opt[1] < '0' || opt[1] > '3')
Peter Collingbourne87202a42015-09-01 20:40:22 +0000212 message(LDPL_FATAL, "Optimization level must be between 0 and 3");
Peter Collingbourne070843d2015-03-19 22:01:00 +0000213 OptLevel = opt[1] - '0';
Peter Collingbourne87202a42015-09-01 20:40:22 +0000214 } else if (opt.startswith("jobs=")) {
215 if (StringRef(opt_ + 5).getAsInteger(10, Parallelism))
216 message(LDPL_FATAL, "Invalid parallelism level: %s", opt_ + 5);
Teresa Johnson8c8fe5a2015-09-16 18:06:45 +0000217 } else if (opt == "disable-verify") {
218 DisableVerify = true;
Viktor Kutuzovfd7ddd92009-10-28 18:55:55 +0000219 } else {
220 // Save this option to pass to the code generator.
Rafael Espindola33466a72014-08-21 20:28:55 +0000221 // ParseCommandLineOptions() expects argv[0] to be program name. Lazily
222 // add that.
223 if (extra.empty())
224 extra.push_back("LLVMgold");
225
Rafael Espindola125b9242014-07-29 19:17:44 +0000226 extra.push_back(opt_);
Viktor Kutuzovfd7ddd92009-10-28 18:55:55 +0000227 }
228 }
229}
230
Dan Gohmanebb4ae02010-04-16 00:42:57 +0000231static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
232 int *claimed);
233static ld_plugin_status all_symbols_read_hook(void);
234static ld_plugin_status cleanup_hook(void);
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000235
236extern "C" ld_plugin_status onload(ld_plugin_tv *tv);
237ld_plugin_status onload(ld_plugin_tv *tv) {
Peter Collingbourne1505c0a2014-07-03 23:28:03 +0000238 InitializeAllTargetInfos();
239 InitializeAllTargets();
240 InitializeAllTargetMCs();
241 InitializeAllAsmParsers();
242 InitializeAllAsmPrinters();
243
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000244 // We're given a pointer to the first transfer vector. We read through them
245 // until we find one where tv_tag == LDPT_NULL. The REGISTER_* tagged values
246 // contain pointers to functions that we need to call to register our own
247 // hooks. The others are addresses of functions we can use to call into gold
248 // for services.
249
250 bool registeredClaimFile = false;
Rafael Espindola6b244b12014-06-19 21:14:13 +0000251 bool RegisteredAllSymbolsRead = false;
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000252
253 for (; tv->tv_tag != LDPT_NULL; ++tv) {
Evgeniy Stepanov330c5a62016-03-04 00:23:29 +0000254 // Cast tv_tag to int to allow values not in "enum ld_plugin_tag", like, for
255 // example, LDPT_GET_SYMBOLS_V3 when building against an older plugin-api.h
256 // header.
257 switch (static_cast<int>(tv->tv_tag)) {
258 case LDPT_OUTPUT_NAME:
259 output_name = tv->tv_u.tv_string;
260 break;
261 case LDPT_LINKER_OUTPUT:
262 switch (tv->tv_u.tv_val) {
263 case LDPO_REL: // .o
264 case LDPO_DYN: // .so
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000265 IsExecutable = false;
266 RelocationModel = Reloc::PIC_;
267 break;
Evgeniy Stepanov330c5a62016-03-04 00:23:29 +0000268 case LDPO_PIE: // position independent executable
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000269 IsExecutable = true;
Evgeniy Stepanov330c5a62016-03-04 00:23:29 +0000270 RelocationModel = Reloc::PIC_;
Rafael Espindola8fb957e2010-06-03 21:11:20 +0000271 break;
Evgeniy Stepanov330c5a62016-03-04 00:23:29 +0000272 case LDPO_EXEC: // .exe
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000273 IsExecutable = true;
Evgeniy Stepanov330c5a62016-03-04 00:23:29 +0000274 RelocationModel = Reloc::Static;
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000275 break;
276 default:
Evgeniy Stepanov330c5a62016-03-04 00:23:29 +0000277 message(LDPL_ERROR, "Unknown output file type %d", tv->tv_u.tv_val);
278 return LDPS_ERR;
279 }
280 break;
281 case LDPT_OPTION:
282 options::process_plugin_option(tv->tv_u.tv_string);
283 break;
284 case LDPT_REGISTER_CLAIM_FILE_HOOK: {
285 ld_plugin_register_claim_file callback;
286 callback = tv->tv_u.tv_register_claim_file;
287
288 if (callback(claim_file_hook) != LDPS_OK)
289 return LDPS_ERR;
290
291 registeredClaimFile = true;
292 } break;
293 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK: {
294 ld_plugin_register_all_symbols_read callback;
295 callback = tv->tv_u.tv_register_all_symbols_read;
296
297 if (callback(all_symbols_read_hook) != LDPS_OK)
298 return LDPS_ERR;
299
300 RegisteredAllSymbolsRead = true;
301 } break;
302 case LDPT_REGISTER_CLEANUP_HOOK: {
303 ld_plugin_register_cleanup callback;
304 callback = tv->tv_u.tv_register_cleanup;
305
306 if (callback(cleanup_hook) != LDPS_OK)
307 return LDPS_ERR;
308 } break;
309 case LDPT_GET_INPUT_FILE:
310 get_input_file = tv->tv_u.tv_get_input_file;
311 break;
312 case LDPT_RELEASE_INPUT_FILE:
313 release_input_file = tv->tv_u.tv_release_input_file;
314 break;
315 case LDPT_ADD_SYMBOLS:
316 add_symbols = tv->tv_u.tv_add_symbols;
317 break;
318 case LDPT_GET_SYMBOLS_V2:
319 // Do not override get_symbols_v3 with get_symbols_v2.
320 if (!get_symbols)
321 get_symbols = tv->tv_u.tv_get_symbols;
322 break;
323 case LDPT_GET_SYMBOLS_V3:
324 get_symbols = tv->tv_u.tv_get_symbols;
325 break;
326 case LDPT_ADD_INPUT_FILE:
327 add_input_file = tv->tv_u.tv_add_input_file;
328 break;
329 case LDPT_SET_EXTRA_LIBRARY_PATH:
330 set_extra_library_path = tv->tv_u.tv_set_extra_library_path;
331 break;
332 case LDPT_GET_VIEW:
333 get_view = tv->tv_u.tv_get_view;
334 break;
335 case LDPT_MESSAGE:
336 message = tv->tv_u.tv_message;
337 break;
338 default:
339 break;
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000340 }
341 }
342
Rafael Espindolae08484d2009-02-18 08:30:15 +0000343 if (!registeredClaimFile) {
Rafael Espindola5ad21fa2014-07-30 00:38:58 +0000344 message(LDPL_ERROR, "register_claim_file not passed to LLVMgold.");
Rafael Espindola6add6182009-02-18 17:49:06 +0000345 return LDPS_ERR;
346 }
Rafael Espindolae08484d2009-02-18 08:30:15 +0000347 if (!add_symbols) {
Rafael Espindola5ad21fa2014-07-30 00:38:58 +0000348 message(LDPL_ERROR, "add_symbols not passed to LLVMgold.");
Rafael Espindola6add6182009-02-18 17:49:06 +0000349 return LDPS_ERR;
350 }
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000351
Rafael Espindolaa0d30a92014-06-19 22:20:07 +0000352 if (!RegisteredAllSymbolsRead)
353 return LDPS_OK;
Rafael Espindola6b244b12014-06-19 21:14:13 +0000354
Rafael Espindola33466a72014-08-21 20:28:55 +0000355 if (!get_input_file) {
356 message(LDPL_ERROR, "get_input_file not passed to LLVMgold.");
357 return LDPS_ERR;
Rafael Espindolac273aac2014-06-19 22:54:47 +0000358 }
Rafael Espindola33466a72014-08-21 20:28:55 +0000359 if (!release_input_file) {
Marianne Mailhot-Sarrasina5a750e2016-03-30 12:20:53 +0000360 message(LDPL_ERROR, "release_input_file not passed to LLVMgold.");
Rafael Espindola33466a72014-08-21 20:28:55 +0000361 return LDPS_ERR;
Tom Roederb5081192014-06-26 20:43:27 +0000362 }
363
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000364 return LDPS_OK;
365}
366
NAKAMURA Takumib13e63c2015-11-19 10:43:44 +0000367static void diagnosticHandler(const DiagnosticInfo &DI) {
Rafael Espindola503f8832015-03-02 19:08:03 +0000368 if (const auto *BDI = dyn_cast<BitcodeDiagnosticInfo>(&DI)) {
369 std::error_code EC = BDI->getError();
370 if (EC == BitcodeError::InvalidBitcodeSignature)
371 return;
372 }
Rafael Espindolad0b23be2015-01-10 00:07:30 +0000373
374 std::string ErrStorage;
375 {
376 raw_string_ostream OS(ErrStorage);
377 DiagnosticPrinterRawOStream DP(OS);
378 DI.print(DP);
379 }
Rafael Espindola503f8832015-03-02 19:08:03 +0000380 ld_plugin_level Level;
381 switch (DI.getSeverity()) {
382 case DS_Error:
383 message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s",
384 ErrStorage.c_str());
Rafael Espindola503f8832015-03-02 19:08:03 +0000385 case DS_Warning:
386 Level = LDPL_WARNING;
387 break;
388 case DS_Note:
Rafael Espindolaf3f18542015-03-04 18:51:45 +0000389 case DS_Remark:
Rafael Espindola503f8832015-03-02 19:08:03 +0000390 Level = LDPL_INFO;
391 break;
Rafael Espindola503f8832015-03-02 19:08:03 +0000392 }
393 message(Level, "LLVM gold plugin: %s", ErrStorage.c_str());
Rafael Espindolad0b23be2015-01-10 00:07:30 +0000394}
395
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000396static void check(Error E, std::string Msg = "LLVM gold plugin") {
397 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
398 message(LDPL_FATAL, "%s: %s", Msg.c_str(), EIB.message().c_str());
399 return Error::success();
400 });
NAKAMURA Takumib13e63c2015-11-19 10:43:44 +0000401}
402
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000403template <typename T> static T check(Expected<T> E) {
404 if (E)
405 return std::move(*E);
406 check(E.takeError());
407 return T();
Rafael Espindolacaabe222015-12-10 14:19:35 +0000408}
409
Rafael Espindolae54d8212014-07-06 14:31:22 +0000410/// Called by gold to see whether this file is one that our plugin can handle.
411/// We'll try to open it and register all the symbols with add_symbol if
412/// possible.
Dan Gohmanebb4ae02010-04-16 00:42:57 +0000413static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
414 int *claimed) {
Rafael Espindolaeeec8e62014-08-27 20:25:55 +0000415 MemoryBufferRef BufferRef;
416 std::unique_ptr<MemoryBuffer> Buffer;
Rafael Espindolaece7c9c2011-04-07 21:11:00 +0000417 if (get_view) {
Rafael Espindola33466a72014-08-21 20:28:55 +0000418 const void *view;
Rafael Espindolaece7c9c2011-04-07 21:11:00 +0000419 if (get_view(file->handle, &view) != LDPS_OK) {
Rafael Espindola5ad21fa2014-07-30 00:38:58 +0000420 message(LDPL_ERROR, "Failed to get a view of %s", file->name);
Rafael Espindolaece7c9c2011-04-07 21:11:00 +0000421 return LDPS_ERR;
422 }
Nick Lewycky7282dd72015-08-05 21:16:02 +0000423 BufferRef =
424 MemoryBufferRef(StringRef((const char *)view, file->filesize), "");
Ivan Krasin5021af52011-09-12 21:47:50 +0000425 } else {
Ivan Krasin639222d2011-09-15 23:13:00 +0000426 int64_t offset = 0;
Nick Lewycky8691c472009-02-05 04:14:23 +0000427 // Gold has found what might be IR part-way inside of a file, such as
428 // an .a archive.
Ivan Krasin5021af52011-09-12 21:47:50 +0000429 if (file->offset) {
430 offset = file->offset;
431 }
Rafael Espindolaadf21f22014-07-06 17:43:13 +0000432 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
433 MemoryBuffer::getOpenFileSlice(file->fd, file->name, file->filesize,
434 offset);
435 if (std::error_code EC = BufferOrErr.getError()) {
Rafael Espindola5ad21fa2014-07-30 00:38:58 +0000436 message(LDPL_ERROR, EC.message().c_str());
Ivan Krasin5021af52011-09-12 21:47:50 +0000437 return LDPS_ERR;
438 }
Rafael Espindolaeeec8e62014-08-27 20:25:55 +0000439 Buffer = std::move(BufferOrErr.get());
440 BufferRef = Buffer->getMemBufferRef();
Rafael Espindola56e41f72011-02-08 22:40:47 +0000441 }
Ivan Krasin5021af52011-09-12 21:47:50 +0000442
Rafael Espindola6c472e52014-07-29 20:46:19 +0000443 *claimed = 1;
444
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000445 Expected<std::unique_ptr<InputFile>> ObjOrErr = InputFile::create(BufferRef);
446 if (!ObjOrErr) {
447 handleAllErrors(ObjOrErr.takeError(), [&](const ErrorInfoBase &EI) {
448 std::error_code EC = EI.convertToErrorCode();
449 if (EC == object::object_error::invalid_file_type ||
450 EC == object::object_error::bitcode_section_not_found)
451 *claimed = 0;
452 else
453 message(LDPL_ERROR,
454 "LLVM gold plugin has failed to create LTO module: %s",
455 EI.message().c_str());
456 });
457
458 return *claimed ? LDPS_ERR : LDPS_OK;
Ivan Krasind5f2d8c2011-09-09 00:14:04 +0000459 }
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000460
461 std::unique_ptr<InputFile> Obj = std::move(*ObjOrErr);
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000462
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000463 Modules.resize(Modules.size() + 1);
464 claimed_file &cf = Modules.back();
Rafael Espindola4ef89f52010-08-09 21:09:46 +0000465
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000466 cf.handle = file->handle;
Teresa Johnson683abe72016-05-26 01:46:41 +0000467 // Keep track of the first handle for each file descriptor, since there are
468 // multiple in the case of an archive. This is used later in the case of
469 // ThinLTO parallel backends to ensure that each file is only opened and
470 // released once.
471 auto LeaderHandle =
472 FDToLeaderHandle.insert(std::make_pair(file->fd, file->handle)).first;
473 cf.leader_handle = LeaderHandle->second;
474 // Save the filesize since for parallel ThinLTO backends we can only
475 // invoke get_input_file once per archive (only for the leader handle).
476 cf.filesize = file->filesize;
477 // In the case of an archive library, all but the first member must have a
478 // non-zero offset, which we can append to the file name to obtain a
479 // unique name.
480 cf.name = file->name;
481 if (file->offset)
482 cf.name += ".llvm." + std::to_string(file->offset) + "." +
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000483 sys::path::filename(Obj->getSourceFileName()).str();
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000484
Rafael Espindola33466a72014-08-21 20:28:55 +0000485 for (auto &Sym : Obj->symbols()) {
486 uint32_t Symflags = Sym.getFlags();
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000487
488 cf.syms.push_back(ld_plugin_symbol());
489 ld_plugin_symbol &sym = cf.syms.back();
Rafael Espindola176e6642014-07-29 21:46:05 +0000490 sym.version = nullptr;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000491 StringRef Name = Sym.getName();
492 sym.name = strdup(Name.str().c_str());
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000493
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000494 ResolutionInfo &Res = ResInfo[Name];
Rafael Espindola33466a72014-08-21 20:28:55 +0000495
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000496 Res.CanOmitFromDynSym &= Sym.canBeOmittedFromSymbolTable();
Rafael Espindolacaabe222015-12-10 14:19:35 +0000497
Rafael Espindola33466a72014-08-21 20:28:55 +0000498 sym.visibility = LDPV_DEFAULT;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000499 GlobalValue::VisibilityTypes Vis = Sym.getVisibility();
500 if (Vis != GlobalValue::DefaultVisibility)
501 Res.DefaultVisibility = false;
502 switch (Vis) {
503 case GlobalValue::DefaultVisibility:
504 break;
505 case GlobalValue::HiddenVisibility:
506 sym.visibility = LDPV_HIDDEN;
507 break;
508 case GlobalValue::ProtectedVisibility:
509 sym.visibility = LDPV_PROTECTED;
510 break;
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000511 }
512
Rafael Espindola33466a72014-08-21 20:28:55 +0000513 if (Symflags & object::BasicSymbolRef::SF_Undefined) {
514 sym.def = LDPK_UNDEF;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000515 if (Symflags & object::BasicSymbolRef::SF_Weak)
Rafael Espindola56548522009-04-24 16:55:21 +0000516 sym.def = LDPK_WEAKUNDEF;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000517 } else if (Symflags & object::BasicSymbolRef::SF_Common)
518 sym.def = LDPK_COMMON;
519 else if (Symflags & object::BasicSymbolRef::SF_Weak)
520 sym.def = LDPK_WEAKDEF;
521 else
Rafael Espindola33466a72014-08-21 20:28:55 +0000522 sym.def = LDPK_DEF;
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000523
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000524 sym.size = 0;
Rafael Espindola33466a72014-08-21 20:28:55 +0000525 sym.comdat_key = nullptr;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000526 const Comdat *C = check(Sym.getComdat());
527 if (C)
528 sym.comdat_key = strdup(C->getName().str().c_str());
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000529
530 sym.resolution = LDPR_UNKNOWN;
531 }
532
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000533 if (!cf.syms.empty()) {
Nick Lewycky7282dd72015-08-05 21:16:02 +0000534 if (add_symbols(cf.handle, cf.syms.size(), cf.syms.data()) != LDPS_OK) {
Rafael Espindola5ad21fa2014-07-30 00:38:58 +0000535 message(LDPL_ERROR, "Unable to add symbols!");
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000536 return LDPS_ERR;
537 }
538 }
539
540 return LDPS_OK;
541}
542
Rafael Espindola538c9a82014-12-23 18:18:37 +0000543static void freeSymName(ld_plugin_symbol &Sym) {
544 free(Sym.name);
545 free(Sym.comdat_key);
546 Sym.name = nullptr;
547 Sym.comdat_key = nullptr;
548}
549
Teresa Johnsona9f65552016-03-04 16:36:06 +0000550/// Helper to get a file's symbols and a view into it via gold callbacks.
551static const void *getSymbolsAndView(claimed_file &F) {
Benjamin Kramer39988a02016-03-08 14:02:46 +0000552 ld_plugin_status status = get_symbols(F.handle, F.syms.size(), F.syms.data());
Evgeniy Stepanov330c5a62016-03-04 00:23:29 +0000553 if (status == LDPS_NO_SYMS)
554 return nullptr;
Teresa Johnson403a7872015-10-04 14:33:43 +0000555
Evgeniy Stepanov330c5a62016-03-04 00:23:29 +0000556 if (status != LDPS_OK)
Teresa Johnson403a7872015-10-04 14:33:43 +0000557 message(LDPL_FATAL, "Failed to get symbol information");
558
559 const void *View;
560 if (get_view(F.handle, &View) != LDPS_OK)
561 message(LDPL_FATAL, "Failed to get a view of file");
562
Teresa Johnsona9f65552016-03-04 16:36:06 +0000563 return View;
564}
565
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000566static void addModule(LTO &Lto, claimed_file &F, const void *View) {
Teresa Johnson683abe72016-05-26 01:46:41 +0000567 MemoryBufferRef BufferRef(StringRef((const char *)View, F.filesize), F.name);
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000568 Expected<std::unique_ptr<InputFile>> ObjOrErr = InputFile::create(BufferRef);
Teresa Johnson6290dbc2015-11-21 21:55:48 +0000569
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000570 if (!ObjOrErr)
Peter Collingbourne10039c02014-09-18 21:28:49 +0000571 message(LDPL_FATAL, "Could not read bitcode from file : %s",
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000572 toString(ObjOrErr.takeError()).c_str());
Peter Collingbourne10039c02014-09-18 21:28:49 +0000573
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000574 InputFile &Obj = **ObjOrErr;
Rafael Espindola33466a72014-08-21 20:28:55 +0000575
Rafael Espindola527e8462014-12-09 16:13:59 +0000576 unsigned SymNum = 0;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000577 std::vector<SymbolResolution> Resols(F.syms.size());
Rafael Espindola527e8462014-12-09 16:13:59 +0000578 for (auto &ObjSym : Obj.symbols()) {
Rafael Espindola527e8462014-12-09 16:13:59 +0000579 ld_plugin_symbol &Sym = F.syms[SymNum];
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000580 SymbolResolution &R = Resols[SymNum];
Rafael Espindola527e8462014-12-09 16:13:59 +0000581 ++SymNum;
582
Rafael Espindola33466a72014-08-21 20:28:55 +0000583 ld_plugin_symbol_resolution Resolution =
584 (ld_plugin_symbol_resolution)Sym.resolution;
585
Rafael Espindolacaabe222015-12-10 14:19:35 +0000586 ResolutionInfo &Res = ResInfo[Sym.name];
Rafael Espindola890db272014-09-09 20:08:22 +0000587
Rafael Espindola33466a72014-08-21 20:28:55 +0000588 switch (Resolution) {
589 case LDPR_UNKNOWN:
590 llvm_unreachable("Unexpected resolution");
591
592 case LDPR_RESOLVED_IR:
593 case LDPR_RESOLVED_EXEC:
594 case LDPR_RESOLVED_DYN:
Rafael Espindolacaabe222015-12-10 14:19:35 +0000595 case LDPR_PREEMPTED_IR:
596 case LDPR_PREEMPTED_REG:
Rafael Espindola5ca7fa12015-01-14 13:53:50 +0000597 case LDPR_UNDEF:
Rafael Espindola5ca7fa12015-01-14 13:53:50 +0000598 break;
599
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000600 case LDPR_PREVAILING_DEF_IRONLY:
601 R.Prevailing = true;
Rafael Espindola33466a72014-08-21 20:28:55 +0000602 break;
Teresa Johnsonf99573b2016-08-11 12:56:40 +0000603
Teresa Johnsoncbf684e2016-08-11 13:03:56 +0000604 case LDPR_PREVAILING_DEF:
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000605 R.Prevailing = true;
606 R.VisibleToRegularObj = true;
Teresa Johnsoncbf684e2016-08-11 13:03:56 +0000607 break;
608
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000609 case LDPR_PREVAILING_DEF_IRONLY_EXP:
610 R.Prevailing = true;
611 if (!Res.CanOmitFromDynSym)
612 R.VisibleToRegularObj = true;
Teresa Johnsoncbf684e2016-08-11 13:03:56 +0000613 break;
614 }
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000615
616 if (Resolution != LDPR_RESOLVED_DYN && Resolution != LDPR_UNDEF &&
617 (IsExecutable || !Res.DefaultVisibility))
618 R.FinalDefinitionInLinkageUnit = true;
619
620 if (ObjSym.getFlags() & object::BasicSymbolRef::SF_Common) {
621 // We ignore gold's resolution for common symbols. A common symbol with
622 // the correct size and alignment is added to the module by the pre-opt
623 // module hook if any common symbol prevailed.
624 CommonResolution &CommonRes = Commons[ObjSym.getIRName()];
625 if (R.Prevailing) {
626 CommonRes.Prevailing = true;
627 CommonRes.VisibleToRegularObj = R.VisibleToRegularObj;
628 }
Saleem Abdulrasool98541b02016-08-14 05:07:20 +0000629 CommonRes.Size = std::max(CommonRes.Size, ObjSym.getCommonSize());
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000630 CommonRes.Align = std::max(CommonRes.Align, ObjSym.getCommonAlignment());
631 R.Prevailing = false;
Rafael Espindola33466a72014-08-21 20:28:55 +0000632 }
633
Rafael Espindola538c9a82014-12-23 18:18:37 +0000634 freeSymName(Sym);
Rafael Espindola33466a72014-08-21 20:28:55 +0000635 }
636
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000637 check(Lto.add(std::move(*ObjOrErr), Resols),
638 std::string("Failed to link module ") + F.name);
Rafael Espindola4a3b6cf2014-10-29 23:54:45 +0000639}
640
Teresa Johnsona9f65552016-03-04 16:36:06 +0000641static void recordFile(std::string Filename, bool TempOutFile) {
642 if (add_input_file(Filename.c_str()) != LDPS_OK)
643 message(LDPL_FATAL,
644 "Unable to add .o file to the link. File left behind in: %s",
645 Filename.c_str());
646 if (TempOutFile)
647 Cleanup.push_back(Filename.c_str());
648}
Rafael Espindola33466a72014-08-21 20:28:55 +0000649
Mehdi Amini970800e2016-08-17 06:23:09 +0000650/// Return the desired output filename given a base input name, a flag
651/// indicating whether a temp file should be generated, and an optional task id.
652/// The new filename generated is returned in \p NewFilename.
653static void getOutputFileName(SmallString<128> InFilename, bool TempOutFile,
654 SmallString<128> &NewFilename, int TaskID = -1) {
Teresa Johnsona9f65552016-03-04 16:36:06 +0000655 if (TempOutFile) {
656 std::error_code EC =
Mehdi Amini970800e2016-08-17 06:23:09 +0000657 sys::fs::createTemporaryFile("lto-llvm", "o", NewFilename);
Teresa Johnsona9f65552016-03-04 16:36:06 +0000658 if (EC)
659 message(LDPL_FATAL, "Could not create temporary file: %s",
660 EC.message().c_str());
661 } else {
662 NewFilename = InFilename;
663 if (TaskID >= 0)
664 NewFilename += utostr(TaskID);
Teresa Johnsona9f65552016-03-04 16:36:06 +0000665 }
Teresa Johnsona9f65552016-03-04 16:36:06 +0000666}
667
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000668/// Add all required common symbols to M, which is expected to be the first
669/// combined module.
670static void addCommons(Module &M) {
671 for (auto &I : Commons) {
672 if (!I.second.Prevailing)
Teresa Johnsoncbf684e2016-08-11 13:03:56 +0000673 continue;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000674 ArrayType *Ty =
675 ArrayType::get(Type::getInt8Ty(M.getContext()), I.second.Size);
676 GlobalVariable *OldGV = M.getNamedGlobal(I.first);
677 auto *GV = new GlobalVariable(M, Ty, false, GlobalValue::CommonLinkage,
678 ConstantAggregateZero::get(Ty), "");
679 GV->setAlignment(I.second.Align);
680 if (OldGV) {
681 OldGV->replaceAllUsesWith(ConstantExpr::getBitCast(GV, OldGV->getType()));
682 GV->takeName(OldGV);
683 OldGV->eraseFromParent();
684 } else {
685 GV->setName(I.first);
Teresa Johnsoncbf684e2016-08-11 13:03:56 +0000686 }
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000687 // We may only internalize commons if there is a single LTO task because
688 // other native object files may require the common.
689 if (MaxTasks == 1 && !I.second.VisibleToRegularObj)
690 GV->setLinkage(GlobalValue::InternalLinkage);
Teresa Johnsonf99573b2016-08-11 12:56:40 +0000691 }
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000692}
Teresa Johnsoncbf684e2016-08-11 13:03:56 +0000693
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000694static CodeGenOpt::Level getCGOptLevel() {
695 switch (options::OptLevel) {
696 case 0:
697 return CodeGenOpt::None;
698 case 1:
699 return CodeGenOpt::Less;
700 case 2:
701 return CodeGenOpt::Default;
702 case 3:
703 return CodeGenOpt::Aggressive;
704 }
705 llvm_unreachable("Invalid optimization level");
Teresa Johnson7cffaf32016-03-04 17:06:02 +0000706}
707
Teresa Johnsonbbd10b42016-05-17 14:45:30 +0000708/// Parse the thinlto_prefix_replace option into the \p OldPrefix and
709/// \p NewPrefix strings, if it was specified.
710static void getThinLTOOldAndNewPrefix(std::string &OldPrefix,
711 std::string &NewPrefix) {
712 StringRef PrefixReplace = options::thinlto_prefix_replace;
Reid Kleckner8e96c3e2016-05-17 18:43:22 +0000713 assert(PrefixReplace.empty() || PrefixReplace.find(";") != StringRef::npos);
714 std::pair<StringRef, StringRef> Split = PrefixReplace.split(";");
Teresa Johnsonbbd10b42016-05-17 14:45:30 +0000715 OldPrefix = Split.first.str();
716 NewPrefix = Split.second.str();
717}
718
Mehdi Amini970800e2016-08-17 06:23:09 +0000719namespace {
720// Define the LTOOutput handling
721class LTOOutput : public lto::NativeObjectOutput {
722 StringRef Path;
723
724public:
725 LTOOutput(StringRef Path) : Path(Path) {}
726 // Open the filename \p Path and allocate a stream.
727 std::unique_ptr<raw_pwrite_stream> getStream() override {
728 int FD;
729 std::error_code EC = sys::fs::openFileForWrite(Path, FD, sys::fs::F_None);
730 if (EC)
731 message(LDPL_FATAL, "Could not open file: %s", EC.message().c_str());
732 return llvm::make_unique<llvm::raw_fd_ostream>(FD, true);
733 }
734};
735}
736
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000737static std::unique_ptr<LTO> createLTO() {
738 Config Conf;
739 ThinBackend Backend;
740 unsigned ParallelCodeGenParallelismLevel = 1;
741
742 Conf.CPU = options::mcpu;
743 Conf.Options = InitTargetOptionsFromCodeGenFlags();
744
745 // Disable the new X86 relax relocations since gold might not support them.
746 // FIXME: Check the gold version or add a new option to enable them.
747 Conf.Options.RelaxELFRelocations = false;
748
749 Conf.MAttrs = MAttrs;
750 Conf.RelocModel = *RelocationModel;
751 Conf.CGOptLevel = getCGOptLevel();
752 Conf.DisableVerify = options::DisableVerify;
753 Conf.OptLevel = options::OptLevel;
754 if (options::Parallelism) {
755 if (options::thinlto)
756 Backend = createInProcessThinBackend(options::Parallelism);
757 else
758 ParallelCodeGenParallelismLevel = options::Parallelism;
Teresa Johnsonbbd10b42016-05-17 14:45:30 +0000759 }
Teresa Johnsoncbf684e2016-08-11 13:03:56 +0000760 if (options::thinlto_index_only) {
Teresa Johnsoncbf684e2016-08-11 13:03:56 +0000761 std::string OldPrefix, NewPrefix;
762 getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000763 Backend = createWriteIndexesThinBackend(
764 OldPrefix, NewPrefix, options::thinlto_emit_imports_files,
765 options::thinlto_linked_objects_file);
Teresa Johnson84174c32016-05-10 13:48:23 +0000766 }
767
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000768 Conf.OverrideTriple = options::triple;
769 Conf.DefaultTriple = sys::getDefaultTargetTriple();
770
771 Conf.DiagHandler = diagnosticHandler;
772
773 Conf.PreOptModuleHook = [](size_t Task, Module &M) {
774 if (Task == 0)
775 addCommons(M);
776 return true;
777 };
778
779 switch (options::TheOutputType) {
780 case options::OT_NORMAL:
781 break;
782
783 case options::OT_DISABLE:
784 Conf.PreOptModuleHook = [](size_t Task, Module &M) { return false; };
785 break;
786
787 case options::OT_BC_ONLY:
788 Conf.PostInternalizeModuleHook = [](size_t Task, Module &M) {
789 std::error_code EC;
790 raw_fd_ostream OS(output_name, EC, sys::fs::OpenFlags::F_None);
791 if (EC)
792 message(LDPL_FATAL, "Failed to write the output file.");
793 WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ false);
794 return false;
795 };
796 break;
797
798 case options::OT_SAVE_TEMPS:
Mehdi Aminieccffad2016-08-18 00:12:33 +0000799 check(Conf.addSaveTemps(output_name + ".",
800 /* UseInputModulePath */ true));
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000801 break;
Teresa Johnsoncbf684e2016-08-11 13:03:56 +0000802 }
803
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000804 return llvm::make_unique<LTO>(std::move(Conf), Backend,
805 ParallelCodeGenParallelismLevel);
Teresa Johnson84174c32016-05-10 13:48:23 +0000806}
807
Rafael Espindolab6393292014-07-30 01:23:45 +0000808/// gold informs us that all symbols have been read. At this point, we use
809/// get_symbols to see if any of our definitions have been overridden by a
810/// native object file. Then, perform optimization and codegen.
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000811static ld_plugin_status allSymbolsReadHook() {
Rafael Espindola33466a72014-08-21 20:28:55 +0000812 if (Modules.empty())
813 return LDPS_OK;
Rafael Espindola9ef90d52011-02-20 18:28:29 +0000814
Teresa Johnsona9f65552016-03-04 16:36:06 +0000815 if (unsigned NumOpts = options::extra.size())
816 cl::ParseCommandLineOptions(NumOpts, &options::extra[0]);
817
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000818 std::unique_ptr<LTO> Lto = createLTO();
Teresa Johnson403a7872015-10-04 14:33:43 +0000819
Rafael Espindolad2aac572014-07-30 01:52:40 +0000820 for (claimed_file &F : Modules) {
Teresa Johnsoncb15b732015-12-16 16:34:06 +0000821 PluginInputFile InputFile(F.handle);
Teresa Johnsona9f65552016-03-04 16:36:06 +0000822 const void *View = getSymbolsAndView(F);
Evgeniy Stepanov4dc3c8d2016-03-11 00:51:57 +0000823 if (!View)
824 continue;
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000825 addModule(*Lto, F, View);
Rafael Espindola77b6d012010-06-14 21:20:52 +0000826 }
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000827
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000828 SmallString<128> Filename;
Mehdi Amini970800e2016-08-17 06:23:09 +0000829 // Note that getOutputFileName will append a unique ID for each task
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000830 if (!options::obj_path.empty())
831 Filename = options::obj_path;
832 else if (options::TheOutputType == options::OT_SAVE_TEMPS)
833 Filename = output_name + ".o";
834 bool SaveTemps = !Filename.empty();
Rafael Espindola33466a72014-08-21 20:28:55 +0000835
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000836 MaxTasks = Lto->getMaxTasks();
837 std::vector<uintptr_t> IsTemporary(MaxTasks);
838 std::vector<SmallString<128>> Filenames(MaxTasks);
839
Mehdi Amini970800e2016-08-17 06:23:09 +0000840 auto AddOutput = [&](size_t Task) {
841 auto &OutputName = Filenames[Task];
842 getOutputFileName(Filename, /*TempOutFile=*/!SaveTemps, OutputName,
843 MaxTasks > 1 ? Task : -1);
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000844 IsTemporary[Task] = !SaveTemps;
Mehdi Amini970800e2016-08-17 06:23:09 +0000845 return llvm::make_unique<LTOOutput>(OutputName);
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000846 };
847
Mehdi Amini970800e2016-08-17 06:23:09 +0000848 check(Lto->run(AddOutput));
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000849
850 if (options::TheOutputType == options::OT_DISABLE ||
851 options::TheOutputType == options::OT_BC_ONLY)
Rafael Espindola6953a3a2014-11-24 21:18:14 +0000852 return LDPS_OK;
853
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000854 if (options::thinlto_index_only) {
855 cleanup_hook();
856 exit(0);
Rafael Espindolaba3398b2010-05-13 13:39:31 +0000857 }
Rafael Espindola143fc3b2013-10-16 12:47:04 +0000858
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000859 for (unsigned I = 0; I != MaxTasks; ++I)
860 if (!Filenames[I].empty())
861 recordFile(Filenames[I].str(), IsTemporary[I]);
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000862
Rafael Espindolaef498152010-06-23 20:20:59 +0000863 if (!options::extra_library_path.empty() &&
Rafael Espindola33466a72014-08-21 20:28:55 +0000864 set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK)
865 message(LDPL_FATAL, "Unable to set the extra library path.");
Shuxin Yang1826ae22013-08-12 21:07:31 +0000866
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000867 return LDPS_OK;
868}
869
Rafael Espindola55b32542014-08-11 19:06:54 +0000870static ld_plugin_status all_symbols_read_hook(void) {
Teresa Johnson9ba95f92016-08-11 14:58:12 +0000871 ld_plugin_status Ret = allSymbolsReadHook();
Rafael Espindola947bdb62014-11-25 20:52:49 +0000872 llvm_shutdown();
873
Rafael Espindola6953a3a2014-11-24 21:18:14 +0000874 if (options::TheOutputType == options::OT_BC_ONLY ||
Michael Kupersteina07d9b92015-02-12 18:21:50 +0000875 options::TheOutputType == options::OT_DISABLE) {
Davide Italiano289a43e2016-03-20 20:12:33 +0000876 if (options::TheOutputType == options::OT_DISABLE) {
Michael Kupersteina07d9b92015-02-12 18:21:50 +0000877 // Remove the output file here since ld.bfd creates the output file
878 // early.
Davide Italiano289a43e2016-03-20 20:12:33 +0000879 std::error_code EC = sys::fs::remove(output_name);
880 if (EC)
881 message(LDPL_ERROR, "Failed to delete '%s': %s", output_name.c_str(),
882 EC.message().c_str());
883 }
Rafael Espindola55b32542014-08-11 19:06:54 +0000884 exit(0);
Michael Kupersteina07d9b92015-02-12 18:21:50 +0000885 }
Rafael Espindola55b32542014-08-11 19:06:54 +0000886
887 return Ret;
888}
889
Dan Gohmanebb4ae02010-04-16 00:42:57 +0000890static ld_plugin_status cleanup_hook(void) {
Rafael Espindolad2aac572014-07-30 01:52:40 +0000891 for (std::string &Name : Cleanup) {
892 std::error_code EC = sys::fs::remove(Name);
Rafael Espindola55ab87f2013-06-17 18:38:18 +0000893 if (EC)
Rafael Espindolad2aac572014-07-30 01:52:40 +0000894 message(LDPL_ERROR, "Failed to delete '%s': %s", Name.c_str(),
Rafael Espindola5ad21fa2014-07-30 00:38:58 +0000895 EC.message().c_str());
Rafael Espindola55ab87f2013-06-17 18:38:18 +0000896 }
Nick Lewyckyfb643e42009-02-03 07:13:24 +0000897
898 return LDPS_OK;
899}