1 //===-- gold-plugin.cpp - Plugin to gold for Link Time Optimization ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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 .
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Config/config.h"
16 #include "plugin-api.h"
18 #include "llvm-c/lto.h"
20 #include "llvm/Support/ToolOutputFile.h"
21 #include "llvm/Support/Errno.h"
22 #include "llvm/Support/Path.h"
23 #include "llvm/Support/Program.h"
32 // Support Windows/MinGW crazyness.
42 ld_plugin_status
discard_message(int level
, const char *format
, ...) {
43 // Die loudly. Recent versions of Gold pass ld_plugin_message as the first
44 // callback in the transfer vector. This should never be called.
48 ld_plugin_add_symbols add_symbols
= NULL
;
49 ld_plugin_get_symbols get_symbols
= NULL
;
50 ld_plugin_add_input_file add_input_file
= NULL
;
51 ld_plugin_add_input_library add_input_library
= NULL
;
52 ld_plugin_set_extra_library_path set_extra_library_path
= NULL
;
53 ld_plugin_get_view get_view
= NULL
;
54 ld_plugin_message message
= discard_message
;
61 std::vector
<ld_plugin_symbol
> syms
;
64 lto_codegen_model output_type
= LTO_CODEGEN_PIC_MODEL_STATIC
;
65 std::string output_name
= "";
66 std::list
<claimed_file
> Modules
;
67 std::vector
<sys::Path
> Cleanup
;
68 lto_code_gen_t code_gen
= NULL
;
72 enum generate_bc
{ BC_NO
, BC_ALSO
, BC_ONLY
};
73 static bool generate_api_file
= false;
74 static generate_bc generate_bc_file
= BC_NO
;
75 static std::string bc_path
;
76 static std::string obj_path
;
77 static std::string extra_library_path
;
78 static std::string triple
;
79 static std::string mcpu
;
80 // Additional options to pass into the code generator.
81 // Note: This array will contain all plugin options which are not claimed
82 // as plugin exclusive to pass to the code generator.
83 // For example, "generate-api-file" and "as"options are for the plugin
84 // use only and will not be passed.
85 static std::vector
<std::string
> extra
;
87 static void process_plugin_option(const char* opt_
)
91 llvm::StringRef opt
= opt_
;
93 if (opt
== "generate-api-file") {
94 generate_api_file
= true;
95 } else if (opt
.startswith("mcpu=")) {
96 mcpu
= opt
.substr(strlen("mcpu="));
97 } else if (opt
.startswith("extra-library-path=")) {
98 extra_library_path
= opt
.substr(strlen("extra_library_path="));
99 } else if (opt
.startswith("mtriple=")) {
100 triple
= opt
.substr(strlen("mtriple="));
101 } else if (opt
.startswith("obj-path=")) {
102 obj_path
= opt
.substr(strlen("obj-path="));
103 } else if (opt
== "emit-llvm") {
104 generate_bc_file
= BC_ONLY
;
105 } else if (opt
== "also-emit-llvm") {
106 generate_bc_file
= BC_ALSO
;
107 } else if (opt
.startswith("also-emit-llvm=")) {
108 llvm::StringRef path
= opt
.substr(strlen("also-emit-llvm="));
109 generate_bc_file
= BC_ALSO
;
110 if (!bc_path
.empty()) {
111 (*message
)(LDPL_WARNING
, "Path to the output IL file specified twice. "
112 "Discarding %s", opt_
);
117 // Save this option to pass to the code generator.
118 extra
.push_back(opt
);
123 static ld_plugin_status
claim_file_hook(const ld_plugin_input_file
*file
,
125 static ld_plugin_status
all_symbols_read_hook(void);
126 static ld_plugin_status
cleanup_hook(void);
128 extern "C" ld_plugin_status
onload(ld_plugin_tv
*tv
);
129 ld_plugin_status
onload(ld_plugin_tv
*tv
) {
130 // We're given a pointer to the first transfer vector. We read through them
131 // until we find one where tv_tag == LDPT_NULL. The REGISTER_* tagged values
132 // contain pointers to functions that we need to call to register our own
133 // hooks. The others are addresses of functions we can use to call into gold
136 bool registeredClaimFile
= false;
138 for (; tv
->tv_tag
!= LDPT_NULL
; ++tv
) {
139 switch (tv
->tv_tag
) {
140 case LDPT_API_VERSION
:
141 api_version
= tv
->tv_u
.tv_val
;
143 case LDPT_GOLD_VERSION
: // major * 100 + minor
144 gold_version
= tv
->tv_u
.tv_val
;
146 case LDPT_OUTPUT_NAME
:
147 output_name
= tv
->tv_u
.tv_string
;
149 case LDPT_LINKER_OUTPUT
:
150 switch (tv
->tv_u
.tv_val
) {
152 case LDPO_DYN
: // .so
153 output_type
= LTO_CODEGEN_PIC_MODEL_DYNAMIC
;
155 case LDPO_EXEC
: // .exe
156 output_type
= LTO_CODEGEN_PIC_MODEL_STATIC
;
159 (*message
)(LDPL_ERROR
, "Unknown output file type %d",
163 // TODO: add an option to disable PIC.
164 //output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC;
167 options::process_plugin_option(tv
->tv_u
.tv_string
);
169 case LDPT_REGISTER_CLAIM_FILE_HOOK
: {
170 ld_plugin_register_claim_file callback
;
171 callback
= tv
->tv_u
.tv_register_claim_file
;
173 if ((*callback
)(claim_file_hook
) != LDPS_OK
)
176 registeredClaimFile
= true;
178 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK
: {
179 ld_plugin_register_all_symbols_read callback
;
180 callback
= tv
->tv_u
.tv_register_all_symbols_read
;
182 if ((*callback
)(all_symbols_read_hook
) != LDPS_OK
)
185 code_gen
= lto_codegen_create();
187 case LDPT_REGISTER_CLEANUP_HOOK
: {
188 ld_plugin_register_cleanup callback
;
189 callback
= tv
->tv_u
.tv_register_cleanup
;
191 if ((*callback
)(cleanup_hook
) != LDPS_OK
)
194 case LDPT_ADD_SYMBOLS
:
195 add_symbols
= tv
->tv_u
.tv_add_symbols
;
197 case LDPT_GET_SYMBOLS
:
198 get_symbols
= tv
->tv_u
.tv_get_symbols
;
200 case LDPT_ADD_INPUT_FILE
:
201 add_input_file
= tv
->tv_u
.tv_add_input_file
;
203 case LDPT_ADD_INPUT_LIBRARY
:
204 add_input_library
= tv
->tv_u
.tv_add_input_file
;
206 case LDPT_SET_EXTRA_LIBRARY_PATH
:
207 set_extra_library_path
= tv
->tv_u
.tv_set_extra_library_path
;
210 get_view
= tv
->tv_u
.tv_get_view
;
213 message
= tv
->tv_u
.tv_message
;
220 if (!registeredClaimFile
) {
221 (*message
)(LDPL_ERROR
, "register_claim_file not passed to LLVMgold.");
225 (*message
)(LDPL_ERROR
, "add_symbols not passed to LLVMgold.");
232 /// claim_file_hook - called by gold to see whether this file is one that
233 /// our plugin can handle. We'll try to open it and register all the symbols
234 /// with add_symbol if possible.
235 static ld_plugin_status
claim_file_hook(const ld_plugin_input_file
*file
,
241 if (get_view(file
->handle
, &view
) != LDPS_OK
) {
242 (*message
)(LDPL_ERROR
, "Failed to get a view of %s", file
->name
);
245 M
= lto_module_create_from_memory(view
, file
->filesize
);
246 } else if (file
->offset
) {
247 // Gold has found what might be IR part-way inside of a file, such as
249 M
= lto_module_create_from_fd_at_offset(file
->fd
, file
->name
, -1,
250 file
->filesize
, file
->offset
);
252 M
= lto_module_create_from_fd(file
->fd
, file
->name
, file
->filesize
);
258 Modules
.resize(Modules
.size() + 1);
259 claimed_file
&cf
= Modules
.back();
261 if (!options::triple
.empty())
262 lto_module_set_target_triple(M
, options::triple
.c_str());
264 cf
.handle
= file
->handle
;
265 unsigned sym_count
= lto_module_get_num_symbols(M
);
266 cf
.syms
.reserve(sym_count
);
268 for (unsigned i
= 0; i
!= sym_count
; ++i
) {
269 lto_symbol_attributes attrs
= lto_module_get_symbol_attribute(M
, i
);
270 if ((attrs
& LTO_SYMBOL_SCOPE_MASK
) == LTO_SYMBOL_SCOPE_INTERNAL
)
273 cf
.syms
.push_back(ld_plugin_symbol());
274 ld_plugin_symbol
&sym
= cf
.syms
.back();
275 sym
.name
= const_cast<char *>(lto_module_get_symbol_name(M
, i
));
276 sym
.name
= strdup(sym
.name
);
279 int scope
= attrs
& LTO_SYMBOL_SCOPE_MASK
;
281 case LTO_SYMBOL_SCOPE_HIDDEN
:
282 sym
.visibility
= LDPV_HIDDEN
;
284 case LTO_SYMBOL_SCOPE_PROTECTED
:
285 sym
.visibility
= LDPV_PROTECTED
;
288 case LTO_SYMBOL_SCOPE_DEFAULT
:
289 sym
.visibility
= LDPV_DEFAULT
;
292 (*message
)(LDPL_ERROR
, "Unknown scope attribute: %d", scope
);
296 int definition
= attrs
& LTO_SYMBOL_DEFINITION_MASK
;
297 sym
.comdat_key
= NULL
;
298 switch (definition
) {
299 case LTO_SYMBOL_DEFINITION_REGULAR
:
302 case LTO_SYMBOL_DEFINITION_UNDEFINED
:
303 sym
.def
= LDPK_UNDEF
;
305 case LTO_SYMBOL_DEFINITION_TENTATIVE
:
306 sym
.def
= LDPK_COMMON
;
308 case LTO_SYMBOL_DEFINITION_WEAK
:
309 sym
.comdat_key
= sym
.name
;
310 sym
.def
= LDPK_WEAKDEF
;
312 case LTO_SYMBOL_DEFINITION_WEAKUNDEF
:
313 sym
.def
= LDPK_WEAKUNDEF
;
316 (*message
)(LDPL_ERROR
, "Unknown definition attribute: %d", definition
);
322 sym
.resolution
= LDPR_UNKNOWN
;
325 cf
.syms
.reserve(cf
.syms
.size());
327 if (!cf
.syms
.empty()) {
328 if ((*add_symbols
)(cf
.handle
, cf
.syms
.size(), &cf
.syms
[0]) != LDPS_OK
) {
329 (*message
)(LDPL_ERROR
, "Unable to add symbols!");
335 lto_codegen_add_module(code_gen
, M
);
337 lto_module_dispose(M
);
342 /// all_symbols_read_hook - gold informs us that all symbols have been read.
343 /// At this point, we use get_symbols to see if any of our definitions have
344 /// been overridden by a native object file. Then, perform optimization and
346 static ld_plugin_status
all_symbols_read_hook(void) {
347 std::ofstream api_file
;
350 if (options::generate_api_file
) {
351 api_file
.open("apifile.txt", std::ofstream::out
| std::ofstream::trunc
);
352 if (!api_file
.is_open()) {
353 (*message
)(LDPL_FATAL
, "Unable to open apifile.txt for writing.");
358 // If we don't preserve any symbols, libLTO will assume that all symbols are
359 // needed. Keep all symbols unless we're producing a final executable.
360 bool anySymbolsPreserved
= false;
361 for (std::list
<claimed_file
>::iterator I
= Modules
.begin(),
362 E
= Modules
.end(); I
!= E
; ++I
) {
363 (*get_symbols
)(I
->handle
, I
->syms
.size(), &I
->syms
[0]);
364 for (unsigned i
= 0, e
= I
->syms
.size(); i
!= e
; i
++) {
365 if (I
->syms
[i
].resolution
== LDPR_PREVAILING_DEF
) {
366 lto_codegen_add_must_preserve_symbol(code_gen
, I
->syms
[i
].name
);
367 anySymbolsPreserved
= true;
369 if (options::generate_api_file
)
370 api_file
<< I
->syms
[i
].name
<< "\n";
375 if (options::generate_api_file
)
378 if (!anySymbolsPreserved
) {
379 // All of the IL is unnecessary!
380 lto_codegen_dispose(code_gen
);
384 lto_codegen_set_pic_model(code_gen
, output_type
);
385 lto_codegen_set_debug_model(code_gen
, LTO_DEBUG_MODEL_DWARF
);
386 if (!options::mcpu
.empty())
387 lto_codegen_set_cpu(code_gen
, options::mcpu
.c_str());
389 // Pass through extra options to the code generator.
390 if (!options::extra
.empty()) {
391 for (std::vector
<std::string
>::iterator it
= options::extra
.begin();
392 it
!= options::extra
.end(); ++it
) {
393 lto_codegen_debug_options(code_gen
, (*it
).c_str());
397 if (options::generate_bc_file
!= options::BC_NO
) {
399 if (options::generate_bc_file
== options::BC_ONLY
)
401 else if (!options::bc_path
.empty())
402 path
= options::bc_path
;
404 path
= output_name
+ ".bc";
405 bool err
= lto_codegen_write_merged_modules(code_gen
, path
.c_str());
407 (*message
)(LDPL_FATAL
, "Failed to write the output file.");
408 if (options::generate_bc_file
== options::BC_ONLY
)
413 if (lto_codegen_compile_to_file(code_gen
, &objPath
)) {
414 (*message
)(LDPL_ERROR
, "Could not produce a combined object file\n");
417 lto_codegen_dispose(code_gen
);
418 for (std::list
<claimed_file
>::iterator I
= Modules
.begin(),
419 E
= Modules
.end(); I
!= E
; ++I
) {
420 for (unsigned i
= 0; i
!= I
->syms
.size(); ++i
) {
421 ld_plugin_symbol
&sym
= I
->syms
[i
];
426 if ((*add_input_file
)(objPath
) != LDPS_OK
) {
427 (*message
)(LDPL_ERROR
, "Unable to add .o file to the link.");
428 (*message
)(LDPL_ERROR
, "File left behind in: %s", objPath
);
432 if (!options::extra_library_path
.empty() &&
433 set_extra_library_path(options::extra_library_path
.c_str()) != LDPS_OK
) {
434 (*message
)(LDPL_ERROR
, "Unable to set the extra library path.");
438 if (options::obj_path
.empty())
439 Cleanup
.push_back(sys::Path(objPath
));
444 static ld_plugin_status
cleanup_hook(void) {
447 for (int i
= 0, e
= Cleanup
.size(); i
!= e
; ++i
)
448 if (Cleanup
[i
].eraseFromDisk(false, &ErrMsg
))
449 (*message
)(LDPL_ERROR
, "Failed to delete '%s': %s", Cleanup
[i
].c_str(),