summaryrefslogtreecommitdiffstats
path: root/tools/gold
diff options
context:
space:
mode:
authorTeresa Johnson <tejohnson@google.com>2016-07-22 18:20:22 +0000
committerTeresa Johnson <tejohnson@google.com>2016-07-22 18:20:22 +0000
commit9493a84086f6da92263636ea019d1a81a968898a (patch)
treeda554fb1d60cc4bda2508167307ddb4886106e18 /tools/gold
parenta6c7a032febea3122c9b14abc33791b6c9e39956 (diff)
[ThinLTO/gold] Support for getting list of included objects from gold
Summary: In the distributed backend case, the ThinLink step and the final native object link are separate processes. This can be problematic when archive libraries are involved in the link (e.g. via --start-lib/--end-lib pairs). The linker only includes objects from libraries when there is a strong reference to them, and depending on the intervening ThinLTO backend processes' importing/inlining, the strong references may appear different in the two link steps. See D22356 and D22467 for two scenarios where this causes issues. To ensure that the final link includes the same objects, this patch adds support for an "=filename" form of the thinlto-index-only plugin option, in which case objects gold included in the link are emitted to the given filename. This should be used as input to the final link (e.g. via the @filename option to gold), instead of listing all the objects within --start-lib/--end-lib pairs again. Note that the support for the gold callback that identifies included objects was added in gold version 1.12. Reviewers: davidxl, mehdi_amini Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D22677 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276450 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/gold')
-rw-r--r--tools/gold/gold-plugin.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp
index e3351c29fcdb..c8b02e6fa14b 100644
--- a/tools/gold/gold-plugin.cpp
+++ b/tools/gold/gold-plugin.cpp
@@ -188,6 +188,16 @@ namespace options {
// the import decisions, and exit afterwards. The assumption is
// that the build system will launch the backend processes.
static bool thinlto_index_only = false;
+ // If non-empty, holds the name of a file in which to write the list of
+ // oject files gold selected for inclusion in the link after symbol
+ // resolution (i.e. they had selected symbols). This will only be non-empty
+ // in the thinlto_index_only case. It is used to identify files, which may
+ // have originally been within archive libraries specified via
+ // --start-lib/--end-lib pairs, that should be included in the final
+ // native link process (since intervening function importing and inlining
+ // may change the symbol resolution detected in the final link and which
+ // files to include out of --start-lib/--end-lib libraries as a result).
+ static std::string thinlto_linked_objects_file;
// If true, when generating individual index files for distributed backends,
// also generate a "${bitcodefile}.imports" file at the same location for each
// bitcode file, listing the files it imports from in plain text. This is to
@@ -233,6 +243,9 @@ namespace options {
thinlto = true;
} else if (opt == "thinlto-index-only") {
thinlto_index_only = true;
+ } else if (opt.startswith("thinlto-index-only=")) {
+ thinlto_index_only = true;
+ thinlto_linked_objects_file = opt.substr(strlen("thinlto-index-only="));
} else if (opt == "thinlto-emit-imports-files") {
thinlto_emit_imports_files = true;
} else if (opt.startswith("thinlto-prefix-replace=")) {
@@ -1409,6 +1422,18 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
std::string OldPrefix, NewPrefix;
getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
+ // If the user requested a list of objects gold included in the link,
+ // create and open the requested file.
+ raw_fd_ostream *ObjFileOS = nullptr;
+ if (!options::thinlto_linked_objects_file.empty()) {
+ std::error_code EC;
+ ObjFileOS = new raw_fd_ostream(options::thinlto_linked_objects_file, EC,
+ sys::fs::OpenFlags::F_None);
+ if (EC)
+ message(LDPL_FATAL, "Unable to open %s for writing: %s",
+ options::thinlto_linked_objects_file.c_str(),
+ EC.message().c_str());
+ }
// For each input bitcode file, generate an individual index that
// contains summaries only for its own global values, and for any that
// should be imported.
@@ -1417,6 +1442,18 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
std::string NewModulePath =
getThinLTOOutputFile(F.name, OldPrefix, NewPrefix);
+
+ if (!options::thinlto_linked_objects_file.empty()) {
+ // If gold included any symbols from ths file in the link, emit path
+ // to the final object file, which should be included in the final
+ // native link.
+ if (get_symbols(F.handle, F.syms.size(), F.syms.data()) !=
+ LDPS_NO_SYMS) {
+ assert(ObjFileOS);
+ *ObjFileOS << NewModulePath << "\n";
+ }
+ }
+
raw_fd_ostream OS((Twine(NewModulePath) + ".thinlto.bc").str(), EC,
sys::fs::OpenFlags::F_None);
if (EC)
@@ -1438,6 +1475,9 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
}
}
+ if (ObjFileOS)
+ ObjFileOS->close();
+
cleanup_hook();
exit(0);
}