diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -379,6 +379,9 @@ Suffix, Plugin); CmdArgs.push_back(Args.MakeArgString(Plugin)); + + // Pass in our own path in case we need to reload + CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=self=") + Plugin)); } // Try to pass driver level flags relevant to LTO code generation down to diff --git a/llvm/tools/gold/CMakeLists.txt b/llvm/tools/gold/CMakeLists.txt --- a/llvm/tools/gold/CMakeLists.txt +++ b/llvm/tools/gold/CMakeLists.txt @@ -1,5 +1,3 @@ -set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/gold.exports) - if( LLVM_ENABLE_PIC AND LLVM_BINUTILS_INCDIR ) include_directories( ${LLVM_BINUTILS_INCDIR} ) diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -23,6 +23,7 @@ #include "llvm/Object/Error.h" #include "llvm/Support/CachePruning.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -207,6 +208,12 @@ static std::string stats_file; // Asserts that LTO link has whole program visibility static bool whole_program_visibility = false; + // List of new PM pass plugins + static std::vector pass_plugins; + // Path to ourselves, and whether we have been reloaded for pass plugin symbol + // resolution + static std::string self; + static bool self_reloaded = false; // Optimization remarks filename, accepted passes and hotness options static std::string RemarksFilename; @@ -300,6 +307,30 @@ RemarksFormat = std::string(opt); } else if (opt.consume_front("stats-file=")) { stats_file = std::string(opt); + } else if (opt.consume_front("self=")) { + // Store our own path, in case we need to be reloaded + self = std::string(opt); + } else if (opt.consume_front("load=")) { + std::string Error, Path(opt); + + // This plugin is loaded by gold under RTLD_LOCAL, which means that our + // LLVM symbols are not available to subsequent pass plugins. Since this + // will break statically-built pass plugins, we reload with RTLD_GLOBAL. + if (!self_reloaded) { + if (self.size()) { + if (sys::DynamicLibrary::LoadLibraryPermanently(self.c_str(), &Error)) + message(LDPL_ERROR, "Unable to reload LLVM gold plugin: %s", + Error.c_str()); + else + self_reloaded = true; + } else + message(LDPL_ERROR, "Unable to retrieve path to LLVM gold plugin!"); + } + + if (sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) + message(LDPL_ERROR, "Unable to load plugin: %s", Error.c_str()); + } else if (opt.consume_front("load-pass-plugin=")) { + pass_plugins.push_back(opt.data()); } else { // Save this option to pass to the code generator. // ParseCommandLineOptions() expects argv[0] to be program name. Lazily @@ -935,6 +966,8 @@ Conf.UseNewPM = options::new_pass_manager; // Debug new pass manager if requested Conf.DebugPassManager = options::debug_pass_manager; + // Pass plugins to load + Conf.PassPlugins = std::move(options::pass_plugins); Conf.HasWholeProgramVisibility = options::whole_program_visibility; diff --git a/llvm/tools/gold/gold.exports b/llvm/tools/gold/gold.exports deleted file mode 100644 --- a/llvm/tools/gold/gold.exports +++ /dev/null @@ -1 +0,0 @@ -onload