22#define DEBUG_TYPE "jitlink"
37class COFFJITLinker_x86_64 :
public JITLinker<COFFJITLinker_x86_64> {
38 friend class JITLinker<COFFJITLinker_x86_64>;
41 COFFJITLinker_x86_64(std::unique_ptr<JITLinkContext> Ctx,
42 std::unique_ptr<LinkGraph>
G,
44 :
JITLinker(std::move(Ctx), std::move(
G), std::move(PassConfig)) {}
57 for (
const auto &RelSect :
sections())
59 RelSect,
this, &COFFLinkGraphBuilder_x86_64::addSingleRelocation))
70 if (SymbolIt ==
getObject().symbol_end()) {
71 return make_error<StringError>(
72 formatv(
"Invalid symbol index in relocation entry. "
73 "index: {0}, section: {1}",
83 return make_error<StringError>(
84 formatv(
"Could not find symbol at given index, did you add it to "
85 "JITSymbolTable? index: {0}, section: {1}",
99 Kind = EdgeKind_coff_x86_64::Pointer32NB;
104 Kind = EdgeKind_coff_x86_64::PCRel32;
109 Kind = EdgeKind_coff_x86_64::PCRel32;
115 Kind = EdgeKind_coff_x86_64::PCRel32;
121 Kind = EdgeKind_coff_x86_64::PCRel32;
127 Kind = EdgeKind_coff_x86_64::PCRel32;
133 Kind = EdgeKind_coff_x86_64::PCRel32;
139 Kind = EdgeKind_coff_x86_64::Pointer64;
144 Kind = EdgeKind_coff_x86_64::SectionIdx16;
154 Scope::Local,
false);
155 GraphSymbol = AbsSym;
162 Kind = EdgeKind_coff_x86_64::SecRel32;
167 return make_error<JITLinkError>(
"Unsupported x86_64 relocation:" +
179 BlockToFix.
addEdge(std::move(GE));
186 std::shared_ptr<orc::SymbolStringPool> SSP,
193class COFFLinkGraphLowering_x86_64 {
195 COFFLinkGraphLowering_x86_64(std::shared_ptr<orc::SymbolStringPool> SSP)
196 : SSP(std::move(SSP)) {
197 ImageBaseName = this->SSP->intern(
"__ImageBase");
201 for (
auto *
B :
G.blocks()) {
202 for (
auto &E :
B->edges()) {
203 switch (E.getKind()) {
204 case EdgeKind_coff_x86_64::Pointer32NB: {
205 auto ImageBase = getImageBaseAddress(
G, Ctx);
207 return ImageBase.takeError();
208 E.setAddend(E.getAddend() - ImageBase->getValue());
212 case EdgeKind_coff_x86_64::PCRel32: {
216 case EdgeKind_coff_x86_64::Pointer64: {
220 case EdgeKind_coff_x86_64::SectionIdx16: {
224 case EdgeKind_coff_x86_64::SecRel32: {
225 E.setAddend(E.getAddend() -
226 getSectionStart(E.getTarget().getBlock().getSection())
241 return this->ImageBaseName;
245 if (!SectionStartCache.count(&Sec)) {
247 SectionStartCache[&Sec] =
Range.getStart();
249 return SectionStartCache[&Sec];
255 return this->ImageBase;
256 for (
auto *S :
G.defined_symbols())
257 if (S->getName() == getImageBaseSymbolName()) {
258 this->ImageBase = S->getAddress();
259 return this->ImageBase;
263 Symbols[getImageBaseSymbolName()] = SymbolLookupFlags::RequiredSymbol;
273 ImageBase = LR->begin()->second.getAddress();
276 return std::move(Err);
277 this->ImageBase = ImageBase;
283 std::shared_ptr<orc::SymbolStringPool> SSP;
289 COFFLinkGraphLowering_x86_64 GraphLowering(
G.getSymbolStringPool());
290 if (
auto Err = GraphLowering.lowerCOFFRelocationEdges(
G, *Ctx))
306 return "Pointer32NB";
310 return "SectionIdx16";
319 MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
321 dbgs() <<
"Building jitlink graph for new input "
327 return COFFObj.takeError();
329 auto Features = (*COFFObj)->getFeatures();
331 return Features.takeError();
333 return COFFLinkGraphBuilder_x86_64(**COFFObj, std::move(SSP),
334 (*COFFObj)->makeTriple(),
335 std::move(*Features))
340 std::unique_ptr<JITLinkContext> Ctx) {
342 const Triple &TT =
G->getTargetTriple();
343 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
345 if (
auto MarkLive = Ctx->getMarkLivePass(TT)) {
346 Config.PrePrunePasses.push_back(std::move(MarkLive));
353 Config.PreFixupPasses.push_back(
354 [CtxPtr](
LinkGraph &
G) {
return lowerEdges_COFF_x86_64(
G, CtxPtr); });
357 if (
auto Err = Ctx->modifyPassConfig(*
G,
Config))
358 return Ctx->notifyFailed(std::move(Err));
360 COFFJITLinker_x86_64::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")
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
Helper for Errors used as out-parameters.
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.
Error takeError()
Take ownership of the stored error.
StringRef getBufferIdentifier() const
Manages the enabling and disabling of subtarget specific features.
Triple - Helper class for working with autoconf configuration names.
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.
virtual Error addRelocations()=0
Error forEachRelocation(const object::SectionRef &RelSec, RelocHandlerFunction &&Func, bool ProcessDebugSections=false)
Traverse all matching relocation records in the given section.
Symbol * getGraphSymbol(COFFSymbolIndex SymIndex) const
object::COFFObjectFile::section_iterator_range sections() const
LinkGraph & getGraph() const
const object::COFFObjectFile & getObject() const
Represents fixups and constraints in the LinkGraph.
Holds context for a single jitLink invocation.
virtual void lookup(const LookupMap &Symbols, std::unique_ptr< JITLinkAsyncLookupContinuation > LC)=0
Called by JITLink to resolve external symbols.
Symbol & addAbsoluteSymbol(orc::SymbolStringPtr Name, orc::ExecutorAddr Address, orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsLive)
Add an absolute symbol.
This pass adds keep-alive edge from SEH frame sections to the parent function content block.
Represents a section address range via a pair of Block pointers to the first and last Blocks in the s...
Represents an object file section.
bool isDefined() const
Returns true if this Symbol has content (potentially) defined within this object file (i....
const coff_relocation * getCOFFRelocation(const RelocationRef &Reloc) const
uint32_t getNumberOfSections() const
uint32_t getSymbolIndex(COFFSymbolRef Symbol) const
COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const
int32_t getSectionNumber() const
static Expected< std::unique_ptr< COFFObjectFile > > createCOFFObjectFile(MemoryBufferRef Object)
This is a value type class that represents a single relocation in the list of relocations in the obje...
uint64_t getOffset() const
symbol_iterator getSymbol() const
This is a value type class that represents a single section in the list of sections in the object fil...
uint64_t getIndex() const
uint64_t getAddress() const
Represents an address in the executor process.
Pointer to a pooled string representing a symbol name.
@ IMAGE_REL_AMD64_REL32_5
@ IMAGE_REL_AMD64_REL32_3
@ IMAGE_REL_AMD64_ADDR32NB
@ IMAGE_REL_AMD64_SECTION
@ IMAGE_REL_AMD64_REL32_2
@ IMAGE_REL_AMD64_REL32_1
@ IMAGE_REL_AMD64_REL32_4
const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given x86-64 edge.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const Symbol *GOTSymbol)
Apply fixup expression for edge to block content.
@ Pointer32
A plain 32-bit pointer value relocation.
@ PCRel32
A 32-bit PC-relative relocation.
@ Pointer16
A plain 16-bit pointer value relocation.
@ Pointer64
A plain 64-bit pointer value relocation.
@ FirstPlatformRelocation
std::unique_ptr< JITLinkAsyncLookupContinuation > createLookupContinuation(Continuation Cont)
Create a lookup continuation from a function object.
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromCOFFObject_x86_64(MemoryBufferRef ObjectBuffer, std::shared_ptr< orc::SymbolStringPool > SSP)
Create a LinkGraph from an COFF/x86-64 relocatable object.
Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
void link_COFF_x86_64(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)
jit-link the given object buffer, which must be a COFF x86-64 object file.
void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
const char * getCOFFX86RelocationKindName(Edge::Kind R)
Return the string name of the given COFF x86-64 edge kind.
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(bool Validate, const char *Fmt, Ts &&...Vals)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
support::ulittle32_t SymbolTableIndex