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