LLVM  15.0.0git
DynamicLibrary.cpp
Go to the documentation of this file.
1 //===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- 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 implements the operating system DynamicLibrary concept.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "llvm-c/Support.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/Config/config.h"
19 #include "llvm/Support/Mutex.h"
20 #include <vector>
21 
22 using namespace llvm;
23 using namespace llvm::sys;
24 
25 // All methods for HandleSet should be used holding SymbolsMutex.
27  typedef std::vector<void *> HandleList;
28  HandleList Handles;
29  void *Process = nullptr;
30 
31 public:
32  static void *DLOpen(const char *Filename, std::string *Err);
33  static void DLClose(void *Handle);
34  static void *DLSym(void *Handle, const char *Symbol);
35 
36  HandleSet() = default;
37  ~HandleSet();
38 
39  HandleList::iterator Find(void *Handle) { return find(Handles, Handle); }
40 
41  bool Contains(void *Handle) {
42  return Handle == Process || Find(Handle) != Handles.end();
43  }
44 
45  bool AddLibrary(void *Handle, bool IsProcess = false, bool CanClose = true) {
46 #ifdef _WIN32
47  assert((Handle == this ? IsProcess : !IsProcess) && "Bad Handle.");
48 #endif
49 
50  if (LLVM_LIKELY(!IsProcess)) {
51  if (Find(Handle) != Handles.end()) {
52  if (CanClose)
53  DLClose(Handle);
54  return false;
55  }
56  Handles.push_back(Handle);
57  } else {
58 #ifndef _WIN32
59  if (Process) {
60  if (CanClose)
62  if (Process == Handle)
63  return false;
64  }
65 #endif
66  Process = Handle;
67  }
68  return true;
69  }
70 
71  void *LibLookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
72  if (Order & SO_LoadOrder) {
73  for (void *Handle : Handles) {
74  if (void *Ptr = DLSym(Handle, Symbol))
75  return Ptr;
76  }
77  } else {
78  for (void *Handle : llvm::reverse(Handles)) {
79  if (void *Ptr = DLSym(Handle, Symbol))
80  return Ptr;
81  }
82  }
83  return nullptr;
84  }
85 
86  void *Lookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
87  assert(!((Order & SO_LoadedFirst) && (Order & SO_LoadedLast)) &&
88  "Invalid Ordering");
89 
90  if (!Process || (Order & SO_LoadedFirst)) {
91  if (void *Ptr = LibLookup(Symbol, Order))
92  return Ptr;
93  }
94  if (Process) {
95  // Use OS facilities to search the current binary and all loaded libs.
96  if (void *Ptr = DLSym(Process, Symbol))
97  return Ptr;
98 
99  // Search any libs that might have been skipped because of RTLD_LOCAL.
100  if (Order & SO_LoadedLast) {
101  if (void *Ptr = LibLookup(Symbol, Order))
102  return Ptr;
103  }
104  }
105  return nullptr;
106  }
107 };
108 
109 namespace {
110 // Collection of symbol name/value pairs to be searched prior to any libraries.
111 static llvm::ManagedStatic<llvm::StringMap<void *>> ExplicitSymbols;
112 // Collection of known library handles.
114 // Lock for ExplicitSymbols and OpenedHandles.
116 } // namespace
117 
118 #ifdef _WIN32
119 
121 
122 #else
123 
124 #include "Unix/DynamicLibrary.inc"
125 
126 #endif
127 
128 char DynamicLibrary::Invalid;
131 
132 namespace llvm {
134  return DoSearch(SymbolName); // DynamicLibrary.inc
135 }
136 } // namespace llvm
137 
139  SmartScopedLock<true> Lock(*SymbolsMutex);
140  (*ExplicitSymbols)[SymbolName] = SymbolValue;
141 }
142 
144  std::string *Err) {
145  // Force OpenedHandles to be added into the ManagedStatic list before any
146  // ManagedStatic can be added from static constructors in HandleSet::DLOpen.
147  HandleSet& HS = *OpenedHandles;
148 
149  void *Handle = HandleSet::DLOpen(FileName, Err);
150  if (Handle != &Invalid) {
151  SmartScopedLock<true> Lock(*SymbolsMutex);
152  HS.AddLibrary(Handle, /*IsProcess*/ FileName == nullptr);
153  }
154 
155  return DynamicLibrary(Handle);
156 }
157 
159  std::string *Err) {
160  SmartScopedLock<true> Lock(*SymbolsMutex);
161  // If we've already loaded this library, tell the caller.
162  if (!OpenedHandles->AddLibrary(Handle, /*IsProcess*/false, /*CanClose*/false))
163  *Err = "Library already loaded";
164 
165  return DynamicLibrary(Handle);
166 }
167 
169  if (!isValid())
170  return nullptr;
171  return HandleSet::DLSym(Data, SymbolName);
172 }
173 
175  {
176  SmartScopedLock<true> Lock(*SymbolsMutex);
177 
178  // First check symbols added via AddSymbol().
179  if (ExplicitSymbols.isConstructed()) {
180  StringMap<void *>::iterator i = ExplicitSymbols->find(SymbolName);
181 
182  if (i != ExplicitSymbols->end())
183  return i->second;
184  }
185 
186  // Now search the libraries.
187  if (OpenedHandles.isConstructed()) {
188  if (void *Ptr = OpenedHandles->Lookup(SymbolName, SearchOrder))
189  return Ptr;
190  }
191  }
192 
194 }
195 
196 //===----------------------------------------------------------------------===//
197 // C API.
198 //===----------------------------------------------------------------------===//
199 
200 LLVMBool LLVMLoadLibraryPermanently(const char *Filename) {
202 }
203 
204 void *LLVMSearchForAddressOfSymbol(const char *symbolName) {
206 }
207 
208 void LLVMAddSymbol(const char *symbolName, void *symbolValue) {
209  return llvm::sys::DynamicLibrary::AddSymbol(symbolName, symbolValue);
210 }
i
i
Definition: README.txt:29
llvm::sys::DynamicLibrary::HandleSet::Contains
bool Contains(void *Handle)
Definition: DynamicLibrary.cpp:41
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::sys::DynamicLibrary::getAddressOfSymbol
void * getAddressOfSymbol(const char *symbolName)
Searches through the library for the symbol symbolName.
Definition: DynamicLibrary.cpp:168
llvm::sys::DynamicLibrary::HandleSet::AddLibrary
bool AddLibrary(void *Handle, bool IsProcess=false, bool CanClose=true)
Definition: DynamicLibrary.cpp:45
llvm::sys::DynamicLibrary::AddSymbol
static void AddSymbol(StringRef symbolName, void *symbolValue)
This functions permanently adds the symbol symbolName with the value symbolValue.
Definition: DynamicLibrary.cpp:138
ManagedStatic.h
DynamicLibrary.h
llvm::reverse
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:380
llvm::sys::DynamicLibrary::HandleSet::HandleSet
HandleSet()=default
llvm::sys::DynamicLibrary::DynamicLibrary
DynamicLibrary(void *data=&Invalid)
Definition: DynamicLibrary.h:46
llvm::sys::DynamicLibrary::SO_LoadedFirst
@ SO_LoadedFirst
SO_LoadedFirst - Search all loaded libraries, then as SO_Linker would.
Definition: DynamicLibrary.h:96
STLExtras.h
llvm::sys
Definition: Atomic.h:28
DynamicLibrary.inc
llvm::sys::DynamicLibrary::HandleSet::DLSym
static void * DLSym(void *Handle, const char *Symbol)
llvm::sys::DynamicLibrary::HandleSet::~HandleSet
~HandleSet()
llvm::sys::DynamicLibrary::addPermanentLibrary
static DynamicLibrary addPermanentLibrary(void *handle, std::string *errMsg=nullptr)
Registers an externally loaded library.
Definition: DynamicLibrary.cpp:158
llvm::sys::DynamicLibrary
This class provides a portable interface to dynamic libraries which also might be known as shared lib...
Definition: DynamicLibrary.h:36
llvm::sys::Process
A collection of legacy interfaces for querying information about the current executing process.
Definition: Process.h:43
llvm::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
LLVMAddSymbol
void LLVMAddSymbol(const char *symbolName, void *symbolValue)
This functions permanently adds the symbol symbolName with the value symbolValue.
Definition: DynamicLibrary.cpp:208
llvm::sys::DynamicLibrary::HandleSet::Lookup
void * Lookup(const char *Symbol, DynamicLibrary::SearchOrdering Order)
Definition: DynamicLibrary.cpp:86
llvm::sys::DynamicLibrary::getPermanentLibrary
static DynamicLibrary getPermanentLibrary(const char *filename, std::string *errMsg=nullptr)
This function permanently loads the dynamic library at the given path.
Definition: DynamicLibrary.cpp:143
llvm::ManagedStatic
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:83
llvm::AArch64CC::HS
@ HS
Definition: AArch64BaseInfo.h:257
llvm::sys::DynamicLibrary::SO_LoadOrder
@ SO_LoadOrder
SO_LoadOrder - Or this in to search libraries in the ordered loaded.
Definition: DynamicLibrary.h:102
StringMap.h
llvm::sys::DynamicLibrary::SearchForAddressOfSymbol
static void * SearchForAddressOfSymbol(const char *symbolName)
This function will search through all previously loaded dynamic libraries for the symbol symbolName.
Definition: DynamicLibrary.cpp:174
llvm::sys::DynamicLibrary::isValid
bool isValid() const
Returns true if the object refers to a valid library.
Definition: DynamicLibrary.h:49
llvm::sys::DynamicLibrary::HandleSet::DLOpen
static void * DLOpen(const char *Filename, std::string *Err)
llvm::sys::DynamicLibrary::SO_LoadedLast
@ SO_LoadedLast
SO_LoadedLast - Search as SO_Linker would, then loaded libraries.
Definition: DynamicLibrary.h:99
DynamicLibrary.inc
llvm::StringMapIterator
Definition: StringMap.h:27
LLVMSearchForAddressOfSymbol
void * LLVMSearchForAddressOfSymbol(const char *symbolName)
This function will search through all previously loaded dynamic libraries for the symbol symbolName.
Definition: DynamicLibrary.cpp:204
llvm::find
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1637
llvm::sys::DynamicLibrary::HandleSet::Find
HandleList::iterator Find(void *Handle)
Definition: DynamicLibrary.cpp:39
llvm::sys::DynamicLibrary::SO_Linker
@ SO_Linker
SO_Linker - Search as a call to dlsym(dlopen(NULL)) would when DynamicLibrary::getPermanentLibrary(NU...
Definition: DynamicLibrary.h:94
llvm::sys::SmartScopedLock
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
Definition: Mutex.h:71
llvm::sys::DynamicLibrary::HandleSet
Definition: DynamicLibrary.cpp:26
Support.h
llvm::sys::DynamicLibrary::SearchOrder
static SearchOrdering SearchOrder
Definition: DynamicLibrary.h:104
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::sys::DynamicLibrary::HandleSet::LibLookup
void * LibLookup(const char *Symbol, DynamicLibrary::SearchOrdering Order)
Definition: DynamicLibrary.cpp:71
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::SearchForAddressOfSpecialSymbol
void * SearchForAddressOfSpecialSymbol(const char *SymbolName)
Definition: DynamicLibrary.cpp:133
Mutex.h
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:386
LLVMBool
int LLVMBool
Definition: Types.h:28
llvm::sys::DynamicLibrary::HandleSet::DLClose
static void DLClose(void *Handle)
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
LLVM_LIKELY
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:219
llvm::sys::DynamicLibrary::SearchOrdering
SearchOrdering
Definition: DynamicLibrary.h:90
llvm::sys::DynamicLibrary::LoadLibraryPermanently
static bool LoadLibraryPermanently(const char *Filename, std::string *ErrMsg=nullptr)
This function permanently loads the dynamic library at the given path.
Definition: DynamicLibrary.h:85
LLVMLoadLibraryPermanently
LLVMBool LLVMLoadLibraryPermanently(const char *Filename)
This function permanently loads the dynamic library at the given path.
Definition: DynamicLibrary.cpp:200