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