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(AtomGraph
&G
) : G(G
) {}
26 // We're going to be adding new atoms, but we don't want to iterate over
27 // the newly added ones, so just copy the existing atoms out.
28 std::vector
<DefinedAtom
*> DAs(G
.defined_atoms().begin(),
29 G
.defined_atoms().end());
32 for (auto &E
: DA
->edges())
33 if (impl().isGOTEdge(E
))
34 impl().fixGOTEdge(E
, getGOTEntryAtom(E
.getTarget()));
35 else if (impl().isExternalBranchEdge(E
))
36 impl().fixExternalBranchEdge(E
, getStubAtom(E
.getTarget()));
40 Atom
&getGOTEntryAtom(Atom
&Target
) {
41 assert(Target
.hasName() && "GOT edge cannot point to anonymous target");
43 auto GOTEntryI
= GOTEntries
.find(Target
.getName());
45 // Build the entry if it doesn't exist.
46 if (GOTEntryI
== GOTEntries
.end()) {
47 auto &GOTEntry
= impl().createGOTEntry(Target
);
49 GOTEntries
.insert(std::make_pair(Target
.getName(), &GOTEntry
)).first
;
52 assert(GOTEntryI
!= GOTEntries
.end() && "Could not get GOT entry atom");
53 return *GOTEntryI
->second
;
56 Atom
&getStubAtom(Atom
&Target
) {
57 assert(Target
.hasName() &&
58 "External branch edge can not point to an anonymous target");
59 auto StubI
= Stubs
.find(Target
.getName());
61 if (StubI
== Stubs
.end()) {
62 auto &StubAtom
= impl().createStub(Target
);
63 StubI
= Stubs
.insert(std::make_pair(Target
.getName(), &StubAtom
)).first
;
66 assert(StubI
!= Stubs
.end() && "Count not get stub atom");
67 return *StubI
->second
;
73 BuilderImpl
&impl() { return static_cast<BuilderImpl
&>(*this); }
75 DenseMap
<StringRef
, DefinedAtom
*> GOTEntries
;
76 DenseMap
<StringRef
, DefinedAtom
*> Stubs
;
79 } // end namespace jitlink
80 } // end namespace llvm
82 #endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_BASICGOTANDSTUBSBUILDER_H