| //===- lib/Passes/PassPluginLoader.cpp - Load Plugins for New PM Passes ---===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/Passes/PassPlugin.h" |
| #include "llvm/Support/raw_ostream.h" |
| |
| #include <cstdint> |
| |
| using namespace llvm; |
| |
| Expected<PassPlugin> PassPlugin::Load(const std::string &Filename) { |
| std::string Error; |
| auto Library = |
| sys::DynamicLibrary::getPermanentLibrary(Filename.c_str(), &Error); |
| if (!Library.isValid()) |
| return make_error<StringError>(Twine("Could not load library '") + |
| Filename + "': " + Error, |
| inconvertibleErrorCode()); |
| |
| PassPlugin P{Filename, Library}; |
| |
| // llvmGetPassPluginInfo should be resolved to the definition from the plugin |
| // we are currently loading. |
| intptr_t getDetailsFn = |
| (intptr_t)Library.getAddressOfSymbol("llvmGetPassPluginInfo"); |
| |
| if (!getDetailsFn) |
| // If the symbol isn't found, this is probably a legacy plugin, which is an |
| // error |
| return make_error<StringError>(Twine("Plugin entry point not found in '") + |
| Filename + "'. Is this a legacy plugin?", |
| inconvertibleErrorCode()); |
| |
| P.Info = reinterpret_cast<decltype(llvmGetPassPluginInfo) *>(getDetailsFn)(); |
| |
| if (P.Info.APIVersion != LLVM_PLUGIN_API_VERSION) |
| return make_error<StringError>( |
| Twine("Wrong API version on plugin '") + Filename + "'. Got version " + |
| Twine(P.Info.APIVersion) + ", supported version is " + |
| Twine(LLVM_PLUGIN_API_VERSION) + ".", |
| inconvertibleErrorCode()); |
| |
| if (!P.Info.RegisterPassBuilderCallbacks) |
| return make_error<StringError>(Twine("Empty entry callback in plugin '") + |
| Filename + "'.'", |
| inconvertibleErrorCode()); |
| |
| return P; |
| } |