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