1 //===- lib/Passes/PassPluginLoader.cpp - Load Plugins for New PM Passes ---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/Passes/PassPlugin.h"
11 #include "llvm/Support/raw_ostream.h"
12 
13 using namespace llvm;
14 
15 Expected<PassPlugin> PassPlugin::Load(const std::string &Filename) {
16   std::string Error;
17   auto Library =
18       sys::DynamicLibrary::getPermanentLibrary(Filename.c_str(), &Error);
19   if (!Library.isValid())
20     return make_error<StringError>(Twine("Could not load library '") +
21                                        Filename + "': " + Error,
22                                    inconvertibleErrorCode());
23 
24   PassPlugin P{Filename, Library};
25   auto *getDetailsFn =
26       Library.SearchForAddressOfSymbol("llvmGetPassPluginInfo");
27 
28   if (!getDetailsFn)
29     // If the symbol isn't found, this is probably a legacy plugin, which is an
30     // error
31     return make_error<StringError>(Twine("Plugin entry point not found in '") +
32                                        Filename + "'. Is this a legacy plugin?",
33                                    inconvertibleErrorCode());
34 
35   P.Info = reinterpret_cast<decltype(llvmGetPassPluginInfo) *>(getDetailsFn)();
36 
37   if (P.Info.APIVersion != LLVM_PLUGIN_API_VERSION)
38     return make_error<StringError>(
39         Twine("Wrong API version on plugin '") + Filename + "'. Got version " +
40             Twine(P.Info.APIVersion) + ", supported version is " +
41             Twine(LLVM_PLUGIN_API_VERSION) + ".",
42         inconvertibleErrorCode());
43 
44   if (!P.Info.RegisterPassBuilderCallbacks)
45     return make_error<StringError>(Twine("Empty entry callback in plugin '") +
46                                        Filename + "'.'",
47                                    inconvertibleErrorCode());
48 
49   return P;
50 }
51