1 | //===- lib/Passes/PassPluginLoader.cpp - Load Plugins for New PM Passes ---===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/Passes/PassPlugin.h" |
10 | #include "llvm/Support/raw_ostream.h" |
11 | |
12 | #include <cstdint> |
13 | |
14 | using namespace llvm; |
15 | |
16 | Expected<PassPlugin> PassPlugin::Load(const std::string &Filename) { |
17 | std::string Error; |
18 | auto Library = |
19 | sys::DynamicLibrary::getPermanentLibrary(filename: Filename.c_str(), errMsg: &Error); |
20 | if (!Library.isValid()) |
21 | return make_error<StringError>(Args: Twine("Could not load library '" ) + |
22 | Filename + "': " + Error, |
23 | Args: inconvertibleErrorCode()); |
24 | |
25 | PassPlugin P{Filename, Library}; |
26 | |
27 | // llvmGetPassPluginInfo should be resolved to the definition from the plugin |
28 | // we are currently loading. |
29 | intptr_t getDetailsFn = |
30 | (intptr_t)Library.getAddressOfSymbol(symbolName: "llvmGetPassPluginInfo" ); |
31 | |
32 | if (!getDetailsFn) |
33 | // If the symbol isn't found, this is probably a legacy plugin, which is an |
34 | // error |
35 | return make_error<StringError>(Args: Twine("Plugin entry point not found in '" ) + |
36 | Filename + "'. Is this a legacy plugin?" , |
37 | Args: inconvertibleErrorCode()); |
38 | |
39 | P.Info = reinterpret_cast<decltype(llvmGetPassPluginInfo) *>(getDetailsFn)(); |
40 | |
41 | if (P.Info.APIVersion != LLVM_PLUGIN_API_VERSION) |
42 | return make_error<StringError>( |
43 | Args: Twine("Wrong API version on plugin '" ) + Filename + "'. Got version " + |
44 | Twine(P.Info.APIVersion) + ", supported version is " + |
45 | Twine(LLVM_PLUGIN_API_VERSION) + "." , |
46 | Args: inconvertibleErrorCode()); |
47 | |
48 | if (!P.Info.RegisterPassBuilderCallbacks) |
49 | return make_error<StringError>(Args: Twine("Empty entry callback in plugin '" ) + |
50 | Filename + "'.'" , |
51 | Args: inconvertibleErrorCode()); |
52 | |
53 | return P; |
54 | } |
55 | |