@@ -29,18 +29,92 @@ using namespace llvm::jitlink;
2929
3030namespace {
3131
32+ constexpr StringRef ELFGOTSymbolName = " _GLOBAL_OFFSET_TABLE_" ;
33+
3234class ELFJITLinker_aarch64 : public JITLinker <ELFJITLinker_aarch64> {
3335 friend class JITLinker <ELFJITLinker_aarch64>;
3436
3537public:
3638 ELFJITLinker_aarch64 (std::unique_ptr<JITLinkContext> Ctx,
3739 std::unique_ptr<LinkGraph> G,
3840 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+ }
4046
4147private:
48+ Symbol *GOTSymbol = nullptr ;
49+
4250 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 ();
44118 }
45119};
46120
@@ -70,6 +144,7 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
70144 ELFPrel64,
71145 ELFAdrGOTPage21,
72146 ELFLd64GOTLo12,
147+ ELFLd64GOTPAGELo15,
73148 ELFTLSDescAdrPage21,
74149 ELFTLSDescAddLo12,
75150 ELFTLSDescLd64Lo12,
@@ -125,6 +200,8 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
125200 return ELFAdrGOTPage21;
126201 case ELF::R_AARCH64_LD64_GOT_LO12_NC:
127202 return ELFLd64GOTLo12;
203+ case ELF::R_AARCH64_LD64_GOTPAGE_LO15:
204+ return ELFLd64GOTPAGELo15;
128205 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
129206 return ELFTLSDescAdrPage21;
130207 case ELF::R_AARCH64_TLSDESC_ADD_LO12:
@@ -362,6 +439,10 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
362439 Kind = aarch64::RequestGOTAndTransformToPageOffset12;
363440 break ;
364441 }
442+ case ELFLd64GOTPAGELo15: {
443+ Kind = aarch64::RequestGOTAndTransformToPageOffset15;
444+ break ;
445+ }
365446 case ELFTLSDescAdrPage21: {
366447 Kind = aarch64::RequestTLSDescEntryAndTransformToPage21;
367448 break ;
@@ -427,6 +508,8 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
427508 return " ELFAdrGOTPage21" ;
428509 case ELFLd64GOTLo12:
429510 return " ELFLd64GOTLo12" ;
511+ case ELFLd64GOTPAGELo15:
512+ return " ELFLd64GOTPAGELo15" ;
430513 case ELFTLSDescAdrPage21:
431514 return " ELFTLSDescAdrPage21" ;
432515 case ELFTLSDescAddLo12:
0 commit comments