Home | History | Annotate | Line # | Download | only in Support
      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   ///
     34   /// Note: there is currently no interface for temporarily loading a library,
     35   /// or for unloading libraries when the LLVM library is unloaded.
     36   class DynamicLibrary {
     37     // Placeholder whose address represents an invalid library.
     38     // We use this instead of NULL or a pointer-int pair because the OS library
     39     // might define 0 or 1 to be "special" handles, such as "search all".
     40     static char Invalid;
     41 
     42     // Opaque data used to interface with OS-specific dynamic library handling.
     43     void *Data;
     44 
     45   public:
     46     explicit DynamicLibrary(void *data = &Invalid) : Data(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     /// The library will only be unloaded when llvm_shutdown() is called.
     61     /// This returns a valid DynamicLibrary instance on success and an invalid
     62     /// instance on failure (see isValid()). \p *errMsg will only be modified
     63     /// if the library fails to load.
     64     ///
     65     /// It is safe to call this function multiple times for the same library.
     66     /// Open a dynamic library permanently.
     67     static DynamicLibrary getPermanentLibrary(const char *filename,
     68                                               std::string *errMsg = nullptr);
     69 
     70     /// Registers an externally loaded library. The library will be unloaded
     71     /// when the program terminates.
     72     ///
     73     /// It is safe to call this function multiple times for the same library,
     74     /// though ownership is only taken if there was no error.
     75     ///
     76     /// \returns An empty \p DynamicLibrary if the library was already loaded.
     77     static DynamicLibrary addPermanentLibrary(void *handle,
     78                                               std::string *errMsg = nullptr);
     79 
     80     /// This function permanently loads the dynamic library at the given path.
     81     /// Use this instead of getPermanentLibrary() when you won't need to get
     82     /// symbols from the library itself.
     83     ///
     84     /// It is safe to call this function multiple times for the same library.
     85     static bool LoadLibraryPermanently(const char *Filename,
     86                                        std::string *ErrMsg = nullptr) {
     87       return !getPermanentLibrary(Filename, ErrMsg).isValid();
     88     }
     89 
     90     enum SearchOrdering {
     91       /// SO_Linker - Search as a call to dlsym(dlopen(NULL)) would when
     92       /// DynamicLibrary::getPermanentLibrary(NULL) has been called or
     93       /// search the list of explcitly loaded symbols if not.
     94       SO_Linker,
     95       /// SO_LoadedFirst - Search all loaded libraries, then as SO_Linker would.
     96       SO_LoadedFirst,
     97       /// SO_LoadedLast - Search as SO_Linker would, then loaded libraries.
     98       /// Only useful to search if libraries with RTLD_LOCAL have been added.
     99       SO_LoadedLast,
    100       /// SO_LoadOrder - Or this in to search libraries in the ordered loaded.
    101       /// The default bahaviour is to search loaded libraries in reverse.
    102       SO_LoadOrder = 4
    103     };
    104     static SearchOrdering SearchOrder; // = SO_Linker
    105 
    106     /// This function will search through all previously loaded dynamic
    107     /// libraries for the symbol \p symbolName. If it is found, the address of
    108     /// that symbol is returned. If not, null is returned. Note that this will
    109     /// search permanently loaded libraries (getPermanentLibrary()) as well
    110     /// as explicitly registered symbols (AddSymbol()).
    111     /// @throws std::string on error.
    112     /// Search through libraries for address of a symbol
    113     static void *SearchForAddressOfSymbol(const char *symbolName);
    114 
    115     /// Convenience function for C++ophiles.
    116     static void *SearchForAddressOfSymbol(const std::string &symbolName) {
    117       return SearchForAddressOfSymbol(symbolName.c_str());
    118     }
    119 
    120     /// This functions permanently adds the symbol \p symbolName with the
    121     /// value \p symbolValue.  These symbols are searched before any
    122     /// libraries.
    123     /// Add searchable symbol/value pair.
    124     static void AddSymbol(StringRef symbolName, void *symbolValue);
    125 
    126     class HandleSet;
    127   };
    128 
    129 } // End sys namespace
    130 } // End llvm namespace
    131 
    132 #endif
    133