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