1 //===-------- JITLink_EHFrameSupport.cpp - JITLink eh-frame utils ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "EHFrameSupportImpl.h" 11 12 #include "llvm/BinaryFormat/Dwarf.h" 13 #include "llvm/Support/DynamicLibrary.h" 14 15 #define DEBUG_TYPE "jitlink" 16 17 namespace llvm { 18 namespace jitlink { 19 20 EHFrameSplitter::EHFrameSplitter(StringRef EHFrameSectionName) 21 : EHFrameSectionName(EHFrameSectionName) {} 22 23 Error EHFrameSplitter::operator()(LinkGraph &G) { 24 auto *EHFrame = G.findSectionByName(EHFrameSectionName); 25 26 if (!EHFrame) { 27 LLVM_DEBUG({ 28 dbgs() << "EHFrameSplitter: No " << EHFrameSectionName 29 << " section. Nothing to do\n"; 30 }); 31 return Error::success(); 32 } 33 34 LLVM_DEBUG({ 35 dbgs() << "EHFrameSplitter: Processing " << EHFrameSectionName << "...\n"; 36 }); 37 38 DenseMap<Block *, LinkGraph::SplitBlockCache> Caches; 39 40 { 41 // Pre-build the split caches. 42 for (auto *B : EHFrame->blocks()) 43 Caches[B] = LinkGraph::SplitBlockCache::value_type(); 44 for (auto *Sym : EHFrame->symbols()) 45 Caches[&Sym->getBlock()]->push_back(Sym); 46 for (auto *B : EHFrame->blocks()) 47 llvm::sort(*Caches[B], [](const Symbol *LHS, const Symbol *RHS) { 48 return LHS->getOffset() > RHS->getOffset(); 49 }); 50 } 51 52 // Iterate over blocks (we do this by iterating over Caches entries rather 53 // than EHFrame->blocks() as we will be inserting new blocks along the way, 54 // which would invalidate iterators in the latter sequence. 55 for (auto &KV : Caches) { 56 auto &B = *KV.first; 57 auto &BCache = KV.second; 58 if (auto Err = processBlock(G, B, BCache)) 59 return Err; 60 } 61 62 return Error::success(); 63 } 64 65 Error EHFrameSplitter::processBlock(LinkGraph &G, Block &B, 66 LinkGraph::SplitBlockCache &Cache) { 67 LLVM_DEBUG({ 68 dbgs() << " Processing block at " << formatv("{0:x16}", B.getAddress()) 69 << "\n"; 70 }); 71 72 // eh-frame should not contain zero-fill blocks. 73 if (B.isZeroFill()) 74 return make_error<JITLinkError>("Unexpected zero-fill block in " + 75 EHFrameSectionName + " section"); 76 77 if (B.getSize() == 0) { 78 LLVM_DEBUG(dbgs() << " Block is empty. Skipping.\n"); 79 return Error::success(); 80 } 81 82 BinaryStreamReader BlockReader(B.getContent(), G.getEndianness()); 83 84 while (true) { 85 uint64_t RecordStartOffset = BlockReader.getOffset(); 86 87 LLVM_DEBUG({ 88 dbgs() << " Processing CFI record at " 89 << formatv("{0:x16}", B.getAddress()) << "\n"; 90 }); 91 92 uint32_t Length; 93 if (auto Err = BlockReader.readInteger(Length)) 94 return Err; 95 if (Length != 0xffffffff) { 96 if (auto Err = BlockReader.skip(Length)) 97 return Err; 98 } else { 99 uint64_t ExtendedLength; 100 if (auto Err = BlockReader.readInteger(ExtendedLength)) 101 return Err; 102 if (auto Err = BlockReader.skip(ExtendedLength)) 103 return Err; 104 } 105 106 // If this was the last block then there's nothing to split 107 if (BlockReader.empty()) { 108 LLVM_DEBUG(dbgs() << " Extracted " << B << "\n"); 109 return Error::success(); 110 } 111 112 uint64_t BlockSize = BlockReader.getOffset() - RecordStartOffset; 113 auto &NewBlock = G.splitBlock(B, BlockSize); 114 (void)NewBlock; 115 LLVM_DEBUG(dbgs() << " Extracted " << NewBlock << "\n"); 116 } 117 } 118 119 EHFrameEdgeFixer::EHFrameEdgeFixer(StringRef EHFrameSectionName, 120 Edge::Kind FDEToCIE, Edge::Kind FDEToPCBegin, 121 Edge::Kind FDEToLSDA) 122 : EHFrameSectionName(EHFrameSectionName), FDEToCIE(FDEToCIE), 123 FDEToPCBegin(FDEToPCBegin), FDEToLSDA(FDEToLSDA) {} 124 125 Error EHFrameEdgeFixer::operator()(LinkGraph &G) { 126 auto *EHFrame = G.findSectionByName(EHFrameSectionName); 127 128 if (!EHFrame) { 129 LLVM_DEBUG({ 130 dbgs() << "EHFrameEdgeFixer: No " << EHFrameSectionName 131 << " section. Nothing to do\n"; 132 }); 133 return Error::success(); 134 } 135 136 LLVM_DEBUG({ 137 dbgs() << "EHFrameEdgeFixer: Processing " << EHFrameSectionName << "...\n"; 138 }); 139 140 ParseContext PC(G); 141 142 // Build a map of all blocks and symbols in the text sections. We will use 143 // these for finding / building edge targets when processing FDEs. 144 for (auto &Sec : G.sections()) { 145 PC.AddrToSyms.addSymbols(Sec.symbols()); 146 if (auto Err = PC.AddrToBlock.addBlocks(Sec.blocks(), 147 BlockAddressMap::includeNonNull)) 148 return Err; 149 } 150 151 // Sort eh-frame blocks into address order to ensure we visit CIEs before 152 // their child FDEs. 153 std::vector<Block *> EHFrameBlocks; 154 for (auto *B : EHFrame->blocks()) 155 EHFrameBlocks.push_back(B); 156 llvm::sort(EHFrameBlocks, [](const Block *LHS, const Block *RHS) { 157 return LHS->getAddress() < RHS->getAddress(); 158 }); 159 160 // Loop over the blocks in address order. 161 for (auto *B : EHFrameBlocks) 162 if (auto Err = processBlock(PC, *B)) 163 return Err; 164 165 return Error::success(); 166 } 167 168 Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) { 169 170 LLVM_DEBUG({ 171 dbgs() << " Processing block at " << formatv("{0:x16}", B.getAddress()) 172 << "\n"; 173 }); 174 175 // eh-frame should not contain zero-fill blocks. 176 if (B.isZeroFill()) 177 return make_error<JITLinkError>("Unexpected zero-fill block in " + 178 EHFrameSectionName + " section"); 179 180 if (B.getSize() == 0) { 181 LLVM_DEBUG(dbgs() << " Block is empty. Skipping.\n"); 182 return Error::success(); 183 } 184 185 // Find the offsets of any existing edges from this block. 186 BlockEdgeMap BlockEdges; 187 for (auto &E : B.edges()) 188 if (E.isRelocation()) { 189 if (BlockEdges.count(E.getOffset())) 190 return make_error<JITLinkError>( 191 "Multiple relocations at offset " + 192 formatv("{0:x16}", E.getOffset()) + " in " + EHFrameSectionName + 193 " block at address " + formatv("{0:x16}", B.getAddress())); 194 195 BlockEdges[E.getOffset()] = EdgeTarget(E); 196 } 197 198 CIEInfosMap CIEInfos; 199 BinaryStreamReader BlockReader(B.getContent(), PC.G.getEndianness()); 200 while (!BlockReader.empty()) { 201 size_t RecordStartOffset = BlockReader.getOffset(); 202 203 LLVM_DEBUG({ 204 dbgs() << " Processing CFI record at " 205 << formatv("{0:x16}", B.getAddress() + RecordStartOffset) << "\n"; 206 }); 207 208 // Get the record length. 209 size_t RecordRemaining; 210 { 211 uint32_t Length; 212 if (auto Err = BlockReader.readInteger(Length)) 213 return Err; 214 // If Length < 0xffffffff then use the regular length field, otherwise 215 // read the extended length field. 216 if (Length != 0xffffffff) 217 RecordRemaining = Length; 218 else { 219 uint64_t ExtendedLength; 220 if (auto Err = BlockReader.readInteger(ExtendedLength)) 221 return Err; 222 RecordRemaining = ExtendedLength; 223 } 224 } 225 226 if (BlockReader.bytesRemaining() < RecordRemaining) 227 return make_error<JITLinkError>( 228 "Incomplete CFI record at " + 229 formatv("{0:x16}", B.getAddress() + RecordStartOffset)); 230 231 // Read the CIE delta for this record. 232 uint64_t CIEDeltaFieldOffset = BlockReader.getOffset() - RecordStartOffset; 233 uint32_t CIEDelta; 234 if (auto Err = BlockReader.readInteger(CIEDelta)) 235 return Err; 236 237 if (CIEDelta == 0) { 238 if (auto Err = processCIE(PC, B, RecordStartOffset, 239 CIEDeltaFieldOffset + RecordRemaining, 240 CIEDeltaFieldOffset)) 241 return Err; 242 } else { 243 if (auto Err = processFDE(PC, B, RecordStartOffset, 244 CIEDeltaFieldOffset + RecordRemaining, 245 CIEDeltaFieldOffset, CIEDelta, BlockEdges)) 246 return Err; 247 } 248 249 // Move to the next record. 250 BlockReader.setOffset(RecordStartOffset + CIEDeltaFieldOffset + 251 RecordRemaining); 252 } 253 254 return Error::success(); 255 } 256 257 Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B, 258 size_t RecordOffset, size_t RecordLength, 259 size_t CIEDeltaFieldOffset) { 260 using namespace dwarf; 261 262 LLVM_DEBUG(dbgs() << " Record is CIE\n"); 263 264 auto RecordContent = B.getContent().substr(RecordOffset, RecordLength); 265 BinaryStreamReader RecordReader(RecordContent, PC.G.getEndianness()); 266 267 // Skip past the CIE delta field: we've already processed this far. 268 RecordReader.setOffset(CIEDeltaFieldOffset + 4); 269 270 auto &CIESymbol = 271 PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false); 272 CIEInformation CIEInfo(CIESymbol); 273 274 uint8_t Version = 0; 275 if (auto Err = RecordReader.readInteger(Version)) 276 return Err; 277 278 if (Version != 0x01) 279 return make_error<JITLinkError>("Bad CIE version " + Twine(Version) + 280 " (should be 0x01) in eh-frame"); 281 282 auto AugInfo = parseAugmentationString(RecordReader); 283 if (!AugInfo) 284 return AugInfo.takeError(); 285 286 // Skip the EH Data field if present. 287 if (AugInfo->EHDataFieldPresent) 288 if (auto Err = RecordReader.skip(PC.G.getPointerSize())) 289 return Err; 290 291 // Read and sanity check the code alignment factor. 292 { 293 uint64_t CodeAlignmentFactor = 0; 294 if (auto Err = RecordReader.readULEB128(CodeAlignmentFactor)) 295 return Err; 296 if (CodeAlignmentFactor != 1) 297 return make_error<JITLinkError>("Unsupported CIE code alignment factor " + 298 Twine(CodeAlignmentFactor) + 299 " (expected 1)"); 300 } 301 302 // Read and sanity check the data alignment factor. 303 { 304 int64_t DataAlignmentFactor = 0; 305 if (auto Err = RecordReader.readSLEB128(DataAlignmentFactor)) 306 return Err; 307 if (DataAlignmentFactor != -8) 308 return make_error<JITLinkError>("Unsupported CIE data alignment factor " + 309 Twine(DataAlignmentFactor) + 310 " (expected -8)"); 311 } 312 313 // Skip the return address register field. 314 if (auto Err = RecordReader.skip(1)) 315 return Err; 316 317 uint64_t AugmentationDataLength = 0; 318 if (auto Err = RecordReader.readULEB128(AugmentationDataLength)) 319 return Err; 320 321 uint32_t AugmentationDataStartOffset = RecordReader.getOffset(); 322 323 uint8_t *NextField = &AugInfo->Fields[0]; 324 while (uint8_t Field = *NextField++) { 325 switch (Field) { 326 case 'L': { 327 CIEInfo.FDEsHaveLSDAField = true; 328 uint8_t LSDAPointerEncoding; 329 if (auto Err = RecordReader.readInteger(LSDAPointerEncoding)) 330 return Err; 331 if (LSDAPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr)) 332 return make_error<JITLinkError>( 333 "Unsupported LSDA pointer encoding " + 334 formatv("{0:x2}", LSDAPointerEncoding) + " in CIE at " + 335 formatv("{0:x16}", CIESymbol.getAddress())); 336 break; 337 } 338 case 'P': { 339 uint8_t PersonalityPointerEncoding = 0; 340 if (auto Err = RecordReader.readInteger(PersonalityPointerEncoding)) 341 return Err; 342 if (PersonalityPointerEncoding != 343 (DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4)) 344 return make_error<JITLinkError>( 345 "Unspported personality pointer " 346 "encoding " + 347 formatv("{0:x2}", PersonalityPointerEncoding) + " in CIE at " + 348 formatv("{0:x16}", CIESymbol.getAddress())); 349 uint32_t PersonalityPointerAddress; 350 if (auto Err = RecordReader.readInteger(PersonalityPointerAddress)) 351 return Err; 352 break; 353 } 354 case 'R': { 355 uint8_t FDEPointerEncoding; 356 if (auto Err = RecordReader.readInteger(FDEPointerEncoding)) 357 return Err; 358 if (FDEPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr)) 359 return make_error<JITLinkError>( 360 "Unsupported FDE address pointer " 361 "encoding " + 362 formatv("{0:x2}", FDEPointerEncoding) + " in CIE at " + 363 formatv("{0:x16}", CIESymbol.getAddress())); 364 break; 365 } 366 default: 367 llvm_unreachable("Invalid augmentation string field"); 368 } 369 } 370 371 if (RecordReader.getOffset() - AugmentationDataStartOffset > 372 AugmentationDataLength) 373 return make_error<JITLinkError>("Read past the end of the augmentation " 374 "data while parsing fields"); 375 376 assert(!PC.CIEInfos.count(CIESymbol.getAddress()) && 377 "Multiple CIEs recorded at the same address?"); 378 PC.CIEInfos[CIESymbol.getAddress()] = std::move(CIEInfo); 379 380 return Error::success(); 381 } 382 383 Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B, 384 size_t RecordOffset, size_t RecordLength, 385 size_t CIEDeltaFieldOffset, 386 uint32_t CIEDelta, 387 BlockEdgeMap &BlockEdges) { 388 LLVM_DEBUG(dbgs() << " Record is FDE\n"); 389 390 JITTargetAddress RecordAddress = B.getAddress() + RecordOffset; 391 392 auto RecordContent = B.getContent().substr(RecordOffset, RecordLength); 393 BinaryStreamReader RecordReader(RecordContent, PC.G.getEndianness()); 394 395 // Skip past the CIE delta field: we've already read this far. 396 RecordReader.setOffset(CIEDeltaFieldOffset + 4); 397 398 auto &FDESymbol = 399 PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false); 400 401 CIEInformation *CIEInfo = nullptr; 402 403 { 404 // Process the CIE pointer field. 405 auto CIEEdgeItr = BlockEdges.find(RecordOffset + CIEDeltaFieldOffset); 406 JITTargetAddress CIEAddress = 407 RecordAddress + CIEDeltaFieldOffset - CIEDelta; 408 if (CIEEdgeItr == BlockEdges.end()) { 409 410 LLVM_DEBUG({ 411 dbgs() << " Adding edge at " 412 << formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset) 413 << " to CIE at: " << formatv("{0:x16}", CIEAddress) << "\n"; 414 }); 415 if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress)) 416 CIEInfo = *CIEInfoOrErr; 417 else 418 return CIEInfoOrErr.takeError(); 419 assert(CIEInfo->CIESymbol && "CIEInfo has no CIE symbol set"); 420 B.addEdge(FDEToCIE, RecordOffset + CIEDeltaFieldOffset, 421 *CIEInfo->CIESymbol, 0); 422 } else { 423 LLVM_DEBUG({ 424 dbgs() << " Already has edge at " 425 << formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset) 426 << " to CIE at " << formatv("{0:x16}", CIEAddress) << "\n"; 427 }); 428 auto &EI = CIEEdgeItr->second; 429 if (EI.Addend) 430 return make_error<JITLinkError>( 431 "CIE edge at " + 432 formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset) + 433 " has non-zero addend"); 434 if (auto CIEInfoOrErr = PC.findCIEInfo(EI.Target->getAddress())) 435 CIEInfo = *CIEInfoOrErr; 436 else 437 return CIEInfoOrErr.takeError(); 438 } 439 } 440 441 { 442 // Process the PC-Begin field. 443 Block *PCBeginBlock = nullptr; 444 JITTargetAddress PCBeginFieldOffset = RecordReader.getOffset(); 445 auto PCEdgeItr = BlockEdges.find(RecordOffset + PCBeginFieldOffset); 446 if (PCEdgeItr == BlockEdges.end()) { 447 auto PCBeginDelta = readAbsolutePointer(PC.G, RecordReader); 448 if (!PCBeginDelta) 449 return PCBeginDelta.takeError(); 450 JITTargetAddress PCBegin = 451 RecordAddress + PCBeginFieldOffset + *PCBeginDelta; 452 LLVM_DEBUG({ 453 dbgs() << " Adding edge at " 454 << formatv("{0:x16}", RecordAddress + PCBeginFieldOffset) 455 << " to PC at " << formatv("{0:x16}", PCBegin) << "\n"; 456 }); 457 auto PCBeginSym = getOrCreateSymbol(PC, PCBegin); 458 if (!PCBeginSym) 459 return PCBeginSym.takeError(); 460 B.addEdge(FDEToPCBegin, RecordOffset + PCBeginFieldOffset, *PCBeginSym, 461 0); 462 PCBeginBlock = &PCBeginSym->getBlock(); 463 } else { 464 auto &EI = PCEdgeItr->second; 465 LLVM_DEBUG({ 466 dbgs() << " Already has edge at " 467 << formatv("{0:x16}", RecordAddress + PCBeginFieldOffset) 468 << " to PC at " << formatv("{0:x16}", EI.Target->getAddress()); 469 if (EI.Addend) 470 dbgs() << " + " << formatv("{0:x16}", EI.Addend); 471 dbgs() << "\n"; 472 }); 473 474 // Make sure the existing edge points at a defined block. 475 if (!EI.Target->isDefined()) { 476 auto EdgeAddr = RecordAddress + PCBeginFieldOffset; 477 return make_error<JITLinkError>("FDE edge at " + 478 formatv("{0:x16}", EdgeAddr) + 479 " points at external block"); 480 } 481 PCBeginBlock = &EI.Target->getBlock(); 482 if (auto Err = RecordReader.skip(PC.G.getPointerSize())) 483 return Err; 484 } 485 486 // Add a keep-alive edge from the FDE target to the FDE to ensure that the 487 // FDE is kept alive if its target is. 488 assert(PCBeginBlock && "PC-begin block not recorded"); 489 PCBeginBlock->addEdge(Edge::KeepAlive, 0, FDESymbol, 0); 490 } 491 492 // Skip over the PC range size field. 493 if (auto Err = RecordReader.skip(PC.G.getPointerSize())) 494 return Err; 495 496 if (CIEInfo->FDEsHaveLSDAField) { 497 uint64_t AugmentationDataSize; 498 if (auto Err = RecordReader.readULEB128(AugmentationDataSize)) 499 return Err; 500 if (AugmentationDataSize != PC.G.getPointerSize()) 501 return make_error<JITLinkError>( 502 "Unexpected FDE augmentation data size (expected " + 503 Twine(PC.G.getPointerSize()) + ", got " + 504 Twine(AugmentationDataSize) + ") for FDE at " + 505 formatv("{0:x16}", RecordAddress)); 506 507 JITTargetAddress LSDAFieldOffset = RecordReader.getOffset(); 508 auto LSDAEdgeItr = BlockEdges.find(RecordOffset + LSDAFieldOffset); 509 if (LSDAEdgeItr == BlockEdges.end()) { 510 auto LSDADelta = readAbsolutePointer(PC.G, RecordReader); 511 if (!LSDADelta) 512 return LSDADelta.takeError(); 513 JITTargetAddress LSDA = RecordAddress + LSDAFieldOffset + *LSDADelta; 514 auto LSDASym = getOrCreateSymbol(PC, LSDA); 515 if (!LSDASym) 516 return LSDASym.takeError(); 517 LLVM_DEBUG({ 518 dbgs() << " Adding edge at " 519 << formatv("{0:x16}", RecordAddress + LSDAFieldOffset) 520 << " to LSDA at " << formatv("{0:x16}", LSDA) << "\n"; 521 }); 522 B.addEdge(FDEToLSDA, RecordOffset + LSDAFieldOffset, *LSDASym, 0); 523 } else { 524 LLVM_DEBUG({ 525 auto &EI = LSDAEdgeItr->second; 526 dbgs() << " Already has edge at " 527 << formatv("{0:x16}", RecordAddress + LSDAFieldOffset) 528 << " to LSDA at " << formatv("{0:x16}", EI.Target->getAddress()); 529 if (EI.Addend) 530 dbgs() << " + " << formatv("{0:x16}", EI.Addend); 531 dbgs() << "\n"; 532 }); 533 if (auto Err = RecordReader.skip(PC.G.getPointerSize())) 534 return Err; 535 } 536 } else { 537 LLVM_DEBUG(dbgs() << " Record does not have LSDA field.\n"); 538 } 539 540 return Error::success(); 541 } 542 543 Expected<EHFrameEdgeFixer::AugmentationInfo> 544 EHFrameEdgeFixer::parseAugmentationString(BinaryStreamReader &RecordReader) { 545 AugmentationInfo AugInfo; 546 uint8_t NextChar; 547 uint8_t *NextField = &AugInfo.Fields[0]; 548 549 if (auto Err = RecordReader.readInteger(NextChar)) 550 return std::move(Err); 551 552 while (NextChar != 0) { 553 switch (NextChar) { 554 case 'z': 555 AugInfo.AugmentationDataPresent = true; 556 break; 557 case 'e': 558 if (auto Err = RecordReader.readInteger(NextChar)) 559 return std::move(Err); 560 if (NextChar != 'h') 561 return make_error<JITLinkError>("Unrecognized substring e" + 562 Twine(NextChar) + 563 " in augmentation string"); 564 AugInfo.EHDataFieldPresent = true; 565 break; 566 case 'L': 567 case 'P': 568 case 'R': 569 *NextField++ = NextChar; 570 break; 571 default: 572 return make_error<JITLinkError>("Unrecognized character " + 573 Twine(NextChar) + 574 " in augmentation string"); 575 } 576 577 if (auto Err = RecordReader.readInteger(NextChar)) 578 return std::move(Err); 579 } 580 581 return std::move(AugInfo); 582 } 583 584 Expected<JITTargetAddress> 585 EHFrameEdgeFixer::readAbsolutePointer(LinkGraph &G, 586 BinaryStreamReader &RecordReader) { 587 static_assert(sizeof(JITTargetAddress) == sizeof(uint64_t), 588 "Result must be able to hold a uint64_t"); 589 JITTargetAddress Addr; 590 if (G.getPointerSize() == 8) { 591 if (auto Err = RecordReader.readInteger(Addr)) 592 return std::move(Err); 593 } else if (G.getPointerSize() == 4) { 594 uint32_t Addr32; 595 if (auto Err = RecordReader.readInteger(Addr32)) 596 return std::move(Err); 597 Addr = Addr32; 598 } else 599 llvm_unreachable("Pointer size is not 32-bit or 64-bit"); 600 return Addr; 601 } 602 603 Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC, 604 JITTargetAddress Addr) { 605 Symbol *CanonicalSym = nullptr; 606 607 auto UpdateCanonicalSym = [&](Symbol *Sym) { 608 if (!CanonicalSym || Sym->getLinkage() < CanonicalSym->getLinkage() || 609 Sym->getScope() < CanonicalSym->getScope() || 610 (Sym->hasName() && !CanonicalSym->hasName()) || 611 Sym->getName() < CanonicalSym->getName()) 612 CanonicalSym = Sym; 613 }; 614 615 if (auto *SymbolsAtAddr = PC.AddrToSyms.getSymbolsAt(Addr)) 616 for (auto *Sym : *SymbolsAtAddr) 617 UpdateCanonicalSym(Sym); 618 619 // If we found an existing symbol at the given address then use it. 620 if (CanonicalSym) 621 return *CanonicalSym; 622 623 // Otherwise search for a block covering the address and create a new symbol. 624 auto *B = PC.AddrToBlock.getBlockCovering(Addr); 625 if (!B) 626 return make_error<JITLinkError>("No symbol or block covering address " + 627 formatv("{0:x16}", Addr)); 628 629 return PC.G.addAnonymousSymbol(*B, Addr - B->getAddress(), 0, false, false); 630 } 631 632 // Determine whether we can register EH tables. 633 #if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) && \ 634 !(defined(_AIX) && defined(__ibmxl__)) && !defined(__SEH__) && \ 635 !defined(__USING_SJLJ_EXCEPTIONS__)) 636 #define HAVE_EHTABLE_SUPPORT 1 637 #else 638 #define HAVE_EHTABLE_SUPPORT 0 639 #endif 640 641 #if HAVE_EHTABLE_SUPPORT 642 extern "C" void __register_frame(const void *); 643 extern "C" void __deregister_frame(const void *); 644 645 Error registerFrameWrapper(const void *P) { 646 __register_frame(P); 647 return Error::success(); 648 } 649 650 Error deregisterFrameWrapper(const void *P) { 651 __deregister_frame(P); 652 return Error::success(); 653 } 654 655 #else 656 657 // The building compiler does not have __(de)register_frame but 658 // it may be found at runtime in a dynamically-loaded library. 659 // For example, this happens when building LLVM with Visual C++ 660 // but using the MingW runtime. 661 static Error registerFrameWrapper(const void *P) { 662 static void((*RegisterFrame)(const void *)) = 0; 663 664 if (!RegisterFrame) 665 *(void **)&RegisterFrame = 666 llvm::sys::DynamicLibrary::SearchForAddressOfSymbol("__register_frame"); 667 668 if (RegisterFrame) { 669 RegisterFrame(P); 670 return Error::success(); 671 } 672 673 return make_error<JITLinkError>("could not register eh-frame: " 674 "__register_frame function not found"); 675 } 676 677 static Error deregisterFrameWrapper(const void *P) { 678 static void((*DeregisterFrame)(const void *)) = 0; 679 680 if (!DeregisterFrame) 681 *(void **)&DeregisterFrame = 682 llvm::sys::DynamicLibrary::SearchForAddressOfSymbol( 683 "__deregister_frame"); 684 685 if (DeregisterFrame) { 686 DeregisterFrame(P); 687 return Error::success(); 688 } 689 690 return make_error<JITLinkError>("could not deregister eh-frame: " 691 "__deregister_frame function not found"); 692 } 693 #endif 694 695 #ifdef __APPLE__ 696 697 template <typename HandleFDEFn> 698 Error walkAppleEHFrameSection(const char *const SectionStart, 699 size_t SectionSize, 700 HandleFDEFn HandleFDE) { 701 const char *CurCFIRecord = SectionStart; 702 const char *End = SectionStart + SectionSize; 703 uint64_t Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord); 704 705 while (CurCFIRecord != End && Size != 0) { 706 const char *OffsetField = CurCFIRecord + (Size == 0xffffffff ? 12 : 4); 707 if (Size == 0xffffffff) 708 Size = *reinterpret_cast<const uint64_t *>(CurCFIRecord + 4) + 12; 709 else 710 Size += 4; 711 uint32_t Offset = *reinterpret_cast<const uint32_t *>(OffsetField); 712 713 LLVM_DEBUG({ 714 dbgs() << "Registering eh-frame section:\n"; 715 dbgs() << "Processing " << (Offset ? "FDE" : "CIE") << " @" 716 << (void *)CurCFIRecord << ": ["; 717 for (unsigned I = 0; I < Size; ++I) 718 dbgs() << format(" 0x%02" PRIx8, *(CurCFIRecord + I)); 719 dbgs() << " ]\n"; 720 }); 721 722 if (Offset != 0) 723 if (auto Err = HandleFDE(CurCFIRecord)) 724 return Err; 725 726 CurCFIRecord += Size; 727 728 Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord); 729 } 730 731 return Error::success(); 732 } 733 734 #endif // __APPLE__ 735 736 Error registerEHFrameSection(const void *EHFrameSectionAddr, 737 size_t EHFrameSectionSize) { 738 #ifdef __APPLE__ 739 // On Darwin __register_frame has to be called for each FDE entry. 740 return walkAppleEHFrameSection(static_cast<const char *>(EHFrameSectionAddr), 741 EHFrameSectionSize, 742 registerFrameWrapper); 743 #else 744 // On Linux __register_frame takes a single argument: 745 // a pointer to the start of the .eh_frame section. 746 747 // How can it find the end? Because crtendS.o is linked 748 // in and it has an .eh_frame section with four zero chars. 749 return registerFrameWrapper(EHFrameSectionAddr); 750 #endif 751 } 752 753 Error deregisterEHFrameSection(const void *EHFrameSectionAddr, 754 size_t EHFrameSectionSize) { 755 #ifdef __APPLE__ 756 return walkAppleEHFrameSection(static_cast<const char *>(EHFrameSectionAddr), 757 EHFrameSectionSize, 758 deregisterFrameWrapper); 759 #else 760 return deregisterFrameWrapper(EHFrameSectionAddr); 761 #endif 762 } 763 764 EHFrameRegistrar::~EHFrameRegistrar() {} 765 766 InProcessEHFrameRegistrar &InProcessEHFrameRegistrar::getInstance() { 767 static InProcessEHFrameRegistrar Instance; 768 return Instance; 769 } 770 771 InProcessEHFrameRegistrar::InProcessEHFrameRegistrar() {} 772 773 LinkGraphPassFunction 774 createEHFrameRecorderPass(const Triple &TT, 775 StoreFrameRangeFunction StoreRangeAddress) { 776 const char *EHFrameSectionName = nullptr; 777 if (TT.getObjectFormat() == Triple::MachO) 778 EHFrameSectionName = "__eh_frame"; 779 else 780 EHFrameSectionName = ".eh_frame"; 781 782 auto RecordEHFrame = 783 [EHFrameSectionName, 784 StoreFrameRange = std::move(StoreRangeAddress)](LinkGraph &G) -> Error { 785 // Search for a non-empty eh-frame and record the address of the first 786 // symbol in it. 787 JITTargetAddress Addr = 0; 788 size_t Size = 0; 789 if (auto *S = G.findSectionByName(EHFrameSectionName)) { 790 auto R = SectionRange(*S); 791 Addr = R.getStart(); 792 Size = R.getSize(); 793 } 794 if (Addr == 0 && Size != 0) 795 return make_error<JITLinkError>("__eh_frame section can not have zero " 796 "address with non-zero size"); 797 StoreFrameRange(Addr, Size); 798 return Error::success(); 799 }; 800 801 return RecordEHFrame; 802 } 803 804 } // end namespace jitlink 805 } // end namespace llvm 806