1 //===----- ELF_aarch64.cpp - JIT linker implementation for ELF/aarch64 ----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // ELF/aarch64 jit-link implementation. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ExecutionEngine/JITLink/ELF_aarch64.h" 14 #include "llvm/BinaryFormat/ELF.h" 15 #include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h" 16 #include "llvm/ExecutionEngine/JITLink/aarch64.h" 17 #include "llvm/Object/ELFObjectFile.h" 18 #include "llvm/Support/Endian.h" 19 20 #include "DefineExternalSectionStartAndEndSymbols.h" 21 #include "EHFrameSupportImpl.h" 22 #include "ELFLinkGraphBuilder.h" 23 #include "JITLinkGeneric.h" 24 25 #define DEBUG_TYPE "jitlink" 26 27 using namespace llvm; 28 using namespace llvm::jitlink; 29 30 namespace { 31 32 constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_"; 33 34 class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> { 35 friend class JITLinker<ELFJITLinker_aarch64>; 36 37 public: 38 ELFJITLinker_aarch64(std::unique_ptr<JITLinkContext> Ctx, 39 std::unique_ptr<LinkGraph> G, 40 PassConfiguration PassConfig) 41 : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) { 42 if (shouldAddDefaultTargetPasses(getGraph().getTargetTriple())) 43 getPassConfig().PostAllocationPasses.push_back( 44 [this](LinkGraph &G) { return getOrCreateGOTSymbol(G); }); 45 } 46 47 private: 48 Symbol *GOTSymbol = nullptr; 49 50 Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const { 51 return aarch64::applyFixup(G, B, E, GOTSymbol); 52 } 53 54 Error getOrCreateGOTSymbol(LinkGraph &G) { 55 auto InteredGOTSymbolName = 56 G.getSymbolStringPool()->intern(ELFGOTSymbolName); 57 58 auto DefineExternalGOTSymbolIfPresent = 59 createDefineExternalSectionStartAndEndSymbolsPass( 60 [&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc { 61 if (*Sym.getName() == ELFGOTSymbolName) 62 if (auto *GOTSection = G.findSectionByName( 63 aarch64::GOTTableManager::getSectionName())) { 64 GOTSymbol = &Sym; 65 return {*GOTSection, true}; 66 } 67 return {}; 68 }); 69 70 // Try to attach _GLOBAL_OFFSET_TABLE_ to the GOT if it's defined as an 71 // external. 72 if (auto Err = DefineExternalGOTSymbolIfPresent(G)) 73 return Err; 74 75 // If we succeeded then we're done. 76 if (GOTSymbol) 77 return Error::success(); 78 79 // Otherwise look for a GOT section: If it already has a start symbol we'll 80 // record it, otherwise we'll create our own. 81 // If there's a GOT section but we didn't find an external GOT symbol... 82 if (auto *GOTSection = 83 G.findSectionByName(aarch64::GOTTableManager::getSectionName())) { 84 85 // Check for an existing defined symbol. 86 for (auto *Sym : GOTSection->symbols()) 87 if (Sym->getName() == InteredGOTSymbolName) { 88 GOTSymbol = Sym; 89 return Error::success(); 90 } 91 92 // If there's no defined symbol then create one. 93 SectionRange SR(*GOTSection); 94 if (SR.empty()) 95 GOTSymbol = 96 // FIXME: we should only do this once 97 &G.addAbsoluteSymbol(InteredGOTSymbolName, orc::ExecutorAddr(), 0, 98 Linkage::Strong, Scope::Local, true); 99 else 100 GOTSymbol = 101 &G.addDefinedSymbol(*SR.getFirstBlock(), 0, InteredGOTSymbolName, 0, 102 Linkage::Strong, Scope::Local, false, true); 103 } 104 105 // If we still haven't found a GOT symbol then double check the externals. 106 // We may have a GOT-relative reference but no GOT section, in which case 107 // we just need to point the GOT symbol at some address in this graph. 108 if (!GOTSymbol) { 109 for (auto *Sym : G.external_symbols()) { 110 if (*Sym->getName() == ELFGOTSymbolName) { 111 auto Blocks = G.blocks(); 112 if (!Blocks.empty()) { 113 G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress()); 114 GOTSymbol = Sym; 115 break; 116 } 117 } 118 } 119 } 120 121 return Error::success(); 122 } 123 }; 124 125 template <typename ELFT> 126 class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> { 127 private: 128 enum ELFAArch64RelocationKind : Edge::Kind { 129 ELFCall26 = Edge::FirstRelocation, 130 ELFLdrLo19, 131 ELFAdrLo21, 132 ELFAdrPage21, 133 ELFAddAbs12, 134 ELFLdSt8Abs12, 135 ELFLdSt16Abs12, 136 ELFLdSt32Abs12, 137 ELFLdSt64Abs12, 138 ELFLdSt128Abs12, 139 ELFMovwAbsG0, 140 ELFMovwAbsG1, 141 ELFMovwAbsG2, 142 ELFMovwAbsG3, 143 ELFTstBr14, 144 ELFCondBr19, 145 ELFAbs32, 146 ELFAbs64, 147 ELFPrel32, 148 ELFPrel64, 149 ELFAdrGOTPage21, 150 ELFLd64GOTLo12, 151 ELFLd64GOTPAGELo15, 152 ELFTLSDescAdrPage21, 153 ELFTLSDescAddLo12, 154 ELFTLSDescLd64Lo12, 155 ELFTLSDescCall, 156 }; 157 158 static Expected<ELFAArch64RelocationKind> 159 getRelocationKind(const uint32_t Type) { 160 using namespace aarch64; 161 switch (Type) { 162 case ELF::R_AARCH64_CALL26: 163 case ELF::R_AARCH64_JUMP26: 164 return ELFCall26; 165 case ELF::R_AARCH64_LD_PREL_LO19: 166 return ELFLdrLo19; 167 case ELF::R_AARCH64_ADR_PREL_LO21: 168 return ELFAdrLo21; 169 case ELF::R_AARCH64_ADR_PREL_PG_HI21: 170 return ELFAdrPage21; 171 case ELF::R_AARCH64_ADD_ABS_LO12_NC: 172 return ELFAddAbs12; 173 case ELF::R_AARCH64_LDST8_ABS_LO12_NC: 174 return ELFLdSt8Abs12; 175 case ELF::R_AARCH64_LDST16_ABS_LO12_NC: 176 return ELFLdSt16Abs12; 177 case ELF::R_AARCH64_LDST32_ABS_LO12_NC: 178 return ELFLdSt32Abs12; 179 case ELF::R_AARCH64_LDST64_ABS_LO12_NC: 180 return ELFLdSt64Abs12; 181 case ELF::R_AARCH64_LDST128_ABS_LO12_NC: 182 return ELFLdSt128Abs12; 183 case ELF::R_AARCH64_MOVW_UABS_G0_NC: 184 return ELFMovwAbsG0; 185 case ELF::R_AARCH64_MOVW_UABS_G1_NC: 186 return ELFMovwAbsG1; 187 case ELF::R_AARCH64_MOVW_UABS_G2_NC: 188 return ELFMovwAbsG2; 189 case ELF::R_AARCH64_MOVW_UABS_G3: 190 return ELFMovwAbsG3; 191 case ELF::R_AARCH64_TSTBR14: 192 return ELFTstBr14; 193 case ELF::R_AARCH64_CONDBR19: 194 return ELFCondBr19; 195 case ELF::R_AARCH64_ABS32: 196 return ELFAbs32; 197 case ELF::R_AARCH64_ABS64: 198 return ELFAbs64; 199 case ELF::R_AARCH64_PREL32: 200 return ELFPrel32; 201 case ELF::R_AARCH64_PREL64: 202 return ELFPrel64; 203 case ELF::R_AARCH64_ADR_GOT_PAGE: 204 return ELFAdrGOTPage21; 205 case ELF::R_AARCH64_LD64_GOT_LO12_NC: 206 return ELFLd64GOTLo12; 207 case ELF::R_AARCH64_LD64_GOTPAGE_LO15: 208 return ELFLd64GOTPAGELo15; 209 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 210 return ELFTLSDescAdrPage21; 211 case ELF::R_AARCH64_TLSDESC_ADD_LO12: 212 return ELFTLSDescAddLo12; 213 case ELF::R_AARCH64_TLSDESC_LD64_LO12: 214 return ELFTLSDescLd64Lo12; 215 case ELF::R_AARCH64_TLSDESC_CALL: 216 return ELFTLSDescCall; 217 } 218 219 return make_error<JITLinkError>( 220 "Unsupported aarch64 relocation:" + formatv("{0:d}: ", Type) + 221 object::getELFRelocationTypeName(ELF::EM_AARCH64, Type)); 222 } 223 224 Error addRelocations() override { 225 LLVM_DEBUG(dbgs() << "Processing relocations:\n"); 226 227 using Base = ELFLinkGraphBuilder<ELFT>; 228 using Self = ELFLinkGraphBuilder_aarch64<ELFT>; 229 for (const auto &RelSect : Base::Sections) 230 if (Error Err = Base::forEachRelaRelocation(RelSect, this, 231 &Self::addSingleRelocation)) 232 return Err; 233 234 return Error::success(); 235 } 236 237 Error addSingleRelocation(const typename ELFT::Rela &Rel, 238 const typename ELFT::Shdr &FixupSect, 239 Block &BlockToFix) { 240 using support::ulittle32_t; 241 using Base = ELFLinkGraphBuilder<ELFT>; 242 243 uint32_t SymbolIndex = Rel.getSymbol(false); 244 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec); 245 if (!ObjSymbol) 246 return ObjSymbol.takeError(); 247 248 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex); 249 if (!GraphSymbol) 250 return make_error<StringError>( 251 formatv("Could not find symbol at given index, did you add it to " 252 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}", 253 SymbolIndex, (*ObjSymbol)->st_shndx, 254 Base::GraphSymbols.size()), 255 inconvertibleErrorCode()); 256 257 uint32_t Type = Rel.getType(false); 258 Expected<ELFAArch64RelocationKind> RelocKind = getRelocationKind(Type); 259 if (!RelocKind) 260 return RelocKind.takeError(); 261 262 int64_t Addend = Rel.r_addend; 263 orc::ExecutorAddr FixupAddress = 264 orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset; 265 Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress(); 266 267 // Get a pointer to the fixup content. 268 const void *FixupContent = BlockToFix.getContent().data() + 269 (FixupAddress - BlockToFix.getAddress()); 270 271 Edge::Kind Kind = Edge::Invalid; 272 273 switch (*RelocKind) { 274 case ELFCall26: { 275 Kind = aarch64::Branch26PCRel; 276 break; 277 } 278 case ELFLdrLo19: { 279 uint32_t Instr = *(const ulittle32_t *)FixupContent; 280 if (!aarch64::isLDRLiteral(Instr)) 281 return make_error<JITLinkError>( 282 "R_AARCH64_LDR_PREL_LO19 target is not an LDR Literal instruction"); 283 284 Kind = aarch64::LDRLiteral19; 285 break; 286 } 287 case ELFAdrLo21: { 288 uint32_t Instr = *(const ulittle32_t *)FixupContent; 289 if (!aarch64::isADR(Instr)) 290 return make_error<JITLinkError>( 291 "R_AARCH64_ADR_PREL_LO21 target is not an ADR instruction"); 292 293 Kind = aarch64::ADRLiteral21; 294 break; 295 } 296 case ELFAdrPage21: { 297 Kind = aarch64::Page21; 298 break; 299 } 300 case ELFAddAbs12: { 301 Kind = aarch64::PageOffset12; 302 break; 303 } 304 case ELFLdSt8Abs12: { 305 uint32_t Instr = *(const ulittle32_t *)FixupContent; 306 if (!aarch64::isLoadStoreImm12(Instr) || 307 aarch64::getPageOffset12Shift(Instr) != 0) 308 return make_error<JITLinkError>( 309 "R_AARCH64_LDST8_ABS_LO12_NC target is not a " 310 "LDRB/STRB (imm12) instruction"); 311 312 Kind = aarch64::PageOffset12; 313 break; 314 } 315 case ELFLdSt16Abs12: { 316 uint32_t Instr = *(const ulittle32_t *)FixupContent; 317 if (!aarch64::isLoadStoreImm12(Instr) || 318 aarch64::getPageOffset12Shift(Instr) != 1) 319 return make_error<JITLinkError>( 320 "R_AARCH64_LDST16_ABS_LO12_NC target is not a " 321 "LDRH/STRH (imm12) instruction"); 322 323 Kind = aarch64::PageOffset12; 324 break; 325 } 326 case ELFLdSt32Abs12: { 327 uint32_t Instr = *(const ulittle32_t *)FixupContent; 328 if (!aarch64::isLoadStoreImm12(Instr) || 329 aarch64::getPageOffset12Shift(Instr) != 2) 330 return make_error<JITLinkError>( 331 "R_AARCH64_LDST32_ABS_LO12_NC target is not a " 332 "LDR/STR (imm12, 32 bit) instruction"); 333 334 Kind = aarch64::PageOffset12; 335 break; 336 } 337 case ELFLdSt64Abs12: { 338 uint32_t Instr = *(const ulittle32_t *)FixupContent; 339 if (!aarch64::isLoadStoreImm12(Instr) || 340 aarch64::getPageOffset12Shift(Instr) != 3) 341 return make_error<JITLinkError>( 342 "R_AARCH64_LDST64_ABS_LO12_NC target is not a " 343 "LDR/STR (imm12, 64 bit) instruction"); 344 345 Kind = aarch64::PageOffset12; 346 break; 347 } 348 case ELFLdSt128Abs12: { 349 uint32_t Instr = *(const ulittle32_t *)FixupContent; 350 if (!aarch64::isLoadStoreImm12(Instr) || 351 aarch64::getPageOffset12Shift(Instr) != 4) 352 return make_error<JITLinkError>( 353 "R_AARCH64_LDST128_ABS_LO12_NC target is not a " 354 "LDR/STR (imm12, 128 bit) instruction"); 355 356 Kind = aarch64::PageOffset12; 357 break; 358 } 359 case ELFMovwAbsG0: { 360 uint32_t Instr = *(const ulittle32_t *)FixupContent; 361 if (!aarch64::isMoveWideImm16(Instr) || 362 aarch64::getMoveWide16Shift(Instr) != 0) 363 return make_error<JITLinkError>( 364 "R_AARCH64_MOVW_UABS_G0_NC target is not a " 365 "MOVK/MOVZ (imm16, LSL #0) instruction"); 366 367 Kind = aarch64::MoveWide16; 368 break; 369 } 370 case ELFMovwAbsG1: { 371 uint32_t Instr = *(const ulittle32_t *)FixupContent; 372 if (!aarch64::isMoveWideImm16(Instr) || 373 aarch64::getMoveWide16Shift(Instr) != 16) 374 return make_error<JITLinkError>( 375 "R_AARCH64_MOVW_UABS_G1_NC target is not a " 376 "MOVK/MOVZ (imm16, LSL #16) instruction"); 377 378 Kind = aarch64::MoveWide16; 379 break; 380 } 381 case ELFMovwAbsG2: { 382 uint32_t Instr = *(const ulittle32_t *)FixupContent; 383 if (!aarch64::isMoveWideImm16(Instr) || 384 aarch64::getMoveWide16Shift(Instr) != 32) 385 return make_error<JITLinkError>( 386 "R_AARCH64_MOVW_UABS_G2_NC target is not a " 387 "MOVK/MOVZ (imm16, LSL #32) instruction"); 388 389 Kind = aarch64::MoveWide16; 390 break; 391 } 392 case ELFMovwAbsG3: { 393 uint32_t Instr = *(const ulittle32_t *)FixupContent; 394 if (!aarch64::isMoveWideImm16(Instr) || 395 aarch64::getMoveWide16Shift(Instr) != 48) 396 return make_error<JITLinkError>( 397 "R_AARCH64_MOVW_UABS_G3 target is not a " 398 "MOVK/MOVZ (imm16, LSL #48) instruction"); 399 400 Kind = aarch64::MoveWide16; 401 break; 402 } 403 case ELFTstBr14: { 404 uint32_t Instr = *(const ulittle32_t *)FixupContent; 405 if (!aarch64::isTestAndBranchImm14(Instr)) 406 return make_error<JITLinkError>("R_AARCH64_TSTBR14 target is not a " 407 "test and branch instruction"); 408 409 Kind = aarch64::TestAndBranch14PCRel; 410 break; 411 } 412 case ELFCondBr19: { 413 uint32_t Instr = *(const ulittle32_t *)FixupContent; 414 if (!aarch64::isCondBranchImm19(Instr) && 415 !aarch64::isCompAndBranchImm19(Instr)) 416 return make_error<JITLinkError>("R_AARCH64_CONDBR19 target is not a " 417 "conditional branch instruction"); 418 419 Kind = aarch64::CondBranch19PCRel; 420 break; 421 } 422 case ELFAbs32: { 423 Kind = aarch64::Pointer32; 424 break; 425 } 426 case ELFAbs64: { 427 Kind = aarch64::Pointer64; 428 break; 429 } 430 case ELFPrel32: { 431 Kind = aarch64::Delta32; 432 break; 433 } 434 case ELFPrel64: { 435 Kind = aarch64::Delta64; 436 break; 437 } 438 case ELFAdrGOTPage21: { 439 Kind = aarch64::RequestGOTAndTransformToPage21; 440 break; 441 } 442 case ELFLd64GOTLo12: { 443 Kind = aarch64::RequestGOTAndTransformToPageOffset12; 444 break; 445 } 446 case ELFLd64GOTPAGELo15: { 447 Kind = aarch64::RequestGOTAndTransformToPageOffset15; 448 break; 449 } 450 case ELFTLSDescAdrPage21: { 451 Kind = aarch64::RequestTLSDescEntryAndTransformToPage21; 452 break; 453 } 454 case ELFTLSDescAddLo12: 455 case ELFTLSDescLd64Lo12: { 456 Kind = aarch64::RequestTLSDescEntryAndTransformToPageOffset12; 457 break; 458 } 459 case ELFTLSDescCall: { 460 return Error::success(); 461 } 462 }; 463 464 Edge GE(Kind, Offset, *GraphSymbol, Addend); 465 LLVM_DEBUG({ 466 dbgs() << " "; 467 printEdge(dbgs(), BlockToFix, GE, aarch64::getEdgeKindName(Kind)); 468 dbgs() << "\n"; 469 }); 470 471 BlockToFix.addEdge(std::move(GE)); 472 473 return Error::success(); 474 } 475 476 /// Return the string name of the given ELF aarch64 edge kind. 477 const char *getELFAArch64RelocationKindName(Edge::Kind R) { 478 switch (R) { 479 case ELFCall26: 480 return "ELFCall26"; 481 case ELFAdrPage21: 482 return "ELFAdrPage21"; 483 case ELFAddAbs12: 484 return "ELFAddAbs12"; 485 case ELFLdSt8Abs12: 486 return "ELFLdSt8Abs12"; 487 case ELFLdSt16Abs12: 488 return "ELFLdSt16Abs12"; 489 case ELFLdSt32Abs12: 490 return "ELFLdSt32Abs12"; 491 case ELFLdSt64Abs12: 492 return "ELFLdSt64Abs12"; 493 case ELFLdSt128Abs12: 494 return "ELFLdSt128Abs12"; 495 case ELFMovwAbsG0: 496 return "ELFMovwAbsG0"; 497 case ELFMovwAbsG1: 498 return "ELFMovwAbsG1"; 499 case ELFMovwAbsG2: 500 return "ELFMovwAbsG2"; 501 case ELFMovwAbsG3: 502 return "ELFMovwAbsG3"; 503 case ELFAbs32: 504 return "ELFAbs32"; 505 case ELFAbs64: 506 return "ELFAbs64"; 507 case ELFPrel32: 508 return "ELFPrel32"; 509 case ELFPrel64: 510 return "ELFPrel64"; 511 case ELFAdrGOTPage21: 512 return "ELFAdrGOTPage21"; 513 case ELFLd64GOTLo12: 514 return "ELFLd64GOTLo12"; 515 case ELFLd64GOTPAGELo15: 516 return "ELFLd64GOTPAGELo15"; 517 case ELFTLSDescAdrPage21: 518 return "ELFTLSDescAdrPage21"; 519 case ELFTLSDescAddLo12: 520 return "ELFTLSDescAddLo12"; 521 case ELFTLSDescLd64Lo12: 522 return "ELFTLSDescLd64Lo12"; 523 case ELFTLSDescCall: 524 return "ELFTLSDescCall"; 525 default: 526 return getGenericEdgeKindName(static_cast<Edge::Kind>(R)); 527 } 528 } 529 530 public: 531 ELFLinkGraphBuilder_aarch64(StringRef FileName, 532 const object::ELFFile<ELFT> &Obj, 533 std::shared_ptr<orc::SymbolStringPool> SSP, 534 Triple TT, SubtargetFeatures Features) 535 536 : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT), 537 std::move(Features), FileName, 538 aarch64::getEdgeKindName) {} 539 }; 540 541 // TLS Info Builder. 542 class TLSInfoTableManager_ELF_aarch64 543 : public TableManager<TLSInfoTableManager_ELF_aarch64> { 544 public: 545 static StringRef getSectionName() { return "$__TLSINFO"; } 546 547 static const uint8_t TLSInfoEntryContent[16]; 548 549 bool visitEdge(LinkGraph &G, Block *B, Edge &E) { return false; } 550 551 Symbol &createEntry(LinkGraph &G, Symbol &Target) { 552 // the TLS Info entry's key value will be written by the fixTLVSectionByName 553 // pass, so create mutable content. 554 auto &TLSInfoEntry = G.createMutableContentBlock( 555 getTLSInfoSection(G), G.allocateContent(getTLSInfoEntryContent()), 556 orc::ExecutorAddr(), 8, 0); 557 TLSInfoEntry.addEdge(aarch64::Pointer64, 8, Target, 0); 558 return G.addAnonymousSymbol(TLSInfoEntry, 0, 16, false, false); 559 } 560 561 private: 562 Section &getTLSInfoSection(LinkGraph &G) { 563 if (!TLSInfoTable) 564 TLSInfoTable = &G.createSection(getSectionName(), orc::MemProt::Read); 565 return *TLSInfoTable; 566 } 567 568 ArrayRef<char> getTLSInfoEntryContent() const { 569 return {reinterpret_cast<const char *>(TLSInfoEntryContent), 570 sizeof(TLSInfoEntryContent)}; 571 } 572 573 Section *TLSInfoTable = nullptr; 574 }; 575 576 const uint8_t TLSInfoTableManager_ELF_aarch64::TLSInfoEntryContent[16] = { 577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*pthread key */ 578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*data address*/ 579 }; 580 581 // TLS Descriptor Builder. 582 class TLSDescTableManager_ELF_aarch64 583 : public TableManager<TLSDescTableManager_ELF_aarch64> { 584 public: 585 TLSDescTableManager_ELF_aarch64( 586 TLSInfoTableManager_ELF_aarch64 &TLSInfoTableManager) 587 : TLSInfoTableManager(TLSInfoTableManager) {} 588 589 static StringRef getSectionName() { return "$__TLSDESC"; } 590 591 static const uint8_t TLSDescEntryContent[16]; 592 593 bool visitEdge(LinkGraph &G, Block *B, Edge &E) { 594 Edge::Kind KindToSet = Edge::Invalid; 595 switch (E.getKind()) { 596 case aarch64::RequestTLSDescEntryAndTransformToPage21: { 597 KindToSet = aarch64::Page21; 598 break; 599 } 600 case aarch64::RequestTLSDescEntryAndTransformToPageOffset12: { 601 KindToSet = aarch64::PageOffset12; 602 break; 603 } 604 default: 605 return false; 606 } 607 assert(KindToSet != Edge::Invalid && 608 "Fell through switch, but no new kind to set"); 609 DEBUG_WITH_TYPE("jitlink", { 610 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at " 611 << B->getFixupAddress(E) << " (" << B->getAddress() << " + " 612 << formatv("{0:x}", E.getOffset()) << ")\n"; 613 }); 614 E.setKind(KindToSet); 615 E.setTarget(getEntryForTarget(G, E.getTarget())); 616 return true; 617 } 618 619 Symbol &createEntry(LinkGraph &G, Symbol &Target) { 620 auto &EntryBlock = 621 G.createContentBlock(getTLSDescSection(G), getTLSDescBlockContent(), 622 orc::ExecutorAddr(), 8, 0); 623 EntryBlock.addEdge(aarch64::Pointer64, 0, getTLSDescResolver(G), 0); 624 EntryBlock.addEdge(aarch64::Pointer64, 8, 625 TLSInfoTableManager.getEntryForTarget(G, Target), 0); 626 return G.addAnonymousSymbol(EntryBlock, 0, 8, false, false); 627 } 628 629 private: 630 Section &getTLSDescSection(LinkGraph &G) { 631 if (!GOTSection) 632 GOTSection = &G.createSection(getSectionName(), orc::MemProt::Read); 633 return *GOTSection; 634 } 635 636 Symbol &getTLSDescResolver(LinkGraph &G) { 637 if (!TLSDescResolver) 638 TLSDescResolver = &G.addExternalSymbol("__tlsdesc_resolver", 8, false); 639 return *TLSDescResolver; 640 } 641 642 ArrayRef<char> getTLSDescBlockContent() { 643 return {reinterpret_cast<const char *>(TLSDescEntryContent), 644 sizeof(TLSDescEntryContent)}; 645 } 646 647 Section *GOTSection = nullptr; 648 Symbol *TLSDescResolver = nullptr; 649 TLSInfoTableManager_ELF_aarch64 &TLSInfoTableManager; 650 }; 651 652 const uint8_t TLSDescTableManager_ELF_aarch64::TLSDescEntryContent[16] = { 653 0x00, 0x00, 0x00, 0x00, 654 0x00, 0x00, 0x00, 0x00, /*resolver function pointer*/ 655 0x00, 0x00, 0x00, 0x00, 656 0x00, 0x00, 0x00, 0x00 /*pointer to tls info*/ 657 }; 658 659 Error buildTables_ELF_aarch64(LinkGraph &G) { 660 LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n"); 661 662 aarch64::GOTTableManager GOT(G); 663 aarch64::PLTTableManager PLT(G, GOT); 664 TLSInfoTableManager_ELF_aarch64 TLSInfo; 665 TLSDescTableManager_ELF_aarch64 TLSDesc(TLSInfo); 666 visitExistingEdges(G, GOT, PLT, TLSDesc, TLSInfo); 667 return Error::success(); 668 } 669 670 } // namespace 671 672 namespace llvm { 673 namespace jitlink { 674 675 Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch64( 676 MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) { 677 LLVM_DEBUG({ 678 dbgs() << "Building jitlink graph for new input " 679 << ObjectBuffer.getBufferIdentifier() << "...\n"; 680 }); 681 682 auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer); 683 if (!ELFObj) 684 return ELFObj.takeError(); 685 686 auto Features = (*ELFObj)->getFeatures(); 687 if (!Features) 688 return Features.takeError(); 689 690 assert((*ELFObj)->getArch() == Triple::aarch64 && 691 "Only AArch64 (little endian) is supported for now"); 692 693 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj); 694 return ELFLinkGraphBuilder_aarch64<object::ELF64LE>( 695 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP), 696 (*ELFObj)->makeTriple(), std::move(*Features)) 697 .buildGraph(); 698 } 699 700 void link_ELF_aarch64(std::unique_ptr<LinkGraph> G, 701 std::unique_ptr<JITLinkContext> Ctx) { 702 PassConfiguration Config; 703 const Triple &TT = G->getTargetTriple(); 704 if (Ctx->shouldAddDefaultTargetPasses(TT)) { 705 // Add eh-frame passes. 706 Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame")); 707 Config.PrePrunePasses.push_back(EHFrameEdgeFixer( 708 ".eh_frame", 8, aarch64::Pointer32, aarch64::Pointer64, 709 aarch64::Delta32, aarch64::Delta64, aarch64::NegDelta32)); 710 Config.PrePrunePasses.push_back(EHFrameNullTerminator(".eh_frame")); 711 712 // Add a mark-live pass. 713 if (auto MarkLive = Ctx->getMarkLivePass(TT)) 714 Config.PrePrunePasses.push_back(std::move(MarkLive)); 715 else 716 Config.PrePrunePasses.push_back(markAllSymbolsLive); 717 718 // Resolve any external section start / end symbols. 719 Config.PostAllocationPasses.push_back( 720 createDefineExternalSectionStartAndEndSymbolsPass( 721 identifyELFSectionStartAndEndSymbols)); 722 723 // Add an in-place GOT/TLS/Stubs build pass. 724 Config.PostPrunePasses.push_back(buildTables_ELF_aarch64); 725 } 726 727 if (auto Err = Ctx->modifyPassConfig(*G, Config)) 728 return Ctx->notifyFailed(std::move(Err)); 729 730 ELFJITLinker_aarch64::link(std::move(Ctx), std::move(G), std::move(Config)); 731 } 732 733 } // namespace jitlink 734 } // namespace llvm 735