[llvm] r358838 - [JITLink] Factor basic common GOT and stub creation code into its own class.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 20 20:14:42 PDT 2019
Author: lhames
Date: Sat Apr 20 20:14:42 2019
New Revision: 358838
URL: http://llvm.org/viewvc/llvm-project?rev=358838&view=rev
Log:
[JITLink] Factor basic common GOT and stub creation code into its own class.
Added:
llvm/trunk/lib/ExecutionEngine/JITLink/BasicGOTAndStubsBuilder.h
Modified:
llvm/trunk/lib/ExecutionEngine/JITLink/JITLink_MachO_x86_64.cpp
Added: llvm/trunk/lib/ExecutionEngine/JITLink/BasicGOTAndStubsBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JITLink/BasicGOTAndStubsBuilder.h?rev=358838&view=auto
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JITLink/BasicGOTAndStubsBuilder.h (added)
+++ llvm/trunk/lib/ExecutionEngine/JITLink/BasicGOTAndStubsBuilder.h Sat Apr 20 20:14:42 2019
@@ -0,0 +1,82 @@
+//===--- BasicGOTAndStubsBuilder.h - Generic GOT/Stub creation --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// A base for simple GOT and stub creation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_EXECUTIONENGINE_JITLINK_BASICGOTANDSTUBSBUILDER_H
+#define LLVM_LIB_EXECUTIONENGINE_JITLINK_BASICGOTANDSTUBSBUILDER_H
+
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+
+namespace llvm {
+namespace jitlink {
+
+template <typename BuilderImpl> class BasicGOTAndStubsBuilder {
+public:
+ BasicGOTAndStubsBuilder(AtomGraph &G) : G(G) {}
+
+ void run() {
+ // We're going to be adding new atoms, but we don't want to iterate over
+ // the newly added ones, so just copy the existing atoms out.
+ std::vector<DefinedAtom *> DAs(G.defined_atoms().begin(),
+ G.defined_atoms().end());
+
+ for (auto *DA : DAs)
+ for (auto &E : DA->edges())
+ if (impl().isGOTEdge(E))
+ impl().fixGOTEdge(E, getGOTEntryAtom(E.getTarget()));
+ else if (impl().isExternalBranchEdge(E))
+ impl().fixExternalBranchEdge(E, getStubAtom(E.getTarget()));
+ }
+
+protected:
+ Atom &getGOTEntryAtom(Atom &Target) {
+ assert(Target.hasName() && "GOT edge cannot point to anonymous target");
+
+ auto GOTEntryI = GOTEntries.find(Target.getName());
+
+ // Build the entry if it doesn't exist.
+ if (GOTEntryI == GOTEntries.end()) {
+ auto &GOTEntry = impl().createGOTEntry(Target);
+ GOTEntryI =
+ GOTEntries.insert(std::make_pair(Target.getName(), &GOTEntry)).first;
+ }
+
+ assert(GOTEntryI != GOTEntries.end() && "Could not get GOT entry atom");
+ return *GOTEntryI->second;
+ }
+
+ Atom &getStubAtom(Atom &Target) {
+ assert(Target.hasName() &&
+ "External branch edge can not point to an anonymous target");
+ auto StubI = Stubs.find(Target.getName());
+
+ if (StubI == Stubs.end()) {
+ auto &StubAtom = impl().createStub(Target);
+ StubI = Stubs.insert(std::make_pair(Target.getName(), &StubAtom)).first;
+ }
+
+ assert(StubI != Stubs.end() && "Count not get stub atom");
+ return *StubI->second;
+ }
+
+ AtomGraph &G;
+
+private:
+ BuilderImpl &impl() { return static_cast<BuilderImpl &>(*this); }
+
+ DenseMap<StringRef, DefinedAtom *> GOTEntries;
+ DenseMap<StringRef, DefinedAtom *> Stubs;
+};
+
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_BASICGOTANDSTUBSBUILDER_H
Modified: llvm/trunk/lib/ExecutionEngine/JITLink/JITLink_MachO_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JITLink/JITLink_MachO_x86_64.cpp?rev=358838&r1=358837&r2=358838&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JITLink/JITLink_MachO_x86_64.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JITLink/JITLink_MachO_x86_64.cpp Sat Apr 20 20:14:42 2019
@@ -12,6 +12,7 @@
#include "llvm/ExecutionEngine/JITLink/JITLink_MachO_x86_64.h"
+#include "BasicGOTAndStubsBuilder.h"
#include "MachOAtomGraphBuilder.h"
#define DEBUG_TYPE "jitlink"
@@ -346,104 +347,79 @@ private:
unsigned NumSymbols = 0;
};
-class MachOInPlaceGOTAndStubsBuilder {
+class MachO_x86_64_GOTAndStubsBuilder
+ : public BasicGOTAndStubsBuilder<MachO_x86_64_GOTAndStubsBuilder> {
public:
- MachOInPlaceGOTAndStubsBuilder(AtomGraph &G) : G(G) {}
+ MachO_x86_64_GOTAndStubsBuilder(AtomGraph &G)
+ : BasicGOTAndStubsBuilder<MachO_x86_64_GOTAndStubsBuilder>(G) {}
- void run() {
- // We're going to be adding new atoms, but we don't want to iterate over
- // the newly added ones, so just copy the existing atoms out.
- std::vector<DefinedAtom *> DAs(G.defined_atoms().begin(),
- G.defined_atoms().end());
-
- for (auto *DA : DAs)
- for (auto &E : DA->edges())
- if (E.getKind() == PCRel32GOT || E.getKind() == PCRel32GOTLoad)
- fixGOTEdge(E);
- else if (E.getKind() == Branch32 && !E.getTarget().isDefined())
- fixExternalBranchEdge(E);
+ bool isGOTEdge(Edge &E) const {
+ return E.getKind() == PCRel32GOT || E.getKind() == PCRel32GOTLoad;
}
- Atom &getGOTEntryAtom(Atom &Target) {
- assert(!Target.getName().empty() &&
- "GOT load edge cannot point to anonymous target");
-
- auto GOTEntryI = GOTEntries.find(Target.getName());
-
- // Build the entry if it doesn't exist.
- if (GOTEntryI == GOTEntries.end()) {
- // Build a GOT section if we don't have one already.
- if (!GOTSection)
- GOTSection = &G.createSection("$__GOT", sys::Memory::MF_READ, false);
-
- auto &GOTEntryAtom = G.addAnonymousAtom(*GOTSection, 0x0, 8);
- GOTEntryAtom.setContent(
- StringRef(reinterpret_cast<const char *>(NullGOTEntryContent), 8));
- GOTEntryAtom.addEdge(Pointer64, 0, Target, 0);
- GOTEntryI =
- GOTEntries.insert(std::make_pair(Target.getName(), &GOTEntryAtom))
- .first;
- }
-
- assert(GOTEntryI != GOTEntries.end() && "Could not get GOT entry atom");
- return *GOTEntryI->second;
+ DefinedAtom &createGOTEntry(Atom &Target) {
+ auto &GOTEntryAtom = G.addAnonymousAtom(getGOTSection(), 0x0, 8);
+ GOTEntryAtom.setContent(
+ StringRef(reinterpret_cast<const char *>(NullGOTEntryContent), 8));
+ GOTEntryAtom.addEdge(Pointer64, 0, Target, 0);
+ return GOTEntryAtom;
}
- void fixGOTEdge(Edge &E) {
+ void fixGOTEdge(Edge &E, Atom &GOTEntry) {
assert((E.getKind() == PCRel32GOT || E.getKind() == PCRel32GOTLoad) &&
"Not a GOT edge?");
- auto &GOTEntryAtom = getGOTEntryAtom(E.getTarget());
E.setKind(PCRel32);
- E.setTarget(GOTEntryAtom);
+ E.setTarget(GOTEntry);
// Leave the edge addend as-is.
}
- Atom &getStubAtom(Atom &Target) {
- assert(!Target.getName().empty() &&
- "Branch edge can not point to an anonymous target");
- auto StubI = Stubs.find(Target.getName());
-
- if (StubI == Stubs.end()) {
- // Build a Stubs section if we don't have one already.
- if (!StubsSection) {
- auto StubsProt = static_cast<sys::Memory::ProtectionFlags>(
- sys::Memory::MF_READ | sys::Memory::MF_EXEC);
- StubsSection = &G.createSection("$__STUBS", StubsProt, false);
- }
-
- auto &StubAtom = G.addAnonymousAtom(*StubsSection, 0x0, 2);
- StubAtom.setContent(
- StringRef(reinterpret_cast<const char *>(StubContent), 6));
+ bool isExternalBranchEdge(Edge &E) {
+ return E.getKind() == Branch32 && !E.getTarget().isDefined();
+ }
- // Re-use GOT entries for stub targets.
- auto &GOTEntryAtom = getGOTEntryAtom(Target);
- StubAtom.addEdge(PCRel32, 2, GOTEntryAtom, 0);
+ DefinedAtom &createStub(Atom &Target) {
+ auto &StubAtom = G.addAnonymousAtom(getStubsSection(), 0x0, 2);
+ StubAtom.setContent(
+ StringRef(reinterpret_cast<const char *>(StubContent), 6));
- StubI = Stubs.insert(std::make_pair(Target.getName(), &StubAtom)).first;
- }
+ // Re-use GOT entries for stub targets.
+ auto &GOTEntryAtom = getGOTEntryAtom(Target);
+ StubAtom.addEdge(PCRel32, 2, GOTEntryAtom, 0);
- assert(StubI != Stubs.end() && "Count not get stub atom");
- return *StubI->second;
+ return StubAtom;
}
- void fixExternalBranchEdge(Edge &E) {
+ void fixExternalBranchEdge(Edge &E, Atom &Stub) {
assert(E.getKind() == Branch32 && "Not a Branch32 edge?");
assert(E.getAddend() == 0 && "Branch32 edge has non-zero addend?");
- E.setTarget(getStubAtom(E.getTarget()));
+ E.setTarget(Stub);
+ }
+
+private:
+ Section &getGOTSection() {
+ if (!GOTSection)
+ GOTSection = &G.createSection("$__GOT", sys::Memory::MF_READ, false);
+ return *GOTSection;
+ }
+
+ Section &getStubsSection() {
+ if (!StubsSection) {
+ auto StubsProt = static_cast<sys::Memory::ProtectionFlags>(
+ sys::Memory::MF_READ | sys::Memory::MF_EXEC);
+ StubsSection = &G.createSection("$__STUBS", StubsProt, false);
+ }
+ return *StubsSection;
}
- AtomGraph &G;
- DenseMap<StringRef, DefinedAtom *> GOTEntries;
- DenseMap<StringRef, DefinedAtom *> Stubs;
static const uint8_t NullGOTEntryContent[8];
static const uint8_t StubContent[6];
Section *GOTSection = nullptr;
Section *StubsSection = nullptr;
};
-const uint8_t MachOInPlaceGOTAndStubsBuilder::NullGOTEntryContent[8] = {
+const uint8_t MachO_x86_64_GOTAndStubsBuilder::NullGOTEntryContent[8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-const uint8_t MachOInPlaceGOTAndStubsBuilder::StubContent[6] = {
+const uint8_t MachO_x86_64_GOTAndStubsBuilder::StubContent[6] = {
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00};
} // namespace
@@ -570,7 +546,7 @@ void jitLink_MachO_x86_64(std::unique_pt
// Add an in-place GOT/Stubs pass.
Config.PostPrunePasses.push_back([](AtomGraph &G) -> Error {
- MachOInPlaceGOTAndStubsBuilder(G).run();
+ MachO_x86_64_GOTAndStubsBuilder(G).run();
return Error::success();
});
}
More information about the llvm-commits
mailing list