//===------------ JITLink.h - JIT linker functionality ----------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Contains generic JIT-linker types. // //===----------------------------------------------------------------------===// #ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H #define LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" #include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h" #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/TargetParser/SubtargetFeature.h" #include "llvm/TargetParser/Triple.h" #include <optional> #include <map> #include <string> #include <system_error> namespace llvm { namespace jitlink { class LinkGraph; class Symbol; class Section; /// Base class for errors originating in JIT linker, e.g. missing relocation /// support. class JITLinkError : public ErrorInfo<JITLinkError> { … }; /// Represents fixups and constraints in the LinkGraph. class Edge { … }; /// Returns the string name of the given generic edge kind, or "unknown" /// otherwise. Useful for debugging. const char *getGenericEdgeKindName(Edge::Kind K); /// Base class for Addressable entities (externals, absolutes, blocks). class Addressable { … }; SectionOrdinal; /// An Addressable with content and edges. class Block : public Addressable { … }; // Align an address to conform with block alignment requirements. inline uint64_t alignToBlock(uint64_t Addr, const Block &B) { … } // Align a orc::ExecutorAddr to conform with block alignment requirements. inline orc::ExecutorAddr alignToBlock(orc::ExecutorAddr Addr, const Block &B) { … } // Returns true if the given blocks contains exactly one valid c-string. // Zero-fill blocks of size 1 count as valid empty strings. Content blocks // must end with a zero, and contain no zeros before the end. bool isCStringBlock(Block &B); /// Describes symbol linkage. This can be used to resolve definition clashes. enum class Linkage : uint8_t { … }; /// Holds target-specific properties for a symbol. TargetFlagsType; /// For errors and debugging output. const char *getLinkageName(Linkage L); /// Defines the scope in which this symbol should be visible: /// Default -- Visible in the public interface of the linkage unit. /// Hidden -- Visible within the linkage unit, but not exported from it. /// Local -- Visible only within the LinkGraph. enum class Scope : uint8_t { … }; /// For debugging output. const char *getScopeName(Scope S); raw_ostream &operator<<(raw_ostream &OS, const Block &B); /// Symbol representation. /// /// Symbols represent locations within Addressable objects. /// They can be either Named or Anonymous. /// Anonymous symbols have neither linkage nor visibility, and must point at /// ContentBlocks. /// Named symbols may be in one of four states: /// - Null: Default initialized. Assignable, but otherwise unusable. /// - Defined: Has both linkage and visibility and points to a ContentBlock /// - Common: Has both linkage and visibility, points to a null Addressable. /// - External: Has neither linkage nor visibility, points to an external /// Addressable. /// class Symbol { … }; raw_ostream &operator<<(raw_ostream &OS, const Symbol &A); void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName); /// Represents an object file section. class Section { … }; /// Represents a section address range via a pair of Block pointers /// to the first and last Blocks in the section. class SectionRange { … }; class LinkGraph { … }; inline MutableArrayRef<char> Block::getMutableContent(LinkGraph &G) { … } /// Enables easy lookup of blocks by addresses. class BlockAddressMap { … }; /// A map of addresses to Symbols. class SymbolAddressMap { … }; /// A function for mutating LinkGraphs. LinkGraphPassFunction; /// A list of LinkGraph passes. LinkGraphPassList; /// An LinkGraph pass configuration, consisting of a list of pre-prune, /// post-prune, and post-fixup passes. struct PassConfiguration { … }; /// Flags for symbol lookup. /// /// FIXME: These basically duplicate orc::SymbolLookupFlags -- We should merge /// the two types once we have an OrcSupport library. enum class SymbolLookupFlags { … }; raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF); /// A map of symbol names to resolved addresses. AsyncLookupResult; /// A function object to call with a resolved symbol map (See AsyncLookupResult) /// or an error if resolution failed. class JITLinkAsyncLookupContinuation { … }; /// Create a lookup continuation from a function object. template <typename Continuation> std::unique_ptr<JITLinkAsyncLookupContinuation> createLookupContinuation(Continuation Cont) { … } /// Holds context for a single jitLink invocation. class JITLinkContext { … }; /// Marks all symbols in a graph live. This can be used as a default, /// conservative mark-live implementation. Error markAllSymbolsLive(LinkGraph &G); /// Create an out of range error for the given edge in the given block. Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B, const Edge &E); Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N, const Edge &E); /// Creates a new pointer block in the given section and returns an /// Anonymous symbol pointing to it. /// /// The pointer block will have the following default values: /// alignment: PointerSize /// alignment-offset: 0 /// address: highest allowable AnonymousPointerCreator; /// Get target-specific AnonymousPointerCreator AnonymousPointerCreator getAnonymousPointerCreator(const Triple &TT); /// Create a jump stub that jumps via the pointer at the given symbol and /// an anonymous symbol pointing to it. Return the anonymous symbol. /// /// The stub block will be created by createPointerJumpStubBlock. PointerJumpStubCreator; /// Get target-specific PointerJumpStubCreator PointerJumpStubCreator getPointerJumpStubCreator(const Triple &TT); /// Base case for edge-visitors where the visitor-list is empty. inline void visitEdge(LinkGraph &G, Block *B, Edge &E) { … } /// Applies the first visitor in the list to the given edge. If the visitor's /// visitEdge method returns true then we return immediately, otherwise we /// apply the next visitor. template <typename VisitorT, typename... VisitorTs> void visitEdge(LinkGraph &G, Block *B, Edge &E, VisitorT &&V, VisitorTs &&...Vs) { … } /// For each edge in the given graph, apply a list of visitors to the edge, /// stopping when the first visitor's visitEdge method returns true. /// /// Only visits edges that were in the graph at call time: if any visitor /// adds new edges those will not be visited. Visitors are not allowed to /// remove edges (though they can change their kind, target, and addend). template <typename... VisitorTs> void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs) { … } /// Create a LinkGraph from the given object buffer. /// /// Note: The graph does not take ownership of the underlying buffer, nor copy /// its contents. The caller is responsible for ensuring that the object buffer /// outlives the graph. Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromObject(MemoryBufferRef ObjectBuffer); /// Create a \c LinkGraph defining the given absolute symbols. std::unique_ptr<LinkGraph> absoluteSymbolsLinkGraph(const Triple &TT, orc::SymbolMap Symbols); /// Link the given graph. void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx); } // end namespace jitlink } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H