1 //===--- BasicGOTAndStubsBuilder.h - Generic GOT/Stub creation --*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // A base for simple GOT and stub creation.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_EXECUTIONENGINE_JITLINK_BASICGOTANDSTUBSBUILDER_H
14 #define LLVM_LIB_EXECUTIONENGINE_JITLINK_BASICGOTANDSTUBSBUILDER_H
16 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
21 template <typename BuilderImpl
> class BasicGOTAndStubsBuilder
{
23 BasicGOTAndStubsBuilder(LinkGraph
&G
) : G(G
) {}
26 // We're going to be adding new blocks, but we don't want to iterate over
27 // the newly added ones, so just copy the existing blocks out.
28 std::vector
<Block
*> Blocks(G
.blocks().begin(), G
.blocks().end());
30 for (auto *B
: Blocks
)
31 for (auto &E
: B
->edges())
32 if (impl().isGOTEdge(E
))
33 impl().fixGOTEdge(E
, getGOTEntrySymbol(E
.getTarget()));
34 else if (impl().isExternalBranchEdge(E
))
35 impl().fixExternalBranchEdge(E
, getStubSymbol(E
.getTarget()));
39 Symbol
&getGOTEntrySymbol(Symbol
&Target
) {
40 assert(Target
.hasName() && "GOT edge cannot point to anonymous target");
42 auto GOTEntryI
= GOTEntries
.find(Target
.getName());
44 // Build the entry if it doesn't exist.
45 if (GOTEntryI
== GOTEntries
.end()) {
46 auto &GOTEntry
= impl().createGOTEntry(Target
);
48 GOTEntries
.insert(std::make_pair(Target
.getName(), &GOTEntry
)).first
;
51 assert(GOTEntryI
!= GOTEntries
.end() && "Could not get GOT entry symbol");
52 return *GOTEntryI
->second
;
55 Symbol
&getStubSymbol(Symbol
&Target
) {
56 assert(Target
.hasName() &&
57 "External branch edge can not point to an anonymous target");
58 auto StubI
= Stubs
.find(Target
.getName());
60 if (StubI
== Stubs
.end()) {
61 auto &StubSymbol
= impl().createStub(Target
);
62 StubI
= Stubs
.insert(std::make_pair(Target
.getName(), &StubSymbol
)).first
;
65 assert(StubI
!= Stubs
.end() && "Count not get stub symbol");
66 return *StubI
->second
;
72 BuilderImpl
&impl() { return static_cast<BuilderImpl
&>(*this); }
74 DenseMap
<StringRef
, Symbol
*> GOTEntries
;
75 DenseMap
<StringRef
, Symbol
*> Stubs
;
78 } // end namespace jitlink
79 } // end namespace llvm
81 #endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_BASICGOTANDSTUBSBUILDER_H