@@ -29,18 +29,92 @@ using namespace llvm::jitlink;
29
29
30
30
namespace {
31
31
32
+ constexpr StringRef ELFGOTSymbolName = " _GLOBAL_OFFSET_TABLE_" ;
33
+
32
34
class ELFJITLinker_aarch64 : public JITLinker <ELFJITLinker_aarch64> {
33
35
friend class JITLinker <ELFJITLinker_aarch64>;
34
36
35
37
public:
36
38
ELFJITLinker_aarch64 (std::unique_ptr<JITLinkContext> Ctx,
37
39
std::unique_ptr<LinkGraph> G,
38
40
PassConfiguration PassConfig)
39
- : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {}
41
+ : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {
42
+ if (shouldAddDefaultTargetPasses (getGraph ().getTargetTriple ()))
43
+ getPassConfig ().PostAllocationPasses .push_back (
44
+ [this ](LinkGraph &G) { return getOrCreateGOTSymbol (G); });
45
+ }
40
46
41
47
private:
48
+ Symbol *GOTSymbol = nullptr ;
49
+
42
50
Error applyFixup (LinkGraph &G, Block &B, const Edge &E) const {
43
- return aarch64::applyFixup (G, B, E);
51
+ return aarch64::applyFixup (G, B, E, GOTSymbol);
52
+ }
53
+
54
+ Error getOrCreateGOTSymbol (LinkGraph &G) {
55
+ auto DefineExternalGOTSymbolIfPresent =
56
+ createDefineExternalSectionStartAndEndSymbolsPass (
57
+ [&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {
58
+ if (Sym.getName () == ELFGOTSymbolName)
59
+ if (auto *GOTSection = G.findSectionByName (
60
+ aarch64::GOTTableManager::getSectionName ())) {
61
+ GOTSymbol = &Sym;
62
+ return {*GOTSection, true };
63
+ }
64
+ return {};
65
+ });
66
+
67
+ // Try to attach _GLOBAL_OFFSET_TABLE_ to the GOT if it's defined as an
68
+ // external.
69
+ if (auto Err = DefineExternalGOTSymbolIfPresent (G))
70
+ return Err;
71
+
72
+ // If we succeeded then we're done.
73
+ if (GOTSymbol)
74
+ return Error::success ();
75
+
76
+ // Otherwise look for a GOT section: If it already has a start symbol we'll
77
+ // record it, otherwise we'll create our own.
78
+ // If there's a GOT section but we didn't find an external GOT symbol...
79
+ if (auto *GOTSection =
80
+ G.findSectionByName (aarch64::GOTTableManager::getSectionName ())) {
81
+
82
+ // Check for an existing defined symbol.
83
+ for (auto *Sym : GOTSection->symbols ())
84
+ if (Sym->getName () == ELFGOTSymbolName) {
85
+ GOTSymbol = Sym;
86
+ return Error::success ();
87
+ }
88
+
89
+ // If there's no defined symbol then create one.
90
+ SectionRange SR (*GOTSection);
91
+ if (SR.empty ())
92
+ GOTSymbol =
93
+ &G.addAbsoluteSymbol (ELFGOTSymbolName, orc::ExecutorAddr (), 0 ,
94
+ Linkage::Strong, Scope::Local, true );
95
+ else
96
+ GOTSymbol =
97
+ &G.addDefinedSymbol (*SR.getFirstBlock (), 0 , ELFGOTSymbolName, 0 ,
98
+ Linkage::Strong, Scope::Local, false , true );
99
+ }
100
+
101
+ // If we still haven't found a GOT symbol then double check the externals.
102
+ // We may have a GOT-relative reference but no GOT section, in which case
103
+ // we just need to point the GOT symbol at some address in this graph.
104
+ if (!GOTSymbol) {
105
+ for (auto *Sym : G.external_symbols ()) {
106
+ if (Sym->getName () == ELFGOTSymbolName) {
107
+ auto Blocks = G.blocks ();
108
+ if (!Blocks.empty ()) {
109
+ G.makeAbsolute (*Sym, (*Blocks.begin ())->getAddress ());
110
+ GOTSymbol = Sym;
111
+ break ;
112
+ }
113
+ }
114
+ }
115
+ }
116
+
117
+ return Error::success ();
44
118
}
45
119
};
46
120
@@ -70,6 +144,7 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
70
144
ELFPrel64,
71
145
ELFAdrGOTPage21,
72
146
ELFLd64GOTLo12,
147
+ ELFLd64GOTPAGELo15,
73
148
ELFTLSDescAdrPage21,
74
149
ELFTLSDescAddLo12,
75
150
ELFTLSDescLd64Lo12,
@@ -125,6 +200,8 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
125
200
return ELFAdrGOTPage21;
126
201
case ELF::R_AARCH64_LD64_GOT_LO12_NC:
127
202
return ELFLd64GOTLo12;
203
+ case ELF::R_AARCH64_LD64_GOTPAGE_LO15:
204
+ return ELFLd64GOTPAGELo15;
128
205
case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
129
206
return ELFTLSDescAdrPage21;
130
207
case ELF::R_AARCH64_TLSDESC_ADD_LO12:
@@ -362,6 +439,10 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
362
439
Kind = aarch64::RequestGOTAndTransformToPageOffset12;
363
440
break ;
364
441
}
442
+ case ELFLd64GOTPAGELo15: {
443
+ Kind = aarch64::RequestGOTAndTransformToPageOffset15;
444
+ break ;
445
+ }
365
446
case ELFTLSDescAdrPage21: {
366
447
Kind = aarch64::RequestTLSDescEntryAndTransformToPage21;
367
448
break ;
@@ -427,6 +508,8 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
427
508
return " ELFAdrGOTPage21" ;
428
509
case ELFLd64GOTLo12:
429
510
return " ELFLd64GOTLo12" ;
511
+ case ELFLd64GOTPAGELo15:
512
+ return " ELFLd64GOTPAGELo15" ;
430
513
case ELFTLSDescAdrPage21:
431
514
return " ELFTLSDescAdrPage21" ;
432
515
case ELFTLSDescAddLo12:
0 commit comments