namespace llvm {
namespace jitlink {
-/// Table like section manager
+/// A CRTP base for tables that are built on demand, e.g. Global Offset Tables
+/// and Procedure Linkage Tables.
+/// The getEntyrForTarget function returns the table entry corresponding to the
+/// given target, calling down to the implementation class to build an entry if
+/// one does not already exist.
template <typename TableManagerImplT> class TableManager {
public:
- /// Visit edge, return true if the edge was dealt with, otherwise return
- /// false(let other managers to visit).
- bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
- if (impl().fixEdgeKind(G, B, E)) {
- fixTarget(G, E);
- return true;
- }
- return false;
- }
-
/// Return the constructed entry
///
/// Use parameter G to construct the entry for target symbol
}
private:
- void fixTarget(LinkGraph &G, Edge &E) {
- E.setTarget(getEntryForTarget(G, E.getTarget()));
- }
-
TableManagerImplT &impl() { return static_cast<TableManagerImplT &>(*this); }
DenseMap<StringRef, Symbol *> Entries;
};
#include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/ExecutionEngine/JITLink/TableManager.h"
#include "llvm/ExecutionEngine/JITLink/x86_64.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Endian.h"
#include "ELFLinkGraphBuilder.h"
#include "JITLinkGeneric.h"
#include "PerGraphGOTAndPLTStubsBuilder.h"
-#include "TableManager.h"
#define DEBUG_TYPE "jitlink"
// Nice name for table
StringRef getTableName() { return "GOT"; }
- bool fixEdgeKind(LinkGraph &G, Block *B, Edge &E) {
- Edge::Kind KindToSet = E.getKind();
+ bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
+ Edge::Kind KindToSet = Edge::Invalid;
switch (E.getKind()) {
case x86_64::Delta64FromGOT: {
// we need to make sure that the GOT section exists, but don't otherwise
default:
return false;
}
+ assert(KindToSet != Edge::Invalid &&
+ "Fell through switch, but no new kind to set");
LLVM_DEBUG({
dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
<< formatv("{0:x}", B->getFixupAddress(E)) << " ("
<< formatv("{0:x}", E.getOffset()) << ")\n";
});
E.setKind(KindToSet);
+ E.setTarget(getEntryForTarget(G, E.getTarget()));
return true;
}
StringRef getTableName() { return "PLT"; }
static const uint8_t StubContent[6];
- bool fixEdgeKind(LinkGraph &G, Block *B, Edge &E) {
+ bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
if (E.getKind() == x86_64::BranchPCRel32 && !E.getTarget().isDefined()) {
LLVM_DEBUG({
dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
// Set the edge kind to Branch32ToPtrJumpStubBypassable to enable it to
// be optimized when the target is in-range.
E.setKind(x86_64::BranchPCRel32ToPtrJumpStubBypassable);
+ E.setTarget(getEntryForTarget(G, E.getTarget()));
return true;
}
return false;
StringRef getTableName() { return "TLSInfo"; }
- bool fixEdgeKind(LinkGraph &G, Block *B, Edge &E) {
+ bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
if (E.getKind() == x86_64::RequestTLSDescInGOTAndTransformToDelta32) {
LLVM_DEBUG({
dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
<< formatv("{0:x}", E.getOffset()) << ")\n";
});
E.setKind(x86_64::Delta32);
+ E.setTarget(getEntryForTarget(G, E.getTarget()));
return true;
}
return false;