LLVM: lib/ExecutionEngine/JITLink/ELF_systemz.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
16
21
22#define DEBUG_TYPE "jitlink"
23
24using namespace llvm;
26
27namespace {
28
29constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";
30
37}
38
39}
40
41namespace llvm {
45
46public:
48 std::unique_ptr G,
53 [this](LinkGraph &G) { return getOrCreateGOTSymbol(G); });
54 }
55
56private:
57 Symbol *GOTSymbol = nullptr;
58
61 }
62
64 auto DefineExternalGOTSymbolIfPresent =
67 if (Sym.getName() != nullptr &&
68 *Sym.getName() == ELFGOTSymbolName)
69 if (auto *GOTSection = G.findSectionByName(
71 GOTSymbol = &Sym;
72 return {*GOTSection, true};
73 }
74 return {};
75 });
76
77
78
79 if (auto Err = DefineExternalGOTSymbolIfPresent(G))
80 return Err;
81
82
83 if (GOTSymbol)
85
86
87
88
89 if (auto *GOTSection =
91
92
93 for (auto *Sym : GOTSection->symbols())
94 if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {
95 GOTSymbol = Sym;
97 }
98
99
100 SectionRange SR(*GOTSection);
101 if (SR.empty())
102 GOTSymbol =
103 &G.addAbsoluteSymbol(ELFGOTSymbolName, orc::ExecutorAddr(), 0,
105 else
106 GOTSymbol =
107 &G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
109 }
110
111
112
113
114 if (!GOTSymbol) {
115 for (auto *Sym : G.external_symbols()) {
116 if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {
117 auto Blocks = G.blocks();
118 if (!Blocks.empty()) {
119 G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress());
120 GOTSymbol = Sym;
121 break;
122 }
123 }
124 }
125 }
126
128 }
129};
130
133private:
136 using Base::G;
137
140
145
147 G->getTargetTriple().getArchName() +
148 " ELF object files",
150
152 &Self::addSingleRelocation))
153 return Err;
154 }
155
157 }
158
159 Error addSingleRelocation(const typename ELFT::Rela &Rel,
160 const typename ELFT::Shdr &FixupSect,
161 Block &BlockToFix) {
164 auto ELFReloc = Rel.getType(false);
165
166
169
170 uint32_t SymbolIndex = Rel.getSymbol(false);
172 if (!ObjSymbol)
173 return ObjSymbol.takeError();
174
176 if (!GraphSymbol)
178 formatv("Could not find symbol at given index, did you add it to "
179 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
180 SymbolIndex, (*ObjSymbol)->st_shndx,
183
184
185 int64_t Addend = Rel.r_addend;
186 Edge::Kind Kind = Edge::Invalid;
187
188 switch (ELFReloc) {
189 case ELF::R_390_PC64: {
191 break;
192 }
193 case ELF::R_390_PC32: {
195 break;
196 }
197 case ELF::R_390_PC16: {
199 break;
200 }
201 case ELF::R_390_PC32DBL: {
203 break;
204 }
205 case ELF::R_390_PC24DBL: {
207 break;
208 }
209 case ELF::R_390_PC16DBL: {
211 break;
212 }
213 case ELF::R_390_PC12DBL: {
215 break;
216 }
217 case ELF::R_390_64: {
219 break;
220 }
221 case ELF::R_390_32: {
223 break;
224 }
225 case ELF::R_390_20: {
227 break;
228 }
229 case ELF::R_390_16: {
231 break;
232 }
233 case ELF::R_390_12: {
235 break;
236 }
237 case ELF::R_390_8: {
239 break;
240 }
241
242 case ELF::R_390_PLT64: {
244 break;
245 }
246 case ELF::R_390_PLT32: {
248 break;
249 }
250 case ELF::R_390_PLT32DBL: {
252 break;
253 }
254 case ELF::R_390_PLT24DBL: {
256 break;
257 }
258 case ELF::R_390_PLT16DBL: {
260 break;
261 }
262 case ELF::R_390_PLT12DBL: {
264 break;
265 }
266 case ELF::R_390_PLTOFF64: {
268 break;
269 }
270 case ELF::R_390_PLTOFF32: {
272 break;
273 }
274 case ELF::R_390_PLTOFF16: {
276 break;
277 }
278
279 case ELF::R_390_GOTOFF64: {
281 break;
282 }
283 case ELF::R_390_GOTOFF: {
285 break;
286 }
287 case ELF::R_390_GOTOFF16: {
289 break;
290 }
291
292 case ELF::R_390_GOT64:
293 case ELF::R_390_GOTPLT64: {
295 break;
296 }
297 case ELF::R_390_GOT32:
298 case ELF::R_390_GOTPLT32: {
300 break;
301 }
302 case ELF::R_390_GOT20:
303 case ELF::R_390_GOTPLT20: {
305 break;
306 }
307 case ELF::R_390_GOT16:
308 case ELF::R_390_GOTPLT16: {
310 break;
311 }
312 case ELF::R_390_GOT12:
313 case ELF::R_390_GOTPLT12: {
315 break;
316 }
317 case ELF::R_390_GOTENT:
318 case ELF::R_390_GOTPLTENT: {
320 break;
321 }
322
323
324 case ELF::R_390_GOTPC: {
326 break;
327 }
328 case ELF::R_390_GOTPCDBL: {
330 break;
331 }
332 default:
334 "In " + G->getName() + ": Unsupported systemz relocation type " +
336 }
337 auto FixupAddress = orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;
338 Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
339 Edge GE(Kind, Offset, *GraphSymbol, Addend);
341 dbgs() << " ";
343 dbgs() << "\n";
344 });
345
346 BlockToFix.addEdge(std::move(GE));
347
349 }
350
351public:
354 std::shared_ptrorc::SymbolStringPool SSP,
357 std::move(Features), FileName,
358 systemz::getEdgeKindName) {}
359};
360
362 MemoryBufferRef ObjectBuffer, std::shared_ptrorc::SymbolStringPool SSP) {
364 dbgs() << "Building jitlink graph for new input "
366 });
367
369 if (!ELFObj)
370 return ELFObj.takeError();
371
372 auto Features = (*ELFObj)->getFeatures();
373 if (!Features)
374 return Features.takeError();
375
377 "Only SystemZ is supported");
378
381 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
382 (*ELFObj)->makeTriple(), std::move(*Features))
384}
385
387 std::unique_ptr Ctx) {
389 const Triple &TT = G->getTargetTriple();
390 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
391
398
399
400 if (auto MarkLive = Ctx->getMarkLivePass(TT))
401 Config.PrePrunePasses.push_back(std::move(MarkLive));
402 else
404
405
406 Config.PostPrunePasses.push_back(buildTables_ELF_systemz);
407
408
412
413
414
415 }
416
417 if (auto Err = Ctx->modifyPassConfig(*G, Config))
418 return Ctx->notifyFailed(std::move(Err));
419
421}
422
423}
424}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_UNLIKELY(EXPR)
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.
orc::ExecutorAddr getAddress() const
An Addressable with content and edges.
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
A LinkGraph pass that splits blocks in a section that follows the DWARF Record format into sub-blocks...
A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA edges.
ELFJITLinker_systemz(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)
Definition ELF_systemz.cpp:47
std::unique_ptr< LinkGraph > G
Definition ELF_systemz.cpp:132
ELFLinkGraphBuilder_systemz(StringRef FileName, const object::ELFFile< ELFT > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features)
Definition ELF_systemz.cpp:352
const ELFFile::Elf_Shdr * SymTabSec
virtual Error addRelocations()=0
ELFLinkGraphBuilder(const object::ELFFile< object::ELF64BE > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
Expected< std::unique_ptr< LinkGraph > > buildGraph()
Attempt to construct and return the LinkGraph.
DenseMap< ELFSymbolIndex, Symbol * > GraphSymbols
ELFFile::Elf_Shdr_Range Sections
Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect, RelocHandlerMethod &&Func)
Traverse all matching ELFT::Rela relocation records in the given section.
Symbol * getGraphSymbol(ELFSymbolIndex SymIndex)
Represents fixups and constraints in the LinkGraph.
PassConfiguration & getPassConfig()
bool shouldAddDefaultTargetPasses(const Triple &TT)
static void link(ArgTs &&... Args)
const orc::SymbolStringPtr & 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 Symbol *GOTSymbol)
Apply fixup expression for edge to block content.
@ DeltaPLT32
A 32-bit Delta.
@ Delta64PLTFromGOT
A 64-bit offset from GOT to PLT.
@ Pointer16
A plain 16-bit pointer value relocation.
@ RequestGOTAndTransformToDelta32FromGOT
A GOT entry getter/constructor, transformed to Delta32FromGOT pointing at the GOT entry for the origi...
@ RequestGOTAndTransformToDelta32dbl
A GOT entry getter/constructor, transformed to Delta32dbl pointing at the GOT entry for the original ...
@ Pointer64
A plain 64-bit pointer value relocation.
@ Pointer20
A plain 20-bit pointer value relocation.
@ RequestGOTAndTransformToDelta16FromGOT
A GOT entry getter/constructor, transformed to Delta16FromGOT pointing at the GOT entry for the origi...
@ RequestGOTAndTransformToDelta12FromGOT
A GOT entry getter/constructor, transformed to Delta12FromGOT pointing at the GOT entry for the origi...
@ RequestGOTAndTransformToDelta64FromGOT
A GOT entry getter/constructor, transformed to Delta64FromGOT pointing at the GOT entry for the origi...
@ DeltaPLT16dbl
A 16-bit Delta shifted by 1.
@ Delta16FromGOT
A 16-bit offset from GOT.
@ Pointer8
A plain 8-bit pointer value relocation.
@ Delta16PLTFromGOT
A 16-bit offset from GOT to PLT.
@ Delta32PLTFromGOT
A 32-bit offset from GOT to PLT.
@ Delta32dblGOTBase
A 32-bit Delta to GOT base shifted by 1.
@ Delta32FromGOT
A 32-bit offset from GOT.
@ Delta32GOTBase
A 32-bit Delta to GOT base.
@ DeltaPLT12dbl
A 12-bit Delta shifted by 1.
@ RequestGOTAndTransformToDelta20FromGOT
A GOT entry getter/constructor, transformed to Delta20FromGOT pointing at the GOT entry for the origi...
@ Delta16dbl
A 16-bit delta shifted by 1.
@ DeltaPLT32dbl
A 32-bit Delta shifted by 1.
@ NegDelta32
A 32-bit negative delta.
@ Delta24dbl
A 24-bit delta shifted by 1.
@ DeltaPLT64
A 64-bit Delta.
@ DeltaPLT24dbl
A 24-bit Delta shifted by 1.
@ Pointer12
A plain 12-bit pointer value relocation.
@ Delta12dbl
A 12-bit delta shifted by 1.
@ Pointer32
A plain 32-bit pointer value relocation.
@ Delta32dbl
A 32-bit delta shifted by 1.
@ Delta64FromGOT
A 64-bit offset from GOT.
const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given systemz edge.
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...
void link_ELF_systemz(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)
jit-link the given object buffer, which must be a ELF systemz relocatable object file.
Definition ELF_systemz.cpp:386
LLVM_ABI Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
LLVM_ABI void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
SectionRangeSymbolDesc identifyELFSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym)
ELF section start/end symbol detection.
DefineExternalSectionStartAndEndSymbols< SymbolIdentifierFunction > createDefineExternalSectionStartAndEndSymbolsPass(SymbolIdentifierFunction &&F)
Returns a JITLink pass (as a function class) that uses the given symbol identification function to id...
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_systemz(MemoryBufferRef ObjectBuffer, std::shared_ptr< orc::SymbolStringPool > SSP)
Create a LinkGraph from an ELF/systemz relocatable object.
Definition ELF_systemz.cpp:361
LLVM_ABI StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
ELFType< llvm::endianness::big, true > ELF64BE
detail::packed_endian_specific_integral< int32_t, llvm::endianness::big, unaligned > big32_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.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
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.
LinkGraphPassList PostPrunePasses
Post-prune passes.
LinkGraphPassList PrePrunePasses
Pre-prune passes.
Elf_Rel_Impl< ELFType< E, Is64 >, true > Rela
Elf_Shdr_Impl< ELFType< E, Is64 > > Shdr