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