LLVM: lib/ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h Source File (original) (raw)

Go to the documentation of this file.

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_EXECUTIONENGINE_JITLINK_PERGRAPHGOTANDPLTSTUBSBUILDER_H

14#define LLVM_EXECUTIONENGINE_JITLINK_PERGRAPHGOTANDPLTSTUBSBUILDER_H

15

18

19#define DEBUG_TYPE "jitlink"

20

21namespace llvm {

22namespace jitlink {

23

24

25

26

27

28

29

30

31template

33public:

35

37

39 LLVM_DEBUG(dbgs() << "Running Per-Graph GOT and Stubs builder:\n");

40

41

42

43 std::vector<Block *> Worklist(G.blocks().begin(), G.blocks().end());

44

45 for (auto *B : Worklist)

46 for (auto &E : B->edges()) {

47 if (impl().isGOTEdgeToFix(E)) {

49 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind())

50 << " edge at " << B->getFixupAddress(E) << " ("

51 << B->getAddress() << " + "

52 << formatv("{0:x}", E.getOffset()) << ")\n";

53 });

55 } else if (impl().isExternalBranchEdge(E)) {

57 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind())

58 << " edge at " << B->getFixupAddress(E) << " ("

59 << B->getAddress() << " + "

60 << formatv("{0:x}", E.getOffset()) << ")\n";

61 });

62 impl().fixPLTEdge(E, getPLTStub(E.getTarget()));

63 }

64 }

65

67 }

68

69protected:

71 assert(Target.hasName() && "GOT edge cannot point to anonymous target");

72

73 auto GOTEntryI = GOTEntries.find(Target.getName());

74

75

76 if (GOTEntryI == GOTEntries.end()) {

77 auto &GOTEntry = impl().createGOTEntry(Target);

80 << GOTEntry << "\n";

81 });

82 GOTEntryI =

83 GOTEntries.insert(std::make_pair(Target.getName(), &GOTEntry)).first;

84 }

85

86 assert(GOTEntryI != GOTEntries.end() && "Could not get GOT entry symbol");

88 { dbgs() << " Using GOT entry " << *GOTEntryI->second << "\n"; });

89 return *GOTEntryI->second;

90 }

91

94 "External branch edge can not point to an anonymous target");

96

97 if (StubI == PLTStubs.end()) {

98 auto &StubSymbol = impl().createPLTStub(Target);

101 << StubSymbol << "\n";

102 });

103 StubI =

104 PLTStubs.insert(std::make_pair(Target.getName(), &StubSymbol)).first;

105 }

106

107 assert(StubI != PLTStubs.end() && "Count not get stub symbol");

108 LLVM_DEBUG({ dbgs() << " Using PLT stub " << *StubI->second << "\n"; });

109 return *StubI->second;

110 }

111

113

114private:

115 BuilderImplT &impl() { return static_cast<BuilderImplT &>(*this); }

116

119};

120

121}

122}

123

124#undef DEBUG_TYPE

125

126#endif

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Target - Wrapper for Target specific information.

const char * getName() const

getName - Get the target name.

Symbol & getPLTStub(Symbol &Target)

Definition PerGraphGOTAndPLTStubsBuilder.h:92

Symbol & getGOTEntry(Symbol &Target)

Definition PerGraphGOTAndPLTStubsBuilder.h:70

Error run()

Definition PerGraphGOTAndPLTStubsBuilder.h:38

PerGraphGOTAndPLTStubsBuilder(LinkGraph &G)

Definition PerGraphGOTAndPLTStubsBuilder.h:34

static Error asPass(LinkGraph &G)

Definition PerGraphGOTAndPLTStubsBuilder.h:36

LinkGraph & G

Definition PerGraphGOTAndPLTStubsBuilder.h:112

This is an optimization pass for GlobalISel generic memory operations.

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.