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