Go to the documentation of this file.
27 I((InitList && End) ? InitList->getNumOperands() : 0) {
31 assert(InitList ==
Other.InitList &&
"Incomparable iterators.");
36 return !(*
this ==
Other);
52 assert(CS &&
"Unrecognized type in llvm.global_ctors/llvm.global_dtors");
59 if (
Function *
F = dyn_cast_or_null<Function>(FuncC)) {
62 }
else if (
ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) {
64 FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0));
73 auto *Priority = cast<ConstantInt>(CS->
getOperand(0));
77 return Element(Priority->getZExtValue(), Func,
Data);
81 const GlobalVariable *CtorsList =
M.getNamedGlobal(
"llvm.global_ctors");
87 const GlobalVariable *DtorsList =
M.getNamedGlobal(
"llvm.global_dtors");
92 bool StaticInitGVIterator::isStaticInitGlobal(
GlobalValue &GV) {
97 GV.
getName() ==
"llvm.global_dtors"))
113 if (CtorDtors.
empty())
118 (*CtorDtors.
begin()).Func->getParent()->getDataLayout());
120 for (
auto CtorDtor : CtorDtors) {
121 assert(CtorDtor.Func && CtorDtor.Func->hasName() &&
122 "Ctor/Dtor function must be named to be runnable under the JIT");
125 if (CtorDtor.Func->hasLocalLinkage()) {
130 if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) {
131 dbgs() <<
" Skipping because why now?\n";
135 CtorDtorsByPriority[CtorDtor.Priority].push_back(
136 Mangle(CtorDtor.Func->getName()));
141 using CtorDtorTy = void (*)();
144 for (
auto &KV : CtorDtorsByPriority)
145 for (
auto &
Name : KV.second)
148 "Ctor/Dtor list contains duplicates");
151 if (
auto CtorDtorMap = ES.lookup(
154 for (
auto &KV : CtorDtorsByPriority) {
155 for (
auto &
Name : KV.second) {
156 assert(CtorDtorMap->count(
Name) &&
"No entry for Name");
157 auto CtorDtor =
reinterpret_cast<CtorDtorTy
>(
158 static_cast<uintptr_t
>((*CtorDtorMap)[
Name].getAddress()));
162 CtorDtorsByPriority.clear();
165 return CtorDtorMap.takeError();
170 for (
auto &
P : CXXDestructorDataPairs)
172 CXXDestructorDataPairs.clear();
178 auto& CXXDestructorDataPairs =
180 CXXDestructorDataPairs.push_back(std::make_pair(Destructor,
Arg));
187 RuntimeInterposes[Mangle(
"__dso_handle")] =
190 RuntimeInterposes[Mangle(
"__cxa_atexit")] =
199 std::lock_guard<std::mutex>
Lock(AtExitsMutex);
200 AtExitRecords[DSOHandle].push_back({
F, Ctx});
204 std::vector<AtExitRecord> AtExitsToRun;
207 std::lock_guard<std::mutex>
Lock(AtExitsMutex);
208 auto I = AtExitRecords.find(DSOHandle);
209 if (
I != AtExitRecords.end()) {
211 AtExitRecords.erase(
I);
215 while (!AtExitsToRun.empty()) {
216 AtExitsToRun.back().F(AtExitsToRun.back().Ctx);
217 AtExitsToRun.pop_back();
233 return std::make_unique<DynamicLibrarySearchGenerator>(
242 bool HasGlobalPrefix = (GlobalPrefix !=
'\0');
244 for (
auto &KV : Symbols) {
245 auto &
Name = KV.first;
250 if (Allow && !Allow(
Name))
253 if (HasGlobalPrefix && (*Name).front() != GlobalPrefix)
256 std::string Tmp((*Name).data() + HasGlobalPrefix,
257 (*Name).size() - HasGlobalPrefix);
265 if (NewSymbols.
empty())
276 return ArchiveBuffer.takeError();
286 return B.takeError();
289 if (isa<object::Archive>(
B->getBinary()))
294 if (
auto *UB = cast<object::MachOUniversalBinary>(
B->getBinary())) {
295 for (
const auto &Obj : UB->objects()) {
296 auto ObjTT = Obj.getTriple();
297 if (ObjTT.getArch() == TT.getArch() &&
298 ObjTT.getSubArch() == TT.getSubArch() &&
300 ObjTT.getVendor() == TT.getVendor())) {
306 return make_error<StringError>(
307 Twine(
"Could not create buffer for ") + TT.str() +
" slice of " +
308 FileName +
": [ " +
formatv(
"{0:x}", Obj.getOffset()) +
309 " .. " +
formatv(
"{0:x}", Obj.getOffset() + Obj.getSize()) +
310 ": " + SliceBuffer.getError().message(),
311 SliceBuffer.getError());
316 return make_error<StringError>(
Twine(
"Universal binary ") + FileName +
317 " does not contain a slice for " +
322 return make_error<StringError>(
Twine(
"Unrecognized file type for ") +
329 ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer) {
332 std::unique_ptr<StaticLibraryDefinitionGenerator> ADG(
356 for (
const auto &KV : Symbols) {
357 const auto &
Name = KV.first;
358 auto Child = Archive->findSym(*
Name);
360 return Child.takeError();
363 auto ChildBuffer = (*Child)->getMemoryBufferRef();
365 return ChildBuffer.takeError();
367 {ChildBuffer->getBuffer(), ChildBuffer->getBufferIdentifier()});
370 for (
auto ChildBufferInfo : ChildBufferInfos) {
372 ChildBufferInfo.second);
381 StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator(
383 : L(L), ArchiveBuffer(
std::
move(ArchiveBuffer)),
384 Archive(
std::make_unique<
object::Archive>(*
this->ArchiveBuffer, Err)) {}
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
This class represents lattice values for constants.
A symbol table that supports asynchoronous symbol queries.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void add(iterator_range< CtorDtorIterator > CtorDtors)
void * getAddressOfSymbol(const char *symbolName)
Searches through the library for the symbol symbolName.
iterator_range< CtorDtorIterator > getConstructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
@ HiddenVisibility
The GV is hidden.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
A set of symbols to look up, each associated with a SymbolLookupFlags value.
static ErrorSuccess success()
Create a success value.
static Expected< std::unique_ptr< StaticLibraryDefinitionGenerator > > Load(ObjectLayer &L, const char *FileName)
Try to create a StaticLibraryDefinitionGenerator from the given path.
Triple - Helper class for working with autoconf configuration names.
Tagged union holding either a T or a Error.
CXXDestructorDataPairList DSOHandleOverride
LookupKind
Describes the kind of lookup being performed.
std::pair< iterator, bool > insert(const ValueT &V)
bool operator==(const CtorDtorIterator &Other) const
Test iterators for equality.
Represents a symbol that has been evaluated to an address already.
This class provides a portable interface to dynamic libraries which also might be known as shared lib...
This iterator provides a convenient way to iterate over the elements of an llvm.global_ctors/llvm....
StringRef getSection() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
DynamicLibrarySearchGenerator(sys::DynamicLibrary Dylib, char GlobalPrefix, SymbolPredicate Allow=SymbolPredicate())
Create a DynamicLibrarySearchGenerator that searches for symbols in the given sys::DynamicLibrary.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
bool containsDuplicates()
Returns true if this set contains any duplicates.
static DynamicLibrary getPermanentLibrary(const char *filename, std::string *errMsg=nullptr)
This function permanently loads the dynamic library at the given path.
Error enable(JITDylib &JD, MangleAndInterner &Mangler)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
ConstantArray - Constant Array Declarations.
Interface for Layers that accept object files.
SymbolLookupSet & add(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Add an element to the set.
void runDestructors()
Run any destructors recorded by the overriden __cxa_atexit function (CXAAtExitOverride).
Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) override
DefinitionGenerators should override this method to insert new definitions into the parent JITDylib.
std::vector< CXXDestructorDataPair > CXXDestructorDataPairList
Implements a dense probed hash-table based set.
void(*)(void *) DestructorPtr
bar al al movzbl eax ret Missed when stored in a memory object
This is an important base class in LLVM.
iterator_range< CtorDtorIterator > getDestructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset, bool IsVolatile=false)
Map a subrange of the specified file as a MemoryBuffer.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg, void *DSOHandle)
Accessor for an element of the global_ctors/global_dtors array.
virtual Error add(ResourceTrackerSP RT, std::unique_ptr< MemoryBuffer > O)
Adds a MaterializationUnit representing the given IR to the given JITDylib.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
bool operator!=(const CtorDtorIterator &Other) const
Test iterators for inequality.
static Constant * getInitializer(Constant *C)
A utility class to expose symbols from a static library.
A Module instance is used to store all the information related to an LLVM module.
static Expected< std::unique_ptr< StaticLibraryDefinitionGenerator > > Create(ObjectLayer &L, std::unique_ptr< MemoryBuffer > ArchiveBuffer)
Try to create a StaticLibrarySearchGenerator from the given memory buffer.
CtorDtorIterator & operator++()
Pre-increment iterator.
Analysis the ScalarEvolution expression for r is this
Wraps state for a lookup-in-progress.
void runAtExits(void *DSOHandle)
StringRef getName() const
Return a constant reference to the value's name.
void registerAtExit(void(*F)(void *), void *Ctx, void *DSOHandle)
Mangles symbol names then uniques them in the context of an ExecutionSession.
LLVM_NODISCARD bool empty() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A constant value that is initialized with an expression using other constant values.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Lightweight error class with error context and mandatory checking.
Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) override
DefinitionGenerators should override this method to insert new definitions into the parent JITDylib.
std::unique_ptr< AbsoluteSymbolsMaterializationUnit > absoluteSymbols(SymbolMap Symbols)
Create an AbsoluteSymbolsMaterializationUnit with the given symbols.
uint64_t JITTargetAddress
Represents an address in the target process's address space.
CtorDtorIterator(const GlobalVariable *GV, bool End)
Construct an iterator instance.
@ ExternalLinkage
Externally visible function.
Element operator*() const
Dereference iterator.
Expected< T > errorOrToExpected(ErrorOr< T > &&EO)
Convert an ErrorOr<T> to an Expected<T>.
unsigned getNumOperands() const
Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)
Define all symbols provided by the materialization unit to be part of this JITDylib.
std::function< bool(const SymbolStringPtr &)> SymbolPredicate
static Expected< std::unique_ptr< DynamicLibrarySearchGenerator > > Load(const char *FileName, char GlobalPrefix, SymbolPredicate Allow=SymbolPredicate())
Permanently loads the library at the given path and, on success, returns a DynamicLibrarySearchGenera...
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
A range adaptor for a pair of iterators.
JITTargetAddress toTargetAddress(PtrTy *P)
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
LLVM_NODISCARD std::enable_if_t< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast_or_null(const Y &Val)
JITDylibLookupFlags
Lookup flags that apply to each dylib in the search order for a lookup.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Value * getOperand(unsigned i) const
LLVM Value Representation.
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
Optional< std::vector< StOtherPiece > > Other