123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- //===--------------- PerGraphGOTAndPLTStubBuilder.h -------------*- 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
- //
- //===----------------------------------------------------------------------===//
- //
- // Construct GOT and PLT entries for each graph.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_EXECUTIONENGINE_JITLINK_PERGRAPHGOTANDPLTSTUBSBUILDER_H
- #define LLVM_EXECUTIONENGINE_JITLINK_PERGRAPHGOTANDPLTSTUBSBUILDER_H
- #include "llvm/ExecutionEngine/JITLink/JITLink.h"
- #include "llvm/Support/Debug.h"
- #define DEBUG_TYPE "jitlink"
- namespace llvm {
- namespace jitlink {
- /// Per-object GOT and PLT Stub builder.
- ///
- /// Constructs GOT entries and PLT stubs in every graph for referenced symbols.
- /// Building these blocks in every graph is likely to lead to duplicate entries
- /// in the JITLinkDylib, but allows graphs to be trivially removed independently
- /// without affecting other graphs (since those other graphs will have their own
- /// copies of any required entries).
- template <typename BuilderImplT>
- class PerGraphGOTAndPLTStubsBuilder {
- public:
- PerGraphGOTAndPLTStubsBuilder(LinkGraph &G) : G(G) {}
- static Error asPass(LinkGraph &G) { return BuilderImplT(G).run(); }
- Error run() {
- LLVM_DEBUG(dbgs() << "Running Per-Graph GOT and Stubs builder:\n");
- // We're going to be adding new blocks, but we don't want to iterate over
- // the new ones, so build a worklist.
- std::vector<Block *> Worklist(G.blocks().begin(), G.blocks().end());
- for (auto *B : Worklist)
- for (auto &E : B->edges()) {
- if (impl().isGOTEdgeToFix(E)) {
- LLVM_DEBUG({
- dbgs() << " Fixing " << G.getEdgeKindName(E.getKind())
- << " edge at " << B->getFixupAddress(E) << " ("
- << B->getAddress() << " + "
- << formatv("{0:x}", E.getOffset()) << ")\n";
- });
- impl().fixGOTEdge(E, getGOTEntry(E.getTarget()));
- } else if (impl().isExternalBranchEdge(E)) {
- LLVM_DEBUG({
- dbgs() << " Fixing " << G.getEdgeKindName(E.getKind())
- << " edge at " << B->getFixupAddress(E) << " ("
- << B->getAddress() << " + "
- << formatv("{0:x}", E.getOffset()) << ")\n";
- });
- impl().fixPLTEdge(E, getPLTStub(E.getTarget()));
- }
- }
- return Error::success();
- }
- protected:
- Symbol &getGOTEntry(Symbol &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);
- LLVM_DEBUG({
- dbgs() << " Created GOT entry for " << Target.getName() << ": "
- << GOTEntry << "\n";
- });
- GOTEntryI =
- GOTEntries.insert(std::make_pair(Target.getName(), &GOTEntry)).first;
- }
- assert(GOTEntryI != GOTEntries.end() && "Could not get GOT entry symbol");
- LLVM_DEBUG(
- { dbgs() << " Using GOT entry " << *GOTEntryI->second << "\n"; });
- return *GOTEntryI->second;
- }
- Symbol &getPLTStub(Symbol &Target) {
- assert(Target.hasName() &&
- "External branch edge can not point to an anonymous target");
- auto StubI = PLTStubs.find(Target.getName());
- if (StubI == PLTStubs.end()) {
- auto &StubSymbol = impl().createPLTStub(Target);
- LLVM_DEBUG({
- dbgs() << " Created PLT stub for " << Target.getName() << ": "
- << StubSymbol << "\n";
- });
- StubI =
- PLTStubs.insert(std::make_pair(Target.getName(), &StubSymbol)).first;
- }
- assert(StubI != PLTStubs.end() && "Count not get stub symbol");
- LLVM_DEBUG({ dbgs() << " Using PLT stub " << *StubI->second << "\n"; });
- return *StubI->second;
- }
- LinkGraph &G;
- private:
- BuilderImplT &impl() { return static_cast<BuilderImplT &>(*this); }
- DenseMap<StringRef, Symbol *> GOTEntries;
- DenseMap<StringRef, Symbol *> PLTStubs;
- };
- } // end namespace jitlink
- } // end namespace llvm
- #undef DEBUG_TYPE
- #endif // LLVM_EXECUTIONENGINE_JITLINK_PERGRAPHGOTANDPLTSTUBSBUILDER_H
|