1 //===- bolt/Rewrite/LinuxKernelRewriter.cpp -------------------------------===// 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 // Support for updating Linux Kernel metadata. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "bolt/Core/BinaryFunction.h" 14 #include "bolt/Rewrite/MetadataRewriter.h" 15 #include "bolt/Rewrite/MetadataRewriters.h" 16 #include "bolt/Utils/CommandLineOpts.h" 17 #include "llvm/Support/BinaryStreamWriter.h" 18 #include "llvm/Support/CommandLine.h" 19 #include "llvm/Support/Debug.h" 20 #include "llvm/Support/Errc.h" 21 22 #define DEBUG_TYPE "bolt-linux" 23 24 using namespace llvm; 25 using namespace bolt; 26 27 namespace opts { 28 29 static cl::opt<bool> 30 PrintORC("print-orc", 31 cl::desc("print ORC unwind information for instructions"), 32 cl::init(true), cl::Hidden, cl::cat(BoltCategory)); 33 34 static cl::opt<bool> 35 DumpORC("dump-orc", cl::desc("dump raw ORC unwind information (sorted)"), 36 cl::init(false), cl::Hidden, cl::cat(BoltCategory)); 37 38 static cl::opt<bool> DumpStaticCalls("dump-static-calls", 39 cl::desc("dump Linux kernel static calls"), 40 cl::init(false), cl::Hidden, 41 cl::cat(BoltCategory)); 42 43 } // namespace opts 44 45 /// Linux Kernel supports stack unwinding using ORC (oops rewind capability). 46 /// ORC state at every IP can be described by the following data structure. 47 struct ORCState { 48 int16_t SPOffset; 49 int16_t BPOffset; 50 int16_t Info; 51 52 bool operator==(const ORCState &Other) const { 53 return SPOffset == Other.SPOffset && BPOffset == Other.BPOffset && 54 Info == Other.Info; 55 } 56 57 bool operator!=(const ORCState &Other) const { return !(*this == Other); } 58 }; 59 60 /// Section terminator ORC entry. 61 static ORCState NullORC = {0, 0, 0}; 62 63 /// Basic printer for ORC entry. It does not provide the same level of 64 /// information as objtool (for now). 65 inline raw_ostream &operator<<(raw_ostream &OS, const ORCState &E) { 66 if (!opts::PrintORC) 67 return OS; 68 if (E != NullORC) 69 OS << format("{sp: %d, bp: %d, info: 0x%x}", E.SPOffset, E.BPOffset, 70 E.Info); 71 else 72 OS << "{terminator}"; 73 74 return OS; 75 } 76 77 namespace { 78 79 class LinuxKernelRewriter final : public MetadataRewriter { 80 /// Linux Kernel special sections point to a specific instruction in many 81 /// cases. Unlike SDTMarkerInfo, these markers can come from different 82 /// sections. 83 struct LKInstructionMarkerInfo { 84 uint64_t SectionOffset; 85 int32_t PCRelativeOffset; 86 bool IsPCRelative; 87 StringRef SectionName; 88 }; 89 90 /// Map linux kernel program locations/instructions to their pointers in 91 /// special linux kernel sections 92 std::unordered_map<uint64_t, std::vector<LKInstructionMarkerInfo>> LKMarkers; 93 94 /// Linux ORC sections. 95 ErrorOr<BinarySection &> ORCUnwindSection = std::errc::bad_address; 96 ErrorOr<BinarySection &> ORCUnwindIPSection = std::errc::bad_address; 97 98 /// Size of entries in ORC sections. 99 static constexpr size_t ORC_UNWIND_ENTRY_SIZE = 6; 100 static constexpr size_t ORC_UNWIND_IP_ENTRY_SIZE = 4; 101 102 struct ORCListEntry { 103 uint64_t IP; /// Instruction address. 104 BinaryFunction *BF; /// Binary function corresponding to the entry. 105 ORCState ORC; /// Stack unwind info in ORC format. 106 107 /// ORC entries are sorted by their IPs. Terminator entries (NullORC) 108 /// should precede other entries with the same address. 109 bool operator<(const ORCListEntry &Other) const { 110 if (IP < Other.IP) 111 return 1; 112 if (IP > Other.IP) 113 return 0; 114 return ORC == NullORC && Other.ORC != NullORC; 115 } 116 }; 117 118 using ORCListType = std::vector<ORCListEntry>; 119 ORCListType ORCEntries; 120 121 /// Number of entries in the input file ORC sections. 122 uint64_t NumORCEntries = 0; 123 124 /// Section containing static call table. 125 ErrorOr<BinarySection &> StaticCallSection = std::errc::bad_address; 126 uint64_t StaticCallTableAddress = 0; 127 static constexpr size_t STATIC_CALL_ENTRY_SIZE = 8; 128 129 struct StaticCallInfo { 130 uint32_t ID; /// Identifier of the entry in the table. 131 BinaryFunction *Function; /// Function containing associated call. 132 MCSymbol *Label; /// Label attached to the call. 133 }; 134 using StaticCallListType = std::vector<StaticCallInfo>; 135 StaticCallListType StaticCallEntries; 136 137 /// Insert an LKMarker for a given code pointer \p PC from a non-code section 138 /// \p SectionName. 139 void insertLKMarker(uint64_t PC, uint64_t SectionOffset, 140 int32_t PCRelativeOffset, bool IsPCRelative, 141 StringRef SectionName); 142 143 /// Process linux kernel special sections and their relocations. 144 void processLKSections(); 145 146 /// Process special linux kernel section, __ex_table. 147 void processLKExTable(); 148 149 /// Process special linux kernel section, .pci_fixup. 150 void processLKPCIFixup(); 151 152 /// Process __ksymtab and __ksymtab_gpl. 153 void processLKKSymtab(bool IsGPL = false); 154 155 /// Process special linux kernel section, __bug_table. 156 void processLKBugTable(); 157 158 /// Process special linux kernel section, .smp_locks. 159 void processLKSMPLocks(); 160 161 /// Update LKMarkers' locations for the output binary. 162 void updateLKMarkers(); 163 164 /// Read ORC unwind information and annotate instructions. 165 Error readORCTables(); 166 167 /// Update ORC for functions once CFG is constructed. 168 Error processORCPostCFG(); 169 170 /// Update ORC data in the binary. 171 Error rewriteORCTables(); 172 173 /// Static call table handling. 174 Error readStaticCalls(); 175 Error rewriteStaticCalls(); 176 177 /// Mark instructions referenced by kernel metadata. 178 Error markInstructions(); 179 180 public: 181 LinuxKernelRewriter(BinaryContext &BC) 182 : MetadataRewriter("linux-kernel-rewriter", BC) {} 183 184 Error preCFGInitializer() override { 185 processLKSections(); 186 if (Error E = markInstructions()) 187 return E; 188 189 if (Error E = readORCTables()) 190 return E; 191 192 if (Error E = readStaticCalls()) 193 return E; 194 195 return Error::success(); 196 } 197 198 Error postCFGInitializer() override { 199 if (Error E = processORCPostCFG()) 200 return E; 201 202 return Error::success(); 203 } 204 205 Error preEmitFinalizer() override { 206 if (Error E = rewriteORCTables()) 207 return E; 208 209 if (Error E = rewriteStaticCalls()) 210 return E; 211 212 return Error::success(); 213 } 214 215 Error postEmitFinalizer() override { 216 updateLKMarkers(); 217 218 return Error::success(); 219 } 220 }; 221 222 Error LinuxKernelRewriter::markInstructions() { 223 for (const uint64_t PC : llvm::make_first_range(LKMarkers)) { 224 BinaryFunction *BF = BC.getBinaryFunctionContainingAddress(PC); 225 226 if (!BF || !BC.shouldEmit(*BF)) 227 continue; 228 229 const uint64_t Offset = PC - BF->getAddress(); 230 MCInst *Inst = BF->getInstructionAtOffset(Offset); 231 if (!Inst) 232 return createStringError(errc::executable_format_error, 233 "no instruction matches kernel marker offset"); 234 235 BC.MIB->setOffset(*Inst, static_cast<uint32_t>(Offset)); 236 237 BF->setHasSDTMarker(true); 238 } 239 240 return Error::success(); 241 } 242 243 void LinuxKernelRewriter::insertLKMarker(uint64_t PC, uint64_t SectionOffset, 244 int32_t PCRelativeOffset, 245 bool IsPCRelative, 246 StringRef SectionName) { 247 LKMarkers[PC].emplace_back(LKInstructionMarkerInfo{ 248 SectionOffset, PCRelativeOffset, IsPCRelative, SectionName}); 249 } 250 251 void LinuxKernelRewriter::processLKSections() { 252 processLKExTable(); 253 processLKPCIFixup(); 254 processLKKSymtab(); 255 processLKKSymtab(true); 256 processLKBugTable(); 257 processLKSMPLocks(); 258 } 259 260 /// Process __ex_table section of Linux Kernel. 261 /// This section contains information regarding kernel level exception 262 /// handling (https://www.kernel.org/doc/html/latest/x86/exception-tables.html). 263 /// More documentation is in arch/x86/include/asm/extable.h. 264 /// 265 /// The section is the list of the following structures: 266 /// 267 /// struct exception_table_entry { 268 /// int insn; 269 /// int fixup; 270 /// int handler; 271 /// }; 272 /// 273 void LinuxKernelRewriter::processLKExTable() { 274 ErrorOr<BinarySection &> SectionOrError = 275 BC.getUniqueSectionByName("__ex_table"); 276 if (!SectionOrError) 277 return; 278 279 const uint64_t SectionSize = SectionOrError->getSize(); 280 const uint64_t SectionAddress = SectionOrError->getAddress(); 281 assert((SectionSize % 12) == 0 && 282 "The size of the __ex_table section should be a multiple of 12"); 283 for (uint64_t I = 0; I < SectionSize; I += 4) { 284 const uint64_t EntryAddress = SectionAddress + I; 285 ErrorOr<uint64_t> Offset = BC.getSignedValueAtAddress(EntryAddress, 4); 286 assert(Offset && "failed reading PC-relative offset for __ex_table"); 287 int32_t SignedOffset = *Offset; 288 const uint64_t RefAddress = EntryAddress + SignedOffset; 289 290 BinaryFunction *ContainingBF = 291 BC.getBinaryFunctionContainingAddress(RefAddress); 292 if (!ContainingBF) 293 continue; 294 295 MCSymbol *ReferencedSymbol = ContainingBF->getSymbol(); 296 const uint64_t FunctionOffset = RefAddress - ContainingBF->getAddress(); 297 switch (I % 12) { 298 default: 299 llvm_unreachable("bad alignment of __ex_table"); 300 break; 301 case 0: 302 // insn 303 insertLKMarker(RefAddress, I, SignedOffset, true, "__ex_table"); 304 break; 305 case 4: 306 // fixup 307 if (FunctionOffset) 308 ReferencedSymbol = ContainingBF->addEntryPointAtOffset(FunctionOffset); 309 BC.addRelocation(EntryAddress, ReferencedSymbol, Relocation::getPC32(), 0, 310 *Offset); 311 break; 312 case 8: 313 // handler 314 assert(!FunctionOffset && 315 "__ex_table handler entry should point to function start"); 316 BC.addRelocation(EntryAddress, ReferencedSymbol, Relocation::getPC32(), 0, 317 *Offset); 318 break; 319 } 320 } 321 } 322 323 /// Process .pci_fixup section of Linux Kernel. 324 /// This section contains a list of entries for different PCI devices and their 325 /// corresponding hook handler (code pointer where the fixup 326 /// code resides, usually on x86_64 it is an entry PC relative 32 bit offset). 327 /// Documentation is in include/linux/pci.h. 328 void LinuxKernelRewriter::processLKPCIFixup() { 329 ErrorOr<BinarySection &> SectionOrError = 330 BC.getUniqueSectionByName(".pci_fixup"); 331 if (!SectionOrError) 332 return; 333 334 const uint64_t SectionSize = SectionOrError->getSize(); 335 const uint64_t SectionAddress = SectionOrError->getAddress(); 336 assert((SectionSize % 16) == 0 && ".pci_fixup size is not a multiple of 16"); 337 338 for (uint64_t I = 12; I + 4 <= SectionSize; I += 16) { 339 const uint64_t PC = SectionAddress + I; 340 ErrorOr<uint64_t> Offset = BC.getSignedValueAtAddress(PC, 4); 341 assert(Offset && "cannot read value from .pci_fixup"); 342 const int32_t SignedOffset = *Offset; 343 const uint64_t HookupAddress = PC + SignedOffset; 344 BinaryFunction *HookupFunction = 345 BC.getBinaryFunctionAtAddress(HookupAddress); 346 assert(HookupFunction && "expected function for entry in .pci_fixup"); 347 BC.addRelocation(PC, HookupFunction->getSymbol(), Relocation::getPC32(), 0, 348 *Offset); 349 } 350 } 351 352 /// Process __ksymtab[_gpl] sections of Linux Kernel. 353 /// This section lists all the vmlinux symbols that kernel modules can access. 354 /// 355 /// All the entries are 4 bytes each and hence we can read them by one by one 356 /// and ignore the ones that are not pointing to the .text section. All pointers 357 /// are PC relative offsets. Always, points to the beginning of the function. 358 void LinuxKernelRewriter::processLKKSymtab(bool IsGPL) { 359 StringRef SectionName = "__ksymtab"; 360 if (IsGPL) 361 SectionName = "__ksymtab_gpl"; 362 ErrorOr<BinarySection &> SectionOrError = 363 BC.getUniqueSectionByName(SectionName); 364 assert(SectionOrError && 365 "__ksymtab[_gpl] section not found in Linux Kernel binary"); 366 const uint64_t SectionSize = SectionOrError->getSize(); 367 const uint64_t SectionAddress = SectionOrError->getAddress(); 368 assert((SectionSize % 4) == 0 && 369 "The size of the __ksymtab[_gpl] section should be a multiple of 4"); 370 371 for (uint64_t I = 0; I < SectionSize; I += 4) { 372 const uint64_t EntryAddress = SectionAddress + I; 373 ErrorOr<uint64_t> Offset = BC.getSignedValueAtAddress(EntryAddress, 4); 374 assert(Offset && "Reading valid PC-relative offset for a ksymtab entry"); 375 const int32_t SignedOffset = *Offset; 376 const uint64_t RefAddress = EntryAddress + SignedOffset; 377 BinaryFunction *BF = BC.getBinaryFunctionAtAddress(RefAddress); 378 if (!BF) 379 continue; 380 381 BC.addRelocation(EntryAddress, BF->getSymbol(), Relocation::getPC32(), 0, 382 *Offset); 383 } 384 } 385 386 /// Process __bug_table section. 387 /// This section contains information useful for kernel debugging. 388 /// Each entry in the section is a struct bug_entry that contains a pointer to 389 /// the ud2 instruction corresponding to the bug, corresponding file name (both 390 /// pointers use PC relative offset addressing), line number, and flags. 391 /// The definition of the struct bug_entry can be found in 392 /// `include/asm-generic/bug.h` 393 void LinuxKernelRewriter::processLKBugTable() { 394 ErrorOr<BinarySection &> SectionOrError = 395 BC.getUniqueSectionByName("__bug_table"); 396 if (!SectionOrError) 397 return; 398 399 const uint64_t SectionSize = SectionOrError->getSize(); 400 const uint64_t SectionAddress = SectionOrError->getAddress(); 401 assert((SectionSize % 12) == 0 && 402 "The size of the __bug_table section should be a multiple of 12"); 403 for (uint64_t I = 0; I < SectionSize; I += 12) { 404 const uint64_t EntryAddress = SectionAddress + I; 405 ErrorOr<uint64_t> Offset = BC.getSignedValueAtAddress(EntryAddress, 4); 406 assert(Offset && 407 "Reading valid PC-relative offset for a __bug_table entry"); 408 const int32_t SignedOffset = *Offset; 409 const uint64_t RefAddress = EntryAddress + SignedOffset; 410 assert(BC.getBinaryFunctionContainingAddress(RefAddress) && 411 "__bug_table entries should point to a function"); 412 413 insertLKMarker(RefAddress, I, SignedOffset, true, "__bug_table"); 414 } 415 } 416 417 /// .smp_locks section contains PC-relative references to instructions with LOCK 418 /// prefix. The prefix can be converted to NOP at boot time on non-SMP systems. 419 void LinuxKernelRewriter::processLKSMPLocks() { 420 ErrorOr<BinarySection &> SectionOrError = 421 BC.getUniqueSectionByName(".smp_locks"); 422 if (!SectionOrError) 423 return; 424 425 uint64_t SectionSize = SectionOrError->getSize(); 426 const uint64_t SectionAddress = SectionOrError->getAddress(); 427 assert((SectionSize % 4) == 0 && 428 "The size of the .smp_locks section should be a multiple of 4"); 429 430 for (uint64_t I = 0; I < SectionSize; I += 4) { 431 const uint64_t EntryAddress = SectionAddress + I; 432 ErrorOr<uint64_t> Offset = BC.getSignedValueAtAddress(EntryAddress, 4); 433 assert(Offset && "Reading valid PC-relative offset for a .smp_locks entry"); 434 int32_t SignedOffset = *Offset; 435 uint64_t RefAddress = EntryAddress + SignedOffset; 436 437 BinaryFunction *ContainingBF = 438 BC.getBinaryFunctionContainingAddress(RefAddress); 439 if (!ContainingBF) 440 continue; 441 442 insertLKMarker(RefAddress, I, SignedOffset, true, ".smp_locks"); 443 } 444 } 445 446 void LinuxKernelRewriter::updateLKMarkers() { 447 if (LKMarkers.size() == 0) 448 return; 449 450 std::unordered_map<std::string, uint64_t> PatchCounts; 451 for (std::pair<const uint64_t, std::vector<LKInstructionMarkerInfo>> 452 &LKMarkerInfoKV : LKMarkers) { 453 const uint64_t OriginalAddress = LKMarkerInfoKV.first; 454 const BinaryFunction *BF = 455 BC.getBinaryFunctionContainingAddress(OriginalAddress, false, true); 456 if (!BF) 457 continue; 458 459 uint64_t NewAddress = BF->translateInputToOutputAddress(OriginalAddress); 460 if (NewAddress == 0) 461 continue; 462 463 // Apply base address. 464 if (OriginalAddress >= 0xffffffff00000000 && NewAddress < 0xffffffff) 465 NewAddress = NewAddress + 0xffffffff00000000; 466 467 if (OriginalAddress == NewAddress) 468 continue; 469 470 for (LKInstructionMarkerInfo &LKMarkerInfo : LKMarkerInfoKV.second) { 471 StringRef SectionName = LKMarkerInfo.SectionName; 472 SimpleBinaryPatcher *LKPatcher; 473 ErrorOr<BinarySection &> BSec = BC.getUniqueSectionByName(SectionName); 474 assert(BSec && "missing section info for kernel section"); 475 if (!BSec->getPatcher()) 476 BSec->registerPatcher(std::make_unique<SimpleBinaryPatcher>()); 477 LKPatcher = static_cast<SimpleBinaryPatcher *>(BSec->getPatcher()); 478 PatchCounts[std::string(SectionName)]++; 479 if (LKMarkerInfo.IsPCRelative) 480 LKPatcher->addLE32Patch(LKMarkerInfo.SectionOffset, 481 NewAddress - OriginalAddress + 482 LKMarkerInfo.PCRelativeOffset); 483 else 484 LKPatcher->addLE64Patch(LKMarkerInfo.SectionOffset, NewAddress); 485 } 486 } 487 BC.outs() << "BOLT-INFO: patching linux kernel sections. Total patches per " 488 "section are as follows:\n"; 489 for (const std::pair<const std::string, uint64_t> &KV : PatchCounts) 490 BC.outs() << " Section: " << KV.first << ", patch-counts: " << KV.second 491 << '\n'; 492 } 493 494 Error LinuxKernelRewriter::readORCTables() { 495 // NOTE: we should ignore relocations for orc tables as the tables are sorted 496 // post-link time and relocations are not updated. 497 ORCUnwindSection = BC.getUniqueSectionByName(".orc_unwind"); 498 ORCUnwindIPSection = BC.getUniqueSectionByName(".orc_unwind_ip"); 499 500 if (!ORCUnwindSection && !ORCUnwindIPSection) 501 return Error::success(); 502 503 if (!ORCUnwindSection || !ORCUnwindIPSection) 504 return createStringError(errc::executable_format_error, 505 "missing ORC section"); 506 507 NumORCEntries = ORCUnwindIPSection->getSize() / ORC_UNWIND_IP_ENTRY_SIZE; 508 if (ORCUnwindSection->getSize() != NumORCEntries * ORC_UNWIND_ENTRY_SIZE || 509 ORCUnwindIPSection->getSize() != NumORCEntries * ORC_UNWIND_IP_ENTRY_SIZE) 510 return createStringError(errc::executable_format_error, 511 "ORC entries number mismatch detected"); 512 513 const uint64_t IPSectionAddress = ORCUnwindIPSection->getAddress(); 514 DataExtractor OrcDE = DataExtractor(ORCUnwindSection->getContents(), 515 BC.AsmInfo->isLittleEndian(), 516 BC.AsmInfo->getCodePointerSize()); 517 DataExtractor IPDE = DataExtractor(ORCUnwindIPSection->getContents(), 518 BC.AsmInfo->isLittleEndian(), 519 BC.AsmInfo->getCodePointerSize()); 520 DataExtractor::Cursor ORCCursor(0); 521 DataExtractor::Cursor IPCursor(0); 522 uint64_t PrevIP = 0; 523 for (uint32_t Index = 0; Index < NumORCEntries; ++Index) { 524 const uint64_t IP = 525 IPSectionAddress + IPCursor.tell() + (int32_t)IPDE.getU32(IPCursor); 526 527 // Consume the status of the cursor. 528 if (!IPCursor) 529 return createStringError(errc::executable_format_error, 530 "out of bounds while reading ORC IP table"); 531 532 if (IP < PrevIP && opts::Verbosity) 533 BC.errs() << "BOLT-WARNING: out of order IP 0x" << Twine::utohexstr(IP) 534 << " detected while reading ORC\n"; 535 536 PrevIP = IP; 537 538 // Store all entries, includes those we are not going to update as the 539 // tables need to be sorted globally before being written out. 540 ORCEntries.push_back(ORCListEntry()); 541 ORCListEntry &Entry = ORCEntries.back(); 542 543 Entry.IP = IP; 544 Entry.ORC.SPOffset = (int16_t)OrcDE.getU16(ORCCursor); 545 Entry.ORC.BPOffset = (int16_t)OrcDE.getU16(ORCCursor); 546 Entry.ORC.Info = (int16_t)OrcDE.getU16(ORCCursor); 547 Entry.BF = nullptr; 548 549 // Consume the status of the cursor. 550 if (!ORCCursor) 551 return createStringError(errc::executable_format_error, 552 "out of bounds while reading ORC"); 553 554 if (Entry.ORC == NullORC) 555 continue; 556 557 BinaryFunction *&BF = Entry.BF; 558 BF = BC.getBinaryFunctionContainingAddress(IP, /*CheckPastEnd*/ true); 559 560 // If the entry immediately pointing past the end of the function is not 561 // the terminator entry, then it does not belong to this function. 562 if (BF && BF->getAddress() + BF->getSize() == IP) 563 BF = 0; 564 565 if (!BF) { 566 if (opts::Verbosity) 567 BC.errs() << "BOLT-WARNING: no binary function found matching ORC 0x" 568 << Twine::utohexstr(IP) << ": " << Entry.ORC << '\n'; 569 continue; 570 } 571 572 BF->setHasORC(true); 573 574 if (!BF->hasInstructions()) 575 continue; 576 577 MCInst *Inst = BF->getInstructionAtOffset(IP - BF->getAddress()); 578 if (!Inst) 579 return createStringError( 580 errc::executable_format_error, 581 "no instruction at address 0x%" PRIx64 " in .orc_unwind_ip", IP); 582 583 // Some addresses will have two entries associated with them. The first 584 // one being a "weak" section terminator. Since we ignore the terminator, 585 // we should only assign one entry per instruction. 586 if (BC.MIB->hasAnnotation(*Inst, "ORC")) 587 return createStringError( 588 errc::executable_format_error, 589 "duplicate non-terminal ORC IP 0x%" PRIx64 " in .orc_unwind_ip", IP); 590 591 BC.MIB->addAnnotation(*Inst, "ORC", Entry.ORC); 592 } 593 594 BC.outs() << "BOLT-INFO: parsed " << NumORCEntries << " ORC entries\n"; 595 596 if (opts::DumpORC) { 597 BC.outs() << "BOLT-INFO: ORC unwind information:\n"; 598 for (const ORCListEntry &E : ORCEntries) { 599 BC.outs() << "0x" << Twine::utohexstr(E.IP) << ": " << E.ORC; 600 if (E.BF) 601 BC.outs() << ": " << *E.BF; 602 BC.outs() << '\n'; 603 } 604 } 605 606 // Add entries for functions that don't have explicit ORC info at the start. 607 // We'll have the correct info for them even if ORC for the preceding function 608 // changes. 609 ORCListType NewEntries; 610 for (BinaryFunction &BF : llvm::make_second_range(BC.getBinaryFunctions())) { 611 auto It = llvm::partition_point(ORCEntries, [&](const ORCListEntry &E) { 612 return E.IP <= BF.getAddress(); 613 }); 614 if (It != ORCEntries.begin()) 615 --It; 616 617 if (It->BF == &BF) 618 continue; 619 620 if (It->ORC == NullORC && It->IP == BF.getAddress()) { 621 assert(!It->BF); 622 It->BF = &BF; 623 continue; 624 } 625 626 NewEntries.push_back({BF.getAddress(), &BF, It->ORC}); 627 if (It->ORC != NullORC) 628 BF.setHasORC(true); 629 } 630 631 llvm::copy(NewEntries, std::back_inserter(ORCEntries)); 632 llvm::sort(ORCEntries); 633 634 if (opts::DumpORC) { 635 BC.outs() << "BOLT-INFO: amended ORC unwind information:\n"; 636 for (const ORCListEntry &E : ORCEntries) { 637 BC.outs() << "0x" << Twine::utohexstr(E.IP) << ": " << E.ORC; 638 if (E.BF) 639 BC.outs() << ": " << *E.BF; 640 BC.outs() << '\n'; 641 } 642 } 643 644 return Error::success(); 645 } 646 647 Error LinuxKernelRewriter::processORCPostCFG() { 648 if (!NumORCEntries) 649 return Error::success(); 650 651 // Propagate ORC to the rest of the function. We can annotate every 652 // instruction in every function, but to minimize the overhead, we annotate 653 // the first instruction in every basic block to reflect the state at the 654 // entry. This way, the ORC state can be calculated based on annotations 655 // regardless of the basic block layout. Note that if we insert/delete 656 // instructions, we must take care to attach ORC info to the new/deleted ones. 657 for (BinaryFunction &BF : llvm::make_second_range(BC.getBinaryFunctions())) { 658 659 std::optional<ORCState> CurrentState; 660 for (BinaryBasicBlock &BB : BF) { 661 for (MCInst &Inst : BB) { 662 ErrorOr<ORCState> State = 663 BC.MIB->tryGetAnnotationAs<ORCState>(Inst, "ORC"); 664 665 if (State) { 666 CurrentState = *State; 667 continue; 668 } 669 670 // Get state for the start of the function. 671 if (!CurrentState) { 672 // A terminator entry (NullORC) can match the function address. If 673 // there's also a non-terminator entry, it will be placed after the 674 // terminator. Hence, we are looking for the last ORC entry that 675 // matches the address. 676 auto It = 677 llvm::partition_point(ORCEntries, [&](const ORCListEntry &E) { 678 return E.IP <= BF.getAddress(); 679 }); 680 if (It != ORCEntries.begin()) 681 --It; 682 683 assert(It->IP == BF.getAddress() && (!It->BF || It->BF == &BF) && 684 "ORC info at function entry expected."); 685 686 if (It->ORC == NullORC && BF.hasORC()) { 687 BC.errs() << "BOLT-WARNING: ORC unwind info excludes prologue for " 688 << BF << '\n'; 689 } 690 691 It->BF = &BF; 692 693 CurrentState = It->ORC; 694 if (It->ORC != NullORC) 695 BF.setHasORC(true); 696 } 697 698 // While printing ORC, attach info to every instruction for convenience. 699 if (opts::PrintORC || &Inst == &BB.front()) 700 BC.MIB->addAnnotation(Inst, "ORC", *CurrentState); 701 } 702 } 703 } 704 705 return Error::success(); 706 } 707 708 Error LinuxKernelRewriter::rewriteORCTables() { 709 if (!NumORCEntries) 710 return Error::success(); 711 712 // Update ORC sections in-place. As we change the code, the number of ORC 713 // entries may increase for some functions. However, as we remove terminator 714 // redundancy (see below), more space is freed up and we should always be able 715 // to fit new ORC tables in the reserved space. 716 auto createInPlaceWriter = [&](BinarySection &Section) -> BinaryStreamWriter { 717 const size_t Size = Section.getSize(); 718 uint8_t *NewContents = new uint8_t[Size]; 719 Section.updateContents(NewContents, Size); 720 Section.setOutputFileOffset(Section.getInputFileOffset()); 721 return BinaryStreamWriter({NewContents, Size}, BC.AsmInfo->isLittleEndian() 722 ? endianness::little 723 : endianness::big); 724 }; 725 BinaryStreamWriter UnwindWriter = createInPlaceWriter(*ORCUnwindSection); 726 BinaryStreamWriter UnwindIPWriter = createInPlaceWriter(*ORCUnwindIPSection); 727 728 uint64_t NumEmitted = 0; 729 std::optional<ORCState> LastEmittedORC; 730 auto emitORCEntry = [&](const uint64_t IP, const ORCState &ORC, 731 MCSymbol *Label = 0, bool Force = false) -> Error { 732 if (LastEmittedORC && ORC == *LastEmittedORC && !Force) 733 return Error::success(); 734 735 LastEmittedORC = ORC; 736 737 if (++NumEmitted > NumORCEntries) 738 return createStringError(errc::executable_format_error, 739 "exceeded the number of allocated ORC entries"); 740 741 if (Label) 742 ORCUnwindIPSection->addRelocation(UnwindIPWriter.getOffset(), Label, 743 Relocation::getPC32(), /*Addend*/ 0); 744 745 const int32_t IPValue = 746 IP - ORCUnwindIPSection->getAddress() - UnwindIPWriter.getOffset(); 747 if (Error E = UnwindIPWriter.writeInteger(IPValue)) 748 return E; 749 750 if (Error E = UnwindWriter.writeInteger(ORC.SPOffset)) 751 return E; 752 if (Error E = UnwindWriter.writeInteger(ORC.BPOffset)) 753 return E; 754 if (Error E = UnwindWriter.writeInteger(ORC.Info)) 755 return E; 756 757 return Error::success(); 758 }; 759 760 // Emit new ORC entries for the emitted function. 761 auto emitORC = [&](const BinaryFunction &BF) -> Error { 762 assert(!BF.isSplit() && "Split functions not supported by ORC writer yet."); 763 764 ORCState CurrentState = NullORC; 765 for (BinaryBasicBlock *BB : BF.getLayout().blocks()) { 766 for (MCInst &Inst : *BB) { 767 ErrorOr<ORCState> ErrorOrState = 768 BC.MIB->tryGetAnnotationAs<ORCState>(Inst, "ORC"); 769 if (!ErrorOrState || *ErrorOrState == CurrentState) 770 continue; 771 772 // Issue label for the instruction. 773 MCSymbol *Label = BC.MIB->getLabel(Inst); 774 if (!Label) { 775 Label = BC.Ctx->createTempSymbol("__ORC_"); 776 BC.MIB->setLabel(Inst, Label); 777 } 778 779 if (Error E = emitORCEntry(0, *ErrorOrState, Label)) 780 return E; 781 782 CurrentState = *ErrorOrState; 783 } 784 } 785 786 return Error::success(); 787 }; 788 789 for (ORCListEntry &Entry : ORCEntries) { 790 // Emit original entries for functions that we haven't modified. 791 if (!Entry.BF || !BC.shouldEmit(*Entry.BF)) { 792 // Emit terminator only if it marks the start of a function. 793 if (Entry.ORC == NullORC && !Entry.BF) 794 continue; 795 if (Error E = emitORCEntry(Entry.IP, Entry.ORC)) 796 return E; 797 continue; 798 } 799 800 // Emit all ORC entries for a function referenced by an entry and skip over 801 // the rest of entries for this function by resetting its ORC attribute. 802 if (Entry.BF->hasORC()) { 803 if (Error E = emitORC(*Entry.BF)) 804 return E; 805 Entry.BF->setHasORC(false); 806 } 807 } 808 809 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: emitted " << NumEmitted 810 << " ORC entries\n"); 811 812 // Replicate terminator entry at the end of sections to match the original 813 // table sizes. 814 const BinaryFunction &LastBF = BC.getBinaryFunctions().rbegin()->second; 815 const uint64_t LastIP = LastBF.getAddress() + LastBF.getMaxSize(); 816 while (UnwindWriter.bytesRemaining()) { 817 if (Error E = emitORCEntry(LastIP, NullORC, nullptr, /*Force*/ true)) 818 return E; 819 } 820 821 return Error::success(); 822 } 823 824 /// The static call site table is created by objtool and contains entries in the 825 /// following format: 826 /// 827 /// struct static_call_site { 828 /// s32 addr; 829 /// s32 key; 830 /// }; 831 /// 832 Error LinuxKernelRewriter::readStaticCalls() { 833 const BinaryData *StaticCallTable = 834 BC.getBinaryDataByName("__start_static_call_sites"); 835 if (!StaticCallTable) 836 return Error::success(); 837 838 StaticCallTableAddress = StaticCallTable->getAddress(); 839 840 const BinaryData *Stop = BC.getBinaryDataByName("__stop_static_call_sites"); 841 if (!Stop) 842 return createStringError(errc::executable_format_error, 843 "missing __stop_static_call_sites symbol"); 844 845 ErrorOr<BinarySection &> ErrorOrSection = 846 BC.getSectionForAddress(StaticCallTableAddress); 847 if (!ErrorOrSection) 848 return createStringError(errc::executable_format_error, 849 "no section matching __start_static_call_sites"); 850 851 StaticCallSection = *ErrorOrSection; 852 if (!StaticCallSection->containsAddress(Stop->getAddress() - 1)) 853 return createStringError(errc::executable_format_error, 854 "__stop_static_call_sites not in the same section " 855 "as __start_static_call_sites"); 856 857 if ((Stop->getAddress() - StaticCallTableAddress) % STATIC_CALL_ENTRY_SIZE) 858 return createStringError(errc::executable_format_error, 859 "static call table size error"); 860 861 const uint64_t SectionAddress = StaticCallSection->getAddress(); 862 DataExtractor DE(StaticCallSection->getContents(), 863 BC.AsmInfo->isLittleEndian(), 864 BC.AsmInfo->getCodePointerSize()); 865 DataExtractor::Cursor Cursor(StaticCallTableAddress - SectionAddress); 866 uint32_t EntryID = 0; 867 while (Cursor && Cursor.tell() < Stop->getAddress() - SectionAddress) { 868 const uint64_t CallAddress = 869 SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor); 870 const uint64_t KeyAddress = 871 SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor); 872 873 // Consume the status of the cursor. 874 if (!Cursor) 875 return createStringError(errc::executable_format_error, 876 "out of bounds while reading static calls"); 877 878 ++EntryID; 879 880 if (opts::DumpStaticCalls) { 881 BC.outs() << "Static Call Site: " << EntryID << '\n'; 882 BC.outs() << "\tCallAddress: 0x" << Twine::utohexstr(CallAddress) 883 << "\n\tKeyAddress: 0x" << Twine::utohexstr(KeyAddress) 884 << '\n'; 885 } 886 887 BinaryFunction *BF = BC.getBinaryFunctionContainingAddress(CallAddress); 888 if (!BF) 889 continue; 890 891 if (!BC.shouldEmit(*BF)) 892 continue; 893 894 if (!BF->hasInstructions()) 895 continue; 896 897 MCInst *Inst = BF->getInstructionAtOffset(CallAddress - BF->getAddress()); 898 if (!Inst) 899 return createStringError(errc::executable_format_error, 900 "no instruction at call site address 0x%" PRIx64, 901 CallAddress); 902 903 // Check for duplicate entries. 904 if (BC.MIB->hasAnnotation(*Inst, "StaticCall")) 905 return createStringError(errc::executable_format_error, 906 "duplicate static call site at 0x%" PRIx64, 907 CallAddress); 908 909 BC.MIB->addAnnotation(*Inst, "StaticCall", EntryID); 910 911 MCSymbol *Label = BC.MIB->getLabel(*Inst); 912 if (!Label) { 913 Label = BC.Ctx->createTempSymbol("__SC_"); 914 BC.MIB->setLabel(*Inst, Label); 915 } 916 917 StaticCallEntries.push_back({EntryID, BF, Label}); 918 } 919 920 BC.outs() << "BOLT-INFO: parsed " << StaticCallEntries.size() 921 << " static call entries\n"; 922 923 return Error::success(); 924 } 925 926 /// The static call table is sorted during boot time in 927 /// static_call_sort_entries(). This makes it possible to update existing 928 /// entries in-place ignoring their relative order. 929 Error LinuxKernelRewriter::rewriteStaticCalls() { 930 if (!StaticCallTableAddress || !StaticCallSection) 931 return Error::success(); 932 933 for (auto &Entry : StaticCallEntries) { 934 if (!Entry.Function) 935 continue; 936 937 BinaryFunction &BF = *Entry.Function; 938 if (!BC.shouldEmit(BF)) 939 continue; 940 941 // Create a relocation against the label. 942 const uint64_t EntryOffset = StaticCallTableAddress - 943 StaticCallSection->getAddress() + 944 (Entry.ID - 1) * STATIC_CALL_ENTRY_SIZE; 945 StaticCallSection->addRelocation(EntryOffset, Entry.Label, 946 ELF::R_X86_64_PC32, /*Addend*/ 0); 947 } 948 949 return Error::success(); 950 } 951 952 } // namespace 953 954 std::unique_ptr<MetadataRewriter> 955 llvm::bolt::createLinuxKernelRewriter(BinaryContext &BC) { 956 return std::make_unique<LinuxKernelRewriter>(BC); 957 } 958