LLVM: lib/ExecutionEngine/JITLink/ELF_x86.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

20

21#define DEBUG_TYPE "jitlink"

22

23using namespace llvm;

25

26namespace {

27constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";

28

31

36}

37}

38

40

43

44public:

49 [this](LinkGraph &G) { return getOrCreateGOTSymbol(G); });

50 }

51

52private:

53 Symbol *GOTSymbol = nullptr;

54

56 auto DefineExternalGOTSymbolIfPresent =

59 if (Sym.getName() != nullptr &&

60 *Sym.getName() == ELFGOTSymbolName)

61 if (auto *GOTSection = G.findSectionByName(

63 GOTSymbol = &Sym;

64 return {*GOTSection, true};

65 }

66 return {};

67 });

68

69

70

71 if (auto Err = DefineExternalGOTSymbolIfPresent(G))

72 return Err;

73

74

75 if (GOTSymbol)

77

78

79

80

81 if (auto *GOTSection =

83

84

85 for (auto *Sym : GOTSection->symbols())

86 if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {

87 GOTSymbol = Sym;

89 }

90

91

92 SectionRange SR(*GOTSection);

93

94 if (SR.empty()) {

95 GOTSymbol =

96 &G.addAbsoluteSymbol(ELFGOTSymbolName, orc::ExecutorAddr(), 0,

98 } else {

99 GOTSymbol =

100 &G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,

102 }

103 }

104

106 }

107

108 Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {

110 }

111};

112

114private:

116

118 switch (Type) {

119 case ELF::R_386_32:

121 case ELF::R_386_PC32:

123 case ELF::R_386_16:

125 case ELF::R_386_PC16:

127 case ELF::R_386_GOT32:

129 case ELF::R_386_GOT32X:

130

132 case ELF::R_386_GOTPC:

134 case ELF::R_386_GOTOFF:

136 case ELF::R_386_PLT32:

138 }

139

141 "In " + G->getName() + ": Unsupported x86 relocation type " +

143 }

144

149

150 for (const auto &RelSect : Base::Sections) {

151

154 "No SHT_RELA in valid x86 ELF object files",

156

157 if (Error Err = Base::forEachRelRelocation(RelSect, this,

158 &Self::addSingleRelocation))

159 return Err;

160 }

161

163 }

164

165 Error addSingleRelocation(const typename ELFT::Rel &Rel,

166 const typename ELFT::Shdr &FixupSection,

167 Block &BlockToFix) {

169

170 auto ELFReloc = Rel.getType(false);

171

172

175

176 uint32_t SymbolIndex = Rel.getSymbol(false);

177 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);

178 if (!ObjSymbol)

179 return ObjSymbol.takeError();

180

181 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);

182 if (!GraphSymbol)

184 formatv("Could not find symbol at given index, did you add it to "

185 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",

186 SymbolIndex, (*ObjSymbol)->st_shndx,

187 Base::GraphSymbols.size()),

189

191 if (!Kind)

192 return Kind.takeError();

193

194 auto FixupAddress = orc::ExecutorAddr(FixupSection.sh_addr) + Rel.r_offset;

195 int64_t Addend = 0;

196

197 switch (*Kind) {

206 const char *FixupContent = BlockToFix.getContent().data() +

207 (FixupAddress - BlockToFix.getAddress());

209 break;

210 }

213 const char *FixupContent = BlockToFix.getContent().data() +

214 (FixupAddress - BlockToFix.getAddress());

216 break;

217 }

218 }

219

220 Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();

221 Edge GE(*Kind, Offset, *GraphSymbol, Addend);

223 dbgs() << " ";

225 dbgs() << "\n";

226 });

227

228 BlockToFix.addEdge(std::move(GE));

230 }

231

232public:

234 std::shared_ptrorc::SymbolStringPool SSP, Triple TT,

237 std::move(Features), FileName,

238 x86::getEdgeKindName) {}

239};

240

243 std::shared_ptrorc::SymbolStringPool SSP) {

245 dbgs() << "Building jitlink graph for new input "

247 });

248

250 if (!ELFObj)

251 return ELFObj.takeError();

252

253 auto Features = (*ELFObj)->getFeatures();

254 if (!Features)

255 return Features.takeError();

256

258 "Only x86 (little endian) is supported for now");

259

261

263 ELFObjFile.getELFFile(), std::move(SSP),

264 (*ELFObj)->makeTriple(), std::move(*Features))

266}

267

269 std::unique_ptr Ctx) {

271 const Triple &TT = G->getTargetTriple();

272 if (Ctx->shouldAddDefaultTargetPasses(TT)) {

273 if (auto MarkLive = Ctx->getMarkLivePass(TT))

274 Config.PrePrunePasses.push_back(std::move(MarkLive));

275 else

277

278

280

281

283 }

284 if (auto Err = Ctx->modifyPassConfig(*G, Config))

285 return Ctx->notifyFailed(std::move(Err));

286

288}

289

290}

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")

#define LLVM_UNLIKELY(EXPR)

std::pair< BasicBlock *, BasicBlock * > Edge

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

StringRef getBufferIdentifier() const

StringRef - Represent a constant reference to a string, i.e.

Manages the enabling and disabling of subtarget specific features.

Triple - Helper class for working with autoconf configuration names.

The instances of the Type class are immutable: once they are created, they are never changed.

orc::ExecutorAddr getAddress() const

An Addressable with content and edges.

ArrayRef< char > getContent() const

Get the content for this block. Block must not be a zero-fill block.

void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)

Add an edge to this block.

ELFJITLinker_x86(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)

Definition ELF_x86.cpp:45

std::unique_ptr< LinkGraph > G

Definition ELF_x86.cpp:113

ELFLinkGraphBuilder_x86(StringRef FileName, const object::ELFFile< ELFT > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features)

Definition ELF_x86.cpp:233

virtual Error addRelocations()=0

ELFLinkGraphBuilder(const object::ELFFile< object::ELF32LE > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)

Expected< std::unique_ptr< LinkGraph > > buildGraph()

Attempt to construct and return the LinkGraph.

Represents fixups and constraints in the LinkGraph.

PassConfiguration & getPassConfig()

static void link(ArgTs &&... Args)

const orc::SymbolStringPtr & getName() const

Returns the name of this symbol (empty if the symbol is anonymous).

Global Offset Table Builder.

static StringRef getSectionName()

Procedure Linkage Table Builder.

static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)

Represents an address in the executor process.

@ BranchPCRel32ToPtrJumpStubBypassable

A relaxable version of BranchPCRel32ToPtrJumpStub.

@ RequestGOTAndTransformToDelta32FromGOT

A GOT entry offset within GOT getter/constructor, transformed to Delta32FromGOT pointing at the GOT e...

@ Pointer16

A plain 16-bit pointer value relocation.

@ BranchPCRel32

A 32-bit PC-relative branch.

@ PCRel32

A 32-bit PC-relative relocation.

@ PCRel16

A 16-bit PC-relative relocation.

@ BranchPCRel32ToPtrJumpStub

A 32-bit PC-relative branch to a pointer jump stub.

@ Pointer32

A plain 32-bit pointer value relocation.

@ Delta32FromGOT

A 32-bit GOT delta.

LLVM_ABI const char * getEdgeKindName(Edge::Kind K)

Returns a string name for the given x86 edge.

LLVM_ABI Error optimizeGOTAndStubAccesses(LinkGraph &G)

Optimize the GOT and Stub relocations if the edge target address is in range.

Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const Symbol *GOTSymbol)

Apply fixup expression for edge to block content.

Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_x86(MemoryBufferRef ObjectBuffer, std::shared_ptr< orc::SymbolStringPool > SSP)

Create a LinkGraph from an ELF/x86 relocatable object.

Definition ELF_x86.cpp:242

void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs)

For each edge in the given graph, apply a list of visitors to the edge, stopping when the first visit...

LLVM_ABI Error markAllSymbolsLive(LinkGraph &G)

Marks all symbols in a graph live.

void link_ELF_x86(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)

jit-link the given object buffer, which must be a ELF x86 relocatable object file.

Definition ELF_x86.cpp:268

LLVM_ABI void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)

DefineExternalSectionStartAndEndSymbols< SymbolIdentifierFunction > createDefineExternalSectionStartAndEndSymbolsPass(SymbolIdentifierFunction &&F)

Returns a JITLink pass (as a function class) that uses the given symbol identification function to id...

LLVM_ABI StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)

ELFType< llvm::endianness::little, false > ELF32LE

detail::packed_endian_specific_integral< int16_t, llvm::endianness::little, unaligned > little16_t

detail::packed_endian_specific_integral< int32_t, llvm::endianness::little, unaligned > little32_t

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

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.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

Implement std::hash so that hash_code can be used in STL containers.

An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...

LinkGraphPassList PostAllocationPasses

Post-allocation passes.

LinkGraphPassList PreFixupPasses

Pre-fixup passes.

LinkGraphPassList PostPrunePasses

Post-prune passes.

LinkGraphPassList PrePrunePasses

Pre-prune passes.

Elf_Rel_Impl< ELFType< E, Is64 >, false > Rel

Elf_Shdr_Impl< ELFType< E, Is64 > > Shdr