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

21public:

22

24

28

30

32

33

36 uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);

37 unsigned NumBytes = 1 << RE.Size;

38 int64_t Addend = 0;

39

41 default: {

42 std::string ErrMsg;

43 {

45 ErrStream << "Unsupported relocation type: "

46 << getRelocName(RE.RelType);

47 }

50 }

53 if (NumBytes != 4 && NumBytes != 8) {

54 std::string ErrMsg;

55 {

57 ErrStream << "Invalid relocation size for relocation "

58 << getRelocName(RE.RelType);

59 }

62 }

63 break;

64 }

70 assert(NumBytes == 4 && "Invalid relocation size.");

71 assert((((uintptr_t)LocalAddress & 0x3) == 0) &&

72 "Instruction address is not aligned to 4 bytes.");

73 break;

74 }

75

77 default:

81

82 if (NumBytes == 4)

84 else

86 break;

88

90 assert(((*p & 0xFC000000) == 0x14000000 ||

91 (*p & 0xFC000000) == 0x94000000) &&

92 "Expected branch instruction.");

93

94

95

96

97 Addend = (*p & 0x03FFFFFF) << 2;

99 break;

100 }

103

105 assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");

106

107

108

109

110 Addend = ((*p & 0x60000000) >> 29) | ((*p & 0x01FFFFE0) >> 3) << 12;

112 break;

113 }

115

116

118 (void)p;

119 assert((*p & 0x3B000000) == 0x39000000 &&

120 "Only expected load / store instructions.");

121 [[fallthrough]];

122 }

124

125

127 assert((((*p & 0x3B000000) == 0x39000000) ||

128 ((*p & 0x11C00000) == 0x11000000) ) &&

129 "Expected load / store or add/sub instruction.");

130

131

132 Addend = (*p & 0x003FFC00) >> 10;

133

134

135

136 int ImplicitShift = 0;

137 if ((*p & 0x3B000000) == 0x39000000) {

138

139 ImplicitShift = ((*p >> 30) & 0x3);

140 if (ImplicitShift == 0) {

141

142 if ((*p & 0x04800000) == 0x04800000)

143 ImplicitShift = 4;

144 }

145 }

146

147 Addend <<= ImplicitShift;

148 break;

149 }

150 }

151 return Addend;

152 }

153

154

157

158 switch (RelType) {

159 default:

163 assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size.");

164 break;

170 assert(NumBytes == 4 && "Invalid relocation size.");

171 assert((((uintptr_t)LocalAddress & 0x3) == 0) &&

172 "Instruction address is not aligned to 4 bytes.");

173 break;

174 }

175

176 switch (RelType) {

177 default:

181

182 if (NumBytes == 4)

184 else

186 break;

189

190 assert(((*p & 0xFC000000) == 0x14000000 ||

191 (*p & 0xFC000000) == 0x94000000) &&

192 "Expected branch instruction.");

193

194

195 assert((Addend & 0x3) == 0 && "Branch target is not aligned");

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

197

198

199 *p = (*p & 0xFC000000) | ((uint32_t)(Addend >> 2) & 0x03FFFFFF);

200 break;

201 }

204

206 assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");

207

208

209 assert((Addend & 0xFFF) == 0 && "ADRP target is not page aligned.");

210 assert(isInt<33>(Addend) && "Invalid page reloc value.");

211

212

215 *p = (*p & 0x9F00001F) | ImmHiValue | ImmLoValue;

216 break;

217 }

219

220

222 assert((*p & 0x3B000000) == 0x39000000 &&

223 "Only expected load / store instructions.");

224 (void)p;

225 [[fallthrough]];

226 }

228

229

231 assert((((*p & 0x3B000000) == 0x39000000) ||

232 ((*p & 0x11C00000) == 0x11000000) ) &&

233 "Expected load / store or add/sub instruction.");

234

235

236

237 int ImplicitShift = 0;

238 if ((*p & 0x3B000000) == 0x39000000) {

239

240 ImplicitShift = ((*p >> 30) & 0x3);

241 switch (ImplicitShift) {

242 case 0:

243

244 if ((*p & 0x04800000) == 0x04800000) {

245 ImplicitShift = 4;

246 assert(((Addend & 0xF) == 0) &&

247 "128-bit LDR/STR not 16-byte aligned.");

248 }

249 break;

250 case 1:

251 assert(((Addend & 0x1) == 0) && "16-bit LDR/STR not 2-byte aligned.");

252 break;

253 case 2:

254 assert(((Addend & 0x3) == 0) && "32-bit LDR/STR not 4-byte aligned.");

255 break;

256 case 3:

257 assert(((Addend & 0x7) == 0) && "64-bit LDR/STR not 8-byte aligned.");

258 break;

259 }

260 }

261

262 Addend >>= ImplicitShift;

264

265

266 *p = (*p & 0xFFC003FF) | ((uint32_t)(Addend << 10) & 0x003FFC00);

267 break;

268 }

269 }

270 }

271

276 StubMap &Stubs) override {

281

282 if (Obj.isRelocationScattered(RelInfo))

284 "for MachO AArch64");

285

286

287

288

289

290 int64_t ExplicitAddend = 0;

292 assert(!Obj.getPlainRelocationExternal(RelInfo));

293 assert(!Obj.getAnyRelocationPCRel(RelInfo));

294 assert(Obj.getAnyRelocationLength(RelInfo) == 2);

295 int64_t RawAddend = Obj.getPlainRelocationSymbolNum(RelInfo);

296

297 ExplicitAddend = SignExtend64(RawAddend, 24);

298 ++RelI;

300 }

301

303 return processSubtractRelocation(SectionID, RelI, Obj, ObjSectionToID);

304

306

308 bool Valid =

310 if (!Valid)

312 "32-bit pc-rel or 64-bit absolute only",

314 }

315

318 else

319 return Addend.takeError();

320

321 assert((ExplicitAddend == 0 || RE.Addend == 0) && "Relocation has "\

322 "ARM64_RELOC_ADDEND and embedded addend in the instruction.");

323 if (ExplicitAddend)

324 RE.Addend = ExplicitAddend;

325

328 Value = *ValueOrErr;

329 else

330 return ValueOrErr.takeError();

331

332 bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);

334

335 Value.Offset = 0;

336 } else if (!IsExtern && RE.IsPCRel)

338

340

344 processGOTRelocation(RE, Value, Stubs);

345 else {

346 if (Value.SymbolName)

348 else

350 }

351

352 return ++RelI;

353 }

354

357

359 uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);

362

363 switch (RelType) {

364 default:

367 assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_UNSIGNED not supported");

368

369

370 if (RE.Size < 2)

372

374 break;

375 }

376

379 "ARM64_RELOC_POINTER_TO_GOT only supports 32-bit pc-rel or 64-bit "

380 "absolute");

381

382

386 break;

387 }

388

390 assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_BRANCH26 not supported");

391

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

393 int64_t PCRelVal = Value - FinalAddress + RE.Addend;

394 encodeAddend(LocalAddress, 4, RelType, PCRelVal);

395 break;

396 }

399 assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_PAGE21 not supported");

400

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

402 int64_t PCRelVal =

403 ((Value + RE.Addend) & (-4096)) - (FinalAddress & (-4096));

404 encodeAddend(LocalAddress, 4, RelType, PCRelVal);

405 break;

406 }

409 assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_PAGEOFF21 not supported");

410

412

415 break;

416 }

421 "Unexpected SUBTRACTOR relocation value.");

422 Value = SectionABase - SectionBBase + RE.Addend;

424 break;

425 }

426

431 llvm_unreachable("ARM64_RELOC_ADDEND should have been handeled by "

432 "processRelocationRef!");

433 }

434 }

435

440

441private:

445 (RE.Size == 2 || RE.Size == 3)) ||

446 RE.Size == 2);

448 auto [It, Inserted] = Stubs.try_emplace(Value);

450 if (!Inserted)

451 Offset = static_cast<int64_t>(It->second);

452 else {

453

454

455 uintptr_t BaseAddress = uintptr_t(Section.getAddress());

457 uintptr_t StubAddress =

458 (BaseAddress + Section.getStubOffset() + StubAlignment - 1) &

459 -StubAlignment;

460 unsigned StubOffset = StubAddress - BaseAddress;

461 It->second = StubOffset;

463 "GOT entry not aligned");

466 false, 3);

467 if (Value.SymbolName)

469 else

472 Offset = static_cast<int64_t>(StubOffset);

473 }

477 }

478

479 Expected<relocation_iterator>

483 const MachOObjectFile &Obj =

484 static_cast<const MachOObjectFile&>(BaseObjT);

485 MachO::any_relocation_info RE =

487

488 unsigned Size = Obj.getAnyRelocationLength(RE);

490 uint8_t *LocalAddress = Sections[SectionID].getAddressWithOffset(Offset);

491 unsigned NumBytes = 1 << Size;

492

493 Expected SubtrahendNameOrErr = RelI->getSymbol()->getName();

494 if (!SubtrahendNameOrErr)

495 return SubtrahendNameOrErr.takeError();

497 unsigned SectionBID = SubtrahendI->second.getSectionID();

498 uint64_t SectionBOffset = SubtrahendI->second.getOffset();

499 int64_t Addend =

501

502 ++RelI;

503 Expected MinuendNameOrErr = RelI->getSymbol()->getName();

504 if (!MinuendNameOrErr)

505 return MinuendNameOrErr.takeError();

507 unsigned SectionAID = MinuendI->second.getSectionID();

508 uint64_t SectionAOffset = MinuendI->second.getOffset();

509

511 SectionAID, SectionAOffset, SectionBID, SectionBOffset,

512 false, Size);

513

515

516 return ++RelI;

517 }

518

519 static const char *getRelocName(uint32_t RelocType) {

520 switch (RelocType) {

532 }

533 return "Unrecognized arm64 addend";

534 }

535

536};