21#define DEBUG_TYPE "jitlink"
27constexpr StringRef ELFGOTSymbolName =
"_GLOBAL_OFFSET_TABLE_";
49 [
this](
LinkGraph &
G) {
return getOrCreateGOTSymbol(
G); });
53 Symbol *GOTSymbol =
nullptr;
56 auto DefineExternalGOTSymbolIfPresent =
60 if (
auto *GOTSection =
G.findSectionByName(
63 return {*GOTSection, true};
70 if (
auto Err = DefineExternalGOTSymbolIfPresent(
G))
80 if (
auto *GOTSection =
84 for (
auto *
Sym : GOTSection->symbols())
99 &
G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
112template <
typename ELFT>
116 using namespace i386;
118 case ELF::R_386_NONE:
119 return EdgeKind_i386::None;
121 return EdgeKind_i386::Pointer32;
122 case ELF::R_386_PC32:
123 return EdgeKind_i386::PCRel32;
125 return EdgeKind_i386::Pointer16;
126 case ELF::R_386_PC16:
127 return EdgeKind_i386::PCRel16;
128 case ELF::R_386_GOT32:
129 return EdgeKind_i386::RequestGOTAndTransformToDelta32FromGOT;
130 case ELF::R_386_GOTPC:
131 return EdgeKind_i386::Delta32;
132 case ELF::R_386_GOTOFF:
133 return EdgeKind_i386::Delta32FromGOT;
134 case ELF::R_386_PLT32:
135 return EdgeKind_i386::BranchPCRel32;
138 return make_error<JITLinkError>(
"Unsupported i386 relocation:" +
142 Error addRelocations()
override {
147 for (
const auto &RelSect : Base::Sections) {
150 return make_error<StringError>(
151 "No SHT_RELA in valid i386 ELF object files",
154 if (
Error Err = Base::forEachRelRelocation(RelSect,
this,
155 &Self::addSingleRelocation))
162 Error addSingleRelocation(
const typename ELFT::Rel &Rel,
163 const typename ELFT::Shdr &FixupSection,
167 uint32_t SymbolIndex = Rel.getSymbol(
false);
168 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
170 return ObjSymbol.takeError();
172 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
174 return make_error<StringError>(
175 formatv(
"Could not find symbol at given index, did you add it to "
176 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
177 SymbolIndex, (*ObjSymbol)->st_shndx,
178 Base::GraphSymbols.size()),
183 return Kind.takeError();
207 BlockToFix.
addEdge(std::move(GE));
215 FileName, i386::getEdgeKindName) {}
221 dbgs() <<
"Building jitlink graph for new input "
227 return ELFObj.takeError();
229 auto Features = (*ELFObj)->getFeatures();
231 return Features.takeError();
234 "Only i386 (little endian) is supported for now");
236 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
238 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
239 (*ELFObj)->makeTriple(), std::move(*Features))
244 std::unique_ptr<JITLinkContext> Ctx) {
246 const Triple &TT =
G->getTargetTriple();
247 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
248 if (
auto MarkLive = Ctx->getMarkLivePass(TT))
249 Config.PrePrunePasses.push_back(std::move(MarkLive));
254 Config.PostPrunePasses.push_back(buildTables_ELF_i386);
259 if (
auto Err = Ctx->modifyPassConfig(*
G,
Config))
260 return Ctx->notifyFailed(std::move(Err));
262 ELFJITLinker_i386::link(std::move(Ctx), std::move(
G), std::move(
Config));
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StringRef getBufferIdentifier() const
StringRef - Represent a constant reference to a string, i.e.
Manages the enabling and disabling of subtarget specific features.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
orc::ExecutorAddr getAddress() const
An Addressable with content and edges.
ArrayRef< char > getContent() const
Get the content for this block. Block must not be a zero-fill block.
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
ELFJITLinker_i386(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)
ELFLinkGraphBuilder_i386(StringRef FileName, const object::ELFFile< ELFT > &Obj, Triple TT, SubtargetFeatures Features)
LinkGraph building code that's specific to the given ELFT, but common across all architectures.
Expected< std::unique_ptr< LinkGraph > > buildGraph()
Attempt to construct and return the LinkGraph.
Represents fixups and constraints in the LinkGraph.
PassConfiguration & getPassConfig()
Represents a section address range via a pair of Block pointers to the first and last Blocks in the s...
StringRef getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
Global Offset Table Builder.
static StringRef getSectionName()
Procedure Linkage Table Builder.
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)
Represents an address in the executor process.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)
Apply fixup expression for edge to block content.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const Symbol *GOTSymbol)
Apply fixup expression for edge to block content.
Error optimizeGOTAndStubAccesses(LinkGraph &G)
Optimize the GOT and Stub relocations if the edge target address is in range.
const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given i386 edge.
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer)
Create a LinkGraph from an ELF/i386 relocatable object.
void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs)
For each edge in the given graph, apply a list of visitors to the edge, stopping when the first visit...
Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
void link_ELF_i386(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)
jit-link the given object buffer, which must be a ELF i386 relocatable object file.
void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
DefineExternalSectionStartAndEndSymbols< SymbolIdentifierFunction > createDefineExternalSectionStartAndEndSymbolsPass(SymbolIdentifierFunction &&F)
Returns a JITLink pass (as a function class) that uses the given symbol identification function to id...
This is an optimization pass for GlobalISel generic memory operations.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
LinkGraphPassList PostAllocationPasses
Post-allocation passes.