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