diff options
author | Teresa Johnson <tejohnson@google.com> | 2016-07-22 18:20:22 +0000 |
---|---|---|
committer | Teresa Johnson <tejohnson@google.com> | 2016-07-22 18:20:22 +0000 |
commit | 9493a84086f6da92263636ea019d1a81a968898a (patch) | |
tree | da554fb1d60cc4bda2508167307ddb4886106e18 /tools/gold | |
parent | a6c7a032febea3122c9b14abc33791b6c9e39956 (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.cpp | 40 |
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); } |