1 //===- bolt/Rewrite/RewriteInstance.cpp - ELF rewriter --------------------===// 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 #include "bolt/Rewrite/RewriteInstance.h" 10 #include "bolt/Core/BinaryContext.h" 11 #include "bolt/Core/BinaryEmitter.h" 12 #include "bolt/Core/BinaryFunction.h" 13 #include "bolt/Core/DebugData.h" 14 #include "bolt/Core/Exceptions.h" 15 #include "bolt/Core/MCPlusBuilder.h" 16 #include "bolt/Core/ParallelUtilities.h" 17 #include "bolt/Core/Relocation.h" 18 #include "bolt/Passes/CacheMetrics.h" 19 #include "bolt/Passes/ReorderFunctions.h" 20 #include "bolt/Profile/BoltAddressTranslation.h" 21 #include "bolt/Profile/DataAggregator.h" 22 #include "bolt/Profile/DataReader.h" 23 #include "bolt/Profile/YAMLProfileReader.h" 24 #include "bolt/Profile/YAMLProfileWriter.h" 25 #include "bolt/Rewrite/BinaryPassManager.h" 26 #include "bolt/Rewrite/DWARFRewriter.h" 27 #include "bolt/Rewrite/ExecutableFileMemoryManager.h" 28 #include "bolt/RuntimeLibs/HugifyRuntimeLibrary.h" 29 #include "bolt/RuntimeLibs/InstrumentationRuntimeLibrary.h" 30 #include "bolt/Utils/CommandLineOpts.h" 31 #include "bolt/Utils/Utils.h" 32 #include "llvm/ADT/Optional.h" 33 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 34 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" 35 #include "llvm/ExecutionEngine/RuntimeDyld.h" 36 #include "llvm/MC/MCAsmBackend.h" 37 #include "llvm/MC/MCAsmInfo.h" 38 #include "llvm/MC/MCAsmLayout.h" 39 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 40 #include "llvm/MC/MCObjectStreamer.h" 41 #include "llvm/MC/MCStreamer.h" 42 #include "llvm/MC/MCSymbol.h" 43 #include "llvm/MC/TargetRegistry.h" 44 #include "llvm/Object/ObjectFile.h" 45 #include "llvm/Support/Alignment.h" 46 #include "llvm/Support/Casting.h" 47 #include "llvm/Support/CommandLine.h" 48 #include "llvm/Support/DataExtractor.h" 49 #include "llvm/Support/Errc.h" 50 #include "llvm/Support/Error.h" 51 #include "llvm/Support/FileSystem.h" 52 #include "llvm/Support/LEB128.h" 53 #include "llvm/Support/ManagedStatic.h" 54 #include "llvm/Support/Timer.h" 55 #include "llvm/Support/ToolOutputFile.h" 56 #include "llvm/Support/raw_ostream.h" 57 #include <algorithm> 58 #include <fstream> 59 #include <memory> 60 #include <system_error> 61 62 #undef DEBUG_TYPE 63 #define DEBUG_TYPE "bolt" 64 65 using namespace llvm; 66 using namespace object; 67 using namespace bolt; 68 69 extern cl::opt<uint32_t> X86AlignBranchBoundary; 70 extern cl::opt<bool> X86AlignBranchWithin32BBoundaries; 71 72 namespace opts { 73 74 extern cl::opt<MacroFusionType> AlignMacroOpFusion; 75 extern cl::list<std::string> HotTextMoveSections; 76 extern cl::opt<bool> Hugify; 77 extern cl::opt<bool> Instrument; 78 extern cl::opt<JumpTableSupportLevel> JumpTables; 79 extern cl::list<std::string> ReorderData; 80 extern cl::opt<bolt::ReorderFunctions::ReorderType> ReorderFunctions; 81 extern cl::opt<bool> TimeBuild; 82 83 static cl::opt<bool> 84 ForceToDataRelocations("force-data-relocations", 85 cl::desc("force relocations to data sections to always be processed"), 86 cl::init(false), 87 cl::Hidden, 88 cl::ZeroOrMore, 89 cl::cat(BoltCategory)); 90 91 cl::opt<std::string> 92 BoltID("bolt-id", 93 cl::desc("add any string to tag this execution in the " 94 "output binary via bolt info section"), 95 cl::ZeroOrMore, 96 cl::cat(BoltCategory)); 97 98 cl::opt<bool> 99 AllowStripped("allow-stripped", 100 cl::desc("allow processing of stripped binaries"), 101 cl::Hidden, 102 cl::cat(BoltCategory)); 103 104 cl::opt<bool> 105 DumpDotAll("dump-dot-all", 106 cl::desc("dump function CFGs to graphviz format after each stage"), 107 cl::ZeroOrMore, 108 cl::Hidden, 109 cl::cat(BoltCategory)); 110 111 static cl::list<std::string> 112 ForceFunctionNames("funcs", 113 cl::CommaSeparated, 114 cl::desc("limit optimizations to functions from the list"), 115 cl::value_desc("func1,func2,func3,..."), 116 cl::Hidden, 117 cl::cat(BoltCategory)); 118 119 static cl::opt<std::string> 120 FunctionNamesFile("funcs-file", 121 cl::desc("file with list of functions to optimize"), 122 cl::Hidden, 123 cl::cat(BoltCategory)); 124 125 static cl::list<std::string> ForceFunctionNamesNR( 126 "funcs-no-regex", cl::CommaSeparated, 127 cl::desc("limit optimizations to functions from the list (non-regex)"), 128 cl::value_desc("func1,func2,func3,..."), cl::Hidden, cl::cat(BoltCategory)); 129 130 static cl::opt<std::string> FunctionNamesFileNR( 131 "funcs-file-no-regex", 132 cl::desc("file with list of functions to optimize (non-regex)"), cl::Hidden, 133 cl::cat(BoltCategory)); 134 135 cl::opt<bool> 136 KeepTmp("keep-tmp", 137 cl::desc("preserve intermediate .o file"), 138 cl::Hidden, 139 cl::cat(BoltCategory)); 140 141 cl::opt<bool> 142 Lite("lite", 143 cl::desc("skip processing of cold functions"), 144 cl::init(false), 145 cl::ZeroOrMore, 146 cl::cat(BoltCategory)); 147 148 static cl::opt<unsigned> 149 LiteThresholdPct("lite-threshold-pct", 150 cl::desc("threshold (in percent) for selecting functions to process in lite " 151 "mode. Higher threshold means fewer functions to process. E.g " 152 "threshold of 90 means only top 10 percent of functions with " 153 "profile will be processed."), 154 cl::init(0), 155 cl::ZeroOrMore, 156 cl::Hidden, 157 cl::cat(BoltOptCategory)); 158 159 static cl::opt<unsigned> 160 LiteThresholdCount("lite-threshold-count", 161 cl::desc("similar to '-lite-threshold-pct' but specify threshold using " 162 "absolute function call count. I.e. limit processing to functions " 163 "executed at least the specified number of times."), 164 cl::init(0), 165 cl::ZeroOrMore, 166 cl::Hidden, 167 cl::cat(BoltOptCategory)); 168 169 static cl::opt<unsigned> 170 MaxFunctions("max-funcs", 171 cl::desc("maximum number of functions to process"), 172 cl::ZeroOrMore, 173 cl::Hidden, 174 cl::cat(BoltCategory)); 175 176 static cl::opt<unsigned> 177 MaxDataRelocations("max-data-relocations", 178 cl::desc("maximum number of data relocations to process"), 179 cl::ZeroOrMore, 180 cl::Hidden, 181 cl::cat(BoltCategory)); 182 183 cl::opt<bool> 184 PrintAll("print-all", 185 cl::desc("print functions after each stage"), 186 cl::ZeroOrMore, 187 cl::Hidden, 188 cl::cat(BoltCategory)); 189 190 cl::opt<bool> 191 PrintCFG("print-cfg", 192 cl::desc("print functions after CFG construction"), 193 cl::ZeroOrMore, 194 cl::Hidden, 195 cl::cat(BoltCategory)); 196 197 cl::opt<bool> PrintDisasm("print-disasm", 198 cl::desc("print function after disassembly"), 199 cl::ZeroOrMore, 200 cl::Hidden, 201 cl::cat(BoltCategory)); 202 203 static cl::opt<bool> 204 PrintGlobals("print-globals", 205 cl::desc("print global symbols after disassembly"), 206 cl::ZeroOrMore, 207 cl::Hidden, 208 cl::cat(BoltCategory)); 209 210 extern cl::opt<bool> PrintSections; 211 212 static cl::opt<bool> 213 PrintLoopInfo("print-loops", 214 cl::desc("print loop related information"), 215 cl::ZeroOrMore, 216 cl::Hidden, 217 cl::cat(BoltCategory)); 218 219 static cl::opt<bool> 220 PrintSDTMarkers("print-sdt", 221 cl::desc("print all SDT markers"), 222 cl::ZeroOrMore, 223 cl::Hidden, 224 cl::cat(BoltCategory)); 225 226 enum PrintPseudoProbesOptions { 227 PPP_None = 0, 228 PPP_Probes_Section_Decode = 0x1, 229 PPP_Probes_Address_Conversion = 0x2, 230 PPP_Encoded_Probes = 0x3, 231 PPP_All = 0xf 232 }; 233 234 cl::opt<PrintPseudoProbesOptions> PrintPseudoProbes( 235 "print-pseudo-probes", cl::desc("print pseudo probe info"), 236 cl::init(PPP_None), 237 cl::values(clEnumValN(PPP_Probes_Section_Decode, "decode", 238 "decode probes section from binary"), 239 clEnumValN(PPP_Probes_Address_Conversion, "address_conversion", 240 "update address2ProbesMap with output block address"), 241 clEnumValN(PPP_Encoded_Probes, "encoded_probes", 242 "display the encoded probes in binary section"), 243 clEnumValN(PPP_All, "all", "enable all debugging printout")), 244 cl::ZeroOrMore, cl::Hidden, cl::cat(BoltCategory)); 245 246 static cl::opt<cl::boolOrDefault> 247 RelocationMode("relocs", 248 cl::desc("use relocations in the binary (default=autodetect)"), 249 cl::ZeroOrMore, 250 cl::cat(BoltCategory)); 251 252 static cl::opt<std::string> 253 SaveProfile("w", 254 cl::desc("save recorded profile to a file"), 255 cl::cat(BoltOutputCategory)); 256 257 static cl::list<std::string> 258 SkipFunctionNames("skip-funcs", 259 cl::CommaSeparated, 260 cl::desc("list of functions to skip"), 261 cl::value_desc("func1,func2,func3,..."), 262 cl::Hidden, 263 cl::cat(BoltCategory)); 264 265 static cl::opt<std::string> 266 SkipFunctionNamesFile("skip-funcs-file", 267 cl::desc("file with list of functions to skip"), 268 cl::Hidden, 269 cl::cat(BoltCategory)); 270 271 cl::opt<bool> 272 TrapOldCode("trap-old-code", 273 cl::desc("insert traps in old function bodies (relocation mode)"), 274 cl::Hidden, 275 cl::cat(BoltCategory)); 276 277 static cl::opt<std::string> DWPPathName("dwp", 278 cl::desc("Path and name to DWP file."), 279 cl::Hidden, cl::ZeroOrMore, 280 cl::init(""), cl::cat(BoltCategory)); 281 282 static cl::opt<bool> 283 UseGnuStack("use-gnu-stack", 284 cl::desc("use GNU_STACK program header for new segment (workaround for " 285 "issues with strip/objcopy)"), 286 cl::ZeroOrMore, 287 cl::cat(BoltCategory)); 288 289 static cl::opt<bool> 290 TimeRewrite("time-rewrite", 291 cl::desc("print time spent in rewriting passes"), 292 cl::ZeroOrMore, 293 cl::Hidden, 294 cl::cat(BoltCategory)); 295 296 static cl::opt<bool> 297 SequentialDisassembly("sequential-disassembly", 298 cl::desc("performs disassembly sequentially"), 299 cl::init(false), 300 cl::cat(BoltOptCategory)); 301 302 static cl::opt<bool> 303 WriteBoltInfoSection("bolt-info", 304 cl::desc("write bolt info section in the output binary"), 305 cl::init(true), 306 cl::ZeroOrMore, 307 cl::Hidden, 308 cl::cat(BoltOutputCategory)); 309 310 } // namespace opts 311 312 constexpr const char *RewriteInstance::SectionsToOverwrite[]; 313 std::vector<std::string> RewriteInstance::DebugSectionsToOverwrite = { 314 ".debug_abbrev", ".debug_aranges", ".debug_line", ".debug_line_str", 315 ".debug_loc", ".debug_loclists", ".debug_ranges", ".debug_rnglists", 316 ".gdb_index", ".debug_addr"}; 317 318 const char RewriteInstance::TimerGroupName[] = "rewrite"; 319 const char RewriteInstance::TimerGroupDesc[] = "Rewrite passes"; 320 321 namespace llvm { 322 namespace bolt { 323 324 extern const char *BoltRevision; 325 326 MCPlusBuilder *createMCPlusBuilder(const Triple::ArchType Arch, 327 const MCInstrAnalysis *Analysis, 328 const MCInstrInfo *Info, 329 const MCRegisterInfo *RegInfo) { 330 #ifdef X86_AVAILABLE 331 if (Arch == Triple::x86_64) 332 return createX86MCPlusBuilder(Analysis, Info, RegInfo); 333 #endif 334 335 #ifdef AARCH64_AVAILABLE 336 if (Arch == Triple::aarch64) 337 return createAArch64MCPlusBuilder(Analysis, Info, RegInfo); 338 #endif 339 340 llvm_unreachable("architecture unsupported by MCPlusBuilder"); 341 } 342 343 } // namespace bolt 344 } // namespace llvm 345 346 namespace { 347 348 bool refersToReorderedSection(ErrorOr<BinarySection &> Section) { 349 auto Itr = 350 std::find_if(opts::ReorderData.begin(), opts::ReorderData.end(), 351 [&](const std::string &SectionName) { 352 return (Section && Section->getName() == SectionName); 353 }); 354 return Itr != opts::ReorderData.end(); 355 } 356 357 } // anonymous namespace 358 359 Expected<std::unique_ptr<RewriteInstance>> 360 RewriteInstance::createRewriteInstance(ELFObjectFileBase *File, const int Argc, 361 const char *const *Argv, 362 StringRef ToolPath) { 363 Error Err = Error::success(); 364 auto RI = std::make_unique<RewriteInstance>(File, Argc, Argv, ToolPath, Err); 365 if (Err) 366 return std::move(Err); 367 return std::move(RI); 368 } 369 370 RewriteInstance::RewriteInstance(ELFObjectFileBase *File, const int Argc, 371 const char *const *Argv, StringRef ToolPath, 372 Error &Err) 373 : InputFile(File), Argc(Argc), Argv(Argv), ToolPath(ToolPath), 374 SHStrTab(StringTableBuilder::ELF) { 375 ErrorAsOutParameter EAO(&Err); 376 auto ELF64LEFile = dyn_cast<ELF64LEObjectFile>(InputFile); 377 if (!ELF64LEFile) { 378 Err = createStringError(errc::not_supported, 379 "Only 64-bit LE ELF binaries are supported"); 380 return; 381 } 382 383 bool IsPIC = false; 384 const ELFFile<ELF64LE> &Obj = ELF64LEFile->getELFFile(); 385 if (Obj.getHeader().e_type != ELF::ET_EXEC) { 386 outs() << "BOLT-INFO: shared object or position-independent executable " 387 "detected\n"; 388 IsPIC = true; 389 } 390 391 auto BCOrErr = BinaryContext::createBinaryContext( 392 File, IsPIC, 393 DWARFContext::create(*File, DWARFContext::ProcessDebugRelocations::Ignore, 394 nullptr, opts::DWPPathName, 395 WithColor::defaultErrorHandler, 396 WithColor::defaultWarningHandler)); 397 if (Error E = BCOrErr.takeError()) { 398 Err = std::move(E); 399 return; 400 } 401 BC = std::move(BCOrErr.get()); 402 BC->initializeTarget(std::unique_ptr<MCPlusBuilder>(createMCPlusBuilder( 403 BC->TheTriple->getArch(), BC->MIA.get(), BC->MII.get(), BC->MRI.get()))); 404 405 BAT = std::make_unique<BoltAddressTranslation>(*BC); 406 407 if (opts::UpdateDebugSections) 408 DebugInfoRewriter = std::make_unique<DWARFRewriter>(*BC); 409 410 if (opts::Instrument) 411 BC->setRuntimeLibrary(std::make_unique<InstrumentationRuntimeLibrary>()); 412 else if (opts::Hugify) 413 BC->setRuntimeLibrary(std::make_unique<HugifyRuntimeLibrary>()); 414 } 415 416 RewriteInstance::~RewriteInstance() {} 417 418 Error RewriteInstance::setProfile(StringRef Filename) { 419 if (!sys::fs::exists(Filename)) 420 return errorCodeToError(make_error_code(errc::no_such_file_or_directory)); 421 422 if (ProfileReader) { 423 // Already exists 424 return make_error<StringError>(Twine("multiple profiles specified: ") + 425 ProfileReader->getFilename() + " and " + 426 Filename, 427 inconvertibleErrorCode()); 428 } 429 430 // Spawn a profile reader based on file contents. 431 if (DataAggregator::checkPerfDataMagic(Filename)) 432 ProfileReader = std::make_unique<DataAggregator>(Filename); 433 else if (YAMLProfileReader::isYAML(Filename)) 434 ProfileReader = std::make_unique<YAMLProfileReader>(Filename); 435 else 436 ProfileReader = std::make_unique<DataReader>(Filename); 437 438 return Error::success(); 439 } 440 441 /// Return true if the function \p BF should be disassembled. 442 static bool shouldDisassemble(const BinaryFunction &BF) { 443 if (BF.isPseudo()) 444 return false; 445 446 if (opts::processAllFunctions()) 447 return true; 448 449 return !BF.isIgnored(); 450 } 451 452 Error RewriteInstance::discoverStorage() { 453 NamedRegionTimer T("discoverStorage", "discover storage", TimerGroupName, 454 TimerGroupDesc, opts::TimeRewrite); 455 456 // Stubs are harmful because RuntimeDyld may try to increase the size of 457 // sections accounting for stubs when we need those sections to match the 458 // same size seen in the input binary, in case this section is a copy 459 // of the original one seen in the binary. 460 BC->EFMM.reset(new ExecutableFileMemoryManager(*BC, /*AllowStubs*/ false)); 461 462 auto ELF64LEFile = dyn_cast<ELF64LEObjectFile>(InputFile); 463 const ELFFile<ELF64LE> &Obj = ELF64LEFile->getELFFile(); 464 465 BC->StartFunctionAddress = Obj.getHeader().e_entry; 466 467 NextAvailableAddress = 0; 468 uint64_t NextAvailableOffset = 0; 469 Expected<ELF64LE::PhdrRange> PHsOrErr = Obj.program_headers(); 470 if (Error E = PHsOrErr.takeError()) 471 return E; 472 473 ELF64LE::PhdrRange PHs = PHsOrErr.get(); 474 for (const ELF64LE::Phdr &Phdr : PHs) { 475 switch (Phdr.p_type) { 476 case ELF::PT_LOAD: 477 BC->FirstAllocAddress = std::min(BC->FirstAllocAddress, 478 static_cast<uint64_t>(Phdr.p_vaddr)); 479 NextAvailableAddress = std::max(NextAvailableAddress, 480 Phdr.p_vaddr + Phdr.p_memsz); 481 NextAvailableOffset = std::max(NextAvailableOffset, 482 Phdr.p_offset + Phdr.p_filesz); 483 484 BC->SegmentMapInfo[Phdr.p_vaddr] = SegmentInfo{Phdr.p_vaddr, 485 Phdr.p_memsz, 486 Phdr.p_offset, 487 Phdr.p_filesz, 488 Phdr.p_align}; 489 break; 490 case ELF::PT_INTERP: 491 BC->HasInterpHeader = true; 492 break; 493 } 494 } 495 496 for (const SectionRef &Section : InputFile->sections()) { 497 Expected<StringRef> SectionNameOrErr = Section.getName(); 498 if (Error E = SectionNameOrErr.takeError()) 499 return E; 500 StringRef SectionName = SectionNameOrErr.get(); 501 if (SectionName == ".text") { 502 BC->OldTextSectionAddress = Section.getAddress(); 503 BC->OldTextSectionSize = Section.getSize(); 504 505 Expected<StringRef> SectionContentsOrErr = Section.getContents(); 506 if (Error E = SectionContentsOrErr.takeError()) 507 return E; 508 StringRef SectionContents = SectionContentsOrErr.get(); 509 BC->OldTextSectionOffset = 510 SectionContents.data() - InputFile->getData().data(); 511 } 512 513 if (!opts::HeatmapMode && 514 !(opts::AggregateOnly && BAT->enabledFor(InputFile)) && 515 (SectionName.startswith(getOrgSecPrefix()) || 516 SectionName == getBOLTTextSectionName())) 517 return createStringError( 518 errc::function_not_supported, 519 "BOLT-ERROR: input file was processed by BOLT. Cannot re-optimize"); 520 } 521 522 if (!NextAvailableAddress || !NextAvailableOffset) 523 return createStringError(errc::executable_format_error, 524 "no PT_LOAD pheader seen"); 525 526 outs() << "BOLT-INFO: first alloc address is 0x" 527 << Twine::utohexstr(BC->FirstAllocAddress) << '\n'; 528 529 FirstNonAllocatableOffset = NextAvailableOffset; 530 531 NextAvailableAddress = alignTo(NextAvailableAddress, BC->PageAlign); 532 NextAvailableOffset = alignTo(NextAvailableOffset, BC->PageAlign); 533 534 if (!opts::UseGnuStack) { 535 // This is where the black magic happens. Creating PHDR table in a segment 536 // other than that containing ELF header is tricky. Some loaders and/or 537 // parts of loaders will apply e_phoff from ELF header assuming both are in 538 // the same segment, while others will do the proper calculation. 539 // We create the new PHDR table in such a way that both of the methods 540 // of loading and locating the table work. There's a slight file size 541 // overhead because of that. 542 // 543 // NB: bfd's strip command cannot do the above and will corrupt the 544 // binary during the process of stripping non-allocatable sections. 545 if (NextAvailableOffset <= NextAvailableAddress - BC->FirstAllocAddress) 546 NextAvailableOffset = NextAvailableAddress - BC->FirstAllocAddress; 547 else 548 NextAvailableAddress = NextAvailableOffset + BC->FirstAllocAddress; 549 550 assert(NextAvailableOffset == 551 NextAvailableAddress - BC->FirstAllocAddress && 552 "PHDR table address calculation error"); 553 554 outs() << "BOLT-INFO: creating new program header table at address 0x" 555 << Twine::utohexstr(NextAvailableAddress) << ", offset 0x" 556 << Twine::utohexstr(NextAvailableOffset) << '\n'; 557 558 PHDRTableAddress = NextAvailableAddress; 559 PHDRTableOffset = NextAvailableOffset; 560 561 // Reserve space for 3 extra pheaders. 562 unsigned Phnum = Obj.getHeader().e_phnum; 563 Phnum += 3; 564 565 NextAvailableAddress += Phnum * sizeof(ELF64LEPhdrTy); 566 NextAvailableOffset += Phnum * sizeof(ELF64LEPhdrTy); 567 } 568 569 // Align at cache line. 570 NextAvailableAddress = alignTo(NextAvailableAddress, 64); 571 NextAvailableOffset = alignTo(NextAvailableOffset, 64); 572 573 NewTextSegmentAddress = NextAvailableAddress; 574 NewTextSegmentOffset = NextAvailableOffset; 575 BC->LayoutStartAddress = NextAvailableAddress; 576 577 // Tools such as objcopy can strip section contents but leave header 578 // entries. Check that at least .text is mapped in the file. 579 if (!getFileOffsetForAddress(BC->OldTextSectionAddress)) 580 return createStringError(errc::executable_format_error, 581 "BOLT-ERROR: input binary is not a valid ELF " 582 "executable as its text section is not " 583 "mapped to a valid segment"); 584 return Error::success(); 585 } 586 587 void RewriteInstance::parseSDTNotes() { 588 if (!SDTSection) 589 return; 590 591 StringRef Buf = SDTSection->getContents(); 592 DataExtractor DE = DataExtractor(Buf, BC->AsmInfo->isLittleEndian(), 593 BC->AsmInfo->getCodePointerSize()); 594 uint64_t Offset = 0; 595 596 while (DE.isValidOffset(Offset)) { 597 uint32_t NameSz = DE.getU32(&Offset); 598 DE.getU32(&Offset); // skip over DescSz 599 uint32_t Type = DE.getU32(&Offset); 600 Offset = alignTo(Offset, 4); 601 602 if (Type != 3) 603 errs() << "BOLT-WARNING: SDT note type \"" << Type 604 << "\" is not expected\n"; 605 606 if (NameSz == 0) 607 errs() << "BOLT-WARNING: SDT note has empty name\n"; 608 609 StringRef Name = DE.getCStr(&Offset); 610 611 if (!Name.equals("stapsdt")) 612 errs() << "BOLT-WARNING: SDT note name \"" << Name 613 << "\" is not expected\n"; 614 615 // Parse description 616 SDTMarkerInfo Marker; 617 Marker.PCOffset = Offset; 618 Marker.PC = DE.getU64(&Offset); 619 Marker.Base = DE.getU64(&Offset); 620 Marker.Semaphore = DE.getU64(&Offset); 621 Marker.Provider = DE.getCStr(&Offset); 622 Marker.Name = DE.getCStr(&Offset); 623 Marker.Args = DE.getCStr(&Offset); 624 Offset = alignTo(Offset, 4); 625 BC->SDTMarkers[Marker.PC] = Marker; 626 } 627 628 if (opts::PrintSDTMarkers) 629 printSDTMarkers(); 630 } 631 632 void RewriteInstance::parsePseudoProbe() { 633 if (!PseudoProbeDescSection && !PseudoProbeSection) { 634 // pesudo probe is not added to binary. It is normal and no warning needed. 635 return; 636 } 637 638 // If only one section is found, it might mean the ELF is corrupted. 639 if (!PseudoProbeDescSection) { 640 errs() << "BOLT-WARNING: fail in reading .pseudo_probe_desc binary\n"; 641 return; 642 } else if (!PseudoProbeSection) { 643 errs() << "BOLT-WARNING: fail in reading .pseudo_probe binary\n"; 644 return; 645 } 646 647 StringRef Contents = PseudoProbeDescSection->getContents(); 648 if (!BC->ProbeDecoder.buildGUID2FuncDescMap( 649 reinterpret_cast<const uint8_t *>(Contents.data()), 650 Contents.size())) { 651 errs() << "BOLT-WARNING: fail in building GUID2FuncDescMap\n"; 652 return; 653 } 654 Contents = PseudoProbeSection->getContents(); 655 if (!BC->ProbeDecoder.buildAddress2ProbeMap( 656 reinterpret_cast<const uint8_t *>(Contents.data()), 657 Contents.size())) { 658 BC->ProbeDecoder.getAddress2ProbesMap().clear(); 659 errs() << "BOLT-WARNING: fail in building Address2ProbeMap\n"; 660 return; 661 } 662 663 if (opts::PrintPseudoProbes == opts::PrintPseudoProbesOptions::PPP_All || 664 opts::PrintPseudoProbes == 665 opts::PrintPseudoProbesOptions::PPP_Probes_Section_Decode) { 666 outs() << "Report of decoding input pseudo probe binaries \n"; 667 BC->ProbeDecoder.printGUID2FuncDescMap(outs()); 668 BC->ProbeDecoder.printProbesForAllAddresses(outs()); 669 } 670 } 671 672 void RewriteInstance::printSDTMarkers() { 673 outs() << "BOLT-INFO: Number of SDT markers is " << BC->SDTMarkers.size() 674 << "\n"; 675 for (auto It : BC->SDTMarkers) { 676 SDTMarkerInfo &Marker = It.second; 677 outs() << "BOLT-INFO: PC: " << utohexstr(Marker.PC) 678 << ", Base: " << utohexstr(Marker.Base) 679 << ", Semaphore: " << utohexstr(Marker.Semaphore) 680 << ", Provider: " << Marker.Provider << ", Name: " << Marker.Name 681 << ", Args: " << Marker.Args << "\n"; 682 } 683 } 684 685 void RewriteInstance::parseBuildID() { 686 if (!BuildIDSection) 687 return; 688 689 StringRef Buf = BuildIDSection->getContents(); 690 691 // Reading notes section (see Portable Formats Specification, Version 1.1, 692 // pg 2-5, section "Note Section"). 693 DataExtractor DE = DataExtractor(Buf, true, 8); 694 uint64_t Offset = 0; 695 if (!DE.isValidOffset(Offset)) 696 return; 697 uint32_t NameSz = DE.getU32(&Offset); 698 if (!DE.isValidOffset(Offset)) 699 return; 700 uint32_t DescSz = DE.getU32(&Offset); 701 if (!DE.isValidOffset(Offset)) 702 return; 703 uint32_t Type = DE.getU32(&Offset); 704 705 LLVM_DEBUG(dbgs() << "NameSz = " << NameSz << "; DescSz = " << DescSz 706 << "; Type = " << Type << "\n"); 707 708 // Type 3 is a GNU build-id note section 709 if (Type != 3) 710 return; 711 712 StringRef Name = Buf.slice(Offset, Offset + NameSz); 713 Offset = alignTo(Offset + NameSz, 4); 714 if (Name.substr(0, 3) != "GNU") 715 return; 716 717 BuildID = Buf.slice(Offset, Offset + DescSz); 718 } 719 720 Optional<std::string> RewriteInstance::getPrintableBuildID() const { 721 if (BuildID.empty()) 722 return NoneType(); 723 724 std::string Str; 725 raw_string_ostream OS(Str); 726 const unsigned char *CharIter = BuildID.bytes_begin(); 727 while (CharIter != BuildID.bytes_end()) { 728 if (*CharIter < 0x10) 729 OS << "0"; 730 OS << Twine::utohexstr(*CharIter); 731 ++CharIter; 732 } 733 return OS.str(); 734 } 735 736 void RewriteInstance::patchBuildID() { 737 raw_fd_ostream &OS = Out->os(); 738 739 if (BuildID.empty()) 740 return; 741 742 size_t IDOffset = BuildIDSection->getContents().rfind(BuildID); 743 assert(IDOffset != StringRef::npos && "failed to patch build-id"); 744 745 uint64_t FileOffset = getFileOffsetForAddress(BuildIDSection->getAddress()); 746 if (!FileOffset) { 747 errs() << "BOLT-WARNING: Non-allocatable build-id will not be updated.\n"; 748 return; 749 } 750 751 char LastIDByte = BuildID[BuildID.size() - 1]; 752 LastIDByte ^= 1; 753 OS.pwrite(&LastIDByte, 1, FileOffset + IDOffset + BuildID.size() - 1); 754 755 outs() << "BOLT-INFO: patched build-id (flipped last bit)\n"; 756 } 757 758 Error RewriteInstance::run() { 759 assert(BC && "failed to create a binary context"); 760 761 outs() << "BOLT-INFO: Target architecture: " 762 << Triple::getArchTypeName( 763 (llvm::Triple::ArchType)InputFile->getArch()) 764 << "\n"; 765 outs() << "BOLT-INFO: BOLT version: " << BoltRevision << "\n"; 766 767 if (Error E = discoverStorage()) 768 return E; 769 if (Error E = readSpecialSections()) 770 return E; 771 adjustCommandLineOptions(); 772 discoverFileObjects(); 773 774 preprocessProfileData(); 775 776 // Skip disassembling if we have a translation table and we are running an 777 // aggregation job. 778 if (opts::AggregateOnly && BAT->enabledFor(InputFile)) { 779 processProfileData(); 780 return Error::success(); 781 } 782 783 selectFunctionsToProcess(); 784 785 readDebugInfo(); 786 787 disassembleFunctions(); 788 789 processProfileDataPreCFG(); 790 791 buildFunctionsCFG(); 792 793 processProfileData(); 794 795 postProcessFunctions(); 796 797 if (opts::DiffOnly) 798 return Error::success(); 799 800 runOptimizationPasses(); 801 802 emitAndLink(); 803 804 updateMetadata(); 805 806 if (opts::LinuxKernelMode) { 807 errs() << "BOLT-WARNING: not writing the output file for Linux Kernel\n"; 808 return Error::success(); 809 } else if (opts::OutputFilename == "/dev/null") { 810 outs() << "BOLT-INFO: skipping writing final binary to disk\n"; 811 return Error::success(); 812 } 813 814 // Rewrite allocatable contents and copy non-allocatable parts with mods. 815 rewriteFile(); 816 return Error::success(); 817 } 818 819 void RewriteInstance::discoverFileObjects() { 820 NamedRegionTimer T("discoverFileObjects", "discover file objects", 821 TimerGroupName, TimerGroupDesc, opts::TimeRewrite); 822 FileSymRefs.clear(); 823 BC->getBinaryFunctions().clear(); 824 BC->clearBinaryData(); 825 826 // For local symbols we want to keep track of associated FILE symbol name for 827 // disambiguation by combined name. 828 StringRef FileSymbolName; 829 bool SeenFileName = false; 830 struct SymbolRefHash { 831 size_t operator()(SymbolRef const &S) const { 832 return std::hash<decltype(DataRefImpl::p)>{}(S.getRawDataRefImpl().p); 833 } 834 }; 835 std::unordered_map<SymbolRef, StringRef, SymbolRefHash> SymbolToFileName; 836 for (const ELFSymbolRef &Symbol : InputFile->symbols()) { 837 Expected<StringRef> NameOrError = Symbol.getName(); 838 if (NameOrError && NameOrError->startswith("__asan_init")) { 839 errs() << "BOLT-ERROR: input file was compiled or linked with sanitizer " 840 "support. Cannot optimize.\n"; 841 exit(1); 842 } 843 if (NameOrError && NameOrError->startswith("__llvm_coverage_mapping")) { 844 errs() << "BOLT-ERROR: input file was compiled or linked with coverage " 845 "support. Cannot optimize.\n"; 846 exit(1); 847 } 848 849 if (cantFail(Symbol.getFlags()) & SymbolRef::SF_Undefined) 850 continue; 851 852 if (cantFail(Symbol.getType()) == SymbolRef::ST_File) { 853 StringRef Name = 854 cantFail(std::move(NameOrError), "cannot get symbol name for file"); 855 // Ignore Clang LTO artificial FILE symbol as it is not always generated, 856 // and this uncertainty is causing havoc in function name matching. 857 if (Name == "ld-temp.o") 858 continue; 859 FileSymbolName = Name; 860 SeenFileName = true; 861 continue; 862 } 863 if (!FileSymbolName.empty() && 864 !(cantFail(Symbol.getFlags()) & SymbolRef::SF_Global)) 865 SymbolToFileName[Symbol] = FileSymbolName; 866 } 867 868 // Sort symbols in the file by value. Ignore symbols from non-allocatable 869 // sections. 870 auto isSymbolInMemory = [this](const SymbolRef &Sym) { 871 if (cantFail(Sym.getType()) == SymbolRef::ST_File) 872 return false; 873 if (cantFail(Sym.getFlags()) & SymbolRef::SF_Absolute) 874 return true; 875 if (cantFail(Sym.getFlags()) & SymbolRef::SF_Undefined) 876 return false; 877 BinarySection Section(*BC, *cantFail(Sym.getSection())); 878 return Section.isAllocatable(); 879 }; 880 std::vector<SymbolRef> SortedFileSymbols; 881 std::copy_if(InputFile->symbol_begin(), InputFile->symbol_end(), 882 std::back_inserter(SortedFileSymbols), isSymbolInMemory); 883 884 std::stable_sort( 885 SortedFileSymbols.begin(), SortedFileSymbols.end(), 886 [](const SymbolRef &A, const SymbolRef &B) { 887 // FUNC symbols have the highest precedence, while SECTIONs 888 // have the lowest. 889 uint64_t AddressA = cantFail(A.getAddress()); 890 uint64_t AddressB = cantFail(B.getAddress()); 891 if (AddressA != AddressB) 892 return AddressA < AddressB; 893 894 SymbolRef::Type AType = cantFail(A.getType()); 895 SymbolRef::Type BType = cantFail(B.getType()); 896 if (AType == SymbolRef::ST_Function && BType != SymbolRef::ST_Function) 897 return true; 898 if (BType == SymbolRef::ST_Debug && AType != SymbolRef::ST_Debug) 899 return true; 900 901 return false; 902 }); 903 904 // For aarch64, the ABI defines mapping symbols so we identify data in the 905 // code section (see IHI0056B). $d identifies data contents. 906 auto LastSymbol = SortedFileSymbols.end() - 1; 907 if (BC->isAArch64()) { 908 LastSymbol = std::stable_partition( 909 SortedFileSymbols.begin(), SortedFileSymbols.end(), 910 [](const SymbolRef &Symbol) { 911 StringRef Name = cantFail(Symbol.getName()); 912 return !(cantFail(Symbol.getType()) == SymbolRef::ST_Unknown && 913 (Name == "$d" || Name.startswith("$d.") || Name == "$x" || 914 Name.startswith("$x."))); 915 }); 916 --LastSymbol; 917 } 918 919 BinaryFunction *PreviousFunction = nullptr; 920 unsigned AnonymousId = 0; 921 922 const auto MarkersBegin = std::next(LastSymbol); 923 for (auto ISym = SortedFileSymbols.begin(); ISym != MarkersBegin; ++ISym) { 924 const SymbolRef &Symbol = *ISym; 925 // Keep undefined symbols for pretty printing? 926 if (cantFail(Symbol.getFlags()) & SymbolRef::SF_Undefined) 927 continue; 928 929 const SymbolRef::Type SymbolType = cantFail(Symbol.getType()); 930 931 if (SymbolType == SymbolRef::ST_File) 932 continue; 933 934 StringRef SymName = cantFail(Symbol.getName(), "cannot get symbol name"); 935 uint64_t Address = 936 cantFail(Symbol.getAddress(), "cannot get symbol address"); 937 if (Address == 0) { 938 if (opts::Verbosity >= 1 && SymbolType == SymbolRef::ST_Function) 939 errs() << "BOLT-WARNING: function with 0 address seen\n"; 940 continue; 941 } 942 943 // Ignore input hot markers 944 if (SymName == "__hot_start" || SymName == "__hot_end") 945 continue; 946 947 FileSymRefs[Address] = Symbol; 948 949 // Skip section symbols that will be registered by disassemblePLT(). 950 if ((cantFail(Symbol.getType()) == SymbolRef::ST_Debug)) { 951 ErrorOr<BinarySection &> BSection = BC->getSectionForAddress(Address); 952 if (BSection && getPLTSectionInfo(BSection->getName())) 953 continue; 954 } 955 956 /// It is possible we are seeing a globalized local. LLVM might treat it as 957 /// a local if it has a "private global" prefix, e.g. ".L". Thus we have to 958 /// change the prefix to enforce global scope of the symbol. 959 std::string Name = SymName.startswith(BC->AsmInfo->getPrivateGlobalPrefix()) 960 ? "PG" + std::string(SymName) 961 : std::string(SymName); 962 963 // Disambiguate all local symbols before adding to symbol table. 964 // Since we don't know if we will see a global with the same name, 965 // always modify the local name. 966 // 967 // NOTE: the naming convention for local symbols should match 968 // the one we use for profile data. 969 std::string UniqueName; 970 std::string AlternativeName; 971 if (Name.empty()) { 972 UniqueName = "ANONYMOUS." + std::to_string(AnonymousId++); 973 } else if (cantFail(Symbol.getFlags()) & SymbolRef::SF_Global) { 974 assert(!BC->getBinaryDataByName(Name) && "global name not unique"); 975 UniqueName = Name; 976 } else { 977 // If we have a local file name, we should create 2 variants for the 978 // function name. The reason is that perf profile might have been 979 // collected on a binary that did not have the local file name (e.g. as 980 // a side effect of stripping debug info from the binary): 981 // 982 // primary: <function>/<id> 983 // alternative: <function>/<file>/<id2> 984 // 985 // The <id> field is used for disambiguation of local symbols since there 986 // could be identical function names coming from identical file names 987 // (e.g. from different directories). 988 std::string AltPrefix; 989 auto SFI = SymbolToFileName.find(Symbol); 990 if (SymbolType == SymbolRef::ST_Function && SFI != SymbolToFileName.end()) 991 AltPrefix = Name + "/" + std::string(SFI->second); 992 993 UniqueName = NR.uniquify(Name); 994 if (!AltPrefix.empty()) 995 AlternativeName = NR.uniquify(AltPrefix); 996 } 997 998 uint64_t SymbolSize = ELFSymbolRef(Symbol).getSize(); 999 uint64_t SymbolAlignment = Symbol.getAlignment(); 1000 unsigned SymbolFlags = cantFail(Symbol.getFlags()); 1001 1002 auto registerName = [&](uint64_t FinalSize) { 1003 // Register names even if it's not a function, e.g. for an entry point. 1004 BC->registerNameAtAddress(UniqueName, Address, FinalSize, SymbolAlignment, 1005 SymbolFlags); 1006 if (!AlternativeName.empty()) 1007 BC->registerNameAtAddress(AlternativeName, Address, FinalSize, 1008 SymbolAlignment, SymbolFlags); 1009 }; 1010 1011 section_iterator Section = 1012 cantFail(Symbol.getSection(), "cannot get symbol section"); 1013 if (Section == InputFile->section_end()) { 1014 // Could be an absolute symbol. Could record for pretty printing. 1015 LLVM_DEBUG(if (opts::Verbosity > 1) { 1016 dbgs() << "BOLT-INFO: absolute sym " << UniqueName << "\n"; 1017 }); 1018 registerName(SymbolSize); 1019 continue; 1020 } 1021 1022 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: considering symbol " << UniqueName 1023 << " for function\n"); 1024 1025 if (!Section->isText()) { 1026 assert(SymbolType != SymbolRef::ST_Function && 1027 "unexpected function inside non-code section"); 1028 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: rejecting as symbol is not in code\n"); 1029 registerName(SymbolSize); 1030 continue; 1031 } 1032 1033 // Assembly functions could be ST_NONE with 0 size. Check that the 1034 // corresponding section is a code section and they are not inside any 1035 // other known function to consider them. 1036 // 1037 // Sometimes assembly functions are not marked as functions and neither are 1038 // their local labels. The only way to tell them apart is to look at 1039 // symbol scope - global vs local. 1040 if (PreviousFunction && SymbolType != SymbolRef::ST_Function) { 1041 if (PreviousFunction->containsAddress(Address)) { 1042 if (PreviousFunction->isSymbolValidInScope(Symbol, SymbolSize)) { 1043 LLVM_DEBUG(dbgs() 1044 << "BOLT-DEBUG: symbol is a function local symbol\n"); 1045 } else if (Address == PreviousFunction->getAddress() && !SymbolSize) { 1046 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: ignoring symbol as a marker\n"); 1047 } else if (opts::Verbosity > 1) { 1048 errs() << "BOLT-WARNING: symbol " << UniqueName 1049 << " seen in the middle of function " << *PreviousFunction 1050 << ". Could be a new entry.\n"; 1051 } 1052 registerName(SymbolSize); 1053 continue; 1054 } else if (PreviousFunction->getSize() == 0 && 1055 PreviousFunction->isSymbolValidInScope(Symbol, SymbolSize)) { 1056 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: symbol is a function local symbol\n"); 1057 registerName(SymbolSize); 1058 continue; 1059 } 1060 } 1061 1062 if (PreviousFunction && PreviousFunction->containsAddress(Address) && 1063 PreviousFunction->getAddress() != Address) { 1064 if (PreviousFunction->isSymbolValidInScope(Symbol, SymbolSize)) { 1065 if (opts::Verbosity >= 1) 1066 outs() << "BOLT-INFO: skipping possibly another entry for function " 1067 << *PreviousFunction << " : " << UniqueName << '\n'; 1068 } else { 1069 outs() << "BOLT-INFO: using " << UniqueName << " as another entry to " 1070 << "function " << *PreviousFunction << '\n'; 1071 1072 registerName(0); 1073 1074 PreviousFunction->addEntryPointAtOffset(Address - 1075 PreviousFunction->getAddress()); 1076 1077 // Remove the symbol from FileSymRefs so that we can skip it from 1078 // in the future. 1079 auto SI = FileSymRefs.find(Address); 1080 assert(SI != FileSymRefs.end() && "symbol expected to be present"); 1081 assert(SI->second == Symbol && "wrong symbol found"); 1082 FileSymRefs.erase(SI); 1083 } 1084 registerName(SymbolSize); 1085 continue; 1086 } 1087 1088 // Checkout for conflicts with function data from FDEs. 1089 bool IsSimple = true; 1090 auto FDEI = CFIRdWrt->getFDEs().lower_bound(Address); 1091 if (FDEI != CFIRdWrt->getFDEs().end()) { 1092 const dwarf::FDE &FDE = *FDEI->second; 1093 if (FDEI->first != Address) { 1094 // There's no matching starting address in FDE. Make sure the previous 1095 // FDE does not contain this address. 1096 if (FDEI != CFIRdWrt->getFDEs().begin()) { 1097 --FDEI; 1098 const dwarf::FDE &PrevFDE = *FDEI->second; 1099 uint64_t PrevStart = PrevFDE.getInitialLocation(); 1100 uint64_t PrevLength = PrevFDE.getAddressRange(); 1101 if (Address > PrevStart && Address < PrevStart + PrevLength) { 1102 errs() << "BOLT-ERROR: function " << UniqueName 1103 << " is in conflict with FDE [" 1104 << Twine::utohexstr(PrevStart) << ", " 1105 << Twine::utohexstr(PrevStart + PrevLength) 1106 << "). Skipping.\n"; 1107 IsSimple = false; 1108 } 1109 } 1110 } else if (FDE.getAddressRange() != SymbolSize) { 1111 if (SymbolSize) { 1112 // Function addresses match but sizes differ. 1113 errs() << "BOLT-WARNING: sizes differ for function " << UniqueName 1114 << ". FDE : " << FDE.getAddressRange() 1115 << "; symbol table : " << SymbolSize << ". Using max size.\n"; 1116 } 1117 SymbolSize = std::max(SymbolSize, FDE.getAddressRange()); 1118 if (BC->getBinaryDataAtAddress(Address)) { 1119 BC->setBinaryDataSize(Address, SymbolSize); 1120 } else { 1121 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: No BD @ 0x" 1122 << Twine::utohexstr(Address) << "\n"); 1123 } 1124 } 1125 } 1126 1127 BinaryFunction *BF = nullptr; 1128 // Since function may not have yet obtained its real size, do a search 1129 // using the list of registered functions instead of calling 1130 // getBinaryFunctionAtAddress(). 1131 auto BFI = BC->getBinaryFunctions().find(Address); 1132 if (BFI != BC->getBinaryFunctions().end()) { 1133 BF = &BFI->second; 1134 // Duplicate the function name. Make sure everything matches before we add 1135 // an alternative name. 1136 if (SymbolSize != BF->getSize()) { 1137 if (opts::Verbosity >= 1) { 1138 if (SymbolSize && BF->getSize()) 1139 errs() << "BOLT-WARNING: size mismatch for duplicate entries " 1140 << *BF << " and " << UniqueName << '\n'; 1141 outs() << "BOLT-INFO: adjusting size of function " << *BF << " old " 1142 << BF->getSize() << " new " << SymbolSize << "\n"; 1143 } 1144 BF->setSize(std::max(SymbolSize, BF->getSize())); 1145 BC->setBinaryDataSize(Address, BF->getSize()); 1146 } 1147 BF->addAlternativeName(UniqueName); 1148 } else { 1149 ErrorOr<BinarySection &> Section = BC->getSectionForAddress(Address); 1150 // Skip symbols from invalid sections 1151 if (!Section) { 1152 errs() << "BOLT-WARNING: " << UniqueName << " (0x" 1153 << Twine::utohexstr(Address) << ") does not have any section\n"; 1154 continue; 1155 } 1156 assert(Section && "section for functions must be registered"); 1157 1158 // Skip symbols from zero-sized sections. 1159 if (!Section->getSize()) 1160 continue; 1161 1162 BF = BC->createBinaryFunction(UniqueName, *Section, Address, SymbolSize); 1163 if (!IsSimple) 1164 BF->setSimple(false); 1165 } 1166 if (!AlternativeName.empty()) 1167 BF->addAlternativeName(AlternativeName); 1168 1169 registerName(SymbolSize); 1170 PreviousFunction = BF; 1171 } 1172 1173 // Read dynamic relocation first as their presence affects the way we process 1174 // static relocations. E.g. we will ignore a static relocation at an address 1175 // that is a subject to dynamic relocation processing. 1176 processDynamicRelocations(); 1177 1178 // Process PLT section. 1179 disassemblePLT(); 1180 1181 // See if we missed any functions marked by FDE. 1182 for (const auto &FDEI : CFIRdWrt->getFDEs()) { 1183 const uint64_t Address = FDEI.first; 1184 const dwarf::FDE *FDE = FDEI.second; 1185 const BinaryFunction *BF = BC->getBinaryFunctionAtAddress(Address); 1186 if (BF) 1187 continue; 1188 1189 BF = BC->getBinaryFunctionContainingAddress(Address); 1190 if (BF) { 1191 errs() << "BOLT-WARNING: FDE [0x" << Twine::utohexstr(Address) << ", 0x" 1192 << Twine::utohexstr(Address + FDE->getAddressRange()) 1193 << ") conflicts with function " << *BF << '\n'; 1194 continue; 1195 } 1196 1197 if (opts::Verbosity >= 1) 1198 errs() << "BOLT-WARNING: FDE [0x" << Twine::utohexstr(Address) << ", 0x" 1199 << Twine::utohexstr(Address + FDE->getAddressRange()) 1200 << ") has no corresponding symbol table entry\n"; 1201 1202 ErrorOr<BinarySection &> Section = BC->getSectionForAddress(Address); 1203 assert(Section && "cannot get section for address from FDE"); 1204 std::string FunctionName = 1205 "__BOLT_FDE_FUNCat" + Twine::utohexstr(Address).str(); 1206 BC->createBinaryFunction(FunctionName, *Section, Address, 1207 FDE->getAddressRange()); 1208 } 1209 1210 BC->setHasSymbolsWithFileName(SeenFileName); 1211 1212 // Now that all the functions were created - adjust their boundaries. 1213 adjustFunctionBoundaries(); 1214 1215 // Annotate functions with code/data markers in AArch64 1216 for (auto ISym = MarkersBegin; ISym != SortedFileSymbols.end(); ++ISym) { 1217 const SymbolRef &Symbol = *ISym; 1218 uint64_t Address = 1219 cantFail(Symbol.getAddress(), "cannot get symbol address"); 1220 uint64_t SymbolSize = ELFSymbolRef(Symbol).getSize(); 1221 BinaryFunction *BF = 1222 BC->getBinaryFunctionContainingAddress(Address, true, true); 1223 if (!BF) { 1224 // Stray marker 1225 continue; 1226 } 1227 const uint64_t EntryOffset = Address - BF->getAddress(); 1228 if (BF->isCodeMarker(Symbol, SymbolSize)) { 1229 BF->markCodeAtOffset(EntryOffset); 1230 continue; 1231 } 1232 if (BF->isDataMarker(Symbol, SymbolSize)) { 1233 BF->markDataAtOffset(EntryOffset); 1234 BC->AddressToConstantIslandMap[Address] = BF; 1235 continue; 1236 } 1237 llvm_unreachable("Unknown marker"); 1238 } 1239 1240 if (opts::LinuxKernelMode) { 1241 // Read all special linux kernel sections and their relocations 1242 processLKSections(); 1243 } else { 1244 // Read all relocations now that we have binary functions mapped. 1245 processRelocations(); 1246 } 1247 } 1248 1249 void RewriteInstance::createPLTBinaryFunction(uint64_t TargetAddress, 1250 uint64_t EntryAddress, 1251 uint64_t EntrySize) { 1252 if (!TargetAddress) 1253 return; 1254 1255 auto setPLTSymbol = [&](BinaryFunction *BF, StringRef Name) { 1256 const unsigned PtrSize = BC->AsmInfo->getCodePointerSize(); 1257 MCSymbol *TargetSymbol = BC->registerNameAtAddress( 1258 Name.str() + "@GOT", TargetAddress, PtrSize, PtrSize); 1259 BF->setPLTSymbol(TargetSymbol); 1260 }; 1261 1262 BinaryFunction *BF = BC->getBinaryFunctionAtAddress(EntryAddress); 1263 if (BF && BC->isAArch64()) { 1264 // Handle IFUNC trampoline 1265 setPLTSymbol(BF, BF->getOneName()); 1266 return; 1267 } 1268 1269 const Relocation *Rel = BC->getDynamicRelocationAt(TargetAddress); 1270 if (!Rel || !Rel->Symbol) 1271 return; 1272 1273 ErrorOr<BinarySection &> Section = BC->getSectionForAddress(EntryAddress); 1274 assert(Section && "cannot get section for address"); 1275 BF = BC->createBinaryFunction(Rel->Symbol->getName().str() + "@PLT", *Section, 1276 EntryAddress, 0, EntrySize, 1277 Section->getAlignment()); 1278 setPLTSymbol(BF, Rel->Symbol->getName()); 1279 } 1280 1281 void RewriteInstance::disassemblePLTSectionAArch64(BinarySection &Section) { 1282 const uint64_t SectionAddress = Section.getAddress(); 1283 const uint64_t SectionSize = Section.getSize(); 1284 StringRef PLTContents = Section.getContents(); 1285 ArrayRef<uint8_t> PLTData( 1286 reinterpret_cast<const uint8_t *>(PLTContents.data()), SectionSize); 1287 1288 auto disassembleInstruction = [&](uint64_t InstrOffset, MCInst &Instruction, 1289 uint64_t &InstrSize) { 1290 const uint64_t InstrAddr = SectionAddress + InstrOffset; 1291 if (!BC->DisAsm->getInstruction(Instruction, InstrSize, 1292 PLTData.slice(InstrOffset), InstrAddr, 1293 nulls())) { 1294 errs() << "BOLT-ERROR: unable to disassemble instruction in PLT section " 1295 << Section.getName() << " at offset 0x" 1296 << Twine::utohexstr(InstrOffset) << '\n'; 1297 exit(1); 1298 } 1299 }; 1300 1301 uint64_t InstrOffset = 0; 1302 // Locate new plt entry 1303 while (InstrOffset < SectionSize) { 1304 InstructionListType Instructions; 1305 MCInst Instruction; 1306 uint64_t EntryOffset = InstrOffset; 1307 uint64_t EntrySize = 0; 1308 uint64_t InstrSize; 1309 // Loop through entry instructions 1310 while (InstrOffset < SectionSize) { 1311 disassembleInstruction(InstrOffset, Instruction, InstrSize); 1312 EntrySize += InstrSize; 1313 if (!BC->MIB->isIndirectBranch(Instruction)) { 1314 Instructions.emplace_back(Instruction); 1315 InstrOffset += InstrSize; 1316 continue; 1317 } 1318 1319 const uint64_t EntryAddress = SectionAddress + EntryOffset; 1320 const uint64_t TargetAddress = BC->MIB->analyzePLTEntry( 1321 Instruction, Instructions.begin(), Instructions.end(), EntryAddress); 1322 1323 createPLTBinaryFunction(TargetAddress, EntryAddress, EntrySize); 1324 break; 1325 } 1326 1327 // Branch instruction 1328 InstrOffset += InstrSize; 1329 1330 // Skip nops if any 1331 while (InstrOffset < SectionSize) { 1332 disassembleInstruction(InstrOffset, Instruction, InstrSize); 1333 if (!BC->MIB->isNoop(Instruction)) 1334 break; 1335 1336 InstrOffset += InstrSize; 1337 } 1338 } 1339 } 1340 1341 void RewriteInstance::disassemblePLTSectionX86(BinarySection &Section, 1342 uint64_t EntrySize) { 1343 const uint64_t SectionAddress = Section.getAddress(); 1344 const uint64_t SectionSize = Section.getSize(); 1345 StringRef PLTContents = Section.getContents(); 1346 ArrayRef<uint8_t> PLTData( 1347 reinterpret_cast<const uint8_t *>(PLTContents.data()), SectionSize); 1348 1349 auto disassembleInstruction = [&](uint64_t InstrOffset, MCInst &Instruction, 1350 uint64_t &InstrSize) { 1351 const uint64_t InstrAddr = SectionAddress + InstrOffset; 1352 if (!BC->DisAsm->getInstruction(Instruction, InstrSize, 1353 PLTData.slice(InstrOffset), InstrAddr, 1354 nulls())) { 1355 errs() << "BOLT-ERROR: unable to disassemble instruction in PLT section " 1356 << Section.getName() << " at offset 0x" 1357 << Twine::utohexstr(InstrOffset) << '\n'; 1358 exit(1); 1359 } 1360 }; 1361 1362 for (uint64_t EntryOffset = 0; EntryOffset + EntrySize <= SectionSize; 1363 EntryOffset += EntrySize) { 1364 MCInst Instruction; 1365 uint64_t InstrSize, InstrOffset = EntryOffset; 1366 while (InstrOffset < EntryOffset + EntrySize) { 1367 disassembleInstruction(InstrOffset, Instruction, InstrSize); 1368 // Check if the entry size needs adjustment. 1369 if (EntryOffset == 0 && BC->MIB->isTerminateBranch(Instruction) && 1370 EntrySize == 8) 1371 EntrySize = 16; 1372 1373 if (BC->MIB->isIndirectBranch(Instruction)) 1374 break; 1375 1376 InstrOffset += InstrSize; 1377 } 1378 1379 if (InstrOffset + InstrSize > EntryOffset + EntrySize) 1380 continue; 1381 1382 uint64_t TargetAddress; 1383 if (!BC->MIB->evaluateMemOperandTarget(Instruction, TargetAddress, 1384 SectionAddress + InstrOffset, 1385 InstrSize)) { 1386 errs() << "BOLT-ERROR: error evaluating PLT instruction at offset 0x" 1387 << Twine::utohexstr(SectionAddress + InstrOffset) << '\n'; 1388 exit(1); 1389 } 1390 1391 createPLTBinaryFunction(TargetAddress, SectionAddress + EntryOffset, 1392 EntrySize); 1393 } 1394 } 1395 1396 void RewriteInstance::disassemblePLT() { 1397 auto analyzeOnePLTSection = [&](BinarySection &Section, uint64_t EntrySize) { 1398 if (BC->isAArch64()) 1399 return disassemblePLTSectionAArch64(Section); 1400 return disassemblePLTSectionX86(Section, EntrySize); 1401 }; 1402 1403 for (BinarySection &Section : BC->allocatableSections()) { 1404 const PLTSectionInfo *PLTSI = getPLTSectionInfo(Section.getName()); 1405 if (!PLTSI) 1406 continue; 1407 1408 analyzeOnePLTSection(Section, PLTSI->EntrySize); 1409 // If we did not register any function at the start of the section, 1410 // then it must be a general PLT entry. Add a function at the location. 1411 if (BC->getBinaryFunctions().find(Section.getAddress()) == 1412 BC->getBinaryFunctions().end()) { 1413 BinaryFunction *BF = BC->createBinaryFunction( 1414 "__BOLT_PSEUDO_" + Section.getName().str(), Section, 1415 Section.getAddress(), 0, PLTSI->EntrySize, Section.getAlignment()); 1416 BF->setPseudo(true); 1417 } 1418 } 1419 } 1420 1421 void RewriteInstance::adjustFunctionBoundaries() { 1422 for (auto BFI = BC->getBinaryFunctions().begin(), 1423 BFE = BC->getBinaryFunctions().end(); 1424 BFI != BFE; ++BFI) { 1425 BinaryFunction &Function = BFI->second; 1426 const BinaryFunction *NextFunction = nullptr; 1427 if (std::next(BFI) != BFE) 1428 NextFunction = &std::next(BFI)->second; 1429 1430 // Check if it's a fragment of a function. 1431 Optional<StringRef> FragName = 1432 Function.hasRestoredNameRegex(".*\\.cold(\\.[0-9]+)?"); 1433 if (FragName) { 1434 static bool PrintedWarning = false; 1435 if (BC->HasRelocations && !PrintedWarning) { 1436 errs() << "BOLT-WARNING: split function detected on input : " 1437 << *FragName << ". The support is limited in relocation mode.\n"; 1438 PrintedWarning = true; 1439 } 1440 Function.IsFragment = true; 1441 } 1442 1443 // Check if there's a symbol or a function with a larger address in the 1444 // same section. If there is - it determines the maximum size for the 1445 // current function. Otherwise, it is the size of a containing section 1446 // the defines it. 1447 // 1448 // NOTE: ignore some symbols that could be tolerated inside the body 1449 // of a function. 1450 auto NextSymRefI = FileSymRefs.upper_bound(Function.getAddress()); 1451 while (NextSymRefI != FileSymRefs.end()) { 1452 SymbolRef &Symbol = NextSymRefI->second; 1453 const uint64_t SymbolAddress = NextSymRefI->first; 1454 const uint64_t SymbolSize = ELFSymbolRef(Symbol).getSize(); 1455 1456 if (NextFunction && SymbolAddress >= NextFunction->getAddress()) 1457 break; 1458 1459 if (!Function.isSymbolValidInScope(Symbol, SymbolSize)) 1460 break; 1461 1462 // This is potentially another entry point into the function. 1463 uint64_t EntryOffset = NextSymRefI->first - Function.getAddress(); 1464 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: adding entry point to function " 1465 << Function << " at offset 0x" 1466 << Twine::utohexstr(EntryOffset) << '\n'); 1467 Function.addEntryPointAtOffset(EntryOffset); 1468 1469 ++NextSymRefI; 1470 } 1471 1472 // Function runs at most till the end of the containing section. 1473 uint64_t NextObjectAddress = Function.getOriginSection()->getEndAddress(); 1474 // Or till the next object marked by a symbol. 1475 if (NextSymRefI != FileSymRefs.end()) 1476 NextObjectAddress = std::min(NextSymRefI->first, NextObjectAddress); 1477 1478 // Or till the next function not marked by a symbol. 1479 if (NextFunction) 1480 NextObjectAddress = 1481 std::min(NextFunction->getAddress(), NextObjectAddress); 1482 1483 const uint64_t MaxSize = NextObjectAddress - Function.getAddress(); 1484 if (MaxSize < Function.getSize()) { 1485 errs() << "BOLT-ERROR: symbol seen in the middle of the function " 1486 << Function << ". Skipping.\n"; 1487 Function.setSimple(false); 1488 Function.setMaxSize(Function.getSize()); 1489 continue; 1490 } 1491 Function.setMaxSize(MaxSize); 1492 if (!Function.getSize() && Function.isSimple()) { 1493 // Some assembly functions have their size set to 0, use the max 1494 // size as their real size. 1495 if (opts::Verbosity >= 1) 1496 outs() << "BOLT-INFO: setting size of function " << Function << " to " 1497 << Function.getMaxSize() << " (was 0)\n"; 1498 Function.setSize(Function.getMaxSize()); 1499 } 1500 } 1501 } 1502 1503 void RewriteInstance::relocateEHFrameSection() { 1504 assert(EHFrameSection && "non-empty .eh_frame section expected"); 1505 1506 DWARFDataExtractor DE(EHFrameSection->getContents(), 1507 BC->AsmInfo->isLittleEndian(), 1508 BC->AsmInfo->getCodePointerSize()); 1509 auto createReloc = [&](uint64_t Value, uint64_t Offset, uint64_t DwarfType) { 1510 if (DwarfType == dwarf::DW_EH_PE_omit) 1511 return; 1512 1513 // Only fix references that are relative to other locations. 1514 if (!(DwarfType & dwarf::DW_EH_PE_pcrel) && 1515 !(DwarfType & dwarf::DW_EH_PE_textrel) && 1516 !(DwarfType & dwarf::DW_EH_PE_funcrel) && 1517 !(DwarfType & dwarf::DW_EH_PE_datarel)) 1518 return; 1519 1520 if (!(DwarfType & dwarf::DW_EH_PE_sdata4)) 1521 return; 1522 1523 uint64_t RelType; 1524 switch (DwarfType & 0x0f) { 1525 default: 1526 llvm_unreachable("unsupported DWARF encoding type"); 1527 case dwarf::DW_EH_PE_sdata4: 1528 case dwarf::DW_EH_PE_udata4: 1529 RelType = Relocation::getPC32(); 1530 Offset -= 4; 1531 break; 1532 case dwarf::DW_EH_PE_sdata8: 1533 case dwarf::DW_EH_PE_udata8: 1534 RelType = Relocation::getPC64(); 1535 Offset -= 8; 1536 break; 1537 } 1538 1539 // Create a relocation against an absolute value since the goal is to 1540 // preserve the contents of the section independent of the new values 1541 // of referenced symbols. 1542 EHFrameSection->addRelocation(Offset, nullptr, RelType, Value); 1543 }; 1544 1545 Error E = EHFrameParser::parse(DE, EHFrameSection->getAddress(), createReloc); 1546 check_error(std::move(E), "failed to patch EH frame"); 1547 } 1548 1549 ArrayRef<uint8_t> RewriteInstance::getLSDAData() { 1550 return ArrayRef<uint8_t>(LSDASection->getData(), 1551 LSDASection->getContents().size()); 1552 } 1553 1554 uint64_t RewriteInstance::getLSDAAddress() { return LSDASection->getAddress(); } 1555 1556 Error RewriteInstance::readSpecialSections() { 1557 NamedRegionTimer T("readSpecialSections", "read special sections", 1558 TimerGroupName, TimerGroupDesc, opts::TimeRewrite); 1559 1560 bool HasTextRelocations = false; 1561 bool HasDebugInfo = false; 1562 1563 // Process special sections. 1564 for (const SectionRef &Section : InputFile->sections()) { 1565 Expected<StringRef> SectionNameOrErr = Section.getName(); 1566 check_error(SectionNameOrErr.takeError(), "cannot get section name"); 1567 StringRef SectionName = *SectionNameOrErr; 1568 1569 // Only register sections with names. 1570 if (!SectionName.empty()) { 1571 if (Error E = Section.getContents().takeError()) 1572 return E; 1573 BC->registerSection(Section); 1574 LLVM_DEBUG( 1575 dbgs() << "BOLT-DEBUG: registering section " << SectionName << " @ 0x" 1576 << Twine::utohexstr(Section.getAddress()) << ":0x" 1577 << Twine::utohexstr(Section.getAddress() + Section.getSize()) 1578 << "\n"); 1579 if (isDebugSection(SectionName)) 1580 HasDebugInfo = true; 1581 if (isKSymtabSection(SectionName)) 1582 opts::LinuxKernelMode = true; 1583 } 1584 } 1585 1586 if (HasDebugInfo && !opts::UpdateDebugSections && !opts::AggregateOnly) { 1587 errs() << "BOLT-WARNING: debug info will be stripped from the binary. " 1588 "Use -update-debug-sections to keep it.\n"; 1589 } 1590 1591 HasTextRelocations = (bool)BC->getUniqueSectionByName(".rela.text"); 1592 LSDASection = BC->getUniqueSectionByName(".gcc_except_table"); 1593 EHFrameSection = BC->getUniqueSectionByName(".eh_frame"); 1594 GOTPLTSection = BC->getUniqueSectionByName(".got.plt"); 1595 RelaPLTSection = BC->getUniqueSectionByName(".rela.plt"); 1596 RelaDynSection = BC->getUniqueSectionByName(".rela.dyn"); 1597 BuildIDSection = BC->getUniqueSectionByName(".note.gnu.build-id"); 1598 SDTSection = BC->getUniqueSectionByName(".note.stapsdt"); 1599 PseudoProbeDescSection = BC->getUniqueSectionByName(".pseudo_probe_desc"); 1600 PseudoProbeSection = BC->getUniqueSectionByName(".pseudo_probe"); 1601 1602 if (ErrorOr<BinarySection &> BATSec = 1603 BC->getUniqueSectionByName(BoltAddressTranslation::SECTION_NAME)) { 1604 // Do not read BAT when plotting a heatmap 1605 if (!opts::HeatmapMode) { 1606 if (std::error_code EC = BAT->parse(BATSec->getContents())) { 1607 errs() << "BOLT-ERROR: failed to parse BOLT address translation " 1608 "table.\n"; 1609 exit(1); 1610 } 1611 } 1612 } 1613 1614 if (opts::PrintSections) { 1615 outs() << "BOLT-INFO: Sections from original binary:\n"; 1616 BC->printSections(outs()); 1617 } 1618 1619 if (opts::RelocationMode == cl::BOU_TRUE && !HasTextRelocations) { 1620 errs() << "BOLT-ERROR: relocations against code are missing from the input " 1621 "file. Cannot proceed in relocations mode (-relocs).\n"; 1622 exit(1); 1623 } 1624 1625 BC->HasRelocations = 1626 HasTextRelocations && (opts::RelocationMode != cl::BOU_FALSE); 1627 1628 // Force non-relocation mode for heatmap generation 1629 if (opts::HeatmapMode) 1630 BC->HasRelocations = false; 1631 1632 if (BC->HasRelocations) 1633 outs() << "BOLT-INFO: enabling " << (opts::StrictMode ? "strict " : "") 1634 << "relocation mode\n"; 1635 1636 // Read EH frame for function boundaries info. 1637 Expected<const DWARFDebugFrame *> EHFrameOrError = BC->DwCtx->getEHFrame(); 1638 if (!EHFrameOrError) 1639 report_error("expected valid eh_frame section", EHFrameOrError.takeError()); 1640 CFIRdWrt.reset(new CFIReaderWriter(*EHFrameOrError.get())); 1641 1642 // Parse build-id 1643 parseBuildID(); 1644 if (Optional<std::string> FileBuildID = getPrintableBuildID()) 1645 BC->setFileBuildID(*FileBuildID); 1646 1647 parseSDTNotes(); 1648 1649 // Read .dynamic/PT_DYNAMIC. 1650 return readELFDynamic(); 1651 } 1652 1653 void RewriteInstance::adjustCommandLineOptions() { 1654 if (BC->isAArch64() && !BC->HasRelocations) 1655 errs() << "BOLT-WARNING: non-relocation mode for AArch64 is not fully " 1656 "supported\n"; 1657 1658 if (RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary()) 1659 RtLibrary->adjustCommandLineOptions(*BC); 1660 1661 if (opts::AlignMacroOpFusion != MFT_NONE && !BC->isX86()) { 1662 outs() << "BOLT-INFO: disabling -align-macro-fusion on non-x86 platform\n"; 1663 opts::AlignMacroOpFusion = MFT_NONE; 1664 } 1665 1666 if (BC->isX86() && BC->MAB->allowAutoPadding()) { 1667 if (!BC->HasRelocations) { 1668 errs() << "BOLT-ERROR: cannot apply mitigations for Intel JCC erratum in " 1669 "non-relocation mode\n"; 1670 exit(1); 1671 } 1672 outs() << "BOLT-WARNING: using mitigation for Intel JCC erratum, layout " 1673 "may take several minutes\n"; 1674 opts::AlignMacroOpFusion = MFT_NONE; 1675 } 1676 1677 if (opts::AlignMacroOpFusion != MFT_NONE && !BC->HasRelocations) { 1678 outs() << "BOLT-INFO: disabling -align-macro-fusion in non-relocation " 1679 "mode\n"; 1680 opts::AlignMacroOpFusion = MFT_NONE; 1681 } 1682 1683 if (opts::SplitEH && !BC->HasRelocations) { 1684 errs() << "BOLT-WARNING: disabling -split-eh in non-relocation mode\n"; 1685 opts::SplitEH = false; 1686 } 1687 1688 if (opts::SplitEH && !BC->HasFixedLoadAddress) { 1689 errs() << "BOLT-WARNING: disabling -split-eh for shared object\n"; 1690 opts::SplitEH = false; 1691 } 1692 1693 if (opts::StrictMode && !BC->HasRelocations) { 1694 errs() << "BOLT-WARNING: disabling strict mode (-strict) in non-relocation " 1695 "mode\n"; 1696 opts::StrictMode = false; 1697 } 1698 1699 if (BC->HasRelocations && opts::AggregateOnly && 1700 !opts::StrictMode.getNumOccurrences()) { 1701 outs() << "BOLT-INFO: enabling strict relocation mode for aggregation " 1702 "purposes\n"; 1703 opts::StrictMode = true; 1704 } 1705 1706 if (BC->isX86() && BC->HasRelocations && 1707 opts::AlignMacroOpFusion == MFT_HOT && !ProfileReader) { 1708 outs() << "BOLT-INFO: enabling -align-macro-fusion=all since no profile " 1709 "was specified\n"; 1710 opts::AlignMacroOpFusion = MFT_ALL; 1711 } 1712 1713 if (!BC->HasRelocations && 1714 opts::ReorderFunctions != ReorderFunctions::RT_NONE) { 1715 errs() << "BOLT-ERROR: function reordering only works when " 1716 << "relocations are enabled\n"; 1717 exit(1); 1718 } 1719 1720 if (opts::ReorderFunctions != ReorderFunctions::RT_NONE && 1721 !opts::HotText.getNumOccurrences()) { 1722 opts::HotText = true; 1723 } else if (opts::HotText && !BC->HasRelocations) { 1724 errs() << "BOLT-WARNING: hot text is disabled in non-relocation mode\n"; 1725 opts::HotText = false; 1726 } 1727 1728 if (opts::HotText && opts::HotTextMoveSections.getNumOccurrences() == 0) { 1729 opts::HotTextMoveSections.addValue(".stub"); 1730 opts::HotTextMoveSections.addValue(".mover"); 1731 opts::HotTextMoveSections.addValue(".never_hugify"); 1732 } 1733 1734 if (opts::UseOldText && !BC->OldTextSectionAddress) { 1735 errs() << "BOLT-WARNING: cannot use old .text as the section was not found" 1736 "\n"; 1737 opts::UseOldText = false; 1738 } 1739 if (opts::UseOldText && !BC->HasRelocations) { 1740 errs() << "BOLT-WARNING: cannot use old .text in non-relocation mode\n"; 1741 opts::UseOldText = false; 1742 } 1743 1744 if (!opts::AlignText.getNumOccurrences()) 1745 opts::AlignText = BC->PageAlign; 1746 1747 if (opts::AlignText < opts::AlignFunctions) 1748 opts::AlignText = (unsigned)opts::AlignFunctions; 1749 1750 if (BC->isX86() && opts::Lite.getNumOccurrences() == 0 && !opts::StrictMode && 1751 !opts::UseOldText) 1752 opts::Lite = true; 1753 1754 if (opts::Lite && opts::UseOldText) { 1755 errs() << "BOLT-WARNING: cannot combine -lite with -use-old-text. " 1756 "Disabling -use-old-text.\n"; 1757 opts::UseOldText = false; 1758 } 1759 1760 if (opts::Lite && opts::StrictMode) { 1761 errs() << "BOLT-ERROR: -strict and -lite cannot be used at the same time\n"; 1762 exit(1); 1763 } 1764 1765 if (opts::Lite) 1766 outs() << "BOLT-INFO: enabling lite mode\n"; 1767 1768 if (!opts::SaveProfile.empty() && BAT->enabledFor(InputFile)) { 1769 errs() << "BOLT-ERROR: unable to save profile in YAML format for input " 1770 "file processed by BOLT. Please remove -w option and use branch " 1771 "profile.\n"; 1772 exit(1); 1773 } 1774 } 1775 1776 namespace { 1777 template <typename ELFT> 1778 int64_t getRelocationAddend(const ELFObjectFile<ELFT> *Obj, 1779 const RelocationRef &RelRef) { 1780 using ELFShdrTy = typename ELFT::Shdr; 1781 using Elf_Rela = typename ELFT::Rela; 1782 int64_t Addend = 0; 1783 const ELFFile<ELFT> &EF = Obj->getELFFile(); 1784 DataRefImpl Rel = RelRef.getRawDataRefImpl(); 1785 const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a)); 1786 switch (RelocationSection->sh_type) { 1787 default: 1788 llvm_unreachable("unexpected relocation section type"); 1789 case ELF::SHT_REL: 1790 break; 1791 case ELF::SHT_RELA: { 1792 const Elf_Rela *RelA = Obj->getRela(Rel); 1793 Addend = RelA->r_addend; 1794 break; 1795 } 1796 } 1797 1798 return Addend; 1799 } 1800 1801 int64_t getRelocationAddend(const ELFObjectFileBase *Obj, 1802 const RelocationRef &Rel) { 1803 if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj)) 1804 return getRelocationAddend(ELF32LE, Rel); 1805 if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj)) 1806 return getRelocationAddend(ELF64LE, Rel); 1807 if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj)) 1808 return getRelocationAddend(ELF32BE, Rel); 1809 auto *ELF64BE = cast<ELF64BEObjectFile>(Obj); 1810 return getRelocationAddend(ELF64BE, Rel); 1811 } 1812 1813 template <typename ELFT> 1814 uint32_t getRelocationSymbol(const ELFObjectFile<ELFT> *Obj, 1815 const RelocationRef &RelRef) { 1816 using ELFShdrTy = typename ELFT::Shdr; 1817 uint32_t Symbol = 0; 1818 const ELFFile<ELFT> &EF = Obj->getELFFile(); 1819 DataRefImpl Rel = RelRef.getRawDataRefImpl(); 1820 const ELFShdrTy *RelocationSection = cantFail(EF.getSection(Rel.d.a)); 1821 switch (RelocationSection->sh_type) { 1822 default: 1823 llvm_unreachable("unexpected relocation section type"); 1824 case ELF::SHT_REL: 1825 Symbol = Obj->getRel(Rel)->getSymbol(EF.isMips64EL()); 1826 break; 1827 case ELF::SHT_RELA: 1828 Symbol = Obj->getRela(Rel)->getSymbol(EF.isMips64EL()); 1829 break; 1830 } 1831 1832 return Symbol; 1833 } 1834 1835 uint32_t getRelocationSymbol(const ELFObjectFileBase *Obj, 1836 const RelocationRef &Rel) { 1837 if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj)) 1838 return getRelocationSymbol(ELF32LE, Rel); 1839 if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj)) 1840 return getRelocationSymbol(ELF64LE, Rel); 1841 if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj)) 1842 return getRelocationSymbol(ELF32BE, Rel); 1843 auto *ELF64BE = cast<ELF64BEObjectFile>(Obj); 1844 return getRelocationSymbol(ELF64BE, Rel); 1845 } 1846 } // anonymous namespace 1847 1848 bool RewriteInstance::analyzeRelocation( 1849 const RelocationRef &Rel, uint64_t RType, std::string &SymbolName, 1850 bool &IsSectionRelocation, uint64_t &SymbolAddress, int64_t &Addend, 1851 uint64_t &ExtractedValue, bool &Skip) const { 1852 Skip = false; 1853 if (!Relocation::isSupported(RType)) 1854 return false; 1855 1856 const bool IsAArch64 = BC->isAArch64(); 1857 1858 const size_t RelSize = Relocation::getSizeForType(RType); 1859 1860 ErrorOr<uint64_t> Value = 1861 BC->getUnsignedValueAtAddress(Rel.getOffset(), RelSize); 1862 assert(Value && "failed to extract relocated value"); 1863 if ((Skip = Relocation::skipRelocationProcess(RType, *Value))) 1864 return true; 1865 1866 ExtractedValue = Relocation::extractValue(RType, *Value, Rel.getOffset()); 1867 Addend = getRelocationAddend(InputFile, Rel); 1868 1869 const bool IsPCRelative = Relocation::isPCRelative(RType); 1870 const uint64_t PCRelOffset = IsPCRelative && !IsAArch64 ? Rel.getOffset() : 0; 1871 bool SkipVerification = false; 1872 auto SymbolIter = Rel.getSymbol(); 1873 if (SymbolIter == InputFile->symbol_end()) { 1874 SymbolAddress = ExtractedValue - Addend + PCRelOffset; 1875 MCSymbol *RelSymbol = 1876 BC->getOrCreateGlobalSymbol(SymbolAddress, "RELSYMat"); 1877 SymbolName = std::string(RelSymbol->getName()); 1878 IsSectionRelocation = false; 1879 } else { 1880 const SymbolRef &Symbol = *SymbolIter; 1881 SymbolName = std::string(cantFail(Symbol.getName())); 1882 SymbolAddress = cantFail(Symbol.getAddress()); 1883 SkipVerification = (cantFail(Symbol.getType()) == SymbolRef::ST_Other); 1884 // Section symbols are marked as ST_Debug. 1885 IsSectionRelocation = (cantFail(Symbol.getType()) == SymbolRef::ST_Debug); 1886 // Check for PLT entry registered with symbol name 1887 if (!SymbolAddress && IsAArch64) { 1888 const BinaryData *BD = BC->getPLTBinaryDataByName(SymbolName); 1889 SymbolAddress = BD ? BD->getAddress() : 0; 1890 } 1891 } 1892 // For PIE or dynamic libs, the linker may choose not to put the relocation 1893 // result at the address if it is a X86_64_64 one because it will emit a 1894 // dynamic relocation (X86_RELATIVE) for the dynamic linker and loader to 1895 // resolve it at run time. The static relocation result goes as the addend 1896 // of the dynamic relocation in this case. We can't verify these cases. 1897 // FIXME: perhaps we can try to find if it really emitted a corresponding 1898 // RELATIVE relocation at this offset with the correct value as the addend. 1899 if (!BC->HasFixedLoadAddress && RelSize == 8) 1900 SkipVerification = true; 1901 1902 if (IsSectionRelocation && !IsAArch64) { 1903 ErrorOr<BinarySection &> Section = BC->getSectionForAddress(SymbolAddress); 1904 assert(Section && "section expected for section relocation"); 1905 SymbolName = "section " + std::string(Section->getName()); 1906 // Convert section symbol relocations to regular relocations inside 1907 // non-section symbols. 1908 if (Section->containsAddress(ExtractedValue) && !IsPCRelative) { 1909 SymbolAddress = ExtractedValue; 1910 Addend = 0; 1911 } else { 1912 Addend = ExtractedValue - (SymbolAddress - PCRelOffset); 1913 } 1914 } 1915 1916 // If no symbol has been found or if it is a relocation requiring the 1917 // creation of a GOT entry, do not link against the symbol but against 1918 // whatever address was extracted from the instruction itself. We are 1919 // not creating a GOT entry as this was already processed by the linker. 1920 // For GOT relocs, do not subtract addend as the addend does not refer 1921 // to this instruction's target, but it refers to the target in the GOT 1922 // entry. 1923 if (Relocation::isGOT(RType)) { 1924 Addend = 0; 1925 SymbolAddress = ExtractedValue + PCRelOffset; 1926 } else if (Relocation::isTLS(RType)) { 1927 SkipVerification = true; 1928 } else if (!SymbolAddress) { 1929 assert(!IsSectionRelocation); 1930 if (ExtractedValue || Addend == 0 || IsPCRelative) { 1931 SymbolAddress = 1932 truncateToSize(ExtractedValue - Addend + PCRelOffset, RelSize); 1933 } else { 1934 // This is weird case. The extracted value is zero but the addend is 1935 // non-zero and the relocation is not pc-rel. Using the previous logic, 1936 // the SymbolAddress would end up as a huge number. Seen in 1937 // exceptions_pic.test. 1938 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: relocation @ 0x" 1939 << Twine::utohexstr(Rel.getOffset()) 1940 << " value does not match addend for " 1941 << "relocation to undefined symbol.\n"); 1942 return true; 1943 } 1944 } 1945 1946 auto verifyExtractedValue = [&]() { 1947 if (SkipVerification) 1948 return true; 1949 1950 if (IsAArch64) 1951 return true; 1952 1953 if (SymbolName == "__hot_start" || SymbolName == "__hot_end") 1954 return true; 1955 1956 if (RType == ELF::R_X86_64_PLT32) 1957 return true; 1958 1959 return truncateToSize(ExtractedValue, RelSize) == 1960 truncateToSize(SymbolAddress + Addend - PCRelOffset, RelSize); 1961 }; 1962 1963 (void)verifyExtractedValue; 1964 assert(verifyExtractedValue() && "mismatched extracted relocation value"); 1965 1966 return true; 1967 } 1968 1969 void RewriteInstance::processDynamicRelocations() { 1970 // Read relocations for PLT - DT_JMPREL. 1971 if (PLTRelocationsSize > 0) { 1972 ErrorOr<BinarySection &> PLTRelSectionOrErr = 1973 BC->getSectionForAddress(*PLTRelocationsAddress); 1974 if (!PLTRelSectionOrErr) 1975 report_error("unable to find section corresponding to DT_JMPREL", 1976 PLTRelSectionOrErr.getError()); 1977 if (PLTRelSectionOrErr->getSize() != PLTRelocationsSize) 1978 report_error("section size mismatch for DT_PLTRELSZ", 1979 errc::executable_format_error); 1980 readDynamicRelocations(PLTRelSectionOrErr->getSectionRef(), 1981 /*IsJmpRel*/ true); 1982 } 1983 1984 // The rest of dynamic relocations - DT_RELA. 1985 if (DynamicRelocationsSize > 0) { 1986 ErrorOr<BinarySection &> DynamicRelSectionOrErr = 1987 BC->getSectionForAddress(*DynamicRelocationsAddress); 1988 if (!DynamicRelSectionOrErr) 1989 report_error("unable to find section corresponding to DT_RELA", 1990 DynamicRelSectionOrErr.getError()); 1991 if (DynamicRelSectionOrErr->getSize() != DynamicRelocationsSize) 1992 report_error("section size mismatch for DT_RELASZ", 1993 errc::executable_format_error); 1994 readDynamicRelocations(DynamicRelSectionOrErr->getSectionRef(), 1995 /*IsJmpRel*/ false); 1996 } 1997 } 1998 1999 void RewriteInstance::processRelocations() { 2000 if (!BC->HasRelocations) 2001 return; 2002 2003 for (const SectionRef &Section : InputFile->sections()) { 2004 if (cantFail(Section.getRelocatedSection()) != InputFile->section_end() && 2005 !BinarySection(*BC, Section).isAllocatable()) 2006 readRelocations(Section); 2007 } 2008 2009 if (NumFailedRelocations) 2010 errs() << "BOLT-WARNING: Failed to analyze " << NumFailedRelocations 2011 << " relocations\n"; 2012 } 2013 2014 void RewriteInstance::insertLKMarker(uint64_t PC, uint64_t SectionOffset, 2015 int32_t PCRelativeOffset, 2016 bool IsPCRelative, StringRef SectionName) { 2017 BC->LKMarkers[PC].emplace_back(LKInstructionMarkerInfo{ 2018 SectionOffset, PCRelativeOffset, IsPCRelative, SectionName}); 2019 } 2020 2021 void RewriteInstance::processLKSections() { 2022 assert(opts::LinuxKernelMode && 2023 "process Linux Kernel special sections and their relocations only in " 2024 "linux kernel mode.\n"); 2025 2026 processLKExTable(); 2027 processLKPCIFixup(); 2028 processLKKSymtab(); 2029 processLKKSymtab(true); 2030 processLKBugTable(); 2031 processLKSMPLocks(); 2032 } 2033 2034 /// Process __ex_table section of Linux Kernel. 2035 /// This section contains information regarding kernel level exception 2036 /// handling (https://www.kernel.org/doc/html/latest/x86/exception-tables.html). 2037 /// More documentation is in arch/x86/include/asm/extable.h. 2038 /// 2039 /// The section is the list of the following structures: 2040 /// 2041 /// struct exception_table_entry { 2042 /// int insn; 2043 /// int fixup; 2044 /// int handler; 2045 /// }; 2046 /// 2047 void RewriteInstance::processLKExTable() { 2048 ErrorOr<BinarySection &> SectionOrError = 2049 BC->getUniqueSectionByName("__ex_table"); 2050 if (!SectionOrError) 2051 return; 2052 2053 const uint64_t SectionSize = SectionOrError->getSize(); 2054 const uint64_t SectionAddress = SectionOrError->getAddress(); 2055 assert((SectionSize % 12) == 0 && 2056 "The size of the __ex_table section should be a multiple of 12"); 2057 for (uint64_t I = 0; I < SectionSize; I += 4) { 2058 const uint64_t EntryAddress = SectionAddress + I; 2059 ErrorOr<uint64_t> Offset = BC->getSignedValueAtAddress(EntryAddress, 4); 2060 assert(Offset && "failed reading PC-relative offset for __ex_table"); 2061 int32_t SignedOffset = *Offset; 2062 const uint64_t RefAddress = EntryAddress + SignedOffset; 2063 2064 BinaryFunction *ContainingBF = 2065 BC->getBinaryFunctionContainingAddress(RefAddress); 2066 if (!ContainingBF) 2067 continue; 2068 2069 MCSymbol *ReferencedSymbol = ContainingBF->getSymbol(); 2070 const uint64_t FunctionOffset = RefAddress - ContainingBF->getAddress(); 2071 switch (I % 12) { 2072 default: 2073 llvm_unreachable("bad alignment of __ex_table"); 2074 break; 2075 case 0: 2076 // insn 2077 insertLKMarker(RefAddress, I, SignedOffset, true, "__ex_table"); 2078 break; 2079 case 4: 2080 // fixup 2081 if (FunctionOffset) 2082 ReferencedSymbol = ContainingBF->addEntryPointAtOffset(FunctionOffset); 2083 BC->addRelocation(EntryAddress, ReferencedSymbol, Relocation::getPC32(), 2084 0, *Offset); 2085 break; 2086 case 8: 2087 // handler 2088 assert(!FunctionOffset && 2089 "__ex_table handler entry should point to function start"); 2090 BC->addRelocation(EntryAddress, ReferencedSymbol, Relocation::getPC32(), 2091 0, *Offset); 2092 break; 2093 } 2094 } 2095 } 2096 2097 /// Process .pci_fixup section of Linux Kernel. 2098 /// This section contains a list of entries for different PCI devices and their 2099 /// corresponding hook handler (code pointer where the fixup 2100 /// code resides, usually on x86_64 it is an entry PC relative 32 bit offset). 2101 /// Documentation is in include/linux/pci.h. 2102 void RewriteInstance::processLKPCIFixup() { 2103 ErrorOr<BinarySection &> SectionOrError = 2104 BC->getUniqueSectionByName(".pci_fixup"); 2105 assert(SectionOrError && 2106 ".pci_fixup section not found in Linux Kernel binary"); 2107 const uint64_t SectionSize = SectionOrError->getSize(); 2108 const uint64_t SectionAddress = SectionOrError->getAddress(); 2109 assert((SectionSize % 16) == 0 && ".pci_fixup size is not a multiple of 16"); 2110 2111 for (uint64_t I = 12; I + 4 <= SectionSize; I += 16) { 2112 const uint64_t PC = SectionAddress + I; 2113 ErrorOr<uint64_t> Offset = BC->getSignedValueAtAddress(PC, 4); 2114 assert(Offset && "cannot read value from .pci_fixup"); 2115 const int32_t SignedOffset = *Offset; 2116 const uint64_t HookupAddress = PC + SignedOffset; 2117 BinaryFunction *HookupFunction = 2118 BC->getBinaryFunctionAtAddress(HookupAddress); 2119 assert(HookupFunction && "expected function for entry in .pci_fixup"); 2120 BC->addRelocation(PC, HookupFunction->getSymbol(), Relocation::getPC32(), 0, 2121 *Offset); 2122 } 2123 } 2124 2125 /// Process __ksymtab[_gpl] sections of Linux Kernel. 2126 /// This section lists all the vmlinux symbols that kernel modules can access. 2127 /// 2128 /// All the entries are 4 bytes each and hence we can read them by one by one 2129 /// and ignore the ones that are not pointing to the .text section. All pointers 2130 /// are PC relative offsets. Always, points to the beginning of the function. 2131 void RewriteInstance::processLKKSymtab(bool IsGPL) { 2132 StringRef SectionName = "__ksymtab"; 2133 if (IsGPL) 2134 SectionName = "__ksymtab_gpl"; 2135 ErrorOr<BinarySection &> SectionOrError = 2136 BC->getUniqueSectionByName(SectionName); 2137 assert(SectionOrError && 2138 "__ksymtab[_gpl] section not found in Linux Kernel binary"); 2139 const uint64_t SectionSize = SectionOrError->getSize(); 2140 const uint64_t SectionAddress = SectionOrError->getAddress(); 2141 assert((SectionSize % 4) == 0 && 2142 "The size of the __ksymtab[_gpl] section should be a multiple of 4"); 2143 2144 for (uint64_t I = 0; I < SectionSize; I += 4) { 2145 const uint64_t EntryAddress = SectionAddress + I; 2146 ErrorOr<uint64_t> Offset = BC->getSignedValueAtAddress(EntryAddress, 4); 2147 assert(Offset && "Reading valid PC-relative offset for a ksymtab entry"); 2148 const int32_t SignedOffset = *Offset; 2149 const uint64_t RefAddress = EntryAddress + SignedOffset; 2150 BinaryFunction *BF = BC->getBinaryFunctionAtAddress(RefAddress); 2151 if (!BF) 2152 continue; 2153 2154 BC->addRelocation(EntryAddress, BF->getSymbol(), Relocation::getPC32(), 0, 2155 *Offset); 2156 } 2157 } 2158 2159 /// Process __bug_table section. 2160 /// This section contains information useful for kernel debugging. 2161 /// Each entry in the section is a struct bug_entry that contains a pointer to 2162 /// the ud2 instruction corresponding to the bug, corresponding file name (both 2163 /// pointers use PC relative offset addressing), line number, and flags. 2164 /// The definition of the struct bug_entry can be found in 2165 /// `include/asm-generic/bug.h` 2166 void RewriteInstance::processLKBugTable() { 2167 ErrorOr<BinarySection &> SectionOrError = 2168 BC->getUniqueSectionByName("__bug_table"); 2169 if (!SectionOrError) 2170 return; 2171 2172 const uint64_t SectionSize = SectionOrError->getSize(); 2173 const uint64_t SectionAddress = SectionOrError->getAddress(); 2174 assert((SectionSize % 12) == 0 && 2175 "The size of the __bug_table section should be a multiple of 12"); 2176 for (uint64_t I = 0; I < SectionSize; I += 12) { 2177 const uint64_t EntryAddress = SectionAddress + I; 2178 ErrorOr<uint64_t> Offset = BC->getSignedValueAtAddress(EntryAddress, 4); 2179 assert(Offset && 2180 "Reading valid PC-relative offset for a __bug_table entry"); 2181 const int32_t SignedOffset = *Offset; 2182 const uint64_t RefAddress = EntryAddress + SignedOffset; 2183 assert(BC->getBinaryFunctionContainingAddress(RefAddress) && 2184 "__bug_table entries should point to a function"); 2185 2186 insertLKMarker(RefAddress, I, SignedOffset, true, "__bug_table"); 2187 } 2188 } 2189 2190 /// .smp_locks section contains PC-relative references to instructions with LOCK 2191 /// prefix. The prefix can be converted to NOP at boot time on non-SMP systems. 2192 void RewriteInstance::processLKSMPLocks() { 2193 ErrorOr<BinarySection &> SectionOrError = 2194 BC->getUniqueSectionByName(".smp_locks"); 2195 if (!SectionOrError) 2196 return; 2197 2198 uint64_t SectionSize = SectionOrError->getSize(); 2199 const uint64_t SectionAddress = SectionOrError->getAddress(); 2200 assert((SectionSize % 4) == 0 && 2201 "The size of the .smp_locks section should be a multiple of 4"); 2202 2203 for (uint64_t I = 0; I < SectionSize; I += 4) { 2204 const uint64_t EntryAddress = SectionAddress + I; 2205 ErrorOr<uint64_t> Offset = BC->getSignedValueAtAddress(EntryAddress, 4); 2206 assert(Offset && "Reading valid PC-relative offset for a .smp_locks entry"); 2207 int32_t SignedOffset = *Offset; 2208 uint64_t RefAddress = EntryAddress + SignedOffset; 2209 2210 BinaryFunction *ContainingBF = 2211 BC->getBinaryFunctionContainingAddress(RefAddress); 2212 if (!ContainingBF) 2213 continue; 2214 2215 insertLKMarker(RefAddress, I, SignedOffset, true, ".smp_locks"); 2216 } 2217 } 2218 2219 void RewriteInstance::readDynamicRelocations(const SectionRef &Section, 2220 bool IsJmpRel) { 2221 assert(BinarySection(*BC, Section).isAllocatable() && "allocatable expected"); 2222 2223 LLVM_DEBUG({ 2224 StringRef SectionName = cantFail(Section.getName()); 2225 dbgs() << "BOLT-DEBUG: reading relocations for section " << SectionName 2226 << ":\n"; 2227 }); 2228 2229 for (const RelocationRef &Rel : Section.relocations()) { 2230 const uint64_t RType = Rel.getType(); 2231 if (Relocation::isNone(RType)) 2232 continue; 2233 2234 StringRef SymbolName = "<none>"; 2235 MCSymbol *Symbol = nullptr; 2236 uint64_t SymbolAddress = 0; 2237 const uint64_t Addend = getRelocationAddend(InputFile, Rel); 2238 2239 symbol_iterator SymbolIter = Rel.getSymbol(); 2240 if (SymbolIter != InputFile->symbol_end()) { 2241 SymbolName = cantFail(SymbolIter->getName()); 2242 BinaryData *BD = BC->getBinaryDataByName(SymbolName); 2243 Symbol = BD ? BD->getSymbol() 2244 : BC->getOrCreateUndefinedGlobalSymbol(SymbolName); 2245 SymbolAddress = cantFail(SymbolIter->getAddress()); 2246 (void)SymbolAddress; 2247 } 2248 2249 LLVM_DEBUG( 2250 SmallString<16> TypeName; 2251 Rel.getTypeName(TypeName); 2252 dbgs() << "BOLT-DEBUG: dynamic relocation at 0x" 2253 << Twine::utohexstr(Rel.getOffset()) << " : " << TypeName 2254 << " : " << SymbolName << " : " << Twine::utohexstr(SymbolAddress) 2255 << " : + 0x" << Twine::utohexstr(Addend) << '\n' 2256 ); 2257 2258 if (IsJmpRel) 2259 IsJmpRelocation[RType] = true; 2260 2261 if (Symbol) 2262 SymbolIndex[Symbol] = getRelocationSymbol(InputFile, Rel); 2263 2264 BC->addDynamicRelocation(Rel.getOffset(), Symbol, RType, Addend); 2265 } 2266 } 2267 2268 void RewriteInstance::readRelocations(const SectionRef &Section) { 2269 LLVM_DEBUG({ 2270 StringRef SectionName = cantFail(Section.getName()); 2271 dbgs() << "BOLT-DEBUG: reading relocations for section " << SectionName 2272 << ":\n"; 2273 }); 2274 if (BinarySection(*BC, Section).isAllocatable()) { 2275 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: ignoring runtime relocations\n"); 2276 return; 2277 } 2278 section_iterator SecIter = cantFail(Section.getRelocatedSection()); 2279 assert(SecIter != InputFile->section_end() && "relocated section expected"); 2280 SectionRef RelocatedSection = *SecIter; 2281 2282 StringRef RelocatedSectionName = cantFail(RelocatedSection.getName()); 2283 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: relocated section is " 2284 << RelocatedSectionName << '\n'); 2285 2286 if (!BinarySection(*BC, RelocatedSection).isAllocatable()) { 2287 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: ignoring relocations against " 2288 << "non-allocatable section\n"); 2289 return; 2290 } 2291 const bool SkipRelocs = StringSwitch<bool>(RelocatedSectionName) 2292 .Cases(".plt", ".rela.plt", ".got.plt", 2293 ".eh_frame", ".gcc_except_table", true) 2294 .Default(false); 2295 if (SkipRelocs) { 2296 LLVM_DEBUG( 2297 dbgs() << "BOLT-DEBUG: ignoring relocations against known section\n"); 2298 return; 2299 } 2300 2301 const bool IsAArch64 = BC->isAArch64(); 2302 const bool IsFromCode = RelocatedSection.isText(); 2303 2304 auto printRelocationInfo = [&](const RelocationRef &Rel, 2305 StringRef SymbolName, 2306 uint64_t SymbolAddress, 2307 uint64_t Addend, 2308 uint64_t ExtractedValue) { 2309 SmallString<16> TypeName; 2310 Rel.getTypeName(TypeName); 2311 const uint64_t Address = SymbolAddress + Addend; 2312 ErrorOr<BinarySection &> Section = BC->getSectionForAddress(SymbolAddress); 2313 dbgs() << "Relocation: offset = 0x" 2314 << Twine::utohexstr(Rel.getOffset()) 2315 << "; type = " << TypeName 2316 << "; value = 0x" << Twine::utohexstr(ExtractedValue) 2317 << "; symbol = " << SymbolName 2318 << " (" << (Section ? Section->getName() : "") << ")" 2319 << "; symbol address = 0x" << Twine::utohexstr(SymbolAddress) 2320 << "; addend = 0x" << Twine::utohexstr(Addend) 2321 << "; address = 0x" << Twine::utohexstr(Address) 2322 << "; in = "; 2323 if (BinaryFunction *Func = BC->getBinaryFunctionContainingAddress( 2324 Rel.getOffset(), false, IsAArch64)) 2325 dbgs() << Func->getPrintName() << "\n"; 2326 else 2327 dbgs() << BC->getSectionForAddress(Rel.getOffset())->getName() << "\n"; 2328 }; 2329 2330 for (const RelocationRef &Rel : Section.relocations()) { 2331 SmallString<16> TypeName; 2332 Rel.getTypeName(TypeName); 2333 uint64_t RType = Rel.getType(); 2334 if (Relocation::isNone(RType)) 2335 continue; 2336 2337 // Adjust the relocation type as the linker might have skewed it. 2338 if (BC->isX86() && (RType & ELF::R_X86_64_converted_reloc_bit)) { 2339 if (opts::Verbosity >= 1) 2340 dbgs() << "BOLT-WARNING: ignoring R_X86_64_converted_reloc_bit\n"; 2341 RType &= ~ELF::R_X86_64_converted_reloc_bit; 2342 } 2343 2344 if (Relocation::isTLS(RType)) { 2345 // No special handling required for TLS relocations on X86. 2346 if (BC->isX86()) 2347 continue; 2348 2349 // The non-got related TLS relocations on AArch64 also could be skipped. 2350 if (!Relocation::isGOT(RType)) 2351 continue; 2352 } 2353 2354 if (!IsAArch64 && BC->getDynamicRelocationAt(Rel.getOffset())) { 2355 LLVM_DEBUG( 2356 dbgs() << "BOLT-DEBUG: address 0x" 2357 << Twine::utohexstr(Rel.getOffset()) 2358 << " has a dynamic relocation against it. Ignoring static " 2359 "relocation.\n"); 2360 continue; 2361 } 2362 2363 std::string SymbolName; 2364 uint64_t SymbolAddress; 2365 int64_t Addend; 2366 uint64_t ExtractedValue; 2367 bool IsSectionRelocation; 2368 bool Skip; 2369 if (!analyzeRelocation(Rel, RType, SymbolName, IsSectionRelocation, 2370 SymbolAddress, Addend, ExtractedValue, Skip)) { 2371 LLVM_DEBUG(dbgs() << "BOLT-WARNING: failed to analyze relocation @ " 2372 << "offset = 0x" << Twine::utohexstr(Rel.getOffset()) 2373 << "; type name = " << TypeName << '\n'); 2374 ++NumFailedRelocations; 2375 continue; 2376 } 2377 2378 if (Skip) { 2379 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: skipping relocation @ offset = 0x" 2380 << Twine::utohexstr(Rel.getOffset()) 2381 << "; type name = " << TypeName << '\n'); 2382 continue; 2383 } 2384 2385 const uint64_t Address = SymbolAddress + Addend; 2386 2387 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: "; printRelocationInfo( 2388 Rel, SymbolName, SymbolAddress, Addend, ExtractedValue)); 2389 2390 BinaryFunction *ContainingBF = nullptr; 2391 if (IsFromCode) { 2392 ContainingBF = 2393 BC->getBinaryFunctionContainingAddress(Rel.getOffset(), 2394 /*CheckPastEnd*/ false, 2395 /*UseMaxSize*/ true); 2396 assert(ContainingBF && "cannot find function for address in code"); 2397 if (!IsAArch64 && !ContainingBF->containsAddress(Rel.getOffset())) { 2398 if (opts::Verbosity >= 1) 2399 outs() << "BOLT-INFO: " << *ContainingBF 2400 << " has relocations in padding area\n"; 2401 ContainingBF->setSize(ContainingBF->getMaxSize()); 2402 ContainingBF->setSimple(false); 2403 continue; 2404 } 2405 } 2406 2407 MCSymbol *ReferencedSymbol = nullptr; 2408 if (!IsSectionRelocation) 2409 if (BinaryData *BD = BC->getBinaryDataByName(SymbolName)) 2410 ReferencedSymbol = BD->getSymbol(); 2411 2412 ErrorOr<BinarySection &> ReferencedSection = 2413 BC->getSectionForAddress(SymbolAddress); 2414 2415 const bool IsToCode = ReferencedSection && ReferencedSection->isText(); 2416 2417 // Special handling of PC-relative relocations. 2418 if (!IsAArch64 && Relocation::isPCRelative(RType)) { 2419 if (!IsFromCode && IsToCode) { 2420 // PC-relative relocations from data to code are tricky since the 2421 // original information is typically lost after linking, even with 2422 // '--emit-relocs'. Such relocations are normally used by PIC-style 2423 // jump tables and they reference both the jump table and jump 2424 // targets by computing the difference between the two. If we blindly 2425 // apply the relocation, it will appear that it references an arbitrary 2426 // location in the code, possibly in a different function from the one 2427 // containing the jump table. 2428 // 2429 // For that reason, we only register the fact that there is a 2430 // PC-relative relocation at a given address against the code. 2431 // The actual referenced label/address will be determined during jump 2432 // table analysis. 2433 BC->addPCRelativeDataRelocation(Rel.getOffset()); 2434 } else if (ContainingBF && !IsSectionRelocation && ReferencedSymbol) { 2435 // If we know the referenced symbol, register the relocation from 2436 // the code. It's required to properly handle cases where 2437 // "symbol + addend" references an object different from "symbol". 2438 ContainingBF->addRelocation(Rel.getOffset(), ReferencedSymbol, RType, 2439 Addend, ExtractedValue); 2440 } else { 2441 LLVM_DEBUG( 2442 dbgs() << "BOLT-DEBUG: not creating PC-relative relocation at 0x" 2443 << Twine::utohexstr(Rel.getOffset()) << " for " << SymbolName 2444 << "\n"); 2445 } 2446 2447 continue; 2448 } 2449 2450 bool ForceRelocation = BC->forceSymbolRelocations(SymbolName); 2451 if (BC->isAArch64() && Relocation::isGOT(RType)) 2452 ForceRelocation = true; 2453 2454 if (!ReferencedSection && !ForceRelocation) { 2455 LLVM_DEBUG( 2456 dbgs() << "BOLT-DEBUG: cannot determine referenced section.\n"); 2457 continue; 2458 } 2459 2460 // Occasionally we may see a reference past the last byte of the function 2461 // typically as a result of __builtin_unreachable(). Check it here. 2462 BinaryFunction *ReferencedBF = BC->getBinaryFunctionContainingAddress( 2463 Address, /*CheckPastEnd*/ true, /*UseMaxSize*/ IsAArch64); 2464 2465 if (!IsSectionRelocation) { 2466 if (BinaryFunction *BF = 2467 BC->getBinaryFunctionContainingAddress(SymbolAddress)) { 2468 if (BF != ReferencedBF) { 2469 // It's possible we are referencing a function without referencing any 2470 // code, e.g. when taking a bitmask action on a function address. 2471 errs() << "BOLT-WARNING: non-standard function reference (e.g. " 2472 "bitmask) detected against function " 2473 << *BF; 2474 if (IsFromCode) 2475 errs() << " from function " << *ContainingBF << '\n'; 2476 else 2477 errs() << " from data section at 0x" 2478 << Twine::utohexstr(Rel.getOffset()) << '\n'; 2479 LLVM_DEBUG(printRelocationInfo(Rel, SymbolName, SymbolAddress, Addend, 2480 ExtractedValue)); 2481 ReferencedBF = BF; 2482 } 2483 } 2484 } else if (ReferencedBF) { 2485 assert(ReferencedSection && "section expected for section relocation"); 2486 if (*ReferencedBF->getOriginSection() != *ReferencedSection) { 2487 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: ignoring false function reference\n"); 2488 ReferencedBF = nullptr; 2489 } 2490 } 2491 2492 // Workaround for a member function pointer de-virtualization bug. We check 2493 // if a non-pc-relative relocation in the code is pointing to (fptr - 1). 2494 if (IsToCode && ContainingBF && !Relocation::isPCRelative(RType) && 2495 (!ReferencedBF || (ReferencedBF->getAddress() != Address))) { 2496 if (const BinaryFunction *RogueBF = 2497 BC->getBinaryFunctionAtAddress(Address + 1)) { 2498 // Do an extra check that the function was referenced previously. 2499 // It's a linear search, but it should rarely happen. 2500 bool Found = false; 2501 for (const auto &RelKV : ContainingBF->Relocations) { 2502 const Relocation &Rel = RelKV.second; 2503 if (Rel.Symbol == RogueBF->getSymbol() && 2504 !Relocation::isPCRelative(Rel.Type)) { 2505 Found = true; 2506 break; 2507 } 2508 } 2509 2510 if (Found) { 2511 errs() << "BOLT-WARNING: detected possible compiler " 2512 "de-virtualization bug: -1 addend used with " 2513 "non-pc-relative relocation against function " 2514 << *RogueBF << " in function " << *ContainingBF << '\n'; 2515 continue; 2516 } 2517 } 2518 } 2519 2520 if (ForceRelocation) { 2521 std::string Name = Relocation::isGOT(RType) ? "Zero" : SymbolName; 2522 ReferencedSymbol = BC->registerNameAtAddress(Name, 0, 0, 0); 2523 SymbolAddress = 0; 2524 if (Relocation::isGOT(RType)) 2525 Addend = Address; 2526 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: forcing relocation against symbol " 2527 << SymbolName << " with addend " << Addend << '\n'); 2528 } else if (ReferencedBF) { 2529 ReferencedSymbol = ReferencedBF->getSymbol(); 2530 uint64_t RefFunctionOffset = 0; 2531 2532 // Adjust the point of reference to a code location inside a function. 2533 if (ReferencedBF->containsAddress(Address, /*UseMaxSize = */true)) { 2534 RefFunctionOffset = Address - ReferencedBF->getAddress(); 2535 if (RefFunctionOffset) { 2536 if (ContainingBF && ContainingBF != ReferencedBF) { 2537 ReferencedSymbol = 2538 ReferencedBF->addEntryPointAtOffset(RefFunctionOffset); 2539 } else { 2540 ReferencedSymbol = 2541 ReferencedBF->getOrCreateLocalLabel(Address, 2542 /*CreatePastEnd =*/true); 2543 ReferencedBF->registerReferencedOffset(RefFunctionOffset); 2544 } 2545 if (opts::Verbosity > 1 && 2546 !BinarySection(*BC, RelocatedSection).isReadOnly()) 2547 errs() << "BOLT-WARNING: writable reference into the middle of " 2548 << "the function " << *ReferencedBF 2549 << " detected at address 0x" 2550 << Twine::utohexstr(Rel.getOffset()) << '\n'; 2551 } 2552 SymbolAddress = Address; 2553 Addend = 0; 2554 } 2555 LLVM_DEBUG( 2556 dbgs() << " referenced function " << *ReferencedBF; 2557 if (Address != ReferencedBF->getAddress()) 2558 dbgs() << " at offset 0x" << Twine::utohexstr(RefFunctionOffset); 2559 dbgs() << '\n' 2560 ); 2561 } else { 2562 if (IsToCode && SymbolAddress) { 2563 // This can happen e.g. with PIC-style jump tables. 2564 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: no corresponding function for " 2565 "relocation against code\n"); 2566 } 2567 2568 // In AArch64 there are zero reasons to keep a reference to the 2569 // "original" symbol plus addend. The original symbol is probably just a 2570 // section symbol. If we are here, this means we are probably accessing 2571 // data, so it is imperative to keep the original address. 2572 if (IsAArch64) { 2573 SymbolName = ("SYMBOLat0x" + Twine::utohexstr(Address)).str(); 2574 SymbolAddress = Address; 2575 Addend = 0; 2576 } 2577 2578 if (BinaryData *BD = BC->getBinaryDataContainingAddress(SymbolAddress)) { 2579 // Note: this assertion is trying to check sanity of BinaryData objects 2580 // but AArch64 has inferred and incomplete object locations coming from 2581 // GOT/TLS or any other non-trivial relocation (that requires creation 2582 // of sections and whose symbol address is not really what should be 2583 // encoded in the instruction). So we essentially disabled this check 2584 // for AArch64 and live with bogus names for objects. 2585 assert((IsAArch64 || IsSectionRelocation || 2586 BD->nameStartsWith(SymbolName) || 2587 BD->nameStartsWith("PG" + SymbolName) || 2588 (BD->nameStartsWith("ANONYMOUS") && 2589 (BD->getSectionName().startswith(".plt") || 2590 BD->getSectionName().endswith(".plt")))) && 2591 "BOLT symbol names of all non-section relocations must match " 2592 "up with symbol names referenced in the relocation"); 2593 2594 if (IsSectionRelocation) 2595 BC->markAmbiguousRelocations(*BD, Address); 2596 2597 ReferencedSymbol = BD->getSymbol(); 2598 Addend += (SymbolAddress - BD->getAddress()); 2599 SymbolAddress = BD->getAddress(); 2600 assert(Address == SymbolAddress + Addend); 2601 } else { 2602 // These are mostly local data symbols but undefined symbols 2603 // in relocation sections can get through here too, from .plt. 2604 assert( 2605 (IsAArch64 || IsSectionRelocation || 2606 BC->getSectionNameForAddress(SymbolAddress)->startswith(".plt")) && 2607 "known symbols should not resolve to anonymous locals"); 2608 2609 if (IsSectionRelocation) { 2610 ReferencedSymbol = 2611 BC->getOrCreateGlobalSymbol(SymbolAddress, "SYMBOLat"); 2612 } else { 2613 SymbolRef Symbol = *Rel.getSymbol(); 2614 const uint64_t SymbolSize = 2615 IsAArch64 ? 0 : ELFSymbolRef(Symbol).getSize(); 2616 const uint64_t SymbolAlignment = 2617 IsAArch64 ? 1 : Symbol.getAlignment(); 2618 const uint32_t SymbolFlags = cantFail(Symbol.getFlags()); 2619 std::string Name; 2620 if (SymbolFlags & SymbolRef::SF_Global) { 2621 Name = SymbolName; 2622 } else { 2623 if (StringRef(SymbolName) 2624 .startswith(BC->AsmInfo->getPrivateGlobalPrefix())) 2625 Name = NR.uniquify("PG" + SymbolName); 2626 else 2627 Name = NR.uniquify(SymbolName); 2628 } 2629 ReferencedSymbol = BC->registerNameAtAddress( 2630 Name, SymbolAddress, SymbolSize, SymbolAlignment, SymbolFlags); 2631 } 2632 2633 if (IsSectionRelocation) { 2634 BinaryData *BD = BC->getBinaryDataByName(ReferencedSymbol->getName()); 2635 BC->markAmbiguousRelocations(*BD, Address); 2636 } 2637 } 2638 } 2639 2640 auto checkMaxDataRelocations = [&]() { 2641 ++NumDataRelocations; 2642 if (opts::MaxDataRelocations && 2643 NumDataRelocations + 1 == opts::MaxDataRelocations) { 2644 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: processing ending on data relocation " 2645 << NumDataRelocations << ": "); 2646 printRelocationInfo(Rel, ReferencedSymbol->getName(), SymbolAddress, 2647 Addend, ExtractedValue); 2648 } 2649 2650 return (!opts::MaxDataRelocations || 2651 NumDataRelocations < opts::MaxDataRelocations); 2652 }; 2653 2654 if ((ReferencedSection && refersToReorderedSection(ReferencedSection)) || 2655 (opts::ForceToDataRelocations && checkMaxDataRelocations())) 2656 ForceRelocation = true; 2657 2658 if (IsFromCode) { 2659 ContainingBF->addRelocation(Rel.getOffset(), ReferencedSymbol, RType, 2660 Addend, ExtractedValue); 2661 } else if (IsToCode || ForceRelocation) { 2662 BC->addRelocation(Rel.getOffset(), ReferencedSymbol, RType, Addend, 2663 ExtractedValue); 2664 } else { 2665 LLVM_DEBUG( 2666 dbgs() << "BOLT-DEBUG: ignoring relocation from data to data\n"); 2667 } 2668 } 2669 } 2670 2671 void RewriteInstance::selectFunctionsToProcess() { 2672 // Extend the list of functions to process or skip from a file. 2673 auto populateFunctionNames = [](cl::opt<std::string> &FunctionNamesFile, 2674 cl::list<std::string> &FunctionNames) { 2675 if (FunctionNamesFile.empty()) 2676 return; 2677 std::ifstream FuncsFile(FunctionNamesFile, std::ios::in); 2678 std::string FuncName; 2679 while (std::getline(FuncsFile, FuncName)) 2680 FunctionNames.push_back(FuncName); 2681 }; 2682 populateFunctionNames(opts::FunctionNamesFile, opts::ForceFunctionNames); 2683 populateFunctionNames(opts::SkipFunctionNamesFile, opts::SkipFunctionNames); 2684 populateFunctionNames(opts::FunctionNamesFileNR, opts::ForceFunctionNamesNR); 2685 2686 // Make a set of functions to process to speed up lookups. 2687 std::unordered_set<std::string> ForceFunctionsNR( 2688 opts::ForceFunctionNamesNR.begin(), opts::ForceFunctionNamesNR.end()); 2689 2690 if ((!opts::ForceFunctionNames.empty() || 2691 !opts::ForceFunctionNamesNR.empty()) && 2692 !opts::SkipFunctionNames.empty()) { 2693 errs() << "BOLT-ERROR: cannot select functions to process and skip at the " 2694 "same time. Please use only one type of selection.\n"; 2695 exit(1); 2696 } 2697 2698 uint64_t LiteThresholdExecCount = 0; 2699 if (opts::LiteThresholdPct) { 2700 if (opts::LiteThresholdPct > 100) 2701 opts::LiteThresholdPct = 100; 2702 2703 std::vector<const BinaryFunction *> TopFunctions; 2704 for (auto &BFI : BC->getBinaryFunctions()) { 2705 const BinaryFunction &Function = BFI.second; 2706 if (ProfileReader->mayHaveProfileData(Function)) 2707 TopFunctions.push_back(&Function); 2708 } 2709 std::sort(TopFunctions.begin(), TopFunctions.end(), 2710 [](const BinaryFunction *A, const BinaryFunction *B) { 2711 return 2712 A->getKnownExecutionCount() < B->getKnownExecutionCount(); 2713 }); 2714 2715 size_t Index = TopFunctions.size() * opts::LiteThresholdPct / 100; 2716 if (Index) 2717 --Index; 2718 LiteThresholdExecCount = TopFunctions[Index]->getKnownExecutionCount(); 2719 outs() << "BOLT-INFO: limiting processing to functions with at least " 2720 << LiteThresholdExecCount << " invocations\n"; 2721 } 2722 LiteThresholdExecCount = std::max( 2723 LiteThresholdExecCount, static_cast<uint64_t>(opts::LiteThresholdCount)); 2724 2725 uint64_t NumFunctionsToProcess = 0; 2726 auto shouldProcess = [&](const BinaryFunction &Function) { 2727 if (opts::MaxFunctions && NumFunctionsToProcess > opts::MaxFunctions) 2728 return false; 2729 2730 // If the list is not empty, only process functions from the list. 2731 if (!opts::ForceFunctionNames.empty() || !ForceFunctionsNR.empty()) { 2732 // Regex check (-funcs and -funcs-file options). 2733 for (std::string &Name : opts::ForceFunctionNames) 2734 if (Function.hasNameRegex(Name)) 2735 return true; 2736 2737 // Non-regex check (-funcs-no-regex and -funcs-file-no-regex). 2738 Optional<StringRef> Match = 2739 Function.forEachName([&ForceFunctionsNR](StringRef Name) { 2740 return ForceFunctionsNR.count(Name.str()); 2741 }); 2742 return Match.hasValue(); 2743 } 2744 2745 for (std::string &Name : opts::SkipFunctionNames) 2746 if (Function.hasNameRegex(Name)) 2747 return false; 2748 2749 if (opts::Lite) { 2750 if (ProfileReader && !ProfileReader->mayHaveProfileData(Function)) 2751 return false; 2752 2753 if (Function.getKnownExecutionCount() < LiteThresholdExecCount) 2754 return false; 2755 } 2756 2757 return true; 2758 }; 2759 2760 for (auto &BFI : BC->getBinaryFunctions()) { 2761 BinaryFunction &Function = BFI.second; 2762 2763 // Pseudo functions are explicitly marked by us not to be processed. 2764 if (Function.isPseudo()) { 2765 Function.IsIgnored = true; 2766 Function.HasExternalRefRelocations = true; 2767 continue; 2768 } 2769 2770 if (!shouldProcess(Function)) { 2771 LLVM_DEBUG(dbgs() << "BOLT-INFO: skipping processing of function " 2772 << Function << " per user request\n"); 2773 Function.setIgnored(); 2774 } else { 2775 ++NumFunctionsToProcess; 2776 if (opts::MaxFunctions && NumFunctionsToProcess == opts::MaxFunctions) 2777 outs() << "BOLT-INFO: processing ending on " << Function << '\n'; 2778 } 2779 } 2780 } 2781 2782 void RewriteInstance::readDebugInfo() { 2783 NamedRegionTimer T("readDebugInfo", "read debug info", TimerGroupName, 2784 TimerGroupDesc, opts::TimeRewrite); 2785 if (!opts::UpdateDebugSections) 2786 return; 2787 2788 BC->preprocessDebugInfo(); 2789 } 2790 2791 void RewriteInstance::preprocessProfileData() { 2792 if (!ProfileReader) 2793 return; 2794 2795 NamedRegionTimer T("preprocessprofile", "pre-process profile data", 2796 TimerGroupName, TimerGroupDesc, opts::TimeRewrite); 2797 2798 outs() << "BOLT-INFO: pre-processing profile using " 2799 << ProfileReader->getReaderName() << '\n'; 2800 2801 if (BAT->enabledFor(InputFile)) { 2802 outs() << "BOLT-INFO: profile collection done on a binary already " 2803 "processed by BOLT\n"; 2804 ProfileReader->setBAT(&*BAT); 2805 } 2806 2807 if (Error E = ProfileReader->preprocessProfile(*BC.get())) 2808 report_error("cannot pre-process profile", std::move(E)); 2809 2810 if (!BC->hasSymbolsWithFileName() && ProfileReader->hasLocalsWithFileName() && 2811 !opts::AllowStripped) { 2812 errs() << "BOLT-ERROR: input binary does not have local file symbols " 2813 "but profile data includes function names with embedded file " 2814 "names. It appears that the input binary was stripped while a " 2815 "profiled binary was not. If you know what you are doing and " 2816 "wish to proceed, use -allow-stripped option.\n"; 2817 exit(1); 2818 } 2819 } 2820 2821 void RewriteInstance::processProfileDataPreCFG() { 2822 if (!ProfileReader) 2823 return; 2824 2825 NamedRegionTimer T("processprofile-precfg", "process profile data pre-CFG", 2826 TimerGroupName, TimerGroupDesc, opts::TimeRewrite); 2827 2828 if (Error E = ProfileReader->readProfilePreCFG(*BC.get())) 2829 report_error("cannot read profile pre-CFG", std::move(E)); 2830 } 2831 2832 void RewriteInstance::processProfileData() { 2833 if (!ProfileReader) 2834 return; 2835 2836 NamedRegionTimer T("processprofile", "process profile data", TimerGroupName, 2837 TimerGroupDesc, opts::TimeRewrite); 2838 2839 if (Error E = ProfileReader->readProfile(*BC.get())) 2840 report_error("cannot read profile", std::move(E)); 2841 2842 if (!opts::SaveProfile.empty()) { 2843 YAMLProfileWriter PW(opts::SaveProfile); 2844 PW.writeProfile(*this); 2845 } 2846 2847 // Release memory used by profile reader. 2848 ProfileReader.reset(); 2849 2850 if (opts::AggregateOnly) 2851 exit(0); 2852 } 2853 2854 void RewriteInstance::disassembleFunctions() { 2855 NamedRegionTimer T("disassembleFunctions", "disassemble functions", 2856 TimerGroupName, TimerGroupDesc, opts::TimeRewrite); 2857 for (auto &BFI : BC->getBinaryFunctions()) { 2858 BinaryFunction &Function = BFI.second; 2859 2860 ErrorOr<ArrayRef<uint8_t>> FunctionData = Function.getData(); 2861 if (!FunctionData) { 2862 errs() << "BOLT-ERROR: corresponding section is non-executable or " 2863 << "empty for function " << Function << '\n'; 2864 exit(1); 2865 } 2866 2867 // Treat zero-sized functions as non-simple ones. 2868 if (Function.getSize() == 0) { 2869 Function.setSimple(false); 2870 continue; 2871 } 2872 2873 // Offset of the function in the file. 2874 const auto *FileBegin = 2875 reinterpret_cast<const uint8_t *>(InputFile->getData().data()); 2876 Function.setFileOffset(FunctionData->begin() - FileBegin); 2877 2878 if (!shouldDisassemble(Function)) { 2879 NamedRegionTimer T("scan", "scan functions", "buildfuncs", 2880 "Scan Binary Functions", opts::TimeBuild); 2881 Function.scanExternalRefs(); 2882 Function.setSimple(false); 2883 continue; 2884 } 2885 2886 if (!Function.disassemble()) { 2887 if (opts::processAllFunctions()) 2888 BC->exitWithBugReport("function cannot be properly disassembled. " 2889 "Unable to continue in relocation mode.", 2890 Function); 2891 if (opts::Verbosity >= 1) 2892 outs() << "BOLT-INFO: could not disassemble function " << Function 2893 << ". Will ignore.\n"; 2894 // Forcefully ignore the function. 2895 Function.setIgnored(); 2896 continue; 2897 } 2898 2899 if (opts::PrintAll || opts::PrintDisasm) 2900 Function.print(outs(), "after disassembly", true); 2901 2902 BC->processInterproceduralReferences(Function); 2903 } 2904 2905 BC->populateJumpTables(); 2906 BC->skipMarkedFragments(); 2907 2908 for (auto &BFI : BC->getBinaryFunctions()) { 2909 BinaryFunction &Function = BFI.second; 2910 2911 if (!shouldDisassemble(Function)) 2912 continue; 2913 2914 Function.postProcessEntryPoints(); 2915 Function.postProcessJumpTables(); 2916 } 2917 2918 BC->adjustCodePadding(); 2919 2920 for (auto &BFI : BC->getBinaryFunctions()) { 2921 BinaryFunction &Function = BFI.second; 2922 2923 if (!shouldDisassemble(Function)) 2924 continue; 2925 2926 if (!Function.isSimple()) { 2927 assert((!BC->HasRelocations || Function.getSize() == 0) && 2928 "unexpected non-simple function in relocation mode"); 2929 continue; 2930 } 2931 2932 // Fill in CFI information for this function 2933 if (!Function.trapsOnEntry() && !CFIRdWrt->fillCFIInfoFor(Function)) { 2934 if (BC->HasRelocations) { 2935 BC->exitWithBugReport("unable to fill CFI.", Function); 2936 } else { 2937 errs() << "BOLT-WARNING: unable to fill CFI for function " << Function 2938 << ". Skipping.\n"; 2939 Function.setSimple(false); 2940 continue; 2941 } 2942 } 2943 2944 // Parse LSDA. 2945 if (Function.getLSDAAddress() != 0) 2946 Function.parseLSDA(getLSDAData(), getLSDAAddress()); 2947 } 2948 } 2949 2950 void RewriteInstance::buildFunctionsCFG() { 2951 NamedRegionTimer T("buildCFG", "buildCFG", "buildfuncs", 2952 "Build Binary Functions", opts::TimeBuild); 2953 2954 // Create annotation indices to allow lock-free execution 2955 BC->MIB->getOrCreateAnnotationIndex("JTIndexReg"); 2956 BC->MIB->getOrCreateAnnotationIndex("NOP"); 2957 BC->MIB->getOrCreateAnnotationIndex("Size"); 2958 2959 ParallelUtilities::WorkFuncWithAllocTy WorkFun = 2960 [&](BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId) { 2961 if (!BF.buildCFG(AllocId)) 2962 return; 2963 2964 if (opts::PrintAll) { 2965 auto L = BC->scopeLock(); 2966 BF.print(outs(), "while building cfg", true); 2967 } 2968 }; 2969 2970 ParallelUtilities::PredicateTy SkipPredicate = [&](const BinaryFunction &BF) { 2971 return !shouldDisassemble(BF) || !BF.isSimple(); 2972 }; 2973 2974 ParallelUtilities::runOnEachFunctionWithUniqueAllocId( 2975 *BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun, 2976 SkipPredicate, "disassembleFunctions-buildCFG", 2977 /*ForceSequential*/ opts::SequentialDisassembly || opts::PrintAll); 2978 2979 BC->postProcessSymbolTable(); 2980 } 2981 2982 void RewriteInstance::postProcessFunctions() { 2983 BC->TotalScore = 0; 2984 BC->SumExecutionCount = 0; 2985 for (auto &BFI : BC->getBinaryFunctions()) { 2986 BinaryFunction &Function = BFI.second; 2987 2988 if (Function.empty()) 2989 continue; 2990 2991 Function.postProcessCFG(); 2992 2993 if (opts::PrintAll || opts::PrintCFG) 2994 Function.print(outs(), "after building cfg", true); 2995 2996 if (opts::DumpDotAll) 2997 Function.dumpGraphForPass("00_build-cfg"); 2998 2999 if (opts::PrintLoopInfo) { 3000 Function.calculateLoopInfo(); 3001 Function.printLoopInfo(outs()); 3002 } 3003 3004 BC->TotalScore += Function.getFunctionScore(); 3005 BC->SumExecutionCount += Function.getKnownExecutionCount(); 3006 } 3007 3008 if (opts::PrintGlobals) { 3009 outs() << "BOLT-INFO: Global symbols:\n"; 3010 BC->printGlobalSymbols(outs()); 3011 } 3012 } 3013 3014 void RewriteInstance::runOptimizationPasses() { 3015 NamedRegionTimer T("runOptimizationPasses", "run optimization passes", 3016 TimerGroupName, TimerGroupDesc, opts::TimeRewrite); 3017 BinaryFunctionPassManager::runAllPasses(*BC); 3018 } 3019 3020 namespace { 3021 3022 class BOLTSymbolResolver : public JITSymbolResolver { 3023 BinaryContext &BC; 3024 3025 public: 3026 BOLTSymbolResolver(BinaryContext &BC) : BC(BC) {} 3027 3028 // We are responsible for all symbols 3029 Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) override { 3030 return Symbols; 3031 } 3032 3033 // Some of our symbols may resolve to zero and this should not be an error 3034 bool allowsZeroSymbols() override { return true; } 3035 3036 /// Resolves the address of each symbol requested 3037 void lookup(const LookupSet &Symbols, 3038 OnResolvedFunction OnResolved) override { 3039 JITSymbolResolver::LookupResult AllResults; 3040 3041 if (BC.EFMM->ObjectsLoaded) { 3042 for (const StringRef &Symbol : Symbols) { 3043 std::string SymName = Symbol.str(); 3044 LLVM_DEBUG(dbgs() << "BOLT: looking for " << SymName << "\n"); 3045 // Resolve to a PLT entry if possible 3046 if (const BinaryData *I = BC.getPLTBinaryDataByName(SymName)) { 3047 AllResults[Symbol] = 3048 JITEvaluatedSymbol(I->getAddress(), JITSymbolFlags()); 3049 continue; 3050 } 3051 OnResolved(make_error<StringError>( 3052 "Symbol not found required by runtime: " + Symbol, 3053 inconvertibleErrorCode())); 3054 return; 3055 } 3056 OnResolved(std::move(AllResults)); 3057 return; 3058 } 3059 3060 for (const StringRef &Symbol : Symbols) { 3061 std::string SymName = Symbol.str(); 3062 LLVM_DEBUG(dbgs() << "BOLT: looking for " << SymName << "\n"); 3063 3064 if (BinaryData *I = BC.getBinaryDataByName(SymName)) { 3065 uint64_t Address = I->isMoved() && !I->isJumpTable() 3066 ? I->getOutputAddress() 3067 : I->getAddress(); 3068 LLVM_DEBUG(dbgs() << "Resolved to address 0x" 3069 << Twine::utohexstr(Address) << "\n"); 3070 AllResults[Symbol] = JITEvaluatedSymbol(Address, JITSymbolFlags()); 3071 continue; 3072 } 3073 LLVM_DEBUG(dbgs() << "Resolved to address 0x0\n"); 3074 AllResults[Symbol] = JITEvaluatedSymbol(0, JITSymbolFlags()); 3075 } 3076 3077 OnResolved(std::move(AllResults)); 3078 } 3079 }; 3080 3081 } // anonymous namespace 3082 3083 void RewriteInstance::emitAndLink() { 3084 NamedRegionTimer T("emitAndLink", "emit and link", TimerGroupName, 3085 TimerGroupDesc, opts::TimeRewrite); 3086 std::error_code EC; 3087 3088 // This is an object file, which we keep for debugging purposes. 3089 // Once we decide it's useless, we should create it in memory. 3090 SmallString<128> OutObjectPath; 3091 sys::fs::getPotentiallyUniqueTempFileName("output", "o", OutObjectPath); 3092 std::unique_ptr<ToolOutputFile> TempOut = 3093 std::make_unique<ToolOutputFile>(OutObjectPath, EC, sys::fs::OF_None); 3094 check_error(EC, "cannot create output object file"); 3095 3096 std::unique_ptr<buffer_ostream> BOS = 3097 std::make_unique<buffer_ostream>(TempOut->os()); 3098 raw_pwrite_stream *OS = BOS.get(); 3099 3100 // Implicitly MCObjectStreamer takes ownership of MCAsmBackend (MAB) 3101 // and MCCodeEmitter (MCE). ~MCObjectStreamer() will delete these 3102 // two instances. 3103 std::unique_ptr<MCStreamer> Streamer = BC->createStreamer(*OS); 3104 3105 if (EHFrameSection) { 3106 if (opts::UseOldText || opts::StrictMode) { 3107 // The section is going to be regenerated from scratch. 3108 // Empty the contents, but keep the section reference. 3109 EHFrameSection->clearContents(); 3110 } else { 3111 // Make .eh_frame relocatable. 3112 relocateEHFrameSection(); 3113 } 3114 } 3115 3116 emitBinaryContext(*Streamer, *BC, getOrgSecPrefix()); 3117 3118 Streamer->Finish(); 3119 if (Streamer->getContext().hadError()) { 3120 errs() << "BOLT-ERROR: Emission failed.\n"; 3121 exit(1); 3122 } 3123 3124 ////////////////////////////////////////////////////////////////////////////// 3125 // Assign addresses to new sections. 3126 ////////////////////////////////////////////////////////////////////////////// 3127 3128 // Get output object as ObjectFile. 3129 std::unique_ptr<MemoryBuffer> ObjectMemBuffer = 3130 MemoryBuffer::getMemBuffer(BOS->str(), "in-memory object file", false); 3131 std::unique_ptr<object::ObjectFile> Obj = cantFail( 3132 object::ObjectFile::createObjectFile(ObjectMemBuffer->getMemBufferRef()), 3133 "error creating in-memory object"); 3134 3135 BOLTSymbolResolver Resolver = BOLTSymbolResolver(*BC); 3136 3137 MCAsmLayout FinalLayout( 3138 static_cast<MCObjectStreamer *>(Streamer.get())->getAssembler()); 3139 3140 RTDyld.reset(new decltype(RTDyld)::element_type(*BC->EFMM, Resolver)); 3141 RTDyld->setProcessAllSections(false); 3142 RTDyld->loadObject(*Obj); 3143 3144 // Assign addresses to all sections. If key corresponds to the object 3145 // created by ourselves, call our regular mapping function. If we are 3146 // loading additional objects as part of runtime libraries for 3147 // instrumentation, treat them as extra sections. 3148 mapFileSections(*RTDyld); 3149 3150 RTDyld->finalizeWithMemoryManagerLocking(); 3151 if (RTDyld->hasError()) { 3152 errs() << "BOLT-ERROR: RTDyld failed: " << RTDyld->getErrorString() << "\n"; 3153 exit(1); 3154 } 3155 3156 // Update output addresses based on the new section map and 3157 // layout. Only do this for the object created by ourselves. 3158 updateOutputValues(FinalLayout); 3159 3160 if (opts::UpdateDebugSections) 3161 DebugInfoRewriter->updateLineTableOffsets(FinalLayout); 3162 3163 if (RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary()) 3164 RtLibrary->link(*BC, ToolPath, *RTDyld, [this](RuntimeDyld &R) { 3165 this->mapExtraSections(*RTDyld); 3166 }); 3167 3168 // Once the code is emitted, we can rename function sections to actual 3169 // output sections and de-register sections used for emission. 3170 for (BinaryFunction *Function : BC->getAllBinaryFunctions()) { 3171 ErrorOr<BinarySection &> Section = Function->getCodeSection(); 3172 if (Section && 3173 (Function->getImageAddress() == 0 || Function->getImageSize() == 0)) 3174 continue; 3175 3176 // Restore origin section for functions that were emitted or supposed to 3177 // be emitted to patch sections. 3178 if (Section) 3179 BC->deregisterSection(*Section); 3180 assert(Function->getOriginSectionName() && "expected origin section"); 3181 Function->CodeSectionName = std::string(*Function->getOriginSectionName()); 3182 if (Function->isSplit()) { 3183 if (ErrorOr<BinarySection &> ColdSection = Function->getColdCodeSection()) 3184 BC->deregisterSection(*ColdSection); 3185 Function->ColdCodeSectionName = std::string(getBOLTTextSectionName()); 3186 } 3187 } 3188 3189 if (opts::PrintCacheMetrics) { 3190 outs() << "BOLT-INFO: cache metrics after emitting functions:\n"; 3191 CacheMetrics::printAll(BC->getSortedFunctions()); 3192 } 3193 3194 if (opts::KeepTmp) { 3195 TempOut->keep(); 3196 outs() << "BOLT-INFO: intermediary output object file saved for debugging " 3197 "purposes: " 3198 << OutObjectPath << "\n"; 3199 } 3200 } 3201 3202 void RewriteInstance::updateMetadata() { 3203 updateSDTMarkers(); 3204 updateLKMarkers(); 3205 parsePseudoProbe(); 3206 updatePseudoProbes(); 3207 3208 if (opts::UpdateDebugSections) { 3209 NamedRegionTimer T("updateDebugInfo", "update debug info", TimerGroupName, 3210 TimerGroupDesc, opts::TimeRewrite); 3211 DebugInfoRewriter->updateDebugInfo(); 3212 } 3213 3214 if (opts::WriteBoltInfoSection) 3215 addBoltInfoSection(); 3216 } 3217 3218 void RewriteInstance::updatePseudoProbes() { 3219 // check if there is pseudo probe section decoded 3220 if (BC->ProbeDecoder.getAddress2ProbesMap().empty()) 3221 return; 3222 // input address converted to output 3223 AddressProbesMap &Address2ProbesMap = BC->ProbeDecoder.getAddress2ProbesMap(); 3224 const GUIDProbeFunctionMap &GUID2Func = 3225 BC->ProbeDecoder.getGUID2FuncDescMap(); 3226 3227 for (auto &AP : Address2ProbesMap) { 3228 BinaryFunction *F = BC->getBinaryFunctionContainingAddress(AP.first); 3229 // If F is removed, eliminate all probes inside it from inline tree 3230 // Setting probes' addresses as INT64_MAX means elimination 3231 if (!F) { 3232 for (MCDecodedPseudoProbe &Probe : AP.second) 3233 Probe.setAddress(INT64_MAX); 3234 continue; 3235 } 3236 // If F is not emitted, the function will remain in the same address as its 3237 // input 3238 if (!F->isEmitted()) 3239 continue; 3240 3241 uint64_t Offset = AP.first - F->getAddress(); 3242 const BinaryBasicBlock *BB = F->getBasicBlockContainingOffset(Offset); 3243 uint64_t BlkOutputAddress = BB->getOutputAddressRange().first; 3244 // Check if block output address is defined. 3245 // If not, such block is removed from binary. Then remove the probes from 3246 // inline tree 3247 if (BlkOutputAddress == 0) { 3248 for (MCDecodedPseudoProbe &Probe : AP.second) 3249 Probe.setAddress(INT64_MAX); 3250 continue; 3251 } 3252 3253 unsigned ProbeTrack = AP.second.size(); 3254 std::list<MCDecodedPseudoProbe>::iterator Probe = AP.second.begin(); 3255 while (ProbeTrack != 0) { 3256 if (Probe->isBlock()) { 3257 Probe->setAddress(BlkOutputAddress); 3258 } else if (Probe->isCall()) { 3259 // A call probe may be duplicated due to ICP 3260 // Go through output of InputOffsetToAddressMap to collect all related 3261 // probes 3262 const InputOffsetToAddressMapTy &Offset2Addr = 3263 F->getInputOffsetToAddressMap(); 3264 auto CallOutputAddresses = Offset2Addr.equal_range(Offset); 3265 auto CallOutputAddress = CallOutputAddresses.first; 3266 if (CallOutputAddress == CallOutputAddresses.second) { 3267 Probe->setAddress(INT64_MAX); 3268 } else { 3269 Probe->setAddress(CallOutputAddress->second); 3270 CallOutputAddress = std::next(CallOutputAddress); 3271 } 3272 3273 while (CallOutputAddress != CallOutputAddresses.second) { 3274 AP.second.push_back(*Probe); 3275 AP.second.back().setAddress(CallOutputAddress->second); 3276 Probe->getInlineTreeNode()->addProbes(&(AP.second.back())); 3277 CallOutputAddress = std::next(CallOutputAddress); 3278 } 3279 } 3280 Probe = std::next(Probe); 3281 ProbeTrack--; 3282 } 3283 } 3284 3285 if (opts::PrintPseudoProbes == opts::PrintPseudoProbesOptions::PPP_All || 3286 opts::PrintPseudoProbes == 3287 opts::PrintPseudoProbesOptions::PPP_Probes_Address_Conversion) { 3288 outs() << "Pseudo Probe Address Conversion results:\n"; 3289 // table that correlates address to block 3290 std::unordered_map<uint64_t, StringRef> Addr2BlockNames; 3291 for (auto &F : BC->getBinaryFunctions()) 3292 for (BinaryBasicBlock &BinaryBlock : F.second) 3293 Addr2BlockNames[BinaryBlock.getOutputAddressRange().first] = 3294 BinaryBlock.getName(); 3295 3296 // scan all addresses -> correlate probe to block when print out 3297 std::vector<uint64_t> Addresses; 3298 for (auto &Entry : Address2ProbesMap) 3299 Addresses.push_back(Entry.first); 3300 std::sort(Addresses.begin(), Addresses.end()); 3301 for (uint64_t Key : Addresses) { 3302 for (MCDecodedPseudoProbe &Probe : Address2ProbesMap[Key]) { 3303 if (Probe.getAddress() == INT64_MAX) 3304 outs() << "Deleted Probe: "; 3305 else 3306 outs() << "Address: " << format_hex(Probe.getAddress(), 8) << " "; 3307 Probe.print(outs(), GUID2Func, true); 3308 // print block name only if the probe is block type and undeleted. 3309 if (Probe.isBlock() && Probe.getAddress() != INT64_MAX) 3310 outs() << format_hex(Probe.getAddress(), 8) << " Probe is in " 3311 << Addr2BlockNames[Probe.getAddress()] << "\n"; 3312 } 3313 } 3314 outs() << "=======================================\n"; 3315 } 3316 3317 // encode pseudo probes with updated addresses 3318 encodePseudoProbes(); 3319 } 3320 3321 template <typename F> 3322 static void emitLEB128IntValue(F encode, uint64_t Value, 3323 SmallString<8> &Contents) { 3324 SmallString<128> Tmp; 3325 raw_svector_ostream OSE(Tmp); 3326 encode(Value, OSE); 3327 Contents.append(OSE.str().begin(), OSE.str().end()); 3328 } 3329 3330 void RewriteInstance::encodePseudoProbes() { 3331 // Buffer for new pseudo probes section 3332 SmallString<8> Contents; 3333 MCDecodedPseudoProbe *LastProbe = nullptr; 3334 3335 auto EmitInt = [&](uint64_t Value, uint32_t Size) { 3336 const bool IsLittleEndian = BC->AsmInfo->isLittleEndian(); 3337 uint64_t Swapped = support::endian::byte_swap( 3338 Value, IsLittleEndian ? support::little : support::big); 3339 unsigned Index = IsLittleEndian ? 0 : 8 - Size; 3340 auto Entry = StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size); 3341 Contents.append(Entry.begin(), Entry.end()); 3342 }; 3343 3344 auto EmitULEB128IntValue = [&](uint64_t Value) { 3345 SmallString<128> Tmp; 3346 raw_svector_ostream OSE(Tmp); 3347 encodeULEB128(Value, OSE, 0); 3348 Contents.append(OSE.str().begin(), OSE.str().end()); 3349 }; 3350 3351 auto EmitSLEB128IntValue = [&](int64_t Value) { 3352 SmallString<128> Tmp; 3353 raw_svector_ostream OSE(Tmp); 3354 encodeSLEB128(Value, OSE); 3355 Contents.append(OSE.str().begin(), OSE.str().end()); 3356 }; 3357 3358 // Emit indiviual pseudo probes in a inline tree node 3359 // Probe index, type, attribute, address type and address are encoded 3360 // Address of the first probe is absolute. 3361 // Other probes' address are represented by delta 3362 auto EmitDecodedPseudoProbe = [&](MCDecodedPseudoProbe *&CurProbe) { 3363 EmitULEB128IntValue(CurProbe->getIndex()); 3364 uint8_t PackedType = CurProbe->getType() | (CurProbe->getAttributes() << 4); 3365 uint8_t Flag = 3366 LastProbe ? ((int8_t)MCPseudoProbeFlag::AddressDelta << 7) : 0; 3367 EmitInt(Flag | PackedType, 1); 3368 if (LastProbe) { 3369 // Emit the delta between the address label and LastProbe. 3370 int64_t Delta = CurProbe->getAddress() - LastProbe->getAddress(); 3371 EmitSLEB128IntValue(Delta); 3372 } else { 3373 // Emit absolute address for encoding the first pseudo probe. 3374 uint32_t AddrSize = BC->AsmInfo->getCodePointerSize(); 3375 EmitInt(CurProbe->getAddress(), AddrSize); 3376 } 3377 }; 3378 3379 std::map<InlineSite, MCDecodedPseudoProbeInlineTree *, 3380 std::greater<InlineSite>> 3381 Inlinees; 3382 3383 // DFS of inline tree to emit pseudo probes in all tree node 3384 // Inline site index of a probe is emitted first. 3385 // Then tree node Guid, size of pseudo probes and children nodes, and detail 3386 // of contained probes are emitted Deleted probes are skipped Root node is not 3387 // encoded to binaries. It's a "wrapper" of inline trees of each function. 3388 std::list<std::pair<uint64_t, MCDecodedPseudoProbeInlineTree *>> NextNodes; 3389 const MCDecodedPseudoProbeInlineTree &Root = 3390 BC->ProbeDecoder.getDummyInlineRoot(); 3391 for (auto Child = Root.getChildren().begin(); 3392 Child != Root.getChildren().end(); ++Child) 3393 Inlinees[Child->first] = Child->second.get(); 3394 3395 for (auto Inlinee : Inlinees) 3396 // INT64_MAX is "placeholder" of unused callsite index field in the pair 3397 NextNodes.push_back({INT64_MAX, Inlinee.second}); 3398 3399 Inlinees.clear(); 3400 3401 while (!NextNodes.empty()) { 3402 uint64_t ProbeIndex = NextNodes.back().first; 3403 MCDecodedPseudoProbeInlineTree *Cur = NextNodes.back().second; 3404 NextNodes.pop_back(); 3405 3406 if (Cur->Parent && !Cur->Parent->isRoot()) 3407 // Emit probe inline site 3408 EmitULEB128IntValue(ProbeIndex); 3409 3410 // Emit probes grouped by GUID. 3411 LLVM_DEBUG({ 3412 dbgs().indent(MCPseudoProbeTable::DdgPrintIndent); 3413 dbgs() << "GUID: " << Cur->Guid << "\n"; 3414 }); 3415 // Emit Guid 3416 EmitInt(Cur->Guid, 8); 3417 // Emit number of probes in this node 3418 uint64_t Deleted = 0; 3419 for (MCDecodedPseudoProbe *&Probe : Cur->getProbes()) 3420 if (Probe->getAddress() == INT64_MAX) 3421 Deleted++; 3422 LLVM_DEBUG(dbgs() << "Deleted Probes:" << Deleted << "\n"); 3423 uint64_t ProbesSize = Cur->getProbes().size() - Deleted; 3424 EmitULEB128IntValue(ProbesSize); 3425 // Emit number of direct inlinees 3426 EmitULEB128IntValue(Cur->getChildren().size()); 3427 // Emit probes in this group 3428 for (MCDecodedPseudoProbe *&Probe : Cur->getProbes()) { 3429 if (Probe->getAddress() == INT64_MAX) 3430 continue; 3431 EmitDecodedPseudoProbe(Probe); 3432 LastProbe = Probe; 3433 } 3434 3435 for (auto Child = Cur->getChildren().begin(); 3436 Child != Cur->getChildren().end(); ++Child) 3437 Inlinees[Child->first] = Child->second.get(); 3438 for (const auto &Inlinee : Inlinees) { 3439 assert(Cur->Guid != 0 && "non root tree node must have nonzero Guid"); 3440 NextNodes.push_back({std::get<1>(Inlinee.first), Inlinee.second}); 3441 LLVM_DEBUG({ 3442 dbgs().indent(MCPseudoProbeTable::DdgPrintIndent); 3443 dbgs() << "InlineSite: " << std::get<1>(Inlinee.first) << "\n"; 3444 }); 3445 } 3446 Inlinees.clear(); 3447 } 3448 3449 // Create buffer for new contents for the section 3450 // Freed when parent section is destroyed 3451 uint8_t *Output = new uint8_t[Contents.str().size()]; 3452 memcpy(Output, Contents.str().data(), Contents.str().size()); 3453 addToDebugSectionsToOverwrite(".pseudo_probe"); 3454 BC->registerOrUpdateSection(".pseudo_probe", PseudoProbeSection->getELFType(), 3455 PseudoProbeSection->getELFFlags(), Output, 3456 Contents.str().size(), 1); 3457 if (opts::PrintPseudoProbes == opts::PrintPseudoProbesOptions::PPP_All || 3458 opts::PrintPseudoProbes == 3459 opts::PrintPseudoProbesOptions::PPP_Encoded_Probes) { 3460 // create a dummy decoder; 3461 MCPseudoProbeDecoder DummyDecoder; 3462 StringRef DescContents = PseudoProbeDescSection->getContents(); 3463 DummyDecoder.buildGUID2FuncDescMap( 3464 reinterpret_cast<const uint8_t *>(DescContents.data()), 3465 DescContents.size()); 3466 StringRef ProbeContents = PseudoProbeSection->getOutputContents(); 3467 DummyDecoder.buildAddress2ProbeMap( 3468 reinterpret_cast<const uint8_t *>(ProbeContents.data()), 3469 ProbeContents.size()); 3470 DummyDecoder.printProbesForAllAddresses(outs()); 3471 } 3472 } 3473 3474 void RewriteInstance::updateSDTMarkers() { 3475 NamedRegionTimer T("updateSDTMarkers", "update SDT markers", TimerGroupName, 3476 TimerGroupDesc, opts::TimeRewrite); 3477 3478 if (!SDTSection) 3479 return; 3480 SDTSection->registerPatcher(std::make_unique<SimpleBinaryPatcher>()); 3481 3482 SimpleBinaryPatcher *SDTNotePatcher = 3483 static_cast<SimpleBinaryPatcher *>(SDTSection->getPatcher()); 3484 for (auto &SDTInfoKV : BC->SDTMarkers) { 3485 const uint64_t OriginalAddress = SDTInfoKV.first; 3486 SDTMarkerInfo &SDTInfo = SDTInfoKV.second; 3487 const BinaryFunction *F = 3488 BC->getBinaryFunctionContainingAddress(OriginalAddress); 3489 if (!F) 3490 continue; 3491 const uint64_t NewAddress = 3492 F->translateInputToOutputAddress(OriginalAddress); 3493 SDTNotePatcher->addLE64Patch(SDTInfo.PCOffset, NewAddress); 3494 } 3495 } 3496 3497 void RewriteInstance::updateLKMarkers() { 3498 if (BC->LKMarkers.size() == 0) 3499 return; 3500 3501 NamedRegionTimer T("updateLKMarkers", "update LK markers", TimerGroupName, 3502 TimerGroupDesc, opts::TimeRewrite); 3503 3504 std::unordered_map<std::string, uint64_t> PatchCounts; 3505 for (std::pair<const uint64_t, std::vector<LKInstructionMarkerInfo>> 3506 &LKMarkerInfoKV : BC->LKMarkers) { 3507 const uint64_t OriginalAddress = LKMarkerInfoKV.first; 3508 const BinaryFunction *BF = 3509 BC->getBinaryFunctionContainingAddress(OriginalAddress, false, true); 3510 if (!BF) 3511 continue; 3512 3513 uint64_t NewAddress = BF->translateInputToOutputAddress(OriginalAddress); 3514 if (NewAddress == 0) 3515 continue; 3516 3517 // Apply base address. 3518 if (OriginalAddress >= 0xffffffff00000000 && NewAddress < 0xffffffff) 3519 NewAddress = NewAddress + 0xffffffff00000000; 3520 3521 if (OriginalAddress == NewAddress) 3522 continue; 3523 3524 for (LKInstructionMarkerInfo &LKMarkerInfo : LKMarkerInfoKV.second) { 3525 StringRef SectionName = LKMarkerInfo.SectionName; 3526 SimpleBinaryPatcher *LKPatcher; 3527 ErrorOr<BinarySection &> BSec = BC->getUniqueSectionByName(SectionName); 3528 assert(BSec && "missing section info for kernel section"); 3529 if (!BSec->getPatcher()) 3530 BSec->registerPatcher(std::make_unique<SimpleBinaryPatcher>()); 3531 LKPatcher = static_cast<SimpleBinaryPatcher *>(BSec->getPatcher()); 3532 PatchCounts[std::string(SectionName)]++; 3533 if (LKMarkerInfo.IsPCRelative) 3534 LKPatcher->addLE32Patch(LKMarkerInfo.SectionOffset, 3535 NewAddress - OriginalAddress + 3536 LKMarkerInfo.PCRelativeOffset); 3537 else 3538 LKPatcher->addLE64Patch(LKMarkerInfo.SectionOffset, NewAddress); 3539 } 3540 } 3541 outs() << "BOLT-INFO: patching linux kernel sections. Total patches per " 3542 "section are as follows:\n"; 3543 for (const std::pair<const std::string, uint64_t> &KV : PatchCounts) 3544 outs() << " Section: " << KV.first << ", patch-counts: " << KV.second 3545 << '\n'; 3546 } 3547 3548 void RewriteInstance::mapFileSections(RuntimeDyld &RTDyld) { 3549 mapCodeSections(RTDyld); 3550 mapDataSections(RTDyld); 3551 } 3552 3553 std::vector<BinarySection *> RewriteInstance::getCodeSections() { 3554 std::vector<BinarySection *> CodeSections; 3555 for (BinarySection &Section : BC->textSections()) 3556 if (Section.hasValidSectionID()) 3557 CodeSections.emplace_back(&Section); 3558 3559 auto compareSections = [&](const BinarySection *A, const BinarySection *B) { 3560 // Place movers before anything else. 3561 if (A->getName() == BC->getHotTextMoverSectionName()) 3562 return true; 3563 if (B->getName() == BC->getHotTextMoverSectionName()) 3564 return false; 3565 3566 // Depending on the option, put main text at the beginning or at the end. 3567 if (opts::HotFunctionsAtEnd) 3568 return B->getName() == BC->getMainCodeSectionName(); 3569 else 3570 return A->getName() == BC->getMainCodeSectionName(); 3571 }; 3572 3573 // Determine the order of sections. 3574 std::stable_sort(CodeSections.begin(), CodeSections.end(), compareSections); 3575 3576 return CodeSections; 3577 } 3578 3579 void RewriteInstance::mapCodeSections(RuntimeDyld &RTDyld) { 3580 if (BC->HasRelocations) { 3581 ErrorOr<BinarySection &> TextSection = 3582 BC->getUniqueSectionByName(BC->getMainCodeSectionName()); 3583 assert(TextSection && ".text section not found in output"); 3584 assert(TextSection->hasValidSectionID() && ".text section should be valid"); 3585 3586 // Map sections for functions with pre-assigned addresses. 3587 for (BinaryFunction *InjectedFunction : BC->getInjectedBinaryFunctions()) { 3588 const uint64_t OutputAddress = InjectedFunction->getOutputAddress(); 3589 if (!OutputAddress) 3590 continue; 3591 3592 ErrorOr<BinarySection &> FunctionSection = 3593 InjectedFunction->getCodeSection(); 3594 assert(FunctionSection && "function should have section"); 3595 FunctionSection->setOutputAddress(OutputAddress); 3596 RTDyld.reassignSectionAddress(FunctionSection->getSectionID(), 3597 OutputAddress); 3598 InjectedFunction->setImageAddress(FunctionSection->getAllocAddress()); 3599 InjectedFunction->setImageSize(FunctionSection->getOutputSize()); 3600 } 3601 3602 // Populate the list of sections to be allocated. 3603 std::vector<BinarySection *> CodeSections = getCodeSections(); 3604 3605 // Remove sections that were pre-allocated (patch sections). 3606 CodeSections.erase( 3607 std::remove_if(CodeSections.begin(), CodeSections.end(), 3608 [](BinarySection *Section) { 3609 return Section->getOutputAddress(); 3610 }), 3611 CodeSections.end()); 3612 LLVM_DEBUG(dbgs() << "Code sections in the order of output:\n"; 3613 for (const BinarySection *Section : CodeSections) 3614 dbgs() << Section->getName() << '\n'; 3615 ); 3616 3617 uint64_t PaddingSize = 0; // size of padding required at the end 3618 3619 // Allocate sections starting at a given Address. 3620 auto allocateAt = [&](uint64_t Address) { 3621 for (BinarySection *Section : CodeSections) { 3622 Address = alignTo(Address, Section->getAlignment()); 3623 Section->setOutputAddress(Address); 3624 Address += Section->getOutputSize(); 3625 } 3626 3627 // Make sure we allocate enough space for huge pages. 3628 if (opts::HotText) { 3629 uint64_t HotTextEnd = 3630 TextSection->getOutputAddress() + TextSection->getOutputSize(); 3631 HotTextEnd = alignTo(HotTextEnd, BC->PageAlign); 3632 if (HotTextEnd > Address) { 3633 PaddingSize = HotTextEnd - Address; 3634 Address = HotTextEnd; 3635 } 3636 } 3637 return Address; 3638 }; 3639 3640 // Check if we can fit code in the original .text 3641 bool AllocationDone = false; 3642 if (opts::UseOldText) { 3643 const uint64_t CodeSize = 3644 allocateAt(BC->OldTextSectionAddress) - BC->OldTextSectionAddress; 3645 3646 if (CodeSize <= BC->OldTextSectionSize) { 3647 outs() << "BOLT-INFO: using original .text for new code with 0x" 3648 << Twine::utohexstr(opts::AlignText) << " alignment\n"; 3649 AllocationDone = true; 3650 } else { 3651 errs() << "BOLT-WARNING: original .text too small to fit the new code" 3652 << " using 0x" << Twine::utohexstr(opts::AlignText) 3653 << " alignment. " << CodeSize << " bytes needed, have " 3654 << BC->OldTextSectionSize << " bytes available.\n"; 3655 opts::UseOldText = false; 3656 } 3657 } 3658 3659 if (!AllocationDone) 3660 NextAvailableAddress = allocateAt(NextAvailableAddress); 3661 3662 // Do the mapping for ORC layer based on the allocation. 3663 for (BinarySection *Section : CodeSections) { 3664 LLVM_DEBUG( 3665 dbgs() << "BOLT: mapping " << Section->getName() << " at 0x" 3666 << Twine::utohexstr(Section->getAllocAddress()) << " to 0x" 3667 << Twine::utohexstr(Section->getOutputAddress()) << '\n'); 3668 RTDyld.reassignSectionAddress(Section->getSectionID(), 3669 Section->getOutputAddress()); 3670 Section->setOutputFileOffset( 3671 getFileOffsetForAddress(Section->getOutputAddress())); 3672 } 3673 3674 // Check if we need to insert a padding section for hot text. 3675 if (PaddingSize && !opts::UseOldText) 3676 outs() << "BOLT-INFO: padding code to 0x" 3677 << Twine::utohexstr(NextAvailableAddress) 3678 << " to accommodate hot text\n"; 3679 3680 return; 3681 } 3682 3683 // Processing in non-relocation mode. 3684 uint64_t NewTextSectionStartAddress = NextAvailableAddress; 3685 3686 for (auto &BFI : BC->getBinaryFunctions()) { 3687 BinaryFunction &Function = BFI.second; 3688 if (!Function.isEmitted()) 3689 continue; 3690 3691 bool TooLarge = false; 3692 ErrorOr<BinarySection &> FuncSection = Function.getCodeSection(); 3693 assert(FuncSection && "cannot find section for function"); 3694 FuncSection->setOutputAddress(Function.getAddress()); 3695 LLVM_DEBUG(dbgs() << "BOLT: mapping 0x" 3696 << Twine::utohexstr(FuncSection->getAllocAddress()) 3697 << " to 0x" << Twine::utohexstr(Function.getAddress()) 3698 << '\n'); 3699 RTDyld.reassignSectionAddress(FuncSection->getSectionID(), 3700 Function.getAddress()); 3701 Function.setImageAddress(FuncSection->getAllocAddress()); 3702 Function.setImageSize(FuncSection->getOutputSize()); 3703 if (Function.getImageSize() > Function.getMaxSize()) { 3704 TooLarge = true; 3705 FailedAddresses.emplace_back(Function.getAddress()); 3706 } 3707 3708 // Map jump tables if updating in-place. 3709 if (opts::JumpTables == JTS_BASIC) { 3710 for (auto &JTI : Function.JumpTables) { 3711 JumpTable *JT = JTI.second; 3712 BinarySection &Section = JT->getOutputSection(); 3713 Section.setOutputAddress(JT->getAddress()); 3714 Section.setOutputFileOffset(getFileOffsetForAddress(JT->getAddress())); 3715 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: mapping " << Section.getName() 3716 << " to 0x" << Twine::utohexstr(JT->getAddress()) 3717 << '\n'); 3718 RTDyld.reassignSectionAddress(Section.getSectionID(), JT->getAddress()); 3719 } 3720 } 3721 3722 if (!Function.isSplit()) 3723 continue; 3724 3725 ErrorOr<BinarySection &> ColdSection = Function.getColdCodeSection(); 3726 assert(ColdSection && "cannot find section for cold part"); 3727 // Cold fragments are aligned at 16 bytes. 3728 NextAvailableAddress = alignTo(NextAvailableAddress, 16); 3729 BinaryFunction::FragmentInfo &ColdPart = Function.cold(); 3730 if (TooLarge) { 3731 // The corresponding FDE will refer to address 0. 3732 ColdPart.setAddress(0); 3733 ColdPart.setImageAddress(0); 3734 ColdPart.setImageSize(0); 3735 ColdPart.setFileOffset(0); 3736 } else { 3737 ColdPart.setAddress(NextAvailableAddress); 3738 ColdPart.setImageAddress(ColdSection->getAllocAddress()); 3739 ColdPart.setImageSize(ColdSection->getOutputSize()); 3740 ColdPart.setFileOffset(getFileOffsetForAddress(NextAvailableAddress)); 3741 ColdSection->setOutputAddress(ColdPart.getAddress()); 3742 } 3743 3744 LLVM_DEBUG(dbgs() << "BOLT: mapping cold fragment 0x" 3745 << Twine::utohexstr(ColdPart.getImageAddress()) 3746 << " to 0x" << Twine::utohexstr(ColdPart.getAddress()) 3747 << " with size " 3748 << Twine::utohexstr(ColdPart.getImageSize()) << '\n'); 3749 RTDyld.reassignSectionAddress(ColdSection->getSectionID(), 3750 ColdPart.getAddress()); 3751 3752 NextAvailableAddress += ColdPart.getImageSize(); 3753 } 3754 3755 // Add the new text section aggregating all existing code sections. 3756 // This is pseudo-section that serves a purpose of creating a corresponding 3757 // entry in section header table. 3758 int64_t NewTextSectionSize = 3759 NextAvailableAddress - NewTextSectionStartAddress; 3760 if (NewTextSectionSize) { 3761 const unsigned Flags = BinarySection::getFlags(/*IsReadOnly=*/true, 3762 /*IsText=*/true, 3763 /*IsAllocatable=*/true); 3764 BinarySection &Section = 3765 BC->registerOrUpdateSection(getBOLTTextSectionName(), 3766 ELF::SHT_PROGBITS, 3767 Flags, 3768 /*Data=*/nullptr, 3769 NewTextSectionSize, 3770 16); 3771 Section.setOutputAddress(NewTextSectionStartAddress); 3772 Section.setOutputFileOffset( 3773 getFileOffsetForAddress(NewTextSectionStartAddress)); 3774 } 3775 } 3776 3777 void RewriteInstance::mapDataSections(RuntimeDyld &RTDyld) { 3778 // Map special sections to their addresses in the output image. 3779 // These are the sections that we generate via MCStreamer. 3780 // The order is important. 3781 std::vector<std::string> Sections = { 3782 ".eh_frame", Twine(getOrgSecPrefix(), ".eh_frame").str(), 3783 ".gcc_except_table", ".rodata", ".rodata.cold"}; 3784 if (RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary()) 3785 RtLibrary->addRuntimeLibSections(Sections); 3786 3787 for (std::string &SectionName : Sections) { 3788 ErrorOr<BinarySection &> Section = BC->getUniqueSectionByName(SectionName); 3789 if (!Section || !Section->isAllocatable() || !Section->isFinalized()) 3790 continue; 3791 NextAvailableAddress = 3792 alignTo(NextAvailableAddress, Section->getAlignment()); 3793 LLVM_DEBUG(dbgs() << "BOLT: mapping section " << SectionName << " (0x" 3794 << Twine::utohexstr(Section->getAllocAddress()) 3795 << ") to 0x" << Twine::utohexstr(NextAvailableAddress) 3796 << ":0x" 3797 << Twine::utohexstr(NextAvailableAddress + 3798 Section->getOutputSize()) 3799 << '\n'); 3800 3801 RTDyld.reassignSectionAddress(Section->getSectionID(), 3802 NextAvailableAddress); 3803 Section->setOutputAddress(NextAvailableAddress); 3804 Section->setOutputFileOffset(getFileOffsetForAddress(NextAvailableAddress)); 3805 3806 NextAvailableAddress += Section->getOutputSize(); 3807 } 3808 3809 // Handling for sections with relocations. 3810 for (BinarySection &Section : BC->sections()) { 3811 if (!Section.hasSectionRef()) 3812 continue; 3813 3814 StringRef SectionName = Section.getName(); 3815 ErrorOr<BinarySection &> OrgSection = 3816 BC->getUniqueSectionByName((getOrgSecPrefix() + SectionName).str()); 3817 if (!OrgSection || 3818 !OrgSection->isAllocatable() || 3819 !OrgSection->isFinalized() || 3820 !OrgSection->hasValidSectionID()) 3821 continue; 3822 3823 if (OrgSection->getOutputAddress()) { 3824 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: section " << SectionName 3825 << " is already mapped at 0x" 3826 << Twine::utohexstr(OrgSection->getOutputAddress()) 3827 << '\n'); 3828 continue; 3829 } 3830 LLVM_DEBUG( 3831 dbgs() << "BOLT: mapping original section " << SectionName << " (0x" 3832 << Twine::utohexstr(OrgSection->getAllocAddress()) << ") to 0x" 3833 << Twine::utohexstr(Section.getAddress()) << '\n'); 3834 3835 RTDyld.reassignSectionAddress(OrgSection->getSectionID(), 3836 Section.getAddress()); 3837 3838 OrgSection->setOutputAddress(Section.getAddress()); 3839 OrgSection->setOutputFileOffset(Section.getContents().data() - 3840 InputFile->getData().data()); 3841 } 3842 } 3843 3844 void RewriteInstance::mapExtraSections(RuntimeDyld &RTDyld) { 3845 for (BinarySection &Section : BC->allocatableSections()) { 3846 if (Section.getOutputAddress() || !Section.hasValidSectionID()) 3847 continue; 3848 NextAvailableAddress = 3849 alignTo(NextAvailableAddress, Section.getAlignment()); 3850 Section.setOutputAddress(NextAvailableAddress); 3851 NextAvailableAddress += Section.getOutputSize(); 3852 3853 LLVM_DEBUG(dbgs() << "BOLT: (extra) mapping " << Section.getName() 3854 << " at 0x" << Twine::utohexstr(Section.getAllocAddress()) 3855 << " to 0x" 3856 << Twine::utohexstr(Section.getOutputAddress()) << '\n'); 3857 3858 RTDyld.reassignSectionAddress(Section.getSectionID(), 3859 Section.getOutputAddress()); 3860 Section.setOutputFileOffset( 3861 getFileOffsetForAddress(Section.getOutputAddress())); 3862 } 3863 } 3864 3865 void RewriteInstance::updateOutputValues(const MCAsmLayout &Layout) { 3866 for (BinaryFunction *Function : BC->getAllBinaryFunctions()) 3867 Function->updateOutputValues(Layout); 3868 } 3869 3870 void RewriteInstance::patchELFPHDRTable() { 3871 auto ELF64LEFile = dyn_cast<ELF64LEObjectFile>(InputFile); 3872 if (!ELF64LEFile) { 3873 errs() << "BOLT-ERROR: only 64-bit LE ELF binaries are supported\n"; 3874 exit(1); 3875 } 3876 const ELFFile<ELF64LE> &Obj = ELF64LEFile->getELFFile(); 3877 raw_fd_ostream &OS = Out->os(); 3878 3879 // Write/re-write program headers. 3880 Phnum = Obj.getHeader().e_phnum; 3881 if (PHDRTableOffset) { 3882 // Writing new pheader table. 3883 Phnum += 1; // only adding one new segment 3884 // Segment size includes the size of the PHDR area. 3885 NewTextSegmentSize = NextAvailableAddress - PHDRTableAddress; 3886 } else { 3887 assert(!PHDRTableAddress && "unexpected address for program header table"); 3888 // Update existing table. 3889 PHDRTableOffset = Obj.getHeader().e_phoff; 3890 NewTextSegmentSize = NextAvailableAddress - NewTextSegmentAddress; 3891 } 3892 OS.seek(PHDRTableOffset); 3893 3894 bool ModdedGnuStack = false; 3895 (void)ModdedGnuStack; 3896 bool AddedSegment = false; 3897 (void)AddedSegment; 3898 3899 auto createNewTextPhdr = [&]() { 3900 ELF64LEPhdrTy NewPhdr; 3901 NewPhdr.p_type = ELF::PT_LOAD; 3902 if (PHDRTableAddress) { 3903 NewPhdr.p_offset = PHDRTableOffset; 3904 NewPhdr.p_vaddr = PHDRTableAddress; 3905 NewPhdr.p_paddr = PHDRTableAddress; 3906 } else { 3907 NewPhdr.p_offset = NewTextSegmentOffset; 3908 NewPhdr.p_vaddr = NewTextSegmentAddress; 3909 NewPhdr.p_paddr = NewTextSegmentAddress; 3910 } 3911 NewPhdr.p_filesz = NewTextSegmentSize; 3912 NewPhdr.p_memsz = NewTextSegmentSize; 3913 NewPhdr.p_flags = ELF::PF_X | ELF::PF_R; 3914 // FIXME: Currently instrumentation is experimental and the runtime data 3915 // is emitted with code, thus everything needs to be writable 3916 if (opts::Instrument) 3917 NewPhdr.p_flags |= ELF::PF_W; 3918 NewPhdr.p_align = BC->PageAlign; 3919 3920 return NewPhdr; 3921 }; 3922 3923 // Copy existing program headers with modifications. 3924 for (const ELF64LE::Phdr &Phdr : cantFail(Obj.program_headers())) { 3925 ELF64LE::Phdr NewPhdr = Phdr; 3926 if (PHDRTableAddress && Phdr.p_type == ELF::PT_PHDR) { 3927 NewPhdr.p_offset = PHDRTableOffset; 3928 NewPhdr.p_vaddr = PHDRTableAddress; 3929 NewPhdr.p_paddr = PHDRTableAddress; 3930 NewPhdr.p_filesz = sizeof(NewPhdr) * Phnum; 3931 NewPhdr.p_memsz = sizeof(NewPhdr) * Phnum; 3932 } else if (Phdr.p_type == ELF::PT_GNU_EH_FRAME) { 3933 ErrorOr<BinarySection &> EHFrameHdrSec = 3934 BC->getUniqueSectionByName(".eh_frame_hdr"); 3935 if (EHFrameHdrSec && EHFrameHdrSec->isAllocatable() && 3936 EHFrameHdrSec->isFinalized()) { 3937 NewPhdr.p_offset = EHFrameHdrSec->getOutputFileOffset(); 3938 NewPhdr.p_vaddr = EHFrameHdrSec->getOutputAddress(); 3939 NewPhdr.p_paddr = EHFrameHdrSec->getOutputAddress(); 3940 NewPhdr.p_filesz = EHFrameHdrSec->getOutputSize(); 3941 NewPhdr.p_memsz = EHFrameHdrSec->getOutputSize(); 3942 } 3943 } else if (opts::UseGnuStack && Phdr.p_type == ELF::PT_GNU_STACK) { 3944 NewPhdr = createNewTextPhdr(); 3945 ModdedGnuStack = true; 3946 } else if (!opts::UseGnuStack && Phdr.p_type == ELF::PT_DYNAMIC) { 3947 // Insert the new header before DYNAMIC. 3948 ELF64LE::Phdr NewTextPhdr = createNewTextPhdr(); 3949 OS.write(reinterpret_cast<const char *>(&NewTextPhdr), 3950 sizeof(NewTextPhdr)); 3951 AddedSegment = true; 3952 } 3953 OS.write(reinterpret_cast<const char *>(&NewPhdr), sizeof(NewPhdr)); 3954 } 3955 3956 if (!opts::UseGnuStack && !AddedSegment) { 3957 // Append the new header to the end of the table. 3958 ELF64LE::Phdr NewTextPhdr = createNewTextPhdr(); 3959 OS.write(reinterpret_cast<const char *>(&NewTextPhdr), sizeof(NewTextPhdr)); 3960 } 3961 3962 assert((!opts::UseGnuStack || ModdedGnuStack) && 3963 "could not find GNU_STACK program header to modify"); 3964 } 3965 3966 namespace { 3967 3968 /// Write padding to \p OS such that its current \p Offset becomes aligned 3969 /// at \p Alignment. Return new (aligned) offset. 3970 uint64_t appendPadding(raw_pwrite_stream &OS, uint64_t Offset, 3971 uint64_t Alignment) { 3972 if (!Alignment) 3973 return Offset; 3974 3975 const uint64_t PaddingSize = 3976 offsetToAlignment(Offset, llvm::Align(Alignment)); 3977 for (unsigned I = 0; I < PaddingSize; ++I) 3978 OS.write((unsigned char)0); 3979 return Offset + PaddingSize; 3980 } 3981 3982 } 3983 3984 void RewriteInstance::rewriteNoteSections() { 3985 auto ELF64LEFile = dyn_cast<ELF64LEObjectFile>(InputFile); 3986 if (!ELF64LEFile) { 3987 errs() << "BOLT-ERROR: only 64-bit LE ELF binaries are supported\n"; 3988 exit(1); 3989 } 3990 const ELFFile<ELF64LE> &Obj = ELF64LEFile->getELFFile(); 3991 raw_fd_ostream &OS = Out->os(); 3992 3993 uint64_t NextAvailableOffset = getFileOffsetForAddress(NextAvailableAddress); 3994 assert(NextAvailableOffset >= FirstNonAllocatableOffset && 3995 "next available offset calculation failure"); 3996 OS.seek(NextAvailableOffset); 3997 3998 // Copy over non-allocatable section contents and update file offsets. 3999 for (const ELF64LE::Shdr &Section : cantFail(Obj.sections())) { 4000 if (Section.sh_type == ELF::SHT_NULL) 4001 continue; 4002 if (Section.sh_flags & ELF::SHF_ALLOC) 4003 continue; 4004 4005 StringRef SectionName = 4006 cantFail(Obj.getSectionName(Section), "cannot get section name"); 4007 ErrorOr<BinarySection &> BSec = BC->getUniqueSectionByName(SectionName); 4008 4009 if (shouldStrip(Section, SectionName)) 4010 continue; 4011 4012 // Insert padding as needed. 4013 NextAvailableOffset = 4014 appendPadding(OS, NextAvailableOffset, Section.sh_addralign); 4015 4016 // New section size. 4017 uint64_t Size = 0; 4018 bool DataWritten = false; 4019 uint8_t *SectionData = nullptr; 4020 // Copy over section contents unless it's one of the sections we overwrite. 4021 if (!willOverwriteSection(SectionName)) { 4022 Size = Section.sh_size; 4023 StringRef Dataref = InputFile->getData().substr(Section.sh_offset, Size); 4024 std::string Data; 4025 if (BSec && BSec->getPatcher()) { 4026 Data = BSec->getPatcher()->patchBinary(Dataref); 4027 Dataref = StringRef(Data); 4028 } 4029 4030 // Section was expanded, so need to treat it as overwrite. 4031 if (Size != Dataref.size()) { 4032 BSec = BC->registerOrUpdateNoteSection( 4033 SectionName, copyByteArray(Dataref), Dataref.size()); 4034 Size = 0; 4035 } else { 4036 OS << Dataref; 4037 DataWritten = true; 4038 4039 // Add padding as the section extension might rely on the alignment. 4040 Size = appendPadding(OS, Size, Section.sh_addralign); 4041 } 4042 } 4043 4044 // Perform section post-processing. 4045 if (BSec && !BSec->isAllocatable()) { 4046 assert(BSec->getAlignment() <= Section.sh_addralign && 4047 "alignment exceeds value in file"); 4048 4049 if (BSec->getAllocAddress()) { 4050 assert(!DataWritten && "Writing section twice."); 4051 SectionData = BSec->getOutputData(); 4052 4053 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: " << (Size ? "appending" : "writing") 4054 << " contents to section " << SectionName << '\n'); 4055 OS.write(reinterpret_cast<char *>(SectionData), BSec->getOutputSize()); 4056 Size += BSec->getOutputSize(); 4057 } 4058 4059 BSec->setOutputFileOffset(NextAvailableOffset); 4060 BSec->flushPendingRelocations(OS, 4061 [this] (const MCSymbol *S) { 4062 return getNewValueForSymbol(S->getName()); 4063 }); 4064 } 4065 4066 // Set/modify section info. 4067 BinarySection &NewSection = 4068 BC->registerOrUpdateNoteSection(SectionName, 4069 SectionData, 4070 Size, 4071 Section.sh_addralign, 4072 BSec ? BSec->isReadOnly() : false, 4073 BSec ? BSec->getELFType() 4074 : ELF::SHT_PROGBITS); 4075 NewSection.setOutputAddress(0); 4076 NewSection.setOutputFileOffset(NextAvailableOffset); 4077 4078 NextAvailableOffset += Size; 4079 } 4080 4081 // Write new note sections. 4082 for (BinarySection &Section : BC->nonAllocatableSections()) { 4083 if (Section.getOutputFileOffset() || !Section.getAllocAddress()) 4084 continue; 4085 4086 assert(!Section.hasPendingRelocations() && "cannot have pending relocs"); 4087 4088 NextAvailableOffset = 4089 appendPadding(OS, NextAvailableOffset, Section.getAlignment()); 4090 Section.setOutputFileOffset(NextAvailableOffset); 4091 4092 LLVM_DEBUG( 4093 dbgs() << "BOLT-DEBUG: writing out new section " << Section.getName() 4094 << " of size " << Section.getOutputSize() << " at offset 0x" 4095 << Twine::utohexstr(Section.getOutputFileOffset()) << '\n'); 4096 4097 OS.write(Section.getOutputContents().data(), Section.getOutputSize()); 4098 NextAvailableOffset += Section.getOutputSize(); 4099 } 4100 } 4101 4102 template <typename ELFT> 4103 void RewriteInstance::finalizeSectionStringTable(ELFObjectFile<ELFT> *File) { 4104 using ELFShdrTy = typename ELFT::Shdr; 4105 const ELFFile<ELFT> &Obj = File->getELFFile(); 4106 4107 // Pre-populate section header string table. 4108 for (const ELFShdrTy &Section : cantFail(Obj.sections())) { 4109 StringRef SectionName = 4110 cantFail(Obj.getSectionName(Section), "cannot get section name"); 4111 SHStrTab.add(SectionName); 4112 std::string OutputSectionName = getOutputSectionName(Obj, Section); 4113 if (OutputSectionName != SectionName) 4114 SHStrTabPool.emplace_back(std::move(OutputSectionName)); 4115 } 4116 for (const std::string &Str : SHStrTabPool) 4117 SHStrTab.add(Str); 4118 for (const BinarySection &Section : BC->sections()) 4119 SHStrTab.add(Section.getName()); 4120 SHStrTab.finalize(); 4121 4122 const size_t SHStrTabSize = SHStrTab.getSize(); 4123 uint8_t *DataCopy = new uint8_t[SHStrTabSize]; 4124 memset(DataCopy, 0, SHStrTabSize); 4125 SHStrTab.write(DataCopy); 4126 BC->registerOrUpdateNoteSection(".shstrtab", 4127 DataCopy, 4128 SHStrTabSize, 4129 /*Alignment=*/1, 4130 /*IsReadOnly=*/true, 4131 ELF::SHT_STRTAB); 4132 } 4133 4134 void RewriteInstance::addBoltInfoSection() { 4135 std::string DescStr; 4136 raw_string_ostream DescOS(DescStr); 4137 4138 DescOS << "BOLT revision: " << BoltRevision << ", " 4139 << "command line:"; 4140 for (int I = 0; I < Argc; ++I) 4141 DescOS << " " << Argv[I]; 4142 DescOS.flush(); 4143 4144 // Encode as GNU GOLD VERSION so it is easily printable by 'readelf -n' 4145 const std::string BoltInfo = 4146 BinarySection::encodeELFNote("GNU", DescStr, 4 /*NT_GNU_GOLD_VERSION*/); 4147 BC->registerOrUpdateNoteSection(".note.bolt_info", copyByteArray(BoltInfo), 4148 BoltInfo.size(), 4149 /*Alignment=*/1, 4150 /*IsReadOnly=*/true, ELF::SHT_NOTE); 4151 } 4152 4153 void RewriteInstance::addBATSection() { 4154 BC->registerOrUpdateNoteSection(BoltAddressTranslation::SECTION_NAME, nullptr, 4155 0, 4156 /*Alignment=*/1, 4157 /*IsReadOnly=*/true, ELF::SHT_NOTE); 4158 } 4159 4160 void RewriteInstance::encodeBATSection() { 4161 std::string DescStr; 4162 raw_string_ostream DescOS(DescStr); 4163 4164 BAT->write(DescOS); 4165 DescOS.flush(); 4166 4167 const std::string BoltInfo = 4168 BinarySection::encodeELFNote("BOLT", DescStr, BinarySection::NT_BOLT_BAT); 4169 BC->registerOrUpdateNoteSection(BoltAddressTranslation::SECTION_NAME, 4170 copyByteArray(BoltInfo), BoltInfo.size(), 4171 /*Alignment=*/1, 4172 /*IsReadOnly=*/true, ELF::SHT_NOTE); 4173 } 4174 4175 template <typename ELFObjType, typename ELFShdrTy> 4176 std::string RewriteInstance::getOutputSectionName(const ELFObjType &Obj, 4177 const ELFShdrTy &Section) { 4178 if (Section.sh_type == ELF::SHT_NULL) 4179 return ""; 4180 4181 StringRef SectionName = 4182 cantFail(Obj.getSectionName(Section), "cannot get section name"); 4183 4184 if ((Section.sh_flags & ELF::SHF_ALLOC) && willOverwriteSection(SectionName)) 4185 return (getOrgSecPrefix() + SectionName).str(); 4186 4187 return std::string(SectionName); 4188 } 4189 4190 template <typename ELFShdrTy> 4191 bool RewriteInstance::shouldStrip(const ELFShdrTy &Section, 4192 StringRef SectionName) { 4193 // Strip non-allocatable relocation sections. 4194 if (!(Section.sh_flags & ELF::SHF_ALLOC) && Section.sh_type == ELF::SHT_RELA) 4195 return true; 4196 4197 // Strip debug sections if not updating them. 4198 if (isDebugSection(SectionName) && !opts::UpdateDebugSections) 4199 return true; 4200 4201 // Strip symtab section if needed 4202 if (opts::RemoveSymtab && Section.sh_type == ELF::SHT_SYMTAB) 4203 return true; 4204 4205 return false; 4206 } 4207 4208 template <typename ELFT> 4209 std::vector<typename object::ELFObjectFile<ELFT>::Elf_Shdr> 4210 RewriteInstance::getOutputSections(ELFObjectFile<ELFT> *File, 4211 std::vector<uint32_t> &NewSectionIndex) { 4212 using ELFShdrTy = typename ELFObjectFile<ELFT>::Elf_Shdr; 4213 const ELFFile<ELFT> &Obj = File->getELFFile(); 4214 typename ELFT::ShdrRange Sections = cantFail(Obj.sections()); 4215 4216 // Keep track of section header entries together with their name. 4217 std::vector<std::pair<std::string, ELFShdrTy>> OutputSections; 4218 auto addSection = [&](const std::string &Name, const ELFShdrTy &Section) { 4219 ELFShdrTy NewSection = Section; 4220 NewSection.sh_name = SHStrTab.getOffset(Name); 4221 OutputSections.emplace_back(Name, std::move(NewSection)); 4222 }; 4223 4224 // Copy over entries for original allocatable sections using modified name. 4225 for (const ELFShdrTy &Section : Sections) { 4226 // Always ignore this section. 4227 if (Section.sh_type == ELF::SHT_NULL) { 4228 OutputSections.emplace_back("", Section); 4229 continue; 4230 } 4231 4232 if (!(Section.sh_flags & ELF::SHF_ALLOC)) 4233 continue; 4234 4235 addSection(getOutputSectionName(Obj, Section), Section); 4236 } 4237 4238 for (const BinarySection &Section : BC->allocatableSections()) { 4239 if (!Section.isFinalized()) 4240 continue; 4241 4242 if (Section.getName().startswith(getOrgSecPrefix()) || 4243 Section.isAnonymous()) { 4244 if (opts::Verbosity) 4245 outs() << "BOLT-INFO: not writing section header for section " 4246 << Section.getName() << '\n'; 4247 continue; 4248 } 4249 4250 if (opts::Verbosity >= 1) 4251 outs() << "BOLT-INFO: writing section header for " << Section.getName() 4252 << '\n'; 4253 ELFShdrTy NewSection; 4254 NewSection.sh_type = ELF::SHT_PROGBITS; 4255 NewSection.sh_addr = Section.getOutputAddress(); 4256 NewSection.sh_offset = Section.getOutputFileOffset(); 4257 NewSection.sh_size = Section.getOutputSize(); 4258 NewSection.sh_entsize = 0; 4259 NewSection.sh_flags = Section.getELFFlags(); 4260 NewSection.sh_link = 0; 4261 NewSection.sh_info = 0; 4262 NewSection.sh_addralign = Section.getAlignment(); 4263 addSection(std::string(Section.getName()), NewSection); 4264 } 4265 4266 // Sort all allocatable sections by their offset. 4267 std::stable_sort(OutputSections.begin(), OutputSections.end(), 4268 [] (const std::pair<std::string, ELFShdrTy> &A, 4269 const std::pair<std::string, ELFShdrTy> &B) { 4270 return A.second.sh_offset < B.second.sh_offset; 4271 }); 4272 4273 // Fix section sizes to prevent overlapping. 4274 ELFShdrTy *PrevSection = nullptr; 4275 StringRef PrevSectionName; 4276 for (auto &SectionKV : OutputSections) { 4277 ELFShdrTy &Section = SectionKV.second; 4278 4279 // TBSS section does not take file or memory space. Ignore it for layout 4280 // purposes. 4281 if (Section.sh_type == ELF::SHT_NOBITS && (Section.sh_flags & ELF::SHF_TLS)) 4282 continue; 4283 4284 if (PrevSection && 4285 PrevSection->sh_addr + PrevSection->sh_size > Section.sh_addr) { 4286 if (opts::Verbosity > 1) 4287 outs() << "BOLT-INFO: adjusting size for section " << PrevSectionName 4288 << '\n'; 4289 PrevSection->sh_size = Section.sh_addr > PrevSection->sh_addr 4290 ? Section.sh_addr - PrevSection->sh_addr 4291 : 0; 4292 } 4293 4294 PrevSection = &Section; 4295 PrevSectionName = SectionKV.first; 4296 } 4297 4298 uint64_t LastFileOffset = 0; 4299 4300 // Copy over entries for non-allocatable sections performing necessary 4301 // adjustments. 4302 for (const ELFShdrTy &Section : Sections) { 4303 if (Section.sh_type == ELF::SHT_NULL) 4304 continue; 4305 if (Section.sh_flags & ELF::SHF_ALLOC) 4306 continue; 4307 4308 StringRef SectionName = 4309 cantFail(Obj.getSectionName(Section), "cannot get section name"); 4310 4311 if (shouldStrip(Section, SectionName)) 4312 continue; 4313 4314 ErrorOr<BinarySection &> BSec = BC->getUniqueSectionByName(SectionName); 4315 assert(BSec && "missing section info for non-allocatable section"); 4316 4317 ELFShdrTy NewSection = Section; 4318 NewSection.sh_offset = BSec->getOutputFileOffset(); 4319 NewSection.sh_size = BSec->getOutputSize(); 4320 4321 if (NewSection.sh_type == ELF::SHT_SYMTAB) 4322 NewSection.sh_info = NumLocalSymbols; 4323 4324 addSection(std::string(SectionName), NewSection); 4325 4326 LastFileOffset = BSec->getOutputFileOffset(); 4327 } 4328 4329 // Create entries for new non-allocatable sections. 4330 for (BinarySection &Section : BC->nonAllocatableSections()) { 4331 if (Section.getOutputFileOffset() <= LastFileOffset) 4332 continue; 4333 4334 if (opts::Verbosity >= 1) 4335 outs() << "BOLT-INFO: writing section header for " << Section.getName() 4336 << '\n'; 4337 4338 ELFShdrTy NewSection; 4339 NewSection.sh_type = Section.getELFType(); 4340 NewSection.sh_addr = 0; 4341 NewSection.sh_offset = Section.getOutputFileOffset(); 4342 NewSection.sh_size = Section.getOutputSize(); 4343 NewSection.sh_entsize = 0; 4344 NewSection.sh_flags = Section.getELFFlags(); 4345 NewSection.sh_link = 0; 4346 NewSection.sh_info = 0; 4347 NewSection.sh_addralign = Section.getAlignment(); 4348 4349 addSection(std::string(Section.getName()), NewSection); 4350 } 4351 4352 // Assign indices to sections. 4353 std::unordered_map<std::string, uint64_t> NameToIndex; 4354 for (uint32_t Index = 1; Index < OutputSections.size(); ++Index) { 4355 const std::string &SectionName = OutputSections[Index].first; 4356 NameToIndex[SectionName] = Index; 4357 if (ErrorOr<BinarySection &> Section = 4358 BC->getUniqueSectionByName(SectionName)) 4359 Section->setIndex(Index); 4360 } 4361 4362 // Update section index mapping 4363 NewSectionIndex.clear(); 4364 NewSectionIndex.resize(Sections.size(), 0); 4365 for (const ELFShdrTy &Section : Sections) { 4366 if (Section.sh_type == ELF::SHT_NULL) 4367 continue; 4368 4369 size_t OrgIndex = std::distance(Sections.begin(), &Section); 4370 std::string SectionName = getOutputSectionName(Obj, Section); 4371 4372 // Some sections are stripped 4373 if (!NameToIndex.count(SectionName)) 4374 continue; 4375 4376 NewSectionIndex[OrgIndex] = NameToIndex[SectionName]; 4377 } 4378 4379 std::vector<ELFShdrTy> SectionsOnly(OutputSections.size()); 4380 std::transform(OutputSections.begin(), OutputSections.end(), 4381 SectionsOnly.begin(), 4382 [](std::pair<std::string, ELFShdrTy> &SectionInfo) { 4383 return SectionInfo.second; 4384 }); 4385 4386 return SectionsOnly; 4387 } 4388 4389 // Rewrite section header table inserting new entries as needed. The sections 4390 // header table size itself may affect the offsets of other sections, 4391 // so we are placing it at the end of the binary. 4392 // 4393 // As we rewrite entries we need to track how many sections were inserted 4394 // as it changes the sh_link value. We map old indices to new ones for 4395 // existing sections. 4396 template <typename ELFT> 4397 void RewriteInstance::patchELFSectionHeaderTable(ELFObjectFile<ELFT> *File) { 4398 using ELFShdrTy = typename ELFObjectFile<ELFT>::Elf_Shdr; 4399 using ELFEhdrTy = typename ELFObjectFile<ELFT>::Elf_Ehdr; 4400 raw_fd_ostream &OS = Out->os(); 4401 const ELFFile<ELFT> &Obj = File->getELFFile(); 4402 4403 std::vector<uint32_t> NewSectionIndex; 4404 std::vector<ELFShdrTy> OutputSections = 4405 getOutputSections(File, NewSectionIndex); 4406 LLVM_DEBUG( 4407 dbgs() << "BOLT-DEBUG: old to new section index mapping:\n"; 4408 for (uint64_t I = 0; I < NewSectionIndex.size(); ++I) 4409 dbgs() << " " << I << " -> " << NewSectionIndex[I] << '\n'; 4410 ); 4411 4412 // Align starting address for section header table. 4413 uint64_t SHTOffset = OS.tell(); 4414 SHTOffset = appendPadding(OS, SHTOffset, sizeof(ELFShdrTy)); 4415 4416 // Write all section header entries while patching section references. 4417 for (ELFShdrTy &Section : OutputSections) { 4418 Section.sh_link = NewSectionIndex[Section.sh_link]; 4419 if (Section.sh_type == ELF::SHT_REL || Section.sh_type == ELF::SHT_RELA) { 4420 if (Section.sh_info) 4421 Section.sh_info = NewSectionIndex[Section.sh_info]; 4422 } 4423 OS.write(reinterpret_cast<const char *>(&Section), sizeof(Section)); 4424 } 4425 4426 // Fix ELF header. 4427 ELFEhdrTy NewEhdr = Obj.getHeader(); 4428 4429 if (BC->HasRelocations) { 4430 if (RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary()) 4431 NewEhdr.e_entry = RtLibrary->getRuntimeStartAddress(); 4432 else 4433 NewEhdr.e_entry = getNewFunctionAddress(NewEhdr.e_entry); 4434 assert((NewEhdr.e_entry || !Obj.getHeader().e_entry) && 4435 "cannot find new address for entry point"); 4436 } 4437 NewEhdr.e_phoff = PHDRTableOffset; 4438 NewEhdr.e_phnum = Phnum; 4439 NewEhdr.e_shoff = SHTOffset; 4440 NewEhdr.e_shnum = OutputSections.size(); 4441 NewEhdr.e_shstrndx = NewSectionIndex[NewEhdr.e_shstrndx]; 4442 OS.pwrite(reinterpret_cast<const char *>(&NewEhdr), sizeof(NewEhdr), 0); 4443 } 4444 4445 template <typename ELFT, typename WriteFuncTy, typename StrTabFuncTy> 4446 void RewriteInstance::updateELFSymbolTable( 4447 ELFObjectFile<ELFT> *File, bool IsDynSym, 4448 const typename object::ELFObjectFile<ELFT>::Elf_Shdr &SymTabSection, 4449 const std::vector<uint32_t> &NewSectionIndex, WriteFuncTy Write, 4450 StrTabFuncTy AddToStrTab) { 4451 const ELFFile<ELFT> &Obj = File->getELFFile(); 4452 using ELFSymTy = typename ELFObjectFile<ELFT>::Elf_Sym; 4453 4454 StringRef StringSection = 4455 cantFail(Obj.getStringTableForSymtab(SymTabSection)); 4456 4457 unsigned NumHotTextSymsUpdated = 0; 4458 unsigned NumHotDataSymsUpdated = 0; 4459 4460 std::map<const BinaryFunction *, uint64_t> IslandSizes; 4461 auto getConstantIslandSize = [&IslandSizes](const BinaryFunction &BF) { 4462 auto Itr = IslandSizes.find(&BF); 4463 if (Itr != IslandSizes.end()) 4464 return Itr->second; 4465 return IslandSizes[&BF] = BF.estimateConstantIslandSize(); 4466 }; 4467 4468 // Symbols for the new symbol table. 4469 std::vector<ELFSymTy> Symbols; 4470 4471 auto getNewSectionIndex = [&](uint32_t OldIndex) { 4472 assert(OldIndex < NewSectionIndex.size() && "section index out of bounds"); 4473 const uint32_t NewIndex = NewSectionIndex[OldIndex]; 4474 4475 // We may have stripped the section that dynsym was referencing due to 4476 // the linker bug. In that case return the old index avoiding marking 4477 // the symbol as undefined. 4478 if (IsDynSym && NewIndex != OldIndex && NewIndex == ELF::SHN_UNDEF) 4479 return OldIndex; 4480 return NewIndex; 4481 }; 4482 4483 // Add extra symbols for the function. 4484 // 4485 // Note that addExtraSymbols() could be called multiple times for the same 4486 // function with different FunctionSymbol matching the main function entry 4487 // point. 4488 auto addExtraSymbols = [&](const BinaryFunction &Function, 4489 const ELFSymTy &FunctionSymbol) { 4490 if (Function.isFolded()) { 4491 BinaryFunction *ICFParent = Function.getFoldedIntoFunction(); 4492 while (ICFParent->isFolded()) 4493 ICFParent = ICFParent->getFoldedIntoFunction(); 4494 ELFSymTy ICFSymbol = FunctionSymbol; 4495 SmallVector<char, 256> Buf; 4496 ICFSymbol.st_name = 4497 AddToStrTab(Twine(cantFail(FunctionSymbol.getName(StringSection))) 4498 .concat(".icf.0") 4499 .toStringRef(Buf)); 4500 ICFSymbol.st_value = ICFParent->getOutputAddress(); 4501 ICFSymbol.st_size = ICFParent->getOutputSize(); 4502 ICFSymbol.st_shndx = ICFParent->getCodeSection()->getIndex(); 4503 Symbols.emplace_back(ICFSymbol); 4504 } 4505 if (Function.isSplit() && Function.cold().getAddress()) { 4506 ELFSymTy NewColdSym = FunctionSymbol; 4507 SmallVector<char, 256> Buf; 4508 NewColdSym.st_name = 4509 AddToStrTab(Twine(cantFail(FunctionSymbol.getName(StringSection))) 4510 .concat(".cold.0") 4511 .toStringRef(Buf)); 4512 NewColdSym.st_shndx = Function.getColdCodeSection()->getIndex(); 4513 NewColdSym.st_value = Function.cold().getAddress(); 4514 NewColdSym.st_size = Function.cold().getImageSize(); 4515 NewColdSym.setBindingAndType(ELF::STB_LOCAL, ELF::STT_FUNC); 4516 Symbols.emplace_back(NewColdSym); 4517 } 4518 if (Function.hasConstantIsland()) { 4519 uint64_t DataMark = Function.getOutputDataAddress(); 4520 uint64_t CISize = getConstantIslandSize(Function); 4521 uint64_t CodeMark = DataMark + CISize; 4522 ELFSymTy DataMarkSym = FunctionSymbol; 4523 DataMarkSym.st_name = AddToStrTab("$d"); 4524 DataMarkSym.st_value = DataMark; 4525 DataMarkSym.st_size = 0; 4526 DataMarkSym.setType(ELF::STT_NOTYPE); 4527 DataMarkSym.setBinding(ELF::STB_LOCAL); 4528 ELFSymTy CodeMarkSym = DataMarkSym; 4529 CodeMarkSym.st_name = AddToStrTab("$x"); 4530 CodeMarkSym.st_value = CodeMark; 4531 Symbols.emplace_back(DataMarkSym); 4532 Symbols.emplace_back(CodeMarkSym); 4533 } 4534 if (Function.hasConstantIsland() && Function.isSplit()) { 4535 uint64_t DataMark = Function.getOutputColdDataAddress(); 4536 uint64_t CISize = getConstantIslandSize(Function); 4537 uint64_t CodeMark = DataMark + CISize; 4538 ELFSymTy DataMarkSym = FunctionSymbol; 4539 DataMarkSym.st_name = AddToStrTab("$d"); 4540 DataMarkSym.st_value = DataMark; 4541 DataMarkSym.st_size = 0; 4542 DataMarkSym.setType(ELF::STT_NOTYPE); 4543 DataMarkSym.setBinding(ELF::STB_LOCAL); 4544 ELFSymTy CodeMarkSym = DataMarkSym; 4545 CodeMarkSym.st_name = AddToStrTab("$x"); 4546 CodeMarkSym.st_value = CodeMark; 4547 Symbols.emplace_back(DataMarkSym); 4548 Symbols.emplace_back(CodeMarkSym); 4549 } 4550 }; 4551 4552 // For regular (non-dynamic) symbol table, exclude symbols referring 4553 // to non-allocatable sections. 4554 auto shouldStrip = [&](const ELFSymTy &Symbol) { 4555 if (Symbol.isAbsolute() || !Symbol.isDefined()) 4556 return false; 4557 4558 // If we cannot link the symbol to a section, leave it as is. 4559 Expected<const typename ELFT::Shdr *> Section = 4560 Obj.getSection(Symbol.st_shndx); 4561 if (!Section) 4562 return false; 4563 4564 // Remove the section symbol iif the corresponding section was stripped. 4565 if (Symbol.getType() == ELF::STT_SECTION) { 4566 if (!getNewSectionIndex(Symbol.st_shndx)) 4567 return true; 4568 return false; 4569 } 4570 4571 // Symbols in non-allocatable sections are typically remnants of relocations 4572 // emitted under "-emit-relocs" linker option. Delete those as we delete 4573 // relocations against non-allocatable sections. 4574 if (!((*Section)->sh_flags & ELF::SHF_ALLOC)) 4575 return true; 4576 4577 return false; 4578 }; 4579 4580 for (const ELFSymTy &Symbol : cantFail(Obj.symbols(&SymTabSection))) { 4581 // For regular (non-dynamic) symbol table strip unneeded symbols. 4582 if (!IsDynSym && shouldStrip(Symbol)) 4583 continue; 4584 4585 const BinaryFunction *Function = 4586 BC->getBinaryFunctionAtAddress(Symbol.st_value); 4587 // Ignore false function references, e.g. when the section address matches 4588 // the address of the function. 4589 if (Function && Symbol.getType() == ELF::STT_SECTION) 4590 Function = nullptr; 4591 4592 // For non-dynamic symtab, make sure the symbol section matches that of 4593 // the function. It can mismatch e.g. if the symbol is a section marker 4594 // in which case we treat the symbol separately from the function. 4595 // For dynamic symbol table, the section index could be wrong on the input, 4596 // and its value is ignored by the runtime if it's different from 4597 // SHN_UNDEF and SHN_ABS. 4598 if (!IsDynSym && Function && 4599 Symbol.st_shndx != 4600 Function->getOriginSection()->getSectionRef().getIndex()) 4601 Function = nullptr; 4602 4603 // Create a new symbol based on the existing symbol. 4604 ELFSymTy NewSymbol = Symbol; 4605 4606 if (Function) { 4607 // If the symbol matched a function that was not emitted, update the 4608 // corresponding section index but otherwise leave it unchanged. 4609 if (Function->isEmitted()) { 4610 NewSymbol.st_value = Function->getOutputAddress(); 4611 NewSymbol.st_size = Function->getOutputSize(); 4612 NewSymbol.st_shndx = Function->getCodeSection()->getIndex(); 4613 } else if (Symbol.st_shndx < ELF::SHN_LORESERVE) { 4614 NewSymbol.st_shndx = getNewSectionIndex(Symbol.st_shndx); 4615 } 4616 4617 // Add new symbols to the symbol table if necessary. 4618 if (!IsDynSym) 4619 addExtraSymbols(*Function, NewSymbol); 4620 } else { 4621 // Check if the function symbol matches address inside a function, i.e. 4622 // it marks a secondary entry point. 4623 Function = 4624 (Symbol.getType() == ELF::STT_FUNC) 4625 ? BC->getBinaryFunctionContainingAddress(Symbol.st_value, 4626 /*CheckPastEnd=*/false, 4627 /*UseMaxSize=*/true) 4628 : nullptr; 4629 4630 if (Function && Function->isEmitted()) { 4631 const uint64_t OutputAddress = 4632 Function->translateInputToOutputAddress(Symbol.st_value); 4633 4634 NewSymbol.st_value = OutputAddress; 4635 // Force secondary entry points to have zero size. 4636 NewSymbol.st_size = 0; 4637 NewSymbol.st_shndx = 4638 OutputAddress >= Function->cold().getAddress() && 4639 OutputAddress < Function->cold().getImageSize() 4640 ? Function->getColdCodeSection()->getIndex() 4641 : Function->getCodeSection()->getIndex(); 4642 } else { 4643 // Check if the symbol belongs to moved data object and update it. 4644 BinaryData *BD = opts::ReorderData.empty() 4645 ? nullptr 4646 : BC->getBinaryDataAtAddress(Symbol.st_value); 4647 if (BD && BD->isMoved() && !BD->isJumpTable()) { 4648 assert((!BD->getSize() || !Symbol.st_size || 4649 Symbol.st_size == BD->getSize()) && 4650 "sizes must match"); 4651 4652 BinarySection &OutputSection = BD->getOutputSection(); 4653 assert(OutputSection.getIndex()); 4654 LLVM_DEBUG(dbgs() 4655 << "BOLT-DEBUG: moving " << BD->getName() << " from " 4656 << *BC->getSectionNameForAddress(Symbol.st_value) << " (" 4657 << Symbol.st_shndx << ") to " << OutputSection.getName() 4658 << " (" << OutputSection.getIndex() << ")\n"); 4659 NewSymbol.st_shndx = OutputSection.getIndex(); 4660 NewSymbol.st_value = BD->getOutputAddress(); 4661 } else { 4662 // Otherwise just update the section for the symbol. 4663 if (Symbol.st_shndx < ELF::SHN_LORESERVE) 4664 NewSymbol.st_shndx = getNewSectionIndex(Symbol.st_shndx); 4665 } 4666 4667 // Detect local syms in the text section that we didn't update 4668 // and that were preserved by the linker to support relocations against 4669 // .text. Remove them from the symtab. 4670 if (Symbol.getType() == ELF::STT_NOTYPE && 4671 Symbol.getBinding() == ELF::STB_LOCAL && Symbol.st_size == 0) { 4672 if (BC->getBinaryFunctionContainingAddress(Symbol.st_value, 4673 /*CheckPastEnd=*/false, 4674 /*UseMaxSize=*/true)) { 4675 // Can only delete the symbol if not patching. Such symbols should 4676 // not exist in the dynamic symbol table. 4677 assert(!IsDynSym && "cannot delete symbol"); 4678 continue; 4679 } 4680 } 4681 } 4682 } 4683 4684 // Handle special symbols based on their name. 4685 Expected<StringRef> SymbolName = Symbol.getName(StringSection); 4686 assert(SymbolName && "cannot get symbol name"); 4687 4688 auto updateSymbolValue = [&](const StringRef Name, unsigned &IsUpdated) { 4689 NewSymbol.st_value = getNewValueForSymbol(Name); 4690 NewSymbol.st_shndx = ELF::SHN_ABS; 4691 outs() << "BOLT-INFO: setting " << Name << " to 0x" 4692 << Twine::utohexstr(NewSymbol.st_value) << '\n'; 4693 ++IsUpdated; 4694 }; 4695 4696 if (opts::HotText && 4697 (*SymbolName == "__hot_start" || *SymbolName == "__hot_end")) 4698 updateSymbolValue(*SymbolName, NumHotTextSymsUpdated); 4699 4700 if (opts::HotData && 4701 (*SymbolName == "__hot_data_start" || *SymbolName == "__hot_data_end")) 4702 updateSymbolValue(*SymbolName, NumHotDataSymsUpdated); 4703 4704 if (*SymbolName == "_end") { 4705 unsigned Ignored; 4706 updateSymbolValue(*SymbolName, Ignored); 4707 } 4708 4709 if (IsDynSym) 4710 Write((&Symbol - cantFail(Obj.symbols(&SymTabSection)).begin()) * 4711 sizeof(ELFSymTy), 4712 NewSymbol); 4713 else 4714 Symbols.emplace_back(NewSymbol); 4715 } 4716 4717 if (IsDynSym) { 4718 assert(Symbols.empty()); 4719 return; 4720 } 4721 4722 // Add symbols of injected functions 4723 for (BinaryFunction *Function : BC->getInjectedBinaryFunctions()) { 4724 ELFSymTy NewSymbol; 4725 BinarySection *OriginSection = Function->getOriginSection(); 4726 NewSymbol.st_shndx = 4727 OriginSection 4728 ? getNewSectionIndex(OriginSection->getSectionRef().getIndex()) 4729 : Function->getCodeSection()->getIndex(); 4730 NewSymbol.st_value = Function->getOutputAddress(); 4731 NewSymbol.st_name = AddToStrTab(Function->getOneName()); 4732 NewSymbol.st_size = Function->getOutputSize(); 4733 NewSymbol.st_other = 0; 4734 NewSymbol.setBindingAndType(ELF::STB_LOCAL, ELF::STT_FUNC); 4735 Symbols.emplace_back(NewSymbol); 4736 4737 if (Function->isSplit()) { 4738 ELFSymTy NewColdSym = NewSymbol; 4739 NewColdSym.setType(ELF::STT_NOTYPE); 4740 SmallVector<char, 256> Buf; 4741 NewColdSym.st_name = AddToStrTab( 4742 Twine(Function->getPrintName()).concat(".cold.0").toStringRef(Buf)); 4743 NewColdSym.st_value = Function->cold().getAddress(); 4744 NewColdSym.st_size = Function->cold().getImageSize(); 4745 Symbols.emplace_back(NewColdSym); 4746 } 4747 } 4748 4749 assert((!NumHotTextSymsUpdated || NumHotTextSymsUpdated == 2) && 4750 "either none or both __hot_start/__hot_end symbols were expected"); 4751 assert((!NumHotDataSymsUpdated || NumHotDataSymsUpdated == 2) && 4752 "either none or both __hot_data_start/__hot_data_end symbols were " 4753 "expected"); 4754 4755 auto addSymbol = [&](const std::string &Name) { 4756 ELFSymTy Symbol; 4757 Symbol.st_value = getNewValueForSymbol(Name); 4758 Symbol.st_shndx = ELF::SHN_ABS; 4759 Symbol.st_name = AddToStrTab(Name); 4760 Symbol.st_size = 0; 4761 Symbol.st_other = 0; 4762 Symbol.setBindingAndType(ELF::STB_WEAK, ELF::STT_NOTYPE); 4763 4764 outs() << "BOLT-INFO: setting " << Name << " to 0x" 4765 << Twine::utohexstr(Symbol.st_value) << '\n'; 4766 4767 Symbols.emplace_back(Symbol); 4768 }; 4769 4770 if (opts::HotText && !NumHotTextSymsUpdated) { 4771 addSymbol("__hot_start"); 4772 addSymbol("__hot_end"); 4773 } 4774 4775 if (opts::HotData && !NumHotDataSymsUpdated) { 4776 addSymbol("__hot_data_start"); 4777 addSymbol("__hot_data_end"); 4778 } 4779 4780 // Put local symbols at the beginning. 4781 std::stable_sort(Symbols.begin(), Symbols.end(), 4782 [](const ELFSymTy &A, const ELFSymTy &B) { 4783 if (A.getBinding() == ELF::STB_LOCAL && 4784 B.getBinding() != ELF::STB_LOCAL) 4785 return true; 4786 return false; 4787 }); 4788 4789 for (const ELFSymTy &Symbol : Symbols) 4790 Write(0, Symbol); 4791 } 4792 4793 template <typename ELFT> 4794 void RewriteInstance::patchELFSymTabs(ELFObjectFile<ELFT> *File) { 4795 const ELFFile<ELFT> &Obj = File->getELFFile(); 4796 using ELFShdrTy = typename ELFObjectFile<ELFT>::Elf_Shdr; 4797 using ELFSymTy = typename ELFObjectFile<ELFT>::Elf_Sym; 4798 4799 // Compute a preview of how section indices will change after rewriting, so 4800 // we can properly update the symbol table based on new section indices. 4801 std::vector<uint32_t> NewSectionIndex; 4802 getOutputSections(File, NewSectionIndex); 4803 4804 // Set pointer at the end of the output file, so we can pwrite old symbol 4805 // tables if we need to. 4806 uint64_t NextAvailableOffset = getFileOffsetForAddress(NextAvailableAddress); 4807 assert(NextAvailableOffset >= FirstNonAllocatableOffset && 4808 "next available offset calculation failure"); 4809 Out->os().seek(NextAvailableOffset); 4810 4811 // Update dynamic symbol table. 4812 const ELFShdrTy *DynSymSection = nullptr; 4813 for (const ELFShdrTy &Section : cantFail(Obj.sections())) { 4814 if (Section.sh_type == ELF::SHT_DYNSYM) { 4815 DynSymSection = &Section; 4816 break; 4817 } 4818 } 4819 assert((DynSymSection || BC->IsStaticExecutable) && 4820 "dynamic symbol table expected"); 4821 if (DynSymSection) { 4822 updateELFSymbolTable( 4823 File, 4824 /*IsDynSym=*/true, 4825 *DynSymSection, 4826 NewSectionIndex, 4827 [&](size_t Offset, const ELFSymTy &Sym) { 4828 Out->os().pwrite(reinterpret_cast<const char *>(&Sym), 4829 sizeof(ELFSymTy), 4830 DynSymSection->sh_offset + Offset); 4831 }, 4832 [](StringRef) -> size_t { return 0; }); 4833 } 4834 4835 if (opts::RemoveSymtab) 4836 return; 4837 4838 // (re)create regular symbol table. 4839 const ELFShdrTy *SymTabSection = nullptr; 4840 for (const ELFShdrTy &Section : cantFail(Obj.sections())) { 4841 if (Section.sh_type == ELF::SHT_SYMTAB) { 4842 SymTabSection = &Section; 4843 break; 4844 } 4845 } 4846 if (!SymTabSection) { 4847 errs() << "BOLT-WARNING: no symbol table found\n"; 4848 return; 4849 } 4850 4851 const ELFShdrTy *StrTabSection = 4852 cantFail(Obj.getSection(SymTabSection->sh_link)); 4853 std::string NewContents; 4854 std::string NewStrTab = std::string( 4855 File->getData().substr(StrTabSection->sh_offset, StrTabSection->sh_size)); 4856 StringRef SecName = cantFail(Obj.getSectionName(*SymTabSection)); 4857 StringRef StrSecName = cantFail(Obj.getSectionName(*StrTabSection)); 4858 4859 NumLocalSymbols = 0; 4860 updateELFSymbolTable( 4861 File, 4862 /*IsDynSym=*/false, 4863 *SymTabSection, 4864 NewSectionIndex, 4865 [&](size_t Offset, const ELFSymTy &Sym) { 4866 if (Sym.getBinding() == ELF::STB_LOCAL) 4867 ++NumLocalSymbols; 4868 NewContents.append(reinterpret_cast<const char *>(&Sym), 4869 sizeof(ELFSymTy)); 4870 }, 4871 [&](StringRef Str) { 4872 size_t Idx = NewStrTab.size(); 4873 NewStrTab.append(NameResolver::restore(Str).str()); 4874 NewStrTab.append(1, '\0'); 4875 return Idx; 4876 }); 4877 4878 BC->registerOrUpdateNoteSection(SecName, 4879 copyByteArray(NewContents), 4880 NewContents.size(), 4881 /*Alignment=*/1, 4882 /*IsReadOnly=*/true, 4883 ELF::SHT_SYMTAB); 4884 4885 BC->registerOrUpdateNoteSection(StrSecName, 4886 copyByteArray(NewStrTab), 4887 NewStrTab.size(), 4888 /*Alignment=*/1, 4889 /*IsReadOnly=*/true, 4890 ELF::SHT_STRTAB); 4891 } 4892 4893 template <typename ELFT> 4894 void 4895 RewriteInstance::patchELFAllocatableRelaSections(ELFObjectFile<ELFT> *File) { 4896 using Elf_Rela = typename ELFT::Rela; 4897 raw_fd_ostream &OS = Out->os(); 4898 const ELFFile<ELFT> &EF = File->getELFFile(); 4899 4900 uint64_t RelDynOffset = 0, RelDynEndOffset = 0; 4901 uint64_t RelPltOffset = 0, RelPltEndOffset = 0; 4902 4903 auto setSectionFileOffsets = [&](uint64_t Address, uint64_t &Start, 4904 uint64_t &End) { 4905 ErrorOr<BinarySection &> Section = BC->getSectionForAddress(Address); 4906 Start = Section->getInputFileOffset(); 4907 End = Start + Section->getSize(); 4908 }; 4909 4910 if (!DynamicRelocationsAddress && !PLTRelocationsAddress) 4911 return; 4912 4913 if (DynamicRelocationsAddress) 4914 setSectionFileOffsets(*DynamicRelocationsAddress, RelDynOffset, 4915 RelDynEndOffset); 4916 4917 if (PLTRelocationsAddress) 4918 setSectionFileOffsets(*PLTRelocationsAddress, RelPltOffset, 4919 RelPltEndOffset); 4920 4921 DynamicRelativeRelocationsCount = 0; 4922 4923 auto writeRela = [&OS](const Elf_Rela *RelA, uint64_t &Offset) { 4924 OS.pwrite(reinterpret_cast<const char *>(RelA), sizeof(*RelA), Offset); 4925 Offset += sizeof(*RelA); 4926 }; 4927 4928 auto writeRelocations = [&](bool PatchRelative) { 4929 for (BinarySection &Section : BC->allocatableSections()) { 4930 for (const Relocation &Rel : Section.dynamicRelocations()) { 4931 const bool IsRelative = Rel.isRelative(); 4932 if (PatchRelative != IsRelative) 4933 continue; 4934 4935 if (IsRelative) 4936 ++DynamicRelativeRelocationsCount; 4937 4938 Elf_Rela NewRelA; 4939 uint64_t SectionAddress = Section.getOutputAddress(); 4940 SectionAddress = 4941 SectionAddress == 0 ? Section.getAddress() : SectionAddress; 4942 MCSymbol *Symbol = Rel.Symbol; 4943 uint32_t SymbolIdx = 0; 4944 uint64_t Addend = Rel.Addend; 4945 4946 if (Rel.Symbol) { 4947 SymbolIdx = getOutputDynamicSymbolIndex(Symbol); 4948 } else { 4949 // Usually this case is used for R_*_(I)RELATIVE relocations 4950 const uint64_t Address = getNewFunctionOrDataAddress(Addend); 4951 if (Address) 4952 Addend = Address; 4953 } 4954 4955 NewRelA.setSymbolAndType(SymbolIdx, Rel.Type, EF.isMips64EL()); 4956 NewRelA.r_offset = SectionAddress + Rel.Offset; 4957 NewRelA.r_addend = Addend; 4958 4959 const bool IsJmpRel = 4960 !!(IsJmpRelocation.find(Rel.Type) != IsJmpRelocation.end()); 4961 uint64_t &Offset = IsJmpRel ? RelPltOffset : RelDynOffset; 4962 const uint64_t &EndOffset = 4963 IsJmpRel ? RelPltEndOffset : RelDynEndOffset; 4964 if (!Offset || !EndOffset) { 4965 errs() << "BOLT-ERROR: Invalid offsets for dynamic relocation\n"; 4966 exit(1); 4967 } 4968 4969 if (Offset + sizeof(NewRelA) > EndOffset) { 4970 errs() << "BOLT-ERROR: Offset overflow for dynamic relocation\n"; 4971 exit(1); 4972 } 4973 4974 writeRela(&NewRelA, Offset); 4975 } 4976 } 4977 }; 4978 4979 // The dynamic linker expects R_*_RELATIVE relocations to be emitted first 4980 writeRelocations(/* PatchRelative */ true); 4981 writeRelocations(/* PatchRelative */ false); 4982 4983 auto fillNone = [&](uint64_t &Offset, uint64_t EndOffset) { 4984 if (!Offset) 4985 return; 4986 4987 typename ELFObjectFile<ELFT>::Elf_Rela RelA; 4988 RelA.setSymbolAndType(0, Relocation::getNone(), EF.isMips64EL()); 4989 RelA.r_offset = 0; 4990 RelA.r_addend = 0; 4991 while (Offset < EndOffset) 4992 writeRela(&RelA, Offset); 4993 4994 assert(Offset == EndOffset && "Unexpected section overflow"); 4995 }; 4996 4997 // Fill the rest of the sections with R_*_NONE relocations 4998 fillNone(RelDynOffset, RelDynEndOffset); 4999 fillNone(RelPltOffset, RelPltEndOffset); 5000 } 5001 5002 template <typename ELFT> 5003 void RewriteInstance::patchELFGOT(ELFObjectFile<ELFT> *File) { 5004 raw_fd_ostream &OS = Out->os(); 5005 5006 SectionRef GOTSection; 5007 for (const SectionRef &Section : File->sections()) { 5008 StringRef SectionName = cantFail(Section.getName()); 5009 if (SectionName == ".got") { 5010 GOTSection = Section; 5011 break; 5012 } 5013 } 5014 if (!GOTSection.getObject()) { 5015 if (!BC->IsStaticExecutable) 5016 errs() << "BOLT-INFO: no .got section found\n"; 5017 return; 5018 } 5019 5020 StringRef GOTContents = cantFail(GOTSection.getContents()); 5021 for (const uint64_t *GOTEntry = 5022 reinterpret_cast<const uint64_t *>(GOTContents.data()); 5023 GOTEntry < reinterpret_cast<const uint64_t *>(GOTContents.data() + 5024 GOTContents.size()); 5025 ++GOTEntry) { 5026 if (uint64_t NewAddress = getNewFunctionAddress(*GOTEntry)) { 5027 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: patching GOT entry 0x" 5028 << Twine::utohexstr(*GOTEntry) << " with 0x" 5029 << Twine::utohexstr(NewAddress) << '\n'); 5030 OS.pwrite(reinterpret_cast<const char *>(&NewAddress), sizeof(NewAddress), 5031 reinterpret_cast<const char *>(GOTEntry) - 5032 File->getData().data()); 5033 } 5034 } 5035 } 5036 5037 template <typename ELFT> 5038 void RewriteInstance::patchELFDynamic(ELFObjectFile<ELFT> *File) { 5039 if (BC->IsStaticExecutable) 5040 return; 5041 5042 const ELFFile<ELFT> &Obj = File->getELFFile(); 5043 raw_fd_ostream &OS = Out->os(); 5044 5045 using Elf_Phdr = typename ELFFile<ELFT>::Elf_Phdr; 5046 using Elf_Dyn = typename ELFFile<ELFT>::Elf_Dyn; 5047 5048 // Locate DYNAMIC by looking through program headers. 5049 uint64_t DynamicOffset = 0; 5050 const Elf_Phdr *DynamicPhdr = 0; 5051 for (const Elf_Phdr &Phdr : cantFail(Obj.program_headers())) { 5052 if (Phdr.p_type == ELF::PT_DYNAMIC) { 5053 DynamicOffset = Phdr.p_offset; 5054 DynamicPhdr = &Phdr; 5055 assert(Phdr.p_memsz == Phdr.p_filesz && "dynamic sizes should match"); 5056 break; 5057 } 5058 } 5059 assert(DynamicPhdr && "missing dynamic in ELF binary"); 5060 5061 bool ZNowSet = false; 5062 5063 // Go through all dynamic entries and patch functions addresses with 5064 // new ones. 5065 typename ELFT::DynRange DynamicEntries = 5066 cantFail(Obj.dynamicEntries(), "error accessing dynamic table"); 5067 auto DTB = DynamicEntries.begin(); 5068 for (const Elf_Dyn &Dyn : DynamicEntries) { 5069 Elf_Dyn NewDE = Dyn; 5070 bool ShouldPatch = true; 5071 switch (Dyn.d_tag) { 5072 default: 5073 ShouldPatch = false; 5074 break; 5075 case ELF::DT_RELACOUNT: 5076 NewDE.d_un.d_val = DynamicRelativeRelocationsCount; 5077 break; 5078 case ELF::DT_INIT: 5079 case ELF::DT_FINI: { 5080 if (BC->HasRelocations) { 5081 if (uint64_t NewAddress = getNewFunctionAddress(Dyn.getPtr())) { 5082 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: patching dynamic entry of type " 5083 << Dyn.getTag() << '\n'); 5084 NewDE.d_un.d_ptr = NewAddress; 5085 } 5086 } 5087 RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary(); 5088 if (RtLibrary && Dyn.getTag() == ELF::DT_FINI) { 5089 if (uint64_t Addr = RtLibrary->getRuntimeFiniAddress()) 5090 NewDE.d_un.d_ptr = Addr; 5091 } 5092 if (RtLibrary && Dyn.getTag() == ELF::DT_INIT && !BC->HasInterpHeader) { 5093 if (auto Addr = RtLibrary->getRuntimeStartAddress()) { 5094 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: Set DT_INIT to 0x" 5095 << Twine::utohexstr(Addr) << '\n'); 5096 NewDE.d_un.d_ptr = Addr; 5097 } 5098 } 5099 break; 5100 } 5101 case ELF::DT_FLAGS: 5102 if (BC->RequiresZNow) { 5103 NewDE.d_un.d_val |= ELF::DF_BIND_NOW; 5104 ZNowSet = true; 5105 } 5106 break; 5107 case ELF::DT_FLAGS_1: 5108 if (BC->RequiresZNow) { 5109 NewDE.d_un.d_val |= ELF::DF_1_NOW; 5110 ZNowSet = true; 5111 } 5112 break; 5113 } 5114 if (ShouldPatch) 5115 OS.pwrite(reinterpret_cast<const char *>(&NewDE), sizeof(NewDE), 5116 DynamicOffset + (&Dyn - DTB) * sizeof(Dyn)); 5117 } 5118 5119 if (BC->RequiresZNow && !ZNowSet) { 5120 errs() << "BOLT-ERROR: output binary requires immediate relocation " 5121 "processing which depends on DT_FLAGS or DT_FLAGS_1 presence in " 5122 ".dynamic. Please re-link the binary with -znow.\n"; 5123 exit(1); 5124 } 5125 } 5126 5127 template <typename ELFT> 5128 Error RewriteInstance::readELFDynamic(ELFObjectFile<ELFT> *File) { 5129 const ELFFile<ELFT> &Obj = File->getELFFile(); 5130 5131 using Elf_Phdr = typename ELFFile<ELFT>::Elf_Phdr; 5132 using Elf_Dyn = typename ELFFile<ELFT>::Elf_Dyn; 5133 5134 // Locate DYNAMIC by looking through program headers. 5135 const Elf_Phdr *DynamicPhdr = 0; 5136 for (const Elf_Phdr &Phdr : cantFail(Obj.program_headers())) { 5137 if (Phdr.p_type == ELF::PT_DYNAMIC) { 5138 DynamicPhdr = &Phdr; 5139 break; 5140 } 5141 } 5142 5143 if (!DynamicPhdr) { 5144 outs() << "BOLT-INFO: static input executable detected\n"; 5145 // TODO: static PIE executable might have dynamic header 5146 BC->IsStaticExecutable = true; 5147 return Error::success(); 5148 } 5149 5150 if (DynamicPhdr->p_memsz != DynamicPhdr->p_filesz) 5151 return createStringError(errc::executable_format_error, 5152 "dynamic section sizes should match"); 5153 5154 // Go through all dynamic entries to locate entries of interest. 5155 auto DynamicEntriesOrErr = Obj.dynamicEntries(); 5156 if (!DynamicEntriesOrErr) 5157 return DynamicEntriesOrErr.takeError(); 5158 typename ELFT::DynRange DynamicEntries = DynamicEntriesOrErr.get(); 5159 5160 for (const Elf_Dyn &Dyn : DynamicEntries) { 5161 switch (Dyn.d_tag) { 5162 case ELF::DT_INIT: 5163 if (!BC->HasInterpHeader) { 5164 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: Set start function address\n"); 5165 BC->StartFunctionAddress = Dyn.getPtr(); 5166 } 5167 break; 5168 case ELF::DT_FINI: 5169 BC->FiniFunctionAddress = Dyn.getPtr(); 5170 break; 5171 case ELF::DT_RELA: 5172 DynamicRelocationsAddress = Dyn.getPtr(); 5173 break; 5174 case ELF::DT_RELASZ: 5175 DynamicRelocationsSize = Dyn.getVal(); 5176 break; 5177 case ELF::DT_JMPREL: 5178 PLTRelocationsAddress = Dyn.getPtr(); 5179 break; 5180 case ELF::DT_PLTRELSZ: 5181 PLTRelocationsSize = Dyn.getVal(); 5182 break; 5183 case ELF::DT_RELACOUNT: 5184 DynamicRelativeRelocationsCount = Dyn.getVal(); 5185 break; 5186 } 5187 } 5188 5189 if (!DynamicRelocationsAddress || !DynamicRelocationsSize) { 5190 DynamicRelocationsAddress.reset(); 5191 DynamicRelocationsSize = 0; 5192 } 5193 5194 if (!PLTRelocationsAddress || !PLTRelocationsSize) { 5195 PLTRelocationsAddress.reset(); 5196 PLTRelocationsSize = 0; 5197 } 5198 return Error::success(); 5199 } 5200 5201 uint64_t RewriteInstance::getNewFunctionAddress(uint64_t OldAddress) { 5202 const BinaryFunction *Function = BC->getBinaryFunctionAtAddress(OldAddress); 5203 if (!Function) 5204 return 0; 5205 5206 assert(!Function->isFragment() && "cannot get new address for a fragment"); 5207 5208 return Function->getOutputAddress(); 5209 } 5210 5211 uint64_t RewriteInstance::getNewFunctionOrDataAddress(uint64_t OldAddress) { 5212 if (uint64_t Function = getNewFunctionAddress(OldAddress)) 5213 return Function; 5214 5215 const BinaryData *BD = BC->getBinaryDataAtAddress(OldAddress); 5216 if (BD && BD->isMoved()) 5217 return BD->getOutputAddress(); 5218 5219 return 0; 5220 } 5221 5222 void RewriteInstance::rewriteFile() { 5223 std::error_code EC; 5224 Out = std::make_unique<ToolOutputFile>(opts::OutputFilename, EC, 5225 sys::fs::OF_None); 5226 check_error(EC, "cannot create output executable file"); 5227 5228 raw_fd_ostream &OS = Out->os(); 5229 5230 // Copy allocatable part of the input. 5231 OS << InputFile->getData().substr(0, FirstNonAllocatableOffset); 5232 5233 // We obtain an asm-specific writer so that we can emit nops in an 5234 // architecture-specific way at the end of the function. 5235 std::unique_ptr<MCAsmBackend> MAB( 5236 BC->TheTarget->createMCAsmBackend(*BC->STI, *BC->MRI, MCTargetOptions())); 5237 auto Streamer = BC->createStreamer(OS); 5238 // Make sure output stream has enough reserved space, otherwise 5239 // pwrite() will fail. 5240 uint64_t Offset = OS.seek(getFileOffsetForAddress(NextAvailableAddress)); 5241 (void)Offset; 5242 assert(Offset == getFileOffsetForAddress(NextAvailableAddress) && 5243 "error resizing output file"); 5244 5245 // Overwrite functions with fixed output address. This is mostly used by 5246 // non-relocation mode, with one exception: injected functions are covered 5247 // here in both modes. 5248 uint64_t CountOverwrittenFunctions = 0; 5249 uint64_t OverwrittenScore = 0; 5250 for (BinaryFunction *Function : BC->getAllBinaryFunctions()) { 5251 if (Function->getImageAddress() == 0 || Function->getImageSize() == 0) 5252 continue; 5253 5254 if (Function->getImageSize() > Function->getMaxSize()) { 5255 if (opts::Verbosity >= 1) 5256 errs() << "BOLT-WARNING: new function size (0x" 5257 << Twine::utohexstr(Function->getImageSize()) 5258 << ") is larger than maximum allowed size (0x" 5259 << Twine::utohexstr(Function->getMaxSize()) << ") for function " 5260 << *Function << '\n'; 5261 5262 // Remove jump table sections that this function owns in non-reloc mode 5263 // because we don't want to write them anymore. 5264 if (!BC->HasRelocations && opts::JumpTables == JTS_BASIC) { 5265 for (auto &JTI : Function->JumpTables) { 5266 JumpTable *JT = JTI.second; 5267 BinarySection &Section = JT->getOutputSection(); 5268 BC->deregisterSection(Section); 5269 } 5270 } 5271 continue; 5272 } 5273 5274 if (Function->isSplit() && (Function->cold().getImageAddress() == 0 || 5275 Function->cold().getImageSize() == 0)) 5276 continue; 5277 5278 OverwrittenScore += Function->getFunctionScore(); 5279 // Overwrite function in the output file. 5280 if (opts::Verbosity >= 2) 5281 outs() << "BOLT: rewriting function \"" << *Function << "\"\n"; 5282 5283 OS.pwrite(reinterpret_cast<char *>(Function->getImageAddress()), 5284 Function->getImageSize(), Function->getFileOffset()); 5285 5286 // Write nops at the end of the function. 5287 if (Function->getMaxSize() != std::numeric_limits<uint64_t>::max()) { 5288 uint64_t Pos = OS.tell(); 5289 OS.seek(Function->getFileOffset() + Function->getImageSize()); 5290 MAB->writeNopData(OS, Function->getMaxSize() - Function->getImageSize(), 5291 &*BC->STI); 5292 5293 OS.seek(Pos); 5294 } 5295 5296 if (!Function->isSplit()) { 5297 ++CountOverwrittenFunctions; 5298 if (opts::MaxFunctions && 5299 CountOverwrittenFunctions == opts::MaxFunctions) { 5300 outs() << "BOLT: maximum number of functions reached\n"; 5301 break; 5302 } 5303 continue; 5304 } 5305 5306 // Write cold part 5307 if (opts::Verbosity >= 2) 5308 outs() << "BOLT: rewriting function \"" << *Function 5309 << "\" (cold part)\n"; 5310 5311 OS.pwrite(reinterpret_cast<char *>(Function->cold().getImageAddress()), 5312 Function->cold().getImageSize(), 5313 Function->cold().getFileOffset()); 5314 5315 ++CountOverwrittenFunctions; 5316 if (opts::MaxFunctions && CountOverwrittenFunctions == opts::MaxFunctions) { 5317 outs() << "BOLT: maximum number of functions reached\n"; 5318 break; 5319 } 5320 } 5321 5322 // Print function statistics for non-relocation mode. 5323 if (!BC->HasRelocations) { 5324 outs() << "BOLT: " << CountOverwrittenFunctions << " out of " 5325 << BC->getBinaryFunctions().size() 5326 << " functions were overwritten.\n"; 5327 if (BC->TotalScore != 0) { 5328 double Coverage = OverwrittenScore / (double)BC->TotalScore * 100.0; 5329 outs() << format("BOLT-INFO: rewritten functions cover %.2lf", Coverage) 5330 << "% of the execution count of simple functions of " 5331 "this binary\n"; 5332 } 5333 } 5334 5335 if (BC->HasRelocations && opts::TrapOldCode) { 5336 uint64_t SavedPos = OS.tell(); 5337 // Overwrite function body to make sure we never execute these instructions. 5338 for (auto &BFI : BC->getBinaryFunctions()) { 5339 BinaryFunction &BF = BFI.second; 5340 if (!BF.getFileOffset() || !BF.isEmitted()) 5341 continue; 5342 OS.seek(BF.getFileOffset()); 5343 for (unsigned I = 0; I < BF.getMaxSize(); ++I) 5344 OS.write((unsigned char)BC->MIB->getTrapFillValue()); 5345 } 5346 OS.seek(SavedPos); 5347 } 5348 5349 // Write all allocatable sections - reloc-mode text is written here as well 5350 for (BinarySection &Section : BC->allocatableSections()) { 5351 if (!Section.isFinalized() || !Section.getOutputData()) 5352 continue; 5353 5354 if (opts::Verbosity >= 1) 5355 outs() << "BOLT: writing new section " << Section.getName() 5356 << "\n data at 0x" << Twine::utohexstr(Section.getAllocAddress()) 5357 << "\n of size " << Section.getOutputSize() << "\n at offset " 5358 << Section.getOutputFileOffset() << '\n'; 5359 OS.pwrite(reinterpret_cast<const char *>(Section.getOutputData()), 5360 Section.getOutputSize(), Section.getOutputFileOffset()); 5361 } 5362 5363 for (BinarySection &Section : BC->allocatableSections()) 5364 Section.flushPendingRelocations(OS, [this](const MCSymbol *S) { 5365 return getNewValueForSymbol(S->getName()); 5366 }); 5367 5368 // If .eh_frame is present create .eh_frame_hdr. 5369 if (EHFrameSection && EHFrameSection->isFinalized()) 5370 writeEHFrameHeader(); 5371 5372 // Add BOLT Addresses Translation maps to allow profile collection to 5373 // happen in the output binary 5374 if (opts::EnableBAT) 5375 addBATSection(); 5376 5377 // Patch program header table. 5378 patchELFPHDRTable(); 5379 5380 // Finalize memory image of section string table. 5381 finalizeSectionStringTable(); 5382 5383 // Update symbol tables. 5384 patchELFSymTabs(); 5385 5386 patchBuildID(); 5387 5388 if (opts::EnableBAT) 5389 encodeBATSection(); 5390 5391 // Copy non-allocatable sections once allocatable part is finished. 5392 rewriteNoteSections(); 5393 5394 if (BC->HasRelocations) { 5395 patchELFAllocatableRelaSections(); 5396 patchELFGOT(); 5397 } 5398 5399 // Patch dynamic section/segment. 5400 patchELFDynamic(); 5401 5402 // Update ELF book-keeping info. 5403 patchELFSectionHeaderTable(); 5404 5405 if (opts::PrintSections) { 5406 outs() << "BOLT-INFO: Sections after processing:\n"; 5407 BC->printSections(outs()); 5408 } 5409 5410 Out->keep(); 5411 EC = sys::fs::setPermissions(opts::OutputFilename, sys::fs::perms::all_all); 5412 check_error(EC, "cannot set permissions of output file"); 5413 } 5414 5415 void RewriteInstance::writeEHFrameHeader() { 5416 DWARFDebugFrame NewEHFrame(BC->TheTriple->getArch(), true, 5417 EHFrameSection->getOutputAddress()); 5418 Error E = NewEHFrame.parse(DWARFDataExtractor( 5419 EHFrameSection->getOutputContents(), BC->AsmInfo->isLittleEndian(), 5420 BC->AsmInfo->getCodePointerSize())); 5421 check_error(std::move(E), "failed to parse EH frame"); 5422 5423 uint64_t OldEHFrameAddress = 0; 5424 StringRef OldEHFrameContents; 5425 ErrorOr<BinarySection &> OldEHFrameSection = 5426 BC->getUniqueSectionByName(Twine(getOrgSecPrefix(), ".eh_frame").str()); 5427 if (OldEHFrameSection) { 5428 OldEHFrameAddress = OldEHFrameSection->getOutputAddress(); 5429 OldEHFrameContents = OldEHFrameSection->getOutputContents(); 5430 } 5431 DWARFDebugFrame OldEHFrame(BC->TheTriple->getArch(), true, OldEHFrameAddress); 5432 Error Er = OldEHFrame.parse( 5433 DWARFDataExtractor(OldEHFrameContents, BC->AsmInfo->isLittleEndian(), 5434 BC->AsmInfo->getCodePointerSize())); 5435 check_error(std::move(Er), "failed to parse EH frame"); 5436 5437 LLVM_DEBUG(dbgs() << "BOLT: writing a new .eh_frame_hdr\n"); 5438 5439 NextAvailableAddress = 5440 appendPadding(Out->os(), NextAvailableAddress, EHFrameHdrAlign); 5441 5442 const uint64_t EHFrameHdrOutputAddress = NextAvailableAddress; 5443 const uint64_t EHFrameHdrFileOffset = 5444 getFileOffsetForAddress(NextAvailableAddress); 5445 5446 std::vector<char> NewEHFrameHdr = CFIRdWrt->generateEHFrameHeader( 5447 OldEHFrame, NewEHFrame, EHFrameHdrOutputAddress, FailedAddresses); 5448 5449 assert(Out->os().tell() == EHFrameHdrFileOffset && "offset mismatch"); 5450 Out->os().write(NewEHFrameHdr.data(), NewEHFrameHdr.size()); 5451 5452 const unsigned Flags = BinarySection::getFlags(/*IsReadOnly=*/true, 5453 /*IsText=*/false, 5454 /*IsAllocatable=*/true); 5455 BinarySection &EHFrameHdrSec = BC->registerOrUpdateSection( 5456 ".eh_frame_hdr", ELF::SHT_PROGBITS, Flags, nullptr, NewEHFrameHdr.size(), 5457 /*Alignment=*/1); 5458 EHFrameHdrSec.setOutputFileOffset(EHFrameHdrFileOffset); 5459 EHFrameHdrSec.setOutputAddress(EHFrameHdrOutputAddress); 5460 5461 NextAvailableAddress += EHFrameHdrSec.getOutputSize(); 5462 5463 // Merge new .eh_frame with original so that gdb can locate all FDEs. 5464 if (OldEHFrameSection) { 5465 const uint64_t EHFrameSectionSize = (OldEHFrameSection->getOutputAddress() + 5466 OldEHFrameSection->getOutputSize() - 5467 EHFrameSection->getOutputAddress()); 5468 EHFrameSection = 5469 BC->registerOrUpdateSection(".eh_frame", 5470 EHFrameSection->getELFType(), 5471 EHFrameSection->getELFFlags(), 5472 EHFrameSection->getOutputData(), 5473 EHFrameSectionSize, 5474 EHFrameSection->getAlignment()); 5475 BC->deregisterSection(*OldEHFrameSection); 5476 } 5477 5478 LLVM_DEBUG(dbgs() << "BOLT-DEBUG: size of .eh_frame after merge is " 5479 << EHFrameSection->getOutputSize() << '\n'); 5480 } 5481 5482 uint64_t RewriteInstance::getNewValueForSymbol(const StringRef Name) { 5483 uint64_t Value = RTDyld->getSymbol(Name).getAddress(); 5484 if (Value != 0) 5485 return Value; 5486 5487 // Return the original value if we haven't emitted the symbol. 5488 BinaryData *BD = BC->getBinaryDataByName(Name); 5489 if (!BD) 5490 return 0; 5491 5492 return BD->getAddress(); 5493 } 5494 5495 uint64_t RewriteInstance::getFileOffsetForAddress(uint64_t Address) const { 5496 // Check if it's possibly part of the new segment. 5497 if (Address >= NewTextSegmentAddress) 5498 return Address - NewTextSegmentAddress + NewTextSegmentOffset; 5499 5500 // Find an existing segment that matches the address. 5501 const auto SegmentInfoI = BC->SegmentMapInfo.upper_bound(Address); 5502 if (SegmentInfoI == BC->SegmentMapInfo.begin()) 5503 return 0; 5504 5505 const SegmentInfo &SegmentInfo = std::prev(SegmentInfoI)->second; 5506 if (Address < SegmentInfo.Address || 5507 Address >= SegmentInfo.Address + SegmentInfo.FileSize) 5508 return 0; 5509 5510 return SegmentInfo.FileOffset + Address - SegmentInfo.Address; 5511 } 5512 5513 bool RewriteInstance::willOverwriteSection(StringRef SectionName) { 5514 for (const char *const &OverwriteName : SectionsToOverwrite) 5515 if (SectionName == OverwriteName) 5516 return true; 5517 for (std::string &OverwriteName : DebugSectionsToOverwrite) 5518 if (SectionName == OverwriteName) 5519 return true; 5520 5521 ErrorOr<BinarySection &> Section = BC->getUniqueSectionByName(SectionName); 5522 return Section && Section->isAllocatable() && Section->isFinalized(); 5523 } 5524 5525 bool RewriteInstance::isDebugSection(StringRef SectionName) { 5526 if (SectionName.startswith(".debug_") || SectionName.startswith(".zdebug_") || 5527 SectionName == ".gdb_index" || SectionName == ".stab" || 5528 SectionName == ".stabstr") 5529 return true; 5530 5531 return false; 5532 } 5533 5534 bool RewriteInstance::isKSymtabSection(StringRef SectionName) { 5535 if (SectionName.startswith("__ksymtab")) 5536 return true; 5537 5538 return false; 5539 } 5540