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