CppInterOp
C++ Language Interoperability Layer
Loading...
Searching...
No Matches
DynamicLibraryManager.h
Go to the documentation of this file.
1//--------------------------------------------------------------------*- C++ -*-
2// CLING - the C++ LLVM-based InterpreterG :)
3// author: Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
4//
5// This file is dual-licensed: you can choose to license it under the University
6// of Illinois Open Source License or the GNU Lesser General Public License. See
7// LICENSE.TXT for details.
8//------------------------------------------------------------------------------
9
10#ifndef CPPINTEROP_DYNAMIC_LIBRARY_MANAGER_H
11#define CPPINTEROP_DYNAMIC_LIBRARY_MANAGER_H
12
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/DenseMap.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/ADT/StringSet.h"
17#include "llvm/Support/Debug.h"
18#include "llvm/Support/Path.h"
19
20namespace CppInternal {
21class Dyld;
22class InterpreterCallbacks;
23
24///\brief A helper class managing dynamic shared objects.
25///
27public:
28 ///\brief Describes the result of loading a library.
29 ///
31 kLoadLibSuccess, ///< library loaded successfully
32 kLoadLibAlreadyLoaded, ///< library was already loaded
33 kLoadLibNotFound, ///< library was not found
34 kLoadLibLoadError, ///< loading the library failed
36 };
37
38 /// Describes the library search paths.
40 /// The search path.
41 ///
42 std::string Path;
43
44 /// True if the Path is on the LD_LIBRARY_PATH.
45 ///
46 bool IsUser;
47
48 bool operator==(const SearchPathInfo& Other) const {
49 return IsUser == Other.IsUser && Path == Other.Path;
50 }
51 };
52 using SearchPathInfos = llvm::SmallVector<SearchPathInfo, 32>;
53
54private:
55 typedef void* DyLibHandle;
56 typedef llvm::DenseMap<DyLibHandle, std::string> DyLibs;
57 ///\brief DynamicLibraries loaded by this Interpreter.
58 ///
59 DyLibs m_DyLibs;
60 llvm::StringSet<> m_LoadedLibraries;
61
62 ///\brief System's include path, get initialized at construction time.
63 ///
64 SearchPathInfos m_SearchPaths;
65
66 InterpreterCallbacks* m_Callbacks = nullptr;
67
68 Dyld* m_Dyld = nullptr;
69
70 ///\brief Concatenates current include paths and the system include paths
71 /// and performs a lookup for the filename.
72 /// See more information for RPATH and RUNPATH:
73 /// https://en.wikipedia.org/wiki/Rpath
74 ///\param[in] libStem - The filename being looked up
75 ///\param[in] RPath - RPATH as provided by loader library, searching for
76 /// libStem \param[in] RunPath - RUNPATH as provided by loader library,
77 /// searching for libStem \param[in] libLoader - The library that loads
78 /// libStem. Use "" for main program.
79 ///
80 ///\returns the canonical path to the file or empty string if not found
81 ///
82 std::string
83 lookupLibInPaths(llvm::StringRef libStem,
84 llvm::SmallVector<llvm::StringRef, 2> RPath = {},
85 llvm::SmallVector<llvm::StringRef, 2> RunPath = {},
86 llvm::StringRef libLoader = "") const;
87
88 ///\brief Concatenates current include paths and the system include paths
89 /// and performs a lookup for the filename. If still not found it tries to
90 /// add the platform-specific extensions (such as so, dll, dylib) and
91 /// retries the lookup (from lookupLibInPaths)
92 /// See more information for RPATH and RUNPATH:
93 /// https://en.wikipedia.org/wiki/Rpath
94 ///\param[in] filename - The filename being looked up
95 ///\param[in] RPath - RPATH as provided by loader library, searching for
96 /// libStem \param[in] RunPath - RUNPATH as provided by loader library,
97 /// searching for libStem \param[in] libLoader - The library that loads
98 /// libStem. Use "" for main program.
99 ///
100 ///\returns the canonical path to the file or empty string if not found
101 ///
102 std::string
103 lookupLibMaybeAddExt(llvm::StringRef filename,
104 llvm::SmallVector<llvm::StringRef, 2> RPath = {},
105 llvm::SmallVector<llvm::StringRef, 2> RunPath = {},
106 llvm::StringRef libLoader = "") const;
107
108 /// On a success returns to full path to a shared object that holds the
109 /// symbol pointed by func.
110 ///
111 static std::string getSymbolLocation(void* func);
112
113public:
118
119 InterpreterCallbacks* getCallbacks() { return m_Callbacks; }
120 const InterpreterCallbacks* getCallbacks() const { return m_Callbacks; }
121 void setCallbacks(InterpreterCallbacks* C) { m_Callbacks = C; }
122
123 ///\brief Returns the system include paths.
124 ///
125 ///\returns System include paths.
126 ///
127 const SearchPathInfos& getSearchPaths() const { return m_SearchPaths; }
128
129 void addSearchPath(llvm::StringRef dir, bool isUser = true,
130 bool prepend = false) {
131 if (!dir.empty()) {
132 for (auto& item : m_SearchPaths)
133 if (dir == item.Path)
134 return;
135 auto pos = prepend ? m_SearchPaths.begin() : m_SearchPaths.end();
136 m_SearchPaths.insert(pos, SearchPathInfo{dir.str(), isUser});
137 }
138 }
139
140 ///\brief Looks up a library taking into account the current include paths
141 /// and the system include paths.
142 /// See more information for RPATH and RUNPATH:
143 /// https://en.wikipedia.org/wiki/Rpath
144 ///\param[in] libStem - The filename being looked up
145 ///\param[in] RPath - RPATH as provided by loader library, searching for
146 /// libStem \param[in] RunPath - RUNPATH as provided by loader library,
147 /// searching for libStem \param[in] libLoader - The library that loads
148 /// libStem. Use "" for main program. \param[in] variateLibStem - If this
149 /// param is true, and libStem is "L", then
150 /// we search for "L", "libL", "L.so", "libL.so"", etc.
151 ///
152 ///\returns the canonical path to the file or empty string if not found
153 ///
154 std::string lookupLibrary(llvm::StringRef libStem,
155 llvm::SmallVector<llvm::StringRef, 2> RPath = {},
156 llvm::SmallVector<llvm::StringRef, 2> RunPath = {},
157 llvm::StringRef libLoader = "",
158 bool variateLibStem = true) const;
159
160 ///\brief Loads a shared library.
161 ///
162 ///\param [in] libStem - The file to load.
163 ///\param [in] permanent - If false, the file can be unloaded later.
164 ///\param [in] resolved - Whether libStem is an absolute path or resolved
165 /// from a previous call to DynamicLibraryManager::lookupLibrary
166 ///
167 ///\returns kLoadLibSuccess on success, kLoadLibAlreadyLoaded if the library
168 /// was already loaded, kLoadLibError if the library cannot be found or any
169 /// other error was encountered.
170 ///
171 LoadLibResult loadLibrary(llvm::StringRef, bool permanent,
172 bool resolved = false);
173
174 void unloadLibrary(llvm::StringRef libStem);
175
176 ///\brief Returns true if the file was a dynamic library and it was already
177 /// loaded.
178 ///
179 bool isLibraryLoaded(llvm::StringRef fullPath) const;
180
181 /// Initialize the dyld.
182 ///
183 ///\param [in] shouldPermanentlyIgnore - a callback deciding if a library
184 /// should be ignored from the result set. Useful for ignoring
185 /// dangerous libraries such as the ones overriding malloc.
186 ///
187 void
188 initializeDyld(std::function<bool(llvm::StringRef)> shouldPermanentlyIgnore);
189
190 /// Find the first not-yet-loaded shared object that contains the symbol
191 ///
192 ///\param[in] mangledName - the mangled name to look for.
193 ///\param[in] searchSystem - whether to descend into system libraries.
194 ///
195 ///\returns the library name if found, and empty string otherwise.
196 ///
197 std::string searchLibrariesForSymbol(llvm::StringRef mangledName,
198 bool searchSystem = true) const;
199
200 void dump(llvm::raw_ostream* S = nullptr) const;
201
202 /// On a success returns to full path to a shared object that holds the
203 /// symbol pointed by func.
204 ///
205 template <class T> static std::string getSymbolLocation(T func) {
206 static_assert(std::is_pointer<T>::value, "Must be a function pointer!");
207 return getSymbolLocation(reinterpret_cast<void*>(func));
208 }
209
210 static std::string normalizePath(llvm::StringRef path);
211
212 /// Returns true if file is a shared library.
213 ///
214 ///\param[in] libFullPath - the full path to file.
215 ///
216 ///\param[out] exists - sets if the file exists. Useful to distinguish if it
217 /// is a library but of incompatible file format.
218 ///
219 static bool isSharedLibrary(llvm::StringRef libFullPath,
220 bool* exists = nullptr);
221};
222} // end namespace CppInternal
223
224#endif // CPPINTEROP_DYNAMIC_LIBRARY_MANAGER_H
A helper class managing dynamic shared objects.
void unloadLibrary(llvm::StringRef libStem)
LoadLibResult loadLibrary(llvm::StringRef, bool permanent, bool resolved=false)
Loads a shared library.
static std::string normalizePath(llvm::StringRef path)
DynamicLibraryManager & operator=(const DynamicLibraryManager &)=delete
static bool isSharedLibrary(llvm::StringRef libFullPath, bool *exists=nullptr)
Returns true if file is a shared library.
DynamicLibraryManager(const DynamicLibraryManager &)=delete
LoadLibResult
Describes the result of loading a library.
@ kLoadLibAlreadyLoaded
library was already loaded
@ kLoadLibLoadError
loading the library failed
@ kLoadLibSuccess
library loaded successfully
void addSearchPath(llvm::StringRef dir, bool isUser=true, bool prepend=false)
const InterpreterCallbacks * getCallbacks() const
void setCallbacks(InterpreterCallbacks *C)
void dump(llvm::raw_ostream *S=nullptr) const
const SearchPathInfos & getSearchPaths() const
Returns the system include paths.
std::string searchLibrariesForSymbol(llvm::StringRef mangledName, bool searchSystem=true) const
Find the first not-yet-loaded shared object that contains the symbol.
bool isLibraryLoaded(llvm::StringRef fullPath) const
Returns true if the file was a dynamic library and it was already loaded.
std::string lookupLibrary(llvm::StringRef libStem, llvm::SmallVector< llvm::StringRef, 2 > RPath={}, llvm::SmallVector< llvm::StringRef, 2 > RunPath={}, llvm::StringRef libLoader="", bool variateLibStem=true) const
Looks up a library taking into account the current include paths and the system include paths.
llvm::SmallVector< SearchPathInfo, 32 > SearchPathInfos
static std::string getSymbolLocation(T func)
On a success returns to full path to a shared object that holds the symbol pointed by func.
void initializeDyld(std::function< bool(llvm::StringRef)> shouldPermanentlyIgnore)
Initialize the dyld.
bool IsUser
True if the Path is on the LD_LIBRARY_PATH.
bool operator==(const SearchPathInfo &Other) const