Go to the documentation of this file.
21 #define DEBUG_TYPE "jitlink"
34 std::unique_ptr<LinkGraph>
G,
40 using namespace aarch64;
43 char *BlockWorkingMem =
B.getAlreadyMutableContent().data();
44 char *FixupPtr = BlockWorkingMem +
E.getOffset();
45 auto FixupAddress =
B.getAddress() +
E.getOffset();
46 switch (
E.getKind()) {
48 assert((FixupAddress.getValue() & 0
x3) == 0 &&
49 "Call-inst is not 32-bit aligned");
50 int64_t
Value =
E.getTarget().getAddress() - FixupAddress +
E.getAddend();
53 return make_error<JITLinkError>(
"Call target is not 32-bit aligned");
55 if (!isInt<28>(
Value))
59 assert((RawInstr & 0x7fffffff) == 0x14000000 &&
60 "RawInstr isn't a B or BR immediate instruction");
62 uint32_t FixedInstr = RawInstr | Imm;
71 template <
typename ELFT>
76 using namespace aarch64;
82 return make_error<JITLinkError>(
"Unsupported aarch64 relocation:" +
86 Error addRelocations()
override {
91 for (
const auto &RelSect : Base::Sections)
92 if (
Error Err = Base::forEachRelocation(RelSect,
this,
93 &Self::addSingleRelocation))
99 Error addSingleRelocation(
const typename ELFT::Rela &Rel,
104 uint32_t SymbolIndex = Rel.getSymbol(
false);
105 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
107 return ObjSymbol.takeError();
109 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
111 return make_error<StringError>(
112 formatv(
"Could not find symbol at given index, did you add it to "
113 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
114 SymbolIndex, (*ObjSymbol)->st_shndx,
115 Base::GraphSymbols.size()),
121 return Kind.takeError();
123 int64_t Addend = Rel.r_addend;
148 dbgs() <<
"Building jitlink graph for new input "
154 return ELFObj.takeError();
157 "Only AArch64 (little endian) is supported for now");
159 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
161 ELFObjFile.getELFFile(),
162 (*ELFObj)->makeTriple())
167 std::unique_ptr<JITLinkContext> Ctx) {
169 const Triple &TT =
G->getTargetTriple();
170 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
171 if (
auto MarkLive = Ctx->getMarkLivePass(TT))
176 if (
auto Err = Ctx->modifyPassConfig(*
G, Config))
177 return Ctx->notifyFailed(
std::move(Err));
ELFJITLinker_aarch64(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)
Represents an address in the executor process.
This is an optimization pass for GlobalISel generic memory operations.
Expected< std::unique_ptr< LinkGraph > > buildGraph()
Attempt to construct and return the LinkGraph.
const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given aarch64 edge.
static ErrorSuccess success()
Create a success value.
Triple - Helper class for working with autoconf configuration names.
An Addressable with content and edges.
The instances of the Type class are immutable: once they are created, they are never changed.
Tagged union holding either a T or a Error.
void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
In x86 we generate this spiffy xmm0 xmm0 ret in x86 we generate this which could be xmm1 movss xmm1 xmm0 ret In sse4 we could use insertps to make both better Here s another testcase that could use x3
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer)
Create a LinkGraph from an ELF/aarch64 relocatable object.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
ELFLinkGraphBuilder_aarch64(StringRef FileName, const object::ELFFile< ELFT > &Obj, const Triple T)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)
LinkGraphPassList PrePrunePasses
Pre-prune passes.
Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
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
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.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
StringRef - Represent a constant reference to a string, i.e.
orc::ExecutorAddr getAddress() const
Represents fixups and constraints in the LinkGraph.
Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B, const Edge &E)
Create an out of range error for the given edge in the given block.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const Symbol *GOTSymbol)
Apply fixup expression for edge to block content.
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.
Ling-graph building code that's specific to the given ELFT, but common across all architectures.
void link_ELF_aarch64(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)
jit-link the given object buffer, which must be a ELF aarch64 relocatable object file.
static void link(ArgTs &&... Args)
Link constructs a LinkerImpl instance and calls linkPhase1.
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
@ R_AARCH64_CALL26
Set a CALL immediate field to bits [27:2] of X = Target - Fixup + Addend.
StringRef getBufferIdentifier() const
LLVM Value Representation.