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

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFAARCH64_H

14#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFAARCH64_H

15

21

22#define DEBUG_TYPE "dyld"

23

24namespace llvm {

25

26

27

31

36

37static void or32le(void *P, int32_t V) {

39

41}

42

45

47 orig &= ~(0xFFF << 10);

48 write32le(T, orig | ((imm & (0xFFF >> rangeLimit)) << 10));

49}

50

53

56

57

58 if ((orig & 0x04800000) == 0x04800000)

60 if ((imm & ((1 << size) - 1)) != 0)

61 assert(0 && "misaligned ldr/str offset");

63}

64

67

68 uint64_t Imm = (s >> shift) - (p >> shift);

69 uint32_t ImmLo = (Imm & 0x3) << 29;

70 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;

71 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);

73}

74

76

77private:

78

79

80

84

85

87 if (!ImageBase) {

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

90

91

92

93

94

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

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

97 }

98 return ImageBase;

99 }

100

101public:

106

108

110

111 std::tuple<uint64_t, uint64_t, uint64_t>

115 uintptr_t StubOffset;

117

119 OriginalRelValueRef.SectionID = SectionID;

121 OriginalRelValueRef.Addend = Addend;

123

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

125 if (Inserted) {

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

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

128

129 StubOffset = Section.getStubOffset();

130 Stub->second = StubOffset;

133 } else {

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

135 << "\n");

136 StubOffset = Stub->second;

137 }

138

139

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

142

143

144

145

146 Addend = 0;

149

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

151 }

152

157 StubMap &Stubs) override {

159

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

163

165 if (!TargetNameOrErr)

166 return TargetNameOrErr.takeError();

167 StringRef TargetName = *TargetNameOrErr;

168

169 auto SectionOrErr = Symbol->getSection();

170 if (!SectionOrErr)

172 auto Section = *SectionOrErr;

173

176

177

178 bool IsExtern = Section == Obj.section_end();

179

180

185

186 unsigned TargetSectionID = -1;

188

190 TargetSectionID = SectionID;

193 IsExtern = false;

194 } else if (!IsExtern) {

196 Obj, *Section, Section->isText(), ObjSectionToID))

197 TargetSectionID = *TargetSectionIDOrErr;

198 else

199 return TargetSectionIDOrErr.takeError();

200

202 }

203

204 switch (RelType) {

209 Addend = read32le(Displacement);

210 break;

213 Addend = (orig & 0x03FFFFFF) << 2;

214

215 if (IsExtern)

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

218 break;

219 }

222 Addend = (orig & 0x00FFFFE0) >> 3;

223 break;

224 }

227 Addend = (orig & 0x000FFFE0) >> 3;

228 break;

229 }

233 Addend = ((orig >> 29) & 0x3) | ((orig >> 3) & 0x1FFFFC);

234 break;

235 }

239 Addend = ((orig >> 10) & 0xFFF);

240 break;

241 }

243 Addend = read64le(Displacement);

244 break;

245 }

246 default:

247 break;

248 }

249

250#if !defined(NDEBUG)

253

255 << " RelType: " << RelTypeName << " TargetName: "

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

257#endif

258

259 if (IsExtern) {

262 } else {

265 }

266 return ++RelI;

267 }

268

271

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

275

277 default:

280

281 break;

282 }

284

287 break;

288 }

290

293 break;

294 }

296

297

300 break;

301 }

303

304

307 break;

308 }

310

313 break;

314 }

316

319 break;

320 }

322

327 break;

328 }

330

331

333 assert(isInt<28>(PCRelVal) && "Branch target is out of range.");

335 (PCRelVal & 0x0FFFFFFC) >> 2);

336 break;

337 }

339

340

342 assert(isInt<21>(PCRelVal) && "Branch target is out of range.");

344 (PCRelVal & 0x001FFFFC) << 3);

345 break;

346 }

348

349

351 assert(isInt<16>(PCRelVal) && "Branch target is out of range.");

353 (PCRelVal & 0x0000FFFC) << 3);

354 break;

355 }

357

359 break;

360 }

362

364 "relocation overflow");

366 break;

367 }

369

370 assert(static_cast<int64_t>(RE.Addend) <= INT32_MAX &&

371 "Relocation overflow");

372 assert(static_cast<int64_t>(RE.Addend) >= INT32_MIN &&

373 "Relocation underflow");

375 break;

376 }

378

381 break;

382 }

383 }

384 }

385

387};

388

389}

390

391#undef DEBUG_TYPE

392

393#endif

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

This file defines the SmallString class.

void write32le(void *P, uint32_t V)

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.

Align getStubAlignment() override

Definition RuntimeDyldCOFFAArch64.h:107

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

A object file specific relocation resolver.

Definition RuntimeDyldCOFFAArch64.h:269

unsigned getMaxStubSize() const override

Definition RuntimeDyldCOFFAArch64.h:109

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

Definition RuntimeDyldCOFFAArch64.h:102

void registerEHFrames() override

Definition RuntimeDyldCOFFAArch64.h:386

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 RuntimeDyldCOFFAArch64.h:112

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 RuntimeDyldCOFFAArch64.h:154

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)

void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)

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

Find Section in LocalSections.

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

Emits long jump instruction to Addr.

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

uintptr_t getObjAddress() const

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

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

void getTypeName(SmallVectorImpl< char > &Result) const

Get a string that represents the type of this relocation.

#define llvm_unreachable(msg)

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

@ IMAGE_REL_ARM64_BRANCH19

@ IMAGE_REL_ARM64_SECTION

@ IMAGE_REL_ARM64_ABSOLUTE

@ IMAGE_REL_ARM64_PAGEOFFSET_12A

@ IMAGE_REL_ARM64_BRANCH14

@ IMAGE_REL_ARM64_BRANCH26

@ IMAGE_REL_ARM64_PAGEOFFSET_12L

@ IMAGE_REL_ARM64_ADDR32NB

@ IMAGE_REL_ARM64_PAGEBASE_REL21

content_iterator< RelocationRef > relocation_iterator

uint64_t read64le(const void *P)

uint16_t read16le(const void *P)

void write64le(void *P, uint64_t V)

void write16le(void *P, uint16_t V)

uint32_t read32le(const void *P)

This is an optimization pass for GlobalISel generic memory operations.

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

InternalRelocationType

Definition RuntimeDyldCOFFAArch64.h:28

@ INTERNAL_REL_ARM64_LONG_BRANCH26

Definition RuntimeDyldCOFFAArch64.h:29

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)

static void write32AArch64Ldr(uint8_t *T, uint64_t imm)

Definition RuntimeDyldCOFFAArch64.h:51

static void or32le(void *P, int32_t V)

Definition RuntimeDyldCOFFAArch64.h:37

static void add16(uint8_t *p, int16_t v)

Definition RuntimeDyldCOFFAArch64.h:32

static void write32AArch64Imm(uint8_t *T, uint64_t imm, uint32_t rangeLimit)

Definition RuntimeDyldCOFFAArch64.h:43

static void write32AArch64Addr(void *T, uint64_t s, uint64_t p, int shift)

Definition RuntimeDyldCOFFAArch64.h:65

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