1 //===--------- JITLinkGeneric.cpp - Generic JIT linker utilities ----------===// 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 // Generic JITLinker utility class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "JITLinkGeneric.h" 14 15 #include "llvm/Support/BinaryStreamReader.h" 16 #include "llvm/Support/MemoryBuffer.h" 17 18 #define DEBUG_TYPE "jitlink" 19 20 namespace llvm { 21 namespace jitlink { 22 23 JITLinkerBase::~JITLinkerBase() {} 24 25 void JITLinkerBase::linkPhase1(std::unique_ptr<JITLinkerBase> Self) { 26 27 LLVM_DEBUG({ dbgs() << "Building jitlink graph for new input...\n"; }); 28 29 // Build the link graph. 30 if (auto GraphOrErr = buildGraph(Ctx->getObjectBuffer())) 31 G = std::move(*GraphOrErr); 32 else 33 return Ctx->notifyFailed(GraphOrErr.takeError()); 34 assert(G && "Graph should have been created by buildGraph above"); 35 36 LLVM_DEBUG({ 37 dbgs() << "Starting link phase 1 for graph " << G->getName() << "\n"; 38 }); 39 40 // Prune and optimize the graph. 41 if (auto Err = runPasses(Passes.PrePrunePasses)) 42 return Ctx->notifyFailed(std::move(Err)); 43 44 LLVM_DEBUG({ 45 dbgs() << "Link graph \"" << G->getName() << "\" pre-pruning:\n"; 46 dumpGraph(dbgs()); 47 }); 48 49 prune(*G); 50 51 LLVM_DEBUG({ 52 dbgs() << "Link graph \"" << G->getName() << "\" post-pruning:\n"; 53 dumpGraph(dbgs()); 54 }); 55 56 // Run post-pruning passes. 57 if (auto Err = runPasses(Passes.PostPrunePasses)) 58 return Ctx->notifyFailed(std::move(Err)); 59 60 // Sort blocks into segments. 61 auto Layout = layOutBlocks(); 62 63 // Allocate memory for segments. 64 if (auto Err = allocateSegments(Layout)) 65 return Ctx->notifyFailed(std::move(Err)); 66 67 // Notify client that the defined symbols have been assigned addresses. 68 LLVM_DEBUG( 69 { dbgs() << "Resolving symbols defined in " << G->getName() << "\n"; }); 70 71 if (auto Err = Ctx->notifyResolved(*G)) 72 return Ctx->notifyFailed(std::move(Err)); 73 74 auto ExternalSymbols = getExternalSymbolNames(); 75 76 LLVM_DEBUG({ 77 dbgs() << "Issuing lookup for external symbols for " << G->getName() 78 << " (may trigger materialization/linking of other graphs)...\n"; 79 }); 80 81 // We're about to hand off ownership of ourself to the continuation. Grab a 82 // pointer to the context so that we can call it to initiate the lookup. 83 // 84 // FIXME: Once callee expressions are defined to be sequenced before argument 85 // expressions (c++17) we can simplify all this to: 86 // 87 // Ctx->lookup(std::move(UnresolvedExternals), 88 // [Self=std::move(Self)](Expected<AsyncLookupResult> Result) { 89 // Self->linkPhase2(std::move(Self), std::move(Result)); 90 // }); 91 auto *TmpCtx = Ctx.get(); 92 TmpCtx->lookup(std::move(ExternalSymbols), 93 createLookupContinuation( 94 [S = std::move(Self), L = std::move(Layout)]( 95 Expected<AsyncLookupResult> LookupResult) mutable { 96 auto &TmpSelf = *S; 97 TmpSelf.linkPhase2(std::move(S), std::move(LookupResult), 98 std::move(L)); 99 })); 100 } 101 102 void JITLinkerBase::linkPhase2(std::unique_ptr<JITLinkerBase> Self, 103 Expected<AsyncLookupResult> LR, 104 SegmentLayoutMap Layout) { 105 106 LLVM_DEBUG({ 107 dbgs() << "Starting link phase 2 for graph " << G->getName() << "\n"; 108 }); 109 110 // If the lookup failed, bail out. 111 if (!LR) 112 return deallocateAndBailOut(LR.takeError()); 113 114 // Assign addresses to external addressables. 115 applyLookupResult(*LR); 116 117 // Copy block content to working memory. 118 copyBlockContentToWorkingMemory(Layout, *Alloc); 119 120 LLVM_DEBUG({ 121 dbgs() << "Link graph \"" << G->getName() 122 << "\" before post-allocation passes:\n"; 123 dumpGraph(dbgs()); 124 }); 125 126 if (auto Err = runPasses(Passes.PostAllocationPasses)) 127 return deallocateAndBailOut(std::move(Err)); 128 129 LLVM_DEBUG({ 130 dbgs() << "Link graph \"" << G->getName() << "\" before copy-and-fixup:\n"; 131 dumpGraph(dbgs()); 132 }); 133 134 // Fix up block content. 135 if (auto Err = fixUpBlocks(*G)) 136 return deallocateAndBailOut(std::move(Err)); 137 138 LLVM_DEBUG({ 139 dbgs() << "Link graph \"" << G->getName() << "\" after copy-and-fixup:\n"; 140 dumpGraph(dbgs()); 141 }); 142 143 if (auto Err = runPasses(Passes.PostFixupPasses)) 144 return deallocateAndBailOut(std::move(Err)); 145 146 // FIXME: Use move capture once we have c++14. 147 auto *UnownedSelf = Self.release(); 148 auto Phase3Continuation = [UnownedSelf](Error Err) { 149 std::unique_ptr<JITLinkerBase> Self(UnownedSelf); 150 UnownedSelf->linkPhase3(std::move(Self), std::move(Err)); 151 }; 152 153 Alloc->finalizeAsync(std::move(Phase3Continuation)); 154 } 155 156 void JITLinkerBase::linkPhase3(std::unique_ptr<JITLinkerBase> Self, Error Err) { 157 158 LLVM_DEBUG({ 159 dbgs() << "Starting link phase 3 for graph " << G->getName() << "\n"; 160 }); 161 162 if (Err) 163 return deallocateAndBailOut(std::move(Err)); 164 Ctx->notifyFinalized(std::move(Alloc)); 165 166 LLVM_DEBUG({ dbgs() << "Link of graph " << G->getName() << " complete\n"; }); 167 } 168 169 Error JITLinkerBase::runPasses(LinkGraphPassList &Passes) { 170 for (auto &P : Passes) 171 if (auto Err = P(*G)) 172 return Err; 173 return Error::success(); 174 } 175 176 JITLinkerBase::SegmentLayoutMap JITLinkerBase::layOutBlocks() { 177 178 SegmentLayoutMap Layout; 179 180 /// Partition blocks based on permissions and content vs. zero-fill. 181 for (auto *B : G->blocks()) { 182 auto &SegLists = Layout[B->getSection().getProtectionFlags()]; 183 if (!B->isZeroFill()) 184 SegLists.ContentBlocks.push_back(B); 185 else 186 SegLists.ZeroFillBlocks.push_back(B); 187 } 188 189 /// Sort blocks within each list. 190 for (auto &KV : Layout) { 191 192 auto CompareBlocks = [](const Block *LHS, const Block *RHS) { 193 // Sort by section, address and size 194 if (LHS->getSection().getOrdinal() != RHS->getSection().getOrdinal()) 195 return LHS->getSection().getOrdinal() < RHS->getSection().getOrdinal(); 196 if (LHS->getAddress() != RHS->getAddress()) 197 return LHS->getAddress() < RHS->getAddress(); 198 return LHS->getSize() < RHS->getSize(); 199 }; 200 201 auto &SegLists = KV.second; 202 llvm::sort(SegLists.ContentBlocks, CompareBlocks); 203 llvm::sort(SegLists.ZeroFillBlocks, CompareBlocks); 204 } 205 206 LLVM_DEBUG({ 207 dbgs() << "Computed segment ordering:\n"; 208 for (auto &KV : Layout) { 209 dbgs() << " Segment " 210 << static_cast<sys::Memory::ProtectionFlags>(KV.first) << ":\n"; 211 auto &SL = KV.second; 212 for (auto &SIEntry : 213 {std::make_pair(&SL.ContentBlocks, "content block"), 214 std::make_pair(&SL.ZeroFillBlocks, "zero-fill block")}) { 215 dbgs() << " " << SIEntry.second << ":\n"; 216 for (auto *B : *SIEntry.first) 217 dbgs() << " " << *B << "\n"; 218 } 219 } 220 }); 221 222 return Layout; 223 } 224 225 Error JITLinkerBase::allocateSegments(const SegmentLayoutMap &Layout) { 226 227 // Compute segment sizes and allocate memory. 228 LLVM_DEBUG(dbgs() << "JIT linker requesting: { "); 229 JITLinkMemoryManager::SegmentsRequestMap Segments; 230 for (auto &KV : Layout) { 231 auto &Prot = KV.first; 232 auto &SegLists = KV.second; 233 234 uint64_t SegAlign = 1; 235 236 // Calculate segment content size. 237 size_t SegContentSize = 0; 238 for (auto *B : SegLists.ContentBlocks) { 239 SegAlign = std::max(SegAlign, B->getAlignment()); 240 SegContentSize = alignToBlock(SegContentSize, *B); 241 SegContentSize += B->getSize(); 242 } 243 244 uint64_t SegZeroFillStart = SegContentSize; 245 uint64_t SegZeroFillEnd = SegZeroFillStart; 246 247 for (auto *B : SegLists.ZeroFillBlocks) { 248 SegAlign = std::max(SegAlign, B->getAlignment()); 249 SegZeroFillEnd = alignToBlock(SegZeroFillEnd, *B); 250 SegZeroFillEnd += B->getSize(); 251 } 252 253 Segments[Prot] = {SegAlign, SegContentSize, 254 SegZeroFillEnd - SegZeroFillStart}; 255 256 LLVM_DEBUG({ 257 dbgs() << (&KV == &*Layout.begin() ? "" : "; ") 258 << static_cast<sys::Memory::ProtectionFlags>(Prot) 259 << ": alignment = " << SegAlign 260 << ", content size = " << SegContentSize 261 << ", zero-fill size = " << (SegZeroFillEnd - SegZeroFillStart); 262 }); 263 } 264 LLVM_DEBUG(dbgs() << " }\n"); 265 266 if (auto AllocOrErr = Ctx->getMemoryManager().allocate(Segments)) 267 Alloc = std::move(*AllocOrErr); 268 else 269 return AllocOrErr.takeError(); 270 271 LLVM_DEBUG({ 272 dbgs() << "JIT linker got memory (working -> target):\n"; 273 for (auto &KV : Layout) { 274 auto Prot = static_cast<sys::Memory::ProtectionFlags>(KV.first); 275 dbgs() << " " << Prot << ": " 276 << (const void *)Alloc->getWorkingMemory(Prot).data() << " -> " 277 << formatv("{0:x16}", Alloc->getTargetMemory(Prot)) << "\n"; 278 } 279 }); 280 281 // Update block target addresses. 282 for (auto &KV : Layout) { 283 auto &Prot = KV.first; 284 auto &SL = KV.second; 285 286 JITTargetAddress NextBlockAddr = 287 Alloc->getTargetMemory(static_cast<sys::Memory::ProtectionFlags>(Prot)); 288 289 for (auto *SIList : {&SL.ContentBlocks, &SL.ZeroFillBlocks}) 290 for (auto *B : *SIList) { 291 NextBlockAddr = alignToBlock(NextBlockAddr, *B); 292 B->setAddress(NextBlockAddr); 293 NextBlockAddr += B->getSize(); 294 } 295 } 296 297 return Error::success(); 298 } 299 300 JITLinkContext::LookupMap JITLinkerBase::getExternalSymbolNames() const { 301 // Identify unresolved external symbols. 302 JITLinkContext::LookupMap UnresolvedExternals; 303 for (auto *Sym : G->external_symbols()) { 304 assert(Sym->getAddress() == 0 && 305 "External has already been assigned an address"); 306 assert(Sym->getName() != StringRef() && Sym->getName() != "" && 307 "Externals must be named"); 308 SymbolLookupFlags LookupFlags = 309 Sym->getLinkage() == Linkage::Weak 310 ? SymbolLookupFlags::WeaklyReferencedSymbol 311 : SymbolLookupFlags::RequiredSymbol; 312 UnresolvedExternals[Sym->getName()] = LookupFlags; 313 } 314 return UnresolvedExternals; 315 } 316 317 void JITLinkerBase::applyLookupResult(AsyncLookupResult Result) { 318 for (auto *Sym : G->external_symbols()) { 319 assert(Sym->getOffset() == 0 && 320 "External symbol is not at the start of its addressable block"); 321 assert(Sym->getAddress() == 0 && "Symbol already resolved"); 322 assert(!Sym->isDefined() && "Symbol being resolved is already defined"); 323 auto ResultI = Result.find(Sym->getName()); 324 if (ResultI != Result.end()) 325 Sym->getAddressable().setAddress(ResultI->second.getAddress()); 326 else 327 assert(Sym->getLinkage() == Linkage::Weak && 328 "Failed to resolve non-weak reference"); 329 } 330 331 LLVM_DEBUG({ 332 dbgs() << "Externals after applying lookup result:\n"; 333 for (auto *Sym : G->external_symbols()) 334 dbgs() << " " << Sym->getName() << ": " 335 << formatv("{0:x16}", Sym->getAddress()) << "\n"; 336 }); 337 assert(llvm::all_of(G->external_symbols(), 338 [](Symbol *Sym) { 339 return Sym->getAddress() != 0 || 340 Sym->getLinkage() == Linkage::Weak; 341 }) && 342 "All strong external symbols should have been resolved by now"); 343 } 344 345 void JITLinkerBase::copyBlockContentToWorkingMemory( 346 const SegmentLayoutMap &Layout, JITLinkMemoryManager::Allocation &Alloc) { 347 348 LLVM_DEBUG(dbgs() << "Copying block content:\n"); 349 for (auto &KV : Layout) { 350 auto &Prot = KV.first; 351 auto &SegLayout = KV.second; 352 353 auto SegMem = 354 Alloc.getWorkingMemory(static_cast<sys::Memory::ProtectionFlags>(Prot)); 355 char *LastBlockEnd = SegMem.data(); 356 char *BlockDataPtr = LastBlockEnd; 357 358 LLVM_DEBUG({ 359 dbgs() << " Processing segment " 360 << static_cast<sys::Memory::ProtectionFlags>(Prot) << " [ " 361 << (const void *)SegMem.data() << " .. " 362 << (const void *)((char *)SegMem.data() + SegMem.size()) 363 << " ]\n Processing content sections:\n"; 364 }); 365 366 for (auto *B : SegLayout.ContentBlocks) { 367 LLVM_DEBUG(dbgs() << " " << *B << ":\n"); 368 369 // Pad to alignment/alignment-offset. 370 BlockDataPtr = alignToBlock(BlockDataPtr, *B); 371 372 LLVM_DEBUG({ 373 dbgs() << " Bumped block pointer to " << (const void *)BlockDataPtr 374 << " to meet block alignment " << B->getAlignment() 375 << " and alignment offset " << B->getAlignmentOffset() << "\n"; 376 }); 377 378 // Zero pad up to alignment. 379 LLVM_DEBUG({ 380 if (LastBlockEnd != BlockDataPtr) 381 dbgs() << " Zero padding from " << (const void *)LastBlockEnd 382 << " to " << (const void *)BlockDataPtr << "\n"; 383 }); 384 385 while (LastBlockEnd != BlockDataPtr) 386 *LastBlockEnd++ = 0; 387 388 // Copy initial block content. 389 LLVM_DEBUG({ 390 dbgs() << " Copying block " << *B << " content, " 391 << B->getContent().size() << " bytes, from " 392 << (const void *)B->getContent().data() << " to " 393 << (const void *)BlockDataPtr << "\n"; 394 }); 395 memcpy(BlockDataPtr, B->getContent().data(), B->getContent().size()); 396 397 // Point the block's content to the fixed up buffer. 398 B->setContent(StringRef(BlockDataPtr, B->getContent().size())); 399 400 // Update block end pointer. 401 LastBlockEnd = BlockDataPtr + B->getContent().size(); 402 BlockDataPtr = LastBlockEnd; 403 } 404 405 // Zero pad the rest of the segment. 406 LLVM_DEBUG({ 407 dbgs() << " Zero padding end of segment from " 408 << (const void *)LastBlockEnd << " to " 409 << (const void *)((char *)SegMem.data() + SegMem.size()) << "\n"; 410 }); 411 while (LastBlockEnd != SegMem.data() + SegMem.size()) 412 *LastBlockEnd++ = 0; 413 } 414 } 415 416 void JITLinkerBase::deallocateAndBailOut(Error Err) { 417 assert(Err && "Should not be bailing out on success value"); 418 assert(Alloc && "can not call deallocateAndBailOut before allocation"); 419 Ctx->notifyFailed(joinErrors(std::move(Err), Alloc->deallocate())); 420 } 421 422 void JITLinkerBase::dumpGraph(raw_ostream &OS) { 423 assert(G && "Graph is not set yet"); 424 G->dump(dbgs(), [this](Edge::Kind K) { return getEdgeKindName(K); }); 425 } 426 427 void prune(LinkGraph &G) { 428 std::vector<Symbol *> Worklist; 429 DenseSet<Block *> VisitedBlocks; 430 431 // Build the initial worklist from all symbols initially live. 432 for (auto *Sym : G.defined_symbols()) 433 if (Sym->isLive()) 434 Worklist.push_back(Sym); 435 436 // Propagate live flags to all symbols reachable from the initial live set. 437 while (!Worklist.empty()) { 438 auto *Sym = Worklist.back(); 439 Worklist.pop_back(); 440 441 auto &B = Sym->getBlock(); 442 443 // Skip addressables that we've visited before. 444 if (VisitedBlocks.count(&B)) 445 continue; 446 447 VisitedBlocks.insert(&B); 448 449 for (auto &E : Sym->getBlock().edges()) { 450 if (E.getTarget().isDefined() && !E.getTarget().isLive()) { 451 E.getTarget().setLive(true); 452 Worklist.push_back(&E.getTarget()); 453 } 454 } 455 } 456 457 // Collect all the symbols to remove, then remove them. 458 { 459 LLVM_DEBUG(dbgs() << "Dead-stripping symbols:\n"); 460 std::vector<Symbol *> SymbolsToRemove; 461 for (auto *Sym : G.defined_symbols()) 462 if (!Sym->isLive()) 463 SymbolsToRemove.push_back(Sym); 464 for (auto *Sym : SymbolsToRemove) { 465 LLVM_DEBUG(dbgs() << " " << *Sym << "...\n"); 466 G.removeDefinedSymbol(*Sym); 467 } 468 } 469 470 // Delete any unused blocks. 471 { 472 LLVM_DEBUG(dbgs() << "Dead-stripping blocks:\n"); 473 std::vector<Block *> BlocksToRemove; 474 for (auto *B : G.blocks()) 475 if (!VisitedBlocks.count(B)) 476 BlocksToRemove.push_back(B); 477 for (auto *B : BlocksToRemove) { 478 LLVM_DEBUG(dbgs() << " " << *B << "...\n"); 479 G.removeBlock(*B); 480 } 481 } 482 } 483 484 } // end namespace jitlink 485 } // end namespace llvm 486