LLVM: lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFF86_64_H

14#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFF86_64_H

15

19

20#define DEBUG_TYPE "dyld"

21

22namespace llvm {

23

25

26private:

27

28

29

33

34

36 if (!ImageBase) {

37 ImageBase = std::numeric_limits<uint64_t>::max();

39

40

41

42

43

44 if (Section.getLoadAddress() != 0)

45 ImageBase = std::min(ImageBase, Section.getLoadAddress());

46 }

47 return ImageBase;

48 }

49

51 uint64_t Result = Addend + Delta;

52 assert(Result <= UINT32_MAX && "Relocation overflow");

54 }

55

56public:

61

63

64

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

90

92

99 uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.Offset);

100

101

103 Value -= FinalAddress + Delta;

105 assert(((int64_t)Result <= INT32_MAX) && "Relocation overflow");

106 assert(((int64_t)Result >= INT32_MIN) && "Relocation underflow");

108 break;

109 }

110

112

113

114

115 const uint64_t ImageBase = getImageBase();

116 if (Value < ImageBase || ((Value - ImageBase) > UINT32_MAX))

117 report_fatal_error("IMAGE_REL_AMD64_ADDR32NB relocation requires an "

118 "ordered section layout");

119 else {

121 }

122 break;

123 }

124

127 break;

128 }

129

131 assert(static_cast<int64_t>(RE.Addend) <= INT32_MAX && "Relocation overflow");

132 assert(static_cast<int64_t>(RE.Addend) >= INT32_MIN && "Relocation underflow");

134 break;

135 }

136

138 assert(static_cast<int16_t>(RE.SectionID) <= INT16_MAX && "Relocation overflow");

139 assert(static_cast<int16_t>(RE.SectionID) >= INT16_MIN && "Relocation underflow");

141 break;

142 }

143

144 default:

146 break;

147 }

148 }

149

150 std::tuple<uint64_t, uint64_t, uint64_t>

154 uintptr_t StubOffset;

156

158 OriginalRelValueRef.SectionID = SectionID;

160 OriginalRelValueRef.Addend = Addend;

162

163 auto [Stub, Inserted] = Stubs.try_emplace(OriginalRelValueRef);

164 if (Inserted) {

165 LLVM_DEBUG(dbgs() << " Create a new stub function for "

166 << TargetName.data() << "\n");

167

168 StubOffset = Section.getStubOffset();

169 Stub->second = StubOffset;

172 } else {

173 LLVM_DEBUG(dbgs() << " Stub function found for " << TargetName.data()

174 << "\n");

175 StubOffset = Stub->second;

176 }

177

178

179

180

181

182

183

184

186 resolveRelocation(RE, Section.getLoadAddressWithOffset(StubOffset));

187

188

189 Addend = 0;

190 Offset = StubOffset + 6;

192

193 return std::make_tuple(Offset, RelType, Addend);

194 }

195

201 StubMap &Stubs) override {

202

203

205 if (Symbol == Obj.symbol_end())

207 auto SectionOrError = Symbol->getSection();

208 if (!SectionOrError)

209 return SectionOrError.takeError();

211

212 bool IsExtern = SecI == Obj.section_end();

213

214

219 uintptr_t ObjTarget = Section.getObjAddress() + Offset;

220

222 if (!TargetNameOrErr)

223 return TargetNameOrErr.takeError();

224

225 StringRef TargetName = *TargetNameOrErr;

226 unsigned TargetSectionID = 0;

228

230 assert(IsExtern && "DLLImport not marked extern?");

231 TargetSectionID = SectionID;

234 IsExtern = false;

235 } else if (!IsExtern) {

236 if (auto TargetSectionIDOrErr =

238 TargetSectionID = *TargetSectionIDOrErr;

239 else

240 return TargetSectionIDOrErr.takeError();

242 }

243

244 switch (RelType) {

245

255

256 if (IsExtern)

258 SectionID, TargetName, Offset, RelType, Addend, Stubs);

259

260 break;

261 }

262

266 break;

267 }

268

269 default:

270 break;

271 }

272

274 << " RelType: " << RelType << " TargetName: "

275 << TargetName << " Addend " << Addend << "\n");

276

277 if (IsExtern) {

280 } else {

283 }

284

285 return ++RelI;

286 }

287

289 for (auto const &EHFrameSID : UnregisteredEHFrameSections) {

290 uint8_t *EHFrameAddr = Sections[EHFrameSID].getAddress();

291 uint64_t EHFrameLoadAddr = Sections[EHFrameSID].getLoadAddress();

292 size_t EHFrameSize = Sections[EHFrameSID].getSize();

293 MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);

294 RegisteredEHFrameSections.push_back(EHFrameSID);

295 }

296 UnregisteredEHFrameSections.clear();

297 }

298

301

302 for (const auto &SectionPair : SectionMap) {

305 if (!NameOrErr)

307

308

309

310

311 if ((*NameOrErr) == ".pdata")

312 UnregisteredEHFrameSections.push_back(SectionPair.second);

313 }

315 }

316};

317

318}

319

320#undef DEBUG_TYPE

321

322#endif

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

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.

Error takeError()

Take ownership of the stored error.

Symbol resolution interface.

RelocationEntry - used to represent relocations internally in the dynamic linker.

uint32_t RelType

RelType - relocation type.

uint64_t Offset

Offset - offset into the section.

int64_t Addend

Addend - the relocation addend encoded in the instruction itself.

unsigned SectionID

SectionID - the section this relocation points to.

Interface for looking up the initializer for a variable name, used by Init::resolveReferences.

void registerEHFrames() override

Definition RuntimeDyldCOFFX86_64.h:288

void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override

A object file specific relocation resolver.

Definition RuntimeDyldCOFFX86_64.h:87

unsigned getMaxStubSize() const override

Definition RuntimeDyldCOFFX86_64.h:65

RuntimeDyldCOFFX86_64(RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver)

Definition RuntimeDyldCOFFX86_64.h:57

Align getStubAlignment() override

Definition RuntimeDyldCOFFX86_64.h:62

Error finalizeLoad(const object::ObjectFile &Obj, ObjSectionToIDMap &SectionMap) override

Definition RuntimeDyldCOFFX86_64.h:299

std::tuple< uint64_t, uint64_t, uint64_t > generateRelocationStub(unsigned SectionID, StringRef TargetName, uint64_t Offset, uint64_t RelType, uint64_t Addend, StubMap &Stubs)

Definition RuntimeDyldCOFFX86_64.h:151

Expected< object::relocation_iterator > processRelocationRef(unsigned SectionID, object::relocation_iterator RelI, const object::ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) override

Parses one or more object file relocations (some object files use relocation pairs) and stores it to ...

Definition RuntimeDyldCOFFX86_64.h:197

uint64_t getSymbolOffset(const SymbolRef &Sym)

static constexpr StringRef getImportSymbolPrefix()

RuntimeDyldCOFF(RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, unsigned PointerSize, uint32_t PointerReloc)

uint64_t getDLLImportOffset(unsigned SectionID, StubMap &Stubs, StringRef Name, bool SetSectionIDMinus1=false)

std::map< SectionRef, unsigned > ObjSectionToIDMap

std::map< RelocationValueRef, uintptr_t > StubMap

void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)

RuntimeDyld::MemoryManager & MemMgr

void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)

Expected< unsigned > findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)

Find Section in LocalSections.

void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const

Endian-aware write.

uint8_t * createStubFunction(uint8_t *Addr, unsigned AbiVariant=0)

Emits long jump instruction to Addr.

uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const

Endian-aware read Read the least significant Size bytes from Src.

SectionEntry - represents a section emitted into memory by the dynamic linker.

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

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

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

Target - Wrapper for Target specific information.

LLVM Value Representation.

This class is the base class for all object file types.

uint64_t getOffset() const

symbol_iterator getSymbol() const

This is a value type class that represents a single section in the list of sections in the object fil...

bool isText() const

Whether this section contains instructions.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ IMAGE_REL_AMD64_REL32_5

@ IMAGE_REL_AMD64_REL32_3

@ IMAGE_REL_AMD64_ADDR32NB

@ IMAGE_REL_AMD64_SECTION

@ IMAGE_REL_AMD64_REL32_2

@ IMAGE_REL_AMD64_REL32_1

@ IMAGE_REL_AMD64_REL32_4

content_iterator< SectionRef > section_iterator

content_iterator< RelocationRef > relocation_iterator

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

This struct is a compact representation of a valid (non-zero power of two) alignment.