Go to the documentation of this file.
28 I((InitList && End) ? InitList->getNumOperands() : 0) {
32 assert(InitList ==
Other.InitList &&
"Incomparable iterators.");
37 return !(*
this ==
Other);
53 assert(CS &&
"Unrecognized type in llvm.global_ctors/llvm.global_dtors");
60 if (
Function *
F = dyn_cast_or_null<Function>(FuncC)) {
63 }
else if (
ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) {
65 FuncC = CE->getOperand(0);
74 auto *Priority = cast<ConstantInt>(CS->
getOperand(0));
78 return Element(Priority->getZExtValue(), Func,
Data);
82 const GlobalVariable *CtorsList =
M.getNamedGlobal(
"llvm.global_ctors");
88 const GlobalVariable *DtorsList =
M.getNamedGlobal(
"llvm.global_dtors");
93 bool StaticInitGVIterator::isStaticInitGlobal(
GlobalValue &GV) {
98 GV.
getName() ==
"llvm.global_dtors"))
114 if (CtorDtors.
empty())
119 (*CtorDtors.
begin()).Func->getParent()->getDataLayout());
121 for (
auto CtorDtor : CtorDtors) {
122 assert(CtorDtor.Func && CtorDtor.Func->hasName() &&
123 "Ctor/Dtor function must be named to be runnable under the JIT");
126 if (CtorDtor.Func->hasLocalLinkage()) {
131 if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) {
132 dbgs() <<
" Skipping because why now?\n";
136 CtorDtorsByPriority[CtorDtor.Priority].push_back(
137 Mangle(CtorDtor.Func->getName()));
142 using CtorDtorTy = void (*)();
145 for (
auto &KV : CtorDtorsByPriority)
146 for (
auto &
Name : KV.second)
149 "Ctor/Dtor list contains duplicates");
152 if (
auto CtorDtorMap = ES.lookup(
155 for (
auto &KV : CtorDtorsByPriority) {
156 for (
auto &
Name : KV.second) {
157 assert(CtorDtorMap->count(
Name) &&
"No entry for Name");
158 auto CtorDtor =
reinterpret_cast<CtorDtorTy
>(
159 static_cast<uintptr_t
>((*CtorDtorMap)[
Name].getAddress()));
163 CtorDtorsByPriority.clear();
166 return CtorDtorMap.takeError();
171 for (
auto &
P : CXXDestructorDataPairs)
173 CXXDestructorDataPairs.clear();
179 auto& CXXDestructorDataPairs =
181 CXXDestructorDataPairs.push_back(std::make_pair(Destructor,
Arg));
188 RuntimeInterposes[Mangle(
"__dso_handle")] =
191 RuntimeInterposes[Mangle(
"__cxa_atexit")] =
200 std::lock_guard<std::mutex>
Lock(AtExitsMutex);
201 AtExitRecords[DSOHandle].push_back({
F, Ctx});
205 std::vector<AtExitRecord> AtExitsToRun;
208 std::lock_guard<std::mutex>
Lock(AtExitsMutex);
209 auto I = AtExitRecords.find(DSOHandle);
210 if (
I != AtExitRecords.end()) {
212 AtExitRecords.erase(
I);
216 while (!AtExitsToRun.empty()) {
217 AtExitsToRun.back().F(AtExitsToRun.back().Ctx);
218 AtExitsToRun.pop_back();
234 return std::make_unique<DynamicLibrarySearchGenerator>(
243 bool HasGlobalPrefix = (GlobalPrefix !=
'\0');
245 for (
auto &KV : Symbols) {
246 auto &
Name = KV.first;
251 if (Allow && !Allow(
Name))
254 if (HasGlobalPrefix && (*Name).front() != GlobalPrefix)
257 std::string Tmp((*Name).data() + HasGlobalPrefix,
258 (*Name).size() - HasGlobalPrefix);
266 if (NewSymbols.
empty())
294 if (isa<object::Archive>(
B->getBinary()))
300 if (
auto *UB = cast<object::MachOUniversalBinary>(
B->getBinary())) {
301 for (
const auto &Obj : UB->objects()) {
302 auto ObjTT = Obj.getTriple();
303 if (ObjTT.getArch() == TT.getArch() &&
304 ObjTT.getSubArch() == TT.getSubArch() &&
306 ObjTT.getVendor() == TT.getVendor())) {
312 return make_error<StringError>(
313 Twine(
"Could not create buffer for ") + TT.str() +
" slice of " +
314 FileName +
": [ " +
formatv(
"{0:x}", Obj.getOffset()) +
315 " .. " +
formatv(
"{0:x}", Obj.getOffset() + Obj.getSize()) +
316 ": " + SliceBuffer.getError().message(),
317 SliceBuffer.getError());
323 return make_error<StringError>(
Twine(
"Universal binary ") + FileName +
324 " does not contain a slice for " +
329 return make_error<StringError>(
Twine(
"Unrecognized file type for ") +
336 ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
340 std::unique_ptr<StaticLibraryDefinitionGenerator> ADG(
365 for (
const auto &KV : Symbols) {
366 const auto &
Name = KV.first;
367 auto Child = Archive->findSym(*
Name);
369 return Child.takeError();
372 auto ChildBuffer = (*Child)->getMemoryBufferRef();
374 return ChildBuffer.takeError();
376 {ChildBuffer->getBuffer(), ChildBuffer->getBufferIdentifier()});
379 for (
auto ChildBufferInfo : ChildBufferInfos) {
381 ChildBufferInfo.second);
385 return I.takeError();
395 StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator(
396 ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
397 GetObjectFileInterface GetObjFileInterface,
Error &Err)
398 : L(L), GetObjFileInterface(
std::
move(GetObjFileInterface)),
399 ArchiveBuffer(
std::
move(ArchiveBuffer)),
400 Archive(
std::make_unique<
object::Archive>(*
this->ArchiveBuffer, Err)) {
402 if (!this->GetObjFileInterface)
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
This is an optimization pass for GlobalISel generic memory operations.
Represents a JIT'd dynamic library.
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.
virtual Error add(ResourceTrackerSP RT, std::unique_ptr< MemoryBuffer > O, MaterializationUnit::Interface I)
Adds a MaterializationUnit for the object file in the given memory buffer to the JITDylib for the giv...
static ErrorSuccess success()
Create a success value.
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 ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
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...
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
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.
ExecutionSession & getExecutionSession()
Returns the execution session for this layer.
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.
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.
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.
CtorDtorIterator & operator++()
Pre-increment iterator.
Analysis the ScalarEvolution expression for r is this
Wraps state for a lookup-in-progress.
static Expected< std::unique_ptr< StaticLibraryDefinitionGenerator > > Load(ObjectLayer &L, const char *FileName, GetObjectFileInterface GetObjFileInterface=GetObjectFileInterface())
Try to create a StaticLibraryDefinitionGenerator from the given path.
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.
CtorDtorIterator(const GlobalVariable *GV, bool End)
Construct an iterator instance.
@ ExternalLinkage
Externally visible function.
Element operator*() const
Dereference iterator.
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...
Expected< MaterializationUnit::Interface > getObjectFileInterface(ExecutionSession &ES, MemoryBufferRef ObjBuffer)
Returns a MaterializationUnit::Interface for the object file contained in the given buffer,...
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.
static Expected< std::unique_ptr< StaticLibraryDefinitionGenerator > > Create(ObjectLayer &L, std::unique_ptr< MemoryBuffer > ArchiveBuffer, GetObjectFileInterface GetObjFileInterface=GetObjectFileInterface())
Try to create a StaticLibrarySearchGenerator from the given memory buffer.
JITDylibLookupFlags
Lookup flags that apply to each dylib in the search order for a lookup.
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
auto dyn_cast_or_null(const Y &Val)