23#define DEBUG_TYPE "jitlink"
30enum EdgeKind_coff_x86_64 : Edge::Kind {
38class COFFJITLinker_x86_64 :
public JITLinker<COFFJITLinker_x86_64> {
39 friend class JITLinker<COFFJITLinker_x86_64>;
42 COFFJITLinker_x86_64(std::unique_ptr<JITLinkContext> Ctx,
43 std::unique_ptr<LinkGraph>
G,
45 :
JITLinker(std::move(Ctx), std::move(
G), std::move(PassConfig)) {}
55 Error addRelocations()
override {
58 for (
const auto &RelSect :
sections())
60 RelSect,
this, &COFFLinkGraphBuilder_x86_64::addSingleRelocation))
71 if (SymbolIt ==
getObject().symbol_end()) {
73 formatv(
"Invalid symbol index in relocation entry. "
74 "index: {0}, section: {1}",
80 COFFSymbolIndex SymIndex =
getObject().getSymbolIndex(COFFSymbol);
82 Symbol *GraphSymbol = getGraphSymbol(SymIndex);
85 formatv(
"Could not find symbol at given index, did you add it to "
86 "JITSymbolTable? index: {0}, section: {1}",
95 Edge::Kind Kind = Edge::Invalid;
102 ImageBase = &addImageBaseSymbol();
103 Kind = EdgeKind_coff_x86_64::Pointer32NB;
108 Kind = EdgeKind_coff_x86_64::PCRel32;
113 Kind = EdgeKind_coff_x86_64::PCRel32;
119 Kind = EdgeKind_coff_x86_64::PCRel32;
125 Kind = EdgeKind_coff_x86_64::PCRel32;
131 Kind = EdgeKind_coff_x86_64::PCRel32;
137 Kind = EdgeKind_coff_x86_64::PCRel32;
143 Kind = EdgeKind_coff_x86_64::Pointer64;
148 Kind = EdgeKind_coff_x86_64::SectionIdx16;
151 if (COFFSymbol.isAbsolute())
152 SectionIdx =
getObject().getNumberOfSections() + 1;
154 SectionIdx = COFFSymbol.getSectionNumber();
156 auto *AbsSym = &getGraph().addAbsoluteSymbol(
159 GraphSymbol = AbsSym;
166 Kind = EdgeKind_coff_x86_64::SecRel32;
183 BlockToFix.
addEdge(std::move(GE));
190 std::shared_ptr<orc::SymbolStringPool> SSP,
197class COFFLinkGraphLowering_x86_64 {
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 = GetImageBase(
G);
206 assert(ImageBase &&
"__ImageBase symbol must be defined");
207 E.setAddend(
E.getAddend() - ImageBase->getAddress().getValue());
211 case EdgeKind_coff_x86_64::PCRel32: {
215 case EdgeKind_coff_x86_64::Pointer64: {
219 case EdgeKind_coff_x86_64::SectionIdx16: {
223 case EdgeKind_coff_x86_64::SecRel32: {
224 E.setAddend(
E.getAddend() -
225 getSectionStart(
E.getTarget().getSection()).getValue());
239 auto [It, Inserted] = SectionStartCache.try_emplace(&Sec);
242 It->second =
Range.getStart();
261 return "Pointer32NB";
265 return "SectionIdx16";
274 MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
276 dbgs() <<
"Building jitlink graph for new input "
282 return COFFObj.takeError();
284 auto Features = (*COFFObj)->getFeatures();
286 return Features.takeError();
288 return COFFLinkGraphBuilder_x86_64(**COFFObj, std::move(SSP),
289 (*COFFObj)->makeTriple(),
290 std::move(*Features))
295 std::unique_ptr<JITLinkContext> Ctx) {
297 const Triple &TT =
G->getTargetTriple();
298 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
300 if (
auto MarkLive = Ctx->getMarkLivePass(TT)) {
310 if (
auto Err = Ctx->modifyPassConfig(*
G, Config))
311 return Ctx->notifyFailed(std::move(Err));
313 COFFJITLinker_x86_64::link(std::move(Ctx), std::move(
G), std::move(Config));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
bbsections Prepares for basic block sections
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static Error getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
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
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.
Error forEachRelocation(const object::SectionRef &RelSec, RelocHandlerFunction &&Func, bool ProcessDebugSections=false)
Traverse all matching relocation records in the given section.
Represents fixups and constraints in the LinkGraph.
GetImageBaseSymbol is a function object that finds the __ImageBase symbol in the given graph if one i...
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....
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.
@ 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
LLVM_ABI 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
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.
LLVM_ABI 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.
LLVM_ABI 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.
detail::packed_endian_specific_integral< int16_t, llvm::endianness::little, unaligned > little16_t
detail::packed_endian_specific_integral< int32_t, llvm::endianness::little, unaligned > little32_t
detail::packed_endian_specific_integral< int64_t, llvm::endianness::little, unaligned > little64_t
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI 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)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
LinkGraphPassList PreFixupPasses
Pre-fixup passes.
LinkGraphPassList PrePrunePasses
Pre-prune passes.
support::ulittle32_t SymbolTableIndex