LLVM  16.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"
18 #include "llvm/Support/Mutex.h"
19 #include <vector>
20 
21 using namespace llvm;
22 using namespace llvm::sys;
23 
24 // All methods for HandleSet should be used holding SymbolsMutex.
26  typedef std::vector<void *> HandleList;
27  HandleList Handles;
28  void *Process = nullptr;
29 
30 public:
31  static void *DLOpen(const char *Filename, std::string *Err);
32  static void DLClose(void *Handle);
33  static void *DLSym(void *Handle, const char *Symbol);
34 
35  HandleSet() = default;
36  ~HandleSet();
37 
38  HandleList::iterator Find(void *Handle) { return find(Handles, Handle); }
39 
40  bool Contains(void *Handle) {
41  return Handle == Process || Find(Handle) != Handles.end();
42  }
43 
44  bool AddLibrary(void *Handle, bool IsProcess = false, bool CanClose = true,
45  bool AllowDuplicates = false) {
46 #ifdef _WIN32
47  assert((Handle == this ? IsProcess : !IsProcess) && "Bad Handle.");
48 #endif
49  assert((!AllowDuplicates || !CanClose) &&
50  "CanClose must be false if AllowDuplicates is true.");
51 
52  if (LLVM_LIKELY(!IsProcess)) {
53  if (!AllowDuplicates && Find(Handle) != Handles.end()) {
54  if (CanClose)
55  DLClose(Handle);
56  return false;
57  }
58  Handles.push_back(Handle);
59  } else {
60 #ifndef _WIN32
61  if (Process) {
62  if (CanClose)
64  if (Process == Handle)
65  return false;
66  }
67 #endif
68  Process = Handle;
69  }
70  return true;
71  }
72 
73  void CloseLibrary(void *Handle) {
74  DLClose(Handle);
75  HandleList::iterator it = Find(Handle);
76  if (it != Handles.end()) {
77  Handles.erase(it);
78  }
79  }
80 
81  void *LibLookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
82  if (Order & SO_LoadOrder) {
83  for (void *Handle : Handles) {
84  if (void *Ptr = DLSym(Handle, Symbol))
85  return Ptr;
86  }
87  } else {
88  for (void *Handle : llvm::reverse(Handles)) {
89  if (void *Ptr = DLSym(Handle, Symbol))
90  return Ptr;
91  }
92  }
93  return nullptr;
94  }
95 
96  void *Lookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
97  assert(!((Order & SO_LoadedFirst) && (Order & SO_LoadedLast)) &&
98  "Invalid Ordering");
99 
100  if (!Process || (Order & SO_LoadedFirst)) {
101  if (void *Ptr = LibLookup(Symbol, Order))
102  return Ptr;
103  }
104  if (Process) {
105  // Use OS facilities to search the current binary and all loaded libs.
106  if (void *Ptr = DLSym(Process, Symbol))
107  return Ptr;
108 
109  // Search any libs that might have been skipped because of RTLD_LOCAL.
110  if (Order & SO_LoadedLast) {
111  if (void *Ptr = LibLookup(Symbol, Order))
112  return Ptr;
113  }
114  }
115  return nullptr;
116  }
117 };
118 
119 namespace {
120 
121 struct Globals {
122  // Collection of symbol name/value pairs to be searched prior to any
123  // libraries.
124  llvm::StringMap<void *> ExplicitSymbols;
125  // Collections of known library handles.
126  DynamicLibrary::HandleSet OpenedHandles;
127  DynamicLibrary::HandleSet OpenedTemporaryHandles;
128  // Lock for ExplicitSymbols, OpenedHandles, and OpenedTemporaryHandles.
129  llvm::sys::SmartMutex<true> SymbolsMutex;
130 };
131 
132 Globals &getGlobals() {
133  static Globals G;
134  return G;
135 }
136 
137 } // namespace
138 
139 #ifdef _WIN32
140 
142 
143 #else
144 
145 #include "Unix/DynamicLibrary.inc"
146 
147 #endif
148 
149 char DynamicLibrary::Invalid;
152 
153 namespace llvm {
155  return DoSearch(SymbolName); // DynamicLibrary.inc
156 }
157 } // namespace llvm
158 
160  auto &G = getGlobals();
161  SmartScopedLock<true> Lock(G.SymbolsMutex);
162  G.ExplicitSymbols[SymbolName] = SymbolValue;
163 }
164 
166  std::string *Err) {
167  auto &G = getGlobals();
168  void *Handle = HandleSet::DLOpen(FileName, Err);
169  if (Handle != &Invalid) {
170  SmartScopedLock<true> Lock(G.SymbolsMutex);
171  G.OpenedHandles.AddLibrary(Handle, /*IsProcess*/ FileName == nullptr);
172  }
173 
174  return DynamicLibrary(Handle);
175 }
176 
178  std::string *Err) {
179  auto &G = getGlobals();
180  SmartScopedLock<true> Lock(G.SymbolsMutex);
181  // If we've already loaded this library, tell the caller.
182  if (!G.OpenedHandles.AddLibrary(Handle, /*IsProcess*/ false,
183  /*CanClose*/ false))
184  *Err = "Library already loaded";
185 
186  return DynamicLibrary(Handle);
187 }
188 
190  std::string *Err) {
191  assert(FileName && "Use getPermanentLibrary() for opening process handle");
192  void *Handle = HandleSet::DLOpen(FileName, Err);
193  if (Handle != &Invalid) {
194  auto &G = getGlobals();
195  SmartScopedLock<true> Lock(G.SymbolsMutex);
196  G.OpenedTemporaryHandles.AddLibrary(Handle, /*IsProcess*/ false,
197  /*CanClose*/ false,
198  /*AllowDuplicates*/ true);
199  }
200  return DynamicLibrary(Handle);
201 }
202 
204  auto &G = getGlobals();
205  SmartScopedLock<true> Lock(G.SymbolsMutex);
206  if (Lib.isValid()) {
207  G.OpenedTemporaryHandles.CloseLibrary(Lib.Data);
208  Lib.Data = &Invalid;
209  }
210 }
211 
213  if (!isValid())
214  return nullptr;
215  return HandleSet::DLSym(Data, SymbolName);
216 }
217 
219  {
220  auto &G = getGlobals();
221  SmartScopedLock<true> Lock(G.SymbolsMutex);
222 
223  // First check symbols added via AddSymbol().
224  StringMap<void *>::iterator i = G.ExplicitSymbols.find(SymbolName);
225 
226  if (i != G.ExplicitSymbols.end())
227  return i->second;
228 
229  // Now search the libraries.
230  if (void *Ptr = G.OpenedHandles.Lookup(SymbolName, SearchOrder))
231  return Ptr;
232  if (void *Ptr = G.OpenedTemporaryHandles.Lookup(SymbolName, SearchOrder))
233  return Ptr;
234  }
235 
237 }
238 
239 //===----------------------------------------------------------------------===//
240 // C API.
241 //===----------------------------------------------------------------------===//
242 
243 LLVMBool LLVMLoadLibraryPermanently(const char *Filename) {
245 }
246 
247 void *LLVMSearchForAddressOfSymbol(const char *symbolName) {
249 }
250 
251 void LLVMAddSymbol(const char *symbolName, void *symbolValue) {
252  return llvm::sys::DynamicLibrary::AddSymbol(symbolName, symbolValue);
253 }
i
i
Definition: README.txt:29
llvm::sys::DynamicLibrary::HandleSet::Contains
bool Contains(void *Handle)
Definition: DynamicLibrary.cpp:40
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
it
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in it
Definition: README-SSE.txt:81
llvm::sys::DynamicLibrary::getAddressOfSymbol
void * getAddressOfSymbol(const char *symbolName)
Searches through the library for the symbol symbolName.
Definition: DynamicLibrary.cpp:212
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:159
llvm::sys::DynamicLibrary::HandleSet::AddLibrary
bool AddLibrary(void *Handle, bool IsProcess=false, bool CanClose=true, bool AllowDuplicates=false)
Definition: DynamicLibrary.cpp:44
llvm::sys::DynamicLibrary::getLibrary
static DynamicLibrary getLibrary(const char *FileName, std::string *Err=nullptr)
This function loads the dynamic library at the given path, using the library load operation from the ...
Definition: DynamicLibrary.cpp:189
llvm::sys::DynamicLibrary::closeLibrary
static void closeLibrary(DynamicLibrary &Lib)
This function closes the dynamic library at the given path, using the library close operation of the ...
Definition: DynamicLibrary.cpp:203
DynamicLibrary.h
llvm::sys::DynamicLibrary::HandleSet::CloseLibrary
void CloseLibrary(void *Handle)
Definition: DynamicLibrary.cpp:73
llvm::sys::DynamicLibrary::HandleSet::HandleSet
HandleSet()=default
llvm::sys::DynamicLibrary::DynamicLibrary
DynamicLibrary(void *data=&Invalid)
Definition: DynamicLibrary.h:43
llvm::sys::DynamicLibrary::SO_LoadedFirst
@ SO_LoadedFirst
SO_LoadedFirst - Search all loaded libraries, then as SO_Linker would.
Definition: DynamicLibrary.h:118
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:177
llvm::sys::DynamicLibrary
This class provides a portable interface to dynamic libraries which also might be known as shared lib...
Definition: DynamicLibrary.h:33
llvm::sys::Process
A collection of legacy interfaces for querying information about the current executing process.
Definition: Process.h:43
LLVMAddSymbol
void LLVMAddSymbol(const char *symbolName, void *symbolValue)
This functions permanently adds the symbol symbolName with the value symbolValue.
Definition: DynamicLibrary.cpp:251
llvm::sys::DynamicLibrary::HandleSet::Lookup
void * Lookup(const char *Symbol, DynamicLibrary::SearchOrdering Order)
Definition: DynamicLibrary.cpp:96
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 using the library load operatio...
Definition: DynamicLibrary.cpp:165
llvm::SubDirectoryType::Lib
@ Lib
llvm::sys::DynamicLibrary::SO_LoadOrder
@ SO_LoadOrder
SO_LoadOrder - Or this in to search libraries in the ordered loaded.
Definition: DynamicLibrary.h:124
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:218
llvm::sys::SmartMutex
SmartMutex - A mutex with a compile time constant parameter that indicates whether this mutex should ...
Definition: Mutex.h:28
llvm::sys::DynamicLibrary::isValid
bool isValid() const
Returns true if the object refers to a valid library.
Definition: DynamicLibrary.h:49
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:110
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:121
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
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:247
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:1754
llvm::sys::DynamicLibrary::HandleSet::Find
HandleList::iterator Find(void *Handle)
Definition: DynamicLibrary.cpp:38
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:116
llvm::sys::SmartScopedLock
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
Definition: Mutex.h:69
llvm::sys::DynamicLibrary::HandleSet
Definition: DynamicLibrary.cpp:25
Support.h
llvm::sys::DynamicLibrary::SearchOrder
static SearchOrdering SearchOrder
Definition: DynamicLibrary.h:126
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
llvm::sys::DynamicLibrary::HandleSet::LibLookup
void * LibLookup(const char *Symbol, DynamicLibrary::SearchOrdering Order)
Definition: DynamicLibrary.cpp:81
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::SearchForAddressOfSpecialSymbol
void * SearchForAddressOfSpecialSymbol(const char *SymbolName)
Definition: DynamicLibrary.cpp:154
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_LIKELY
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:209
llvm::reverse
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:485
llvm::sys::DynamicLibrary::SearchOrdering
SearchOrdering
Definition: DynamicLibrary.h:112
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:86
StringMap.h
LLVMLoadLibraryPermanently
LLVMBool LLVMLoadLibraryPermanently(const char *Filename)
This function permanently loads the dynamic library at the given path.
Definition: DynamicLibrary.cpp:243