1218885Sdim//===-- llvm/Support/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
2218885Sdim//
3218885Sdim//                     The LLVM Compiler Infrastructure
4218885Sdim//
5218885Sdim// This file is distributed under the University of Illinois Open Source
6218885Sdim// License. See LICENSE.TXT for details.
7218885Sdim//
8218885Sdim//===----------------------------------------------------------------------===//
9218885Sdim//
10218885Sdim// This file declares the sys::DynamicLibrary class.
11218885Sdim//
12218885Sdim//===----------------------------------------------------------------------===//
13218885Sdim
14249423Sdim#ifndef LLVM_SYSTEM_DYNAMICLIBRARY_H
15249423Sdim#define LLVM_SYSTEM_DYNAMICLIBRARY_H
16218885Sdim
17218885Sdim#include <string>
18218885Sdim
19218885Sdimnamespace llvm {
20234353Sdim
21234353Sdimclass StringRef;
22234353Sdim
23218885Sdimnamespace sys {
24218885Sdim
25218885Sdim  /// This class provides a portable interface to dynamic libraries which also
26218885Sdim  /// might be known as shared libraries, shared objects, dynamic shared
27218885Sdim  /// objects, or dynamic link libraries. Regardless of the terminology or the
28218885Sdim  /// operating system interface, this class provides a portable interface that
29218885Sdim  /// allows dynamic libraries to be loaded and searched for externally
30218885Sdim  /// defined symbols. This is typically used to provide "plug-in" support.
31218885Sdim  /// It also allows for symbols to be defined which don't live in any library,
32218885Sdim  /// but rather the main program itself, useful on Windows where the main
33218885Sdim  /// executable cannot be searched.
34226633Sdim  ///
35226633Sdim  /// Note: there is currently no interface for temporarily loading a library,
36226633Sdim  /// or for unloading libraries when the LLVM library is unloaded.
37218885Sdim  class DynamicLibrary {
38226633Sdim    // Placeholder whose address represents an invalid library.
39226633Sdim    // We use this instead of NULL or a pointer-int pair because the OS library
40226633Sdim    // might define 0 or 1 to be "special" handles, such as "search all".
41226633Sdim    static char Invalid;
42226633Sdim
43226633Sdim    // Opaque data used to interface with OS-specific dynamic library handling.
44226633Sdim    void *Data;
45226633Sdim
46226633Sdim    explicit DynamicLibrary(void *data = &Invalid) : Data(data) {}
47218885Sdim  public:
48226633Sdim    /// Returns true if the object refers to a valid library.
49226633Sdim    bool isValid() { return Data != &Invalid; }
50226633Sdim
51226633Sdim    /// Searches through the library for the symbol \p symbolName. If it is
52226633Sdim    /// found, the address of that symbol is returned. If not, NULL is returned.
53226633Sdim    /// Note that NULL will also be returned if the library failed to load.
54226633Sdim    /// Use isValid() to distinguish these cases if it is important.
55226633Sdim    /// Note that this will \e not search symbols explicitly registered by
56226633Sdim    /// AddSymbol().
57226633Sdim    void *getAddressOfSymbol(const char *symbolName);
58226633Sdim
59226633Sdim    /// This function permanently loads the dynamic library at the given path.
60226633Sdim    /// The library will only be unloaded when the program terminates.
61226633Sdim    /// This returns a valid DynamicLibrary instance on success and an invalid
62226633Sdim    /// instance on failure (see isValid()). \p *errMsg will only be modified
63226633Sdim    /// if the library fails to load.
64226633Sdim    ///
65226633Sdim    /// It is safe to call this function multiple times for the same library.
66218885Sdim    /// @brief Open a dynamic library permanently.
67226633Sdim    static DynamicLibrary getPermanentLibrary(const char *filename,
68226633Sdim                                              std::string *errMsg = 0);
69226633Sdim
70226633Sdim    /// This function permanently loads the dynamic library at the given path.
71226633Sdim    /// Use this instead of getPermanentLibrary() when you won't need to get
72226633Sdim    /// symbols from the library itself.
73218885Sdim    ///
74226633Sdim    /// It is safe to call this function multiple times for the same library.
75226633Sdim    static bool LoadLibraryPermanently(const char *Filename,
76226633Sdim                                       std::string *ErrMsg = 0) {
77226633Sdim      return !getPermanentLibrary(Filename, ErrMsg).isValid();
78226633Sdim    }
79218885Sdim
80218885Sdim    /// This function will search through all previously loaded dynamic
81226633Sdim    /// libraries for the symbol \p symbolName. If it is found, the address of
82218885Sdim    /// that symbol is returned. If not, null is returned. Note that this will
83226633Sdim    /// search permanently loaded libraries (getPermanentLibrary()) as well
84226633Sdim    /// as explicitly registered symbols (AddSymbol()).
85218885Sdim    /// @throws std::string on error.
86218885Sdim    /// @brief Search through libraries for address of a symbol
87218885Sdim    static void *SearchForAddressOfSymbol(const char *symbolName);
88218885Sdim
89218885Sdim    /// @brief Convenience function for C++ophiles.
90218885Sdim    static void *SearchForAddressOfSymbol(const std::string &symbolName) {
91218885Sdim      return SearchForAddressOfSymbol(symbolName.c_str());
92218885Sdim    }
93218885Sdim
94218885Sdim    /// This functions permanently adds the symbol \p symbolName with the
95218885Sdim    /// value \p symbolValue.  These symbols are searched before any
96218885Sdim    /// libraries.
97218885Sdim    /// @brief Add searchable symbol/value pair.
98226633Sdim    static void AddSymbol(StringRef symbolName, void *symbolValue);
99218885Sdim  };
100218885Sdim
101218885Sdim} // End sys namespace
102218885Sdim} // End llvm namespace
103218885Sdim
104218885Sdim#endif // LLVM_SYSTEM_DYNAMIC_LIBRARY_H
105