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