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