xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Support/DynamicLibrary.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- llvm/Support/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
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 // This file declares the sys::DynamicLibrary class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_SUPPORT_DYNAMICLIBRARY_H
14 #define LLVM_SUPPORT_DYNAMICLIBRARY_H
15 
16 #include "llvm/Support/Compiler.h"
17 #include <string>
18 
19 namespace llvm {
20 
21 class StringRef;
22 
23 namespace sys {
24 
25 /// This class provides a portable interface to dynamic libraries which also
26 /// might be known as shared libraries, shared objects, dynamic shared
27 /// objects, or dynamic link libraries. Regardless of the terminology or the
28 /// operating system interface, this class provides a portable interface that
29 /// allows dynamic libraries to be loaded and searched for externally
30 /// defined symbols. This is typically used to provide "plug-in" support.
31 /// It also allows for symbols to be defined which don't live in any library,
32 /// but rather the main program itself, useful on Windows where the main
33 /// executable cannot be searched.
34 class DynamicLibrary {
35   // Placeholder whose address represents an invalid library.
36   // We use this instead of NULL or a pointer-int pair because the OS library
37   // might define 0 or 1 to be "special" handles, such as "search all".
38   LLVM_ABI static char Invalid;
39 
40   // Opaque data used to interface with OS-specific dynamic library handling.
41   void *Data;
42 
43 public:
Data(data)44   explicit DynamicLibrary(void *data = &Invalid) : Data(data) {}
45 
46   /// Return the OS specific handle value.
getOSSpecificHandle()47   void *getOSSpecificHandle() const { return Data; }
48 
49   /// Returns true if the object refers to a valid library.
isValid()50   bool isValid() const { return Data != &Invalid; }
51 
52   /// Searches through the library for the symbol \p symbolName. If it is
53   /// found, the address of that symbol is returned. If not, NULL is returned.
54   /// Note that NULL will also be returned if the library failed to load.
55   /// Use isValid() to distinguish these cases if it is important.
56   /// Note that this will \e not search symbols explicitly registered by
57   /// AddSymbol().
58   LLVM_ABI void *getAddressOfSymbol(const char *symbolName);
59 
60   /// This function permanently loads the dynamic library at the given path
61   /// using the library load operation from the host operating system. The
62   /// library instance will only be closed when global destructors run, and
63   /// there is no guarantee when the library will be unloaded.
64   ///
65   /// This returns a valid DynamicLibrary instance on success and an invalid
66   /// instance on failure (see isValid()). \p *errMsg will only be modified if
67   /// the library fails to load.
68   ///
69   /// It is safe to call this function multiple times for the same library.
70   /// Open a dynamic library permanently.
71   LLVM_ABI static DynamicLibrary
72   getPermanentLibrary(const char *filename, std::string *errMsg = nullptr);
73 
74   /// Registers an externally loaded library. The library will be unloaded
75   /// when the program terminates.
76   ///
77   /// It is safe to call this function multiple times for the same library,
78   /// though ownership is only taken if there was no error.
79   LLVM_ABI static DynamicLibrary
80   addPermanentLibrary(void *handle, std::string *errMsg = nullptr);
81 
82   /// This function permanently loads the dynamic library at the given path.
83   /// Use this instead of getPermanentLibrary() when you won't need to get
84   /// symbols from the library itself.
85   ///
86   /// It is safe to call this function multiple times for the same library.
87   static bool LoadLibraryPermanently(const char *Filename,
88                                      std::string *ErrMsg = nullptr) {
89     return !getPermanentLibrary(Filename, ErrMsg).isValid();
90   }
91 
92   /// This function loads the dynamic library at the given path, using the
93   /// library load operation from the host operating system. The library
94   /// instance will be closed when closeLibrary is called or global destructors
95   /// are run, but there is no guarantee when the library will be unloaded.
96   ///
97   /// This returns a valid DynamicLibrary instance on success and an invalid
98   /// instance on failure (see isValid()). \p *Err will only be modified if the
99   /// library fails to load.
100   ///
101   /// It is safe to call this function multiple times for the same library.
102   LLVM_ABI static DynamicLibrary getLibrary(const char *FileName,
103                                             std::string *Err = nullptr);
104 
105   /// This function closes the dynamic library at the given path, using the
106   /// library close operation of the host operating system, and there is no
107   /// guarantee if or when this will cause the library to be unloaded.
108   ///
109   /// This function should be called only if the library was loaded using the
110   /// getLibrary() function.
111   LLVM_ABI static void closeLibrary(DynamicLibrary &Lib);
112 
113   enum SearchOrdering {
114     /// SO_Linker - Search as a call to dlsym(dlopen(NULL)) would when
115     /// DynamicLibrary::getPermanentLibrary(NULL) has been called or
116     /// search the list of explcitly loaded symbols if not.
117     SO_Linker,
118     /// SO_LoadedFirst - Search all loaded libraries, then as SO_Linker would.
119     SO_LoadedFirst,
120     /// SO_LoadedLast - Search as SO_Linker would, then loaded libraries.
121     /// Only useful to search if libraries with RTLD_LOCAL have been added.
122     SO_LoadedLast,
123     /// SO_LoadOrder - Or this in to search libraries in the ordered loaded.
124     /// The default bahaviour is to search loaded libraries in reverse.
125     SO_LoadOrder = 4
126   };
127   LLVM_ABI static SearchOrdering SearchOrder; // = SO_Linker
128 
129   /// This function will search through all previously loaded dynamic
130   /// libraries for the symbol \p symbolName. If it is found, the address of
131   /// that symbol is returned. If not, null is returned. Note that this will
132   /// search permanently loaded libraries (getPermanentLibrary()) as well
133   /// as explicitly registered symbols (AddSymbol()).
134   /// @throws std::string on error.
135   /// Search through libraries for address of a symbol
136   LLVM_ABI static void *SearchForAddressOfSymbol(const char *symbolName);
137 
138   /// Convenience function for C++ophiles.
SearchForAddressOfSymbol(const std::string & symbolName)139   static void *SearchForAddressOfSymbol(const std::string &symbolName) {
140     return SearchForAddressOfSymbol(symbolName.c_str());
141   }
142 
143   /// This functions permanently adds the symbol \p symbolName with the
144   /// value \p symbolValue.  These symbols are searched before any
145   /// libraries.
146   /// Add searchable symbol/value pair.
147   LLVM_ABI static void AddSymbol(StringRef symbolName, void *symbolValue);
148 
149   class HandleSet;
150 };
151 
152 } // End sys namespace
153 } // End llvm namespace
154 
155 #endif
156