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