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