xref: /freebsd/contrib/llvm-project/llvm/lib/Passes/PassPlugin.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
10b57cec5SDimitry Andric //===- lib/Passes/PassPluginLoader.cpp - Load Plugins for New PM Passes ---===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/Passes/PassPlugin.h"
100b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include <cstdint>
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric using namespace llvm;
150b57cec5SDimitry Andric 
Load(const std::string & Filename)160b57cec5SDimitry Andric Expected<PassPlugin> PassPlugin::Load(const std::string &Filename) {
170b57cec5SDimitry Andric   std::string Error;
180b57cec5SDimitry Andric   auto Library =
190b57cec5SDimitry Andric       sys::DynamicLibrary::getPermanentLibrary(Filename.c_str(), &Error);
200b57cec5SDimitry Andric   if (!Library.isValid())
210b57cec5SDimitry Andric     return make_error<StringError>(Twine("Could not load library '") +
220b57cec5SDimitry Andric                                        Filename + "': " + Error,
230b57cec5SDimitry Andric                                    inconvertibleErrorCode());
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric   PassPlugin P{Filename, Library};
26*fe6060f1SDimitry Andric 
27*fe6060f1SDimitry Andric   // llvmGetPassPluginInfo should be resolved to the definition from the plugin
28*fe6060f1SDimitry Andric   // we are currently loading.
290b57cec5SDimitry Andric   intptr_t getDetailsFn =
30*fe6060f1SDimitry Andric       (intptr_t)Library.getAddressOfSymbol("llvmGetPassPluginInfo");
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric   if (!getDetailsFn)
330b57cec5SDimitry Andric     // If the symbol isn't found, this is probably a legacy plugin, which is an
340b57cec5SDimitry Andric     // error
350b57cec5SDimitry Andric     return make_error<StringError>(Twine("Plugin entry point not found in '") +
360b57cec5SDimitry Andric                                        Filename + "'. Is this a legacy plugin?",
370b57cec5SDimitry Andric                                    inconvertibleErrorCode());
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   P.Info = reinterpret_cast<decltype(llvmGetPassPluginInfo) *>(getDetailsFn)();
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   if (P.Info.APIVersion != LLVM_PLUGIN_API_VERSION)
420b57cec5SDimitry Andric     return make_error<StringError>(
430b57cec5SDimitry Andric         Twine("Wrong API version on plugin '") + Filename + "'. Got version " +
440b57cec5SDimitry Andric             Twine(P.Info.APIVersion) + ", supported version is " +
450b57cec5SDimitry Andric             Twine(LLVM_PLUGIN_API_VERSION) + ".",
460b57cec5SDimitry Andric         inconvertibleErrorCode());
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   if (!P.Info.RegisterPassBuilderCallbacks)
490b57cec5SDimitry Andric     return make_error<StringError>(Twine("Empty entry callback in plugin '") +
500b57cec5SDimitry Andric                                        Filename + "'.'",
510b57cec5SDimitry Andric                                    inconvertibleErrorCode());
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   return P;
540b57cec5SDimitry Andric }
55