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 #ifdef _WIN32
46  assert((Handle == this ? IsProcess : !IsProcess) && "Bad Handle.");
47 #endif
48 
49  if (LLVM_LIKELY(!IsProcess)) {
50  if (Find(Handle) != Handles.end()) {
51  if (CanClose)
52  DLClose(Handle);
53  return false;
54  }
55  Handles.push_back(Handle);
56  } else {
57 #ifndef _WIN32
58  if (Process) {
59  if (CanClose)
61  if (Process == Handle)
62  return false;
63  }
64 #endif
65  Process = Handle;
66  }
67  return true;
68  }
69 
70  void *LibLookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
71  if (Order & SO_LoadOrder) {
72  for (void *Handle : Handles) {
73  if (void *Ptr = DLSym(Handle, Symbol))
74  return Ptr;
75  }
76  } else {
77  for (void *Handle : llvm::reverse(Handles)) {
78  if (void *Ptr = DLSym(Handle, Symbol))
79  return Ptr;
80  }
81  }
82  return nullptr;
83  }
84 
85  void *Lookup(const char *Symbol, DynamicLibrary::SearchOrdering Order) {
86  assert(!((Order & SO_LoadedFirst) && (Order & SO_LoadedLast)) &&
87  "Invalid Ordering");
88 
89  if (!Process || (Order & SO_LoadedFirst)) {
90  if (void *Ptr = LibLookup(Symbol, Order))
91  return Ptr;
92  }
93  if (Process) {
94  // Use OS facilities to search the current binary and all loaded libs.
95  if (void *Ptr = DLSym(Process, Symbol))
96  return Ptr;
97 
98  // Search any libs that might have been skipped because of RTLD_LOCAL.
99  if (Order & SO_LoadedLast) {
100  if (void *Ptr = LibLookup(Symbol, Order))
101  return Ptr;
102  }
103  }
104  return nullptr;
105  }
106 };
107 
108 namespace {
109 
110 struct Globals {
111  // Collection of symbol name/value pairs to be searched prior to any
112  // libraries.
113  llvm::StringMap<void *> ExplicitSymbols;
114  // Collection of known library handles.
115  DynamicLibrary::HandleSet OpenedHandles;
116  // Lock for ExplicitSymbols and OpenedHandles.
117  llvm::sys::SmartMutex<true> SymbolsMutex;
118 };
119 
120 Globals &getGlobals() {
121  static Globals G;
122  return G;
123 }
124 
125 } // namespace
126 
127 #ifdef _WIN32
128 
130 
131 #else
132 
133 #include "Unix/DynamicLibrary.inc"
134 
135 #endif
136 
137 char DynamicLibrary::Invalid;
140 
141 namespace llvm {
143  return DoSearch(SymbolName); // DynamicLibrary.inc
144 }
145 } // namespace llvm
146 
148  auto &G = getGlobals();
149  SmartScopedLock<true> Lock(G.SymbolsMutex);
150  G.ExplicitSymbols[SymbolName] = SymbolValue;
151 }
152 
154  std::string *Err) {
155  auto &G = getGlobals();
156  void *Handle = HandleSet::DLOpen(FileName, Err);
157  if (Handle != &Invalid) {
158  SmartScopedLock<true> Lock(G.SymbolsMutex);
159  G.OpenedHandles.AddLibrary(Handle, /*IsProcess*/ FileName == nullptr);
160  }
161 
162  return DynamicLibrary(Handle);
163 }
164 
166  std::string *Err) {
167  auto &G = getGlobals();
168  SmartScopedLock<true> Lock(G.SymbolsMutex);
169  // If we've already loaded this library, tell the caller.
170  if (!G.OpenedHandles.AddLibrary(Handle, /*IsProcess*/ false,
171  /*CanClose*/ false))
172  *Err = "Library already loaded";
173 
174  return DynamicLibrary(Handle);
175 }
176 
178  if (!isValid())
179  return nullptr;
180  return HandleSet::DLSym(Data, SymbolName);
181 }
182 
184  {
185  auto &G = getGlobals();
186  SmartScopedLock<true> Lock(G.SymbolsMutex);
187 
188  // First check symbols added via AddSymbol().
189  StringMap<void *>::iterator i = G.ExplicitSymbols.find(SymbolName);
190 
191  if (i != G.ExplicitSymbols.end())
192  return i->second;
193 
194  // Now search the libraries.
195  if (void *Ptr = G.OpenedHandles.Lookup(SymbolName, SearchOrder))
196  return Ptr;
197  }
198 
200 }
201 
202 //===----------------------------------------------------------------------===//
203 // C API.
204 //===----------------------------------------------------------------------===//
205 
206 LLVMBool LLVMLoadLibraryPermanently(const char *Filename) {
208 }
209 
210 void *LLVMSearchForAddressOfSymbol(const char *symbolName) {
212 }
213 
214 void LLVMAddSymbol(const char *symbolName, void *symbolValue) {
215  return llvm::sys::DynamicLibrary::AddSymbol(symbolName, symbolValue);
216 }
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
llvm::sys::DynamicLibrary::getAddressOfSymbol
void * getAddressOfSymbol(const char *symbolName)
Searches through the library for the symbol symbolName.
Definition: DynamicLibrary.cpp:177
llvm::sys::DynamicLibrary::HandleSet::AddLibrary
bool AddLibrary(void *Handle, bool IsProcess=false, bool CanClose=true)
Definition: DynamicLibrary.cpp:44
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:147
DynamicLibrary.h
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:165
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
LLVMAddSymbol
void LLVMAddSymbol(const char *symbolName, void *symbolValue)
This functions permanently adds the symbol symbolName with the value symbolValue.
Definition: DynamicLibrary.cpp:214
llvm::sys::DynamicLibrary::HandleSet::Lookup
void * Lookup(const char *Symbol, DynamicLibrary::SearchOrdering Order)
Definition: DynamicLibrary.cpp:85
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:153
llvm::sys::DynamicLibrary::SO_LoadOrder
@ SO_LoadOrder
SO_LoadOrder - Or this in to search libraries in the ordered loaded.
Definition: DynamicLibrary.h:102
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:183
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:99
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:210
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:1610
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:94
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:104
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:70
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:142
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:209
llvm::reverse
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:365
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
StringMap.h
LLVMLoadLibraryPermanently
LLVMBool LLVMLoadLibraryPermanently(const char *Filename)
This function permanently loads the dynamic library at the given path.
Definition: DynamicLibrary.cpp:206