1 //===- bolt/Core/BinaryFunction.h - Low-level function ----------*- C++ -*-===// 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 // This file contains the declaration of the BinaryFunction class. It represents 10 // a function at the lowest IR level. Typically, a BinaryFunction represents a 11 // function object in a compiled and linked binary file. However, a 12 // BinaryFunction can also be constructed manually, e.g. for injecting into a 13 // binary file. 14 // 15 // A BinaryFunction could be in one of the several states described in 16 // BinaryFunction::State. While in the disassembled state, it will contain a 17 // list of instructions with their offsets. In the CFG state, it will contain a 18 // list of BinaryBasicBlocks that form a control-flow graph. This state is best 19 // suited for binary analysis and optimizations. However, sometimes it's 20 // impossible to build the precise CFG due to the ambiguity of indirect 21 // branches. 22 // 23 //===----------------------------------------------------------------------===// 24 25 #ifndef BOLT_CORE_BINARY_FUNCTION_H 26 #define BOLT_CORE_BINARY_FUNCTION_H 27 28 #include "bolt/Core/BinaryBasicBlock.h" 29 #include "bolt/Core/BinaryContext.h" 30 #include "bolt/Core/BinaryLoop.h" 31 #include "bolt/Core/BinarySection.h" 32 #include "bolt/Core/DebugData.h" 33 #include "bolt/Core/JumpTable.h" 34 #include "bolt/Core/MCPlus.h" 35 #include "bolt/Utils/NameResolver.h" 36 #include "llvm/ADT/StringRef.h" 37 #include "llvm/ADT/iterator.h" 38 #include "llvm/BinaryFormat/Dwarf.h" 39 #include "llvm/MC/MCContext.h" 40 #include "llvm/MC/MCDwarf.h" 41 #include "llvm/MC/MCInst.h" 42 #include "llvm/MC/MCSymbol.h" 43 #include "llvm/Object/ObjectFile.h" 44 #include "llvm/Support/raw_ostream.h" 45 #include <algorithm> 46 #include <limits> 47 #include <unordered_map> 48 #include <unordered_set> 49 #include <vector> 50 51 using namespace llvm::object; 52 53 namespace llvm { 54 55 class DWARFUnit; 56 57 namespace bolt { 58 59 using InputOffsetToAddressMapTy = std::unordered_multimap<uint64_t, uint64_t>; 60 61 /// Types of macro-fusion alignment corrections. 62 enum MacroFusionType { MFT_NONE, MFT_HOT, MFT_ALL }; 63 64 enum IndirectCallPromotionType : char { 65 ICP_NONE, /// Don't perform ICP. 66 ICP_CALLS, /// Perform ICP on indirect calls. 67 ICP_JUMP_TABLES, /// Perform ICP on jump tables. 68 ICP_ALL /// Perform ICP on calls and jump tables. 69 }; 70 71 /// Information on a single indirect call to a particular callee. 72 struct IndirectCallProfile { 73 MCSymbol *Symbol; 74 uint32_t Offset; 75 uint64_t Count; 76 uint64_t Mispreds; 77 78 IndirectCallProfile(MCSymbol *Symbol, uint64_t Count, uint64_t Mispreds, 79 uint32_t Offset = 0) 80 : Symbol(Symbol), Offset(Offset), Count(Count), Mispreds(Mispreds) {} 81 82 bool operator==(const IndirectCallProfile &Other) const { 83 return Symbol == Other.Symbol && Offset == Other.Offset; 84 } 85 }; 86 87 /// Aggregated information for an indirect call site. 88 using IndirectCallSiteProfile = SmallVector<IndirectCallProfile, 4>; 89 90 inline raw_ostream &operator<<(raw_ostream &OS, 91 const bolt::IndirectCallSiteProfile &ICSP) { 92 std::string TempString; 93 raw_string_ostream SS(TempString); 94 95 const char *Sep = "\n "; 96 uint64_t TotalCount = 0; 97 uint64_t TotalMispreds = 0; 98 for (const IndirectCallProfile &CSP : ICSP) { 99 SS << Sep << "{ " << (CSP.Symbol ? CSP.Symbol->getName() : "<unknown>") 100 << ": " << CSP.Count << " (" << CSP.Mispreds << " misses) }"; 101 Sep = ",\n "; 102 TotalCount += CSP.Count; 103 TotalMispreds += CSP.Mispreds; 104 } 105 SS.flush(); 106 107 OS << TotalCount << " (" << TotalMispreds << " misses) :" << TempString; 108 return OS; 109 } 110 111 /// BinaryFunction is a representation of machine-level function. 112 /// 113 /// In the input binary, an instance of BinaryFunction can represent a fragment 114 /// of a function if the higher-level function was split, e.g. into hot and cold 115 /// parts. The fragment containing the main entry point is called a parent 116 /// or the main fragment. 117 class BinaryFunction { 118 public: 119 enum class State : char { 120 Empty = 0, /// Function body is empty. 121 Disassembled, /// Function have been disassembled. 122 CFG, /// Control flow graph has been built. 123 CFG_Finalized, /// CFG is finalized. No optimizations allowed. 124 EmittedCFG, /// Instructions have been emitted to output. 125 Emitted, /// Same as above plus CFG is destroyed. 126 }; 127 128 /// Types of profile the function can use. Could be a combination. 129 enum { 130 PF_NONE = 0, /// No profile. 131 PF_LBR = 1, /// Profile is based on last branch records. 132 PF_SAMPLE = 2, /// Non-LBR sample-based profile. 133 PF_MEMEVENT = 4, /// Profile has mem events. 134 }; 135 136 /// Struct for tracking exception handling ranges. 137 struct CallSite { 138 const MCSymbol *Start; 139 const MCSymbol *End; 140 const MCSymbol *LP; 141 uint64_t Action; 142 }; 143 144 using CallSitesType = SmallVector<CallSite, 0>; 145 146 using IslandProxiesType = 147 std::map<BinaryFunction *, std::map<const MCSymbol *, MCSymbol *>>; 148 149 struct IslandInfo { 150 /// Temporary holder of offsets that are data markers (used in AArch) 151 /// It is possible to have data in code sections. To ease the identification 152 /// of data in code sections, the ABI requires the symbol table to have 153 /// symbols named "$d" identifying the start of data inside code and "$x" 154 /// identifying the end of a chunk of data inside code. DataOffsets contain 155 /// all offsets of $d symbols and CodeOffsets all offsets of $x symbols. 156 std::set<uint64_t> DataOffsets; 157 std::set<uint64_t> CodeOffsets; 158 159 /// List of relocations associated with data in the constant island 160 std::map<uint64_t, Relocation> Relocations; 161 162 /// Offsets in function that are data values in a constant island identified 163 /// after disassembling 164 std::map<uint64_t, MCSymbol *> Offsets; 165 SmallPtrSet<MCSymbol *, 4> Symbols; 166 DenseMap<const MCSymbol *, BinaryFunction *> ProxySymbols; 167 DenseMap<const MCSymbol *, MCSymbol *> ColdSymbols; 168 /// Keeps track of other functions we depend on because there is a reference 169 /// to the constant islands in them. 170 IslandProxiesType Proxies, ColdProxies; 171 SmallPtrSet<BinaryFunction *, 1> Dependency; // The other way around 172 173 mutable MCSymbol *FunctionConstantIslandLabel{nullptr}; 174 mutable MCSymbol *FunctionColdConstantIslandLabel{nullptr}; 175 }; 176 177 static constexpr uint64_t COUNT_NO_PROFILE = 178 BinaryBasicBlock::COUNT_NO_PROFILE; 179 180 /// We have to use at least 2-byte alignment for functions because of C++ ABI. 181 static constexpr unsigned MinAlign = 2; 182 183 static const char TimerGroupName[]; 184 static const char TimerGroupDesc[]; 185 186 using BasicBlockOrderType = SmallVector<BinaryBasicBlock *, 0>; 187 188 /// Mark injected functions 189 bool IsInjected = false; 190 191 using LSDATypeTableTy = SmallVector<uint64_t, 0>; 192 193 /// List of DWARF CFI instructions. Original CFI from the binary must be 194 /// sorted w.r.t. offset that it appears. We rely on this to replay CFIs 195 /// if needed (to fix state after reordering BBs). 196 using CFIInstrMapType = SmallVector<MCCFIInstruction, 0>; 197 using cfi_iterator = CFIInstrMapType::iterator; 198 using const_cfi_iterator = CFIInstrMapType::const_iterator; 199 200 private: 201 /// Current state of the function. 202 State CurrentState{State::Empty}; 203 204 /// A list of symbols associated with the function entry point. 205 /// 206 /// Multiple symbols would typically result from identical code-folding 207 /// optimization. 208 typedef SmallVector<MCSymbol *, 1> SymbolListTy; 209 SymbolListTy Symbols; 210 211 /// The list of names this function is known under. Used for fuzzy-matching 212 /// the function to its name in a profile, command line, etc. 213 SmallVector<std::string, 0> Aliases; 214 215 /// Containing section in the input file. 216 BinarySection *OriginSection = nullptr; 217 218 /// Address of the function in memory. Also could be an offset from 219 /// base address for position independent binaries. 220 uint64_t Address; 221 222 /// Original size of the function. 223 uint64_t Size; 224 225 /// Address of the function in output. 226 uint64_t OutputAddress{0}; 227 228 /// Size of the function in the output file. 229 uint64_t OutputSize{0}; 230 231 /// Offset in the file. 232 uint64_t FileOffset{0}; 233 234 /// Maximum size this function is allowed to have. 235 uint64_t MaxSize{std::numeric_limits<uint64_t>::max()}; 236 237 /// Alignment requirements for the function. 238 uint16_t Alignment{2}; 239 240 /// Maximum number of bytes used for alignment of hot part of the function. 241 uint16_t MaxAlignmentBytes{0}; 242 243 /// Maximum number of bytes used for alignment of cold part of the function. 244 uint16_t MaxColdAlignmentBytes{0}; 245 246 const MCSymbol *PersonalityFunction{nullptr}; 247 uint8_t PersonalityEncoding{dwarf::DW_EH_PE_sdata4 | dwarf::DW_EH_PE_pcrel}; 248 249 BinaryContext &BC; 250 251 std::unique_ptr<BinaryLoopInfo> BLI; 252 253 /// Set of external addresses in the code that are not a function start 254 /// and are referenced from this function. 255 std::set<uint64_t> InterproceduralReferences; 256 257 /// All labels in the function that are referenced via relocations from 258 /// data objects. Typically these are jump table destinations and computed 259 /// goto labels. 260 std::set<uint64_t> ExternallyReferencedOffsets; 261 262 /// Offsets of indirect branches with unknown destinations. 263 std::set<uint64_t> UnknownIndirectBranchOffsets; 264 265 /// A set of local and global symbols corresponding to secondary entry points. 266 /// Each additional function entry point has a corresponding entry in the map. 267 /// The key is a local symbol corresponding to a basic block and the value 268 /// is a global symbol corresponding to an external entry point. 269 DenseMap<const MCSymbol *, MCSymbol *> SecondaryEntryPoints; 270 271 /// False if the function is too complex to reconstruct its control 272 /// flow graph. 273 /// In relocation mode we still disassemble and re-assemble such functions. 274 bool IsSimple{true}; 275 276 /// Indication that the function should be ignored for optimization purposes. 277 /// If we can skip emission of some functions, then ignored functions could 278 /// be not fully disassembled and will not be emitted. 279 bool IsIgnored{false}; 280 281 /// Pseudo functions should not be disassembled or emitted. 282 bool IsPseudo{false}; 283 284 /// True if the original function code has all necessary relocations to track 285 /// addresses of functions emitted to new locations. Typically set for 286 /// functions that we are not going to emit. 287 bool HasExternalRefRelocations{false}; 288 289 /// True if the function has an indirect branch with unknown destination. 290 bool HasUnknownControlFlow{false}; 291 292 /// The code from inside the function references one of the code locations 293 /// from the same function as a data, i.e. it's possible the label is used 294 /// inside an address calculation or could be referenced from outside. 295 bool HasInternalLabelReference{false}; 296 297 /// In AArch64, preserve nops to maintain code equal to input (assuming no 298 /// optimizations are done). 299 bool PreserveNops{false}; 300 301 /// Indicate if this function has associated exception handling metadata. 302 bool HasEHRanges{false}; 303 304 /// True if the function uses DW_CFA_GNU_args_size CFIs. 305 bool UsesGnuArgsSize{false}; 306 307 /// True if the function might have a profile available externally. 308 /// Used to check if processing of the function is required under certain 309 /// conditions. 310 bool HasProfileAvailable{false}; 311 312 bool HasMemoryProfile{false}; 313 314 /// Execution halts whenever this function is entered. 315 bool TrapsOnEntry{false}; 316 317 /// True if the function had an indirect branch with a fixed internal 318 /// destination. 319 bool HasFixedIndirectBranch{false}; 320 321 /// True if the function is a fragment of another function. This means that 322 /// this function could only be entered via its parent or one of its sibling 323 /// fragments. It could be entered at any basic block. It can also return 324 /// the control to any basic block of its parent or its sibling. 325 bool IsFragment{false}; 326 327 /// Indicate that the function body has SDT marker 328 bool HasSDTMarker{false}; 329 330 /// Indicate that the function body has Pseudo Probe 331 bool HasPseudoProbe{BC.getUniqueSectionByName(".pseudo_probe_desc") && 332 BC.getUniqueSectionByName(".pseudo_probe")}; 333 334 /// True if the original entry point was patched. 335 bool IsPatched{false}; 336 337 /// True if the function contains jump table with entries pointing to 338 /// locations in fragments. 339 bool HasSplitJumpTable{false}; 340 341 /// True if there are no control-flow edges with successors in other functions 342 /// (i.e. if tail calls have edges to function-local basic blocks). 343 /// Set to false by SCTC. Dynostats can't be reliably computed for 344 /// functions with non-canonical CFG. 345 /// This attribute is only valid when hasCFG() == true. 346 bool HasCanonicalCFG{true}; 347 348 /// The address for the code for this function in codegen memory. 349 /// Used for functions that are emitted in a dedicated section with a fixed 350 /// address. E.g. for functions that are overwritten in-place. 351 uint64_t ImageAddress{0}; 352 353 /// The size of the code in memory. 354 uint64_t ImageSize{0}; 355 356 /// Name for the section this function code should reside in. 357 std::string CodeSectionName; 358 359 /// Name for the corresponding cold code section. 360 std::string ColdCodeSectionName; 361 362 /// Parent function fragment for split function fragments. 363 SmallPtrSet<BinaryFunction *, 1> ParentFragments; 364 365 /// Indicate if the function body was folded into another function. 366 /// Used by ICF optimization. 367 BinaryFunction *FoldedIntoFunction{nullptr}; 368 369 /// All fragments for a parent function. 370 SmallPtrSet<BinaryFunction *, 1> Fragments; 371 372 /// The profile data for the number of times the function was executed. 373 uint64_t ExecutionCount{COUNT_NO_PROFILE}; 374 375 /// Profile match ratio. 376 float ProfileMatchRatio{0.0f}; 377 378 /// Raw branch count for this function in the profile 379 uint64_t RawBranchCount{0}; 380 381 /// Indicates the type of profile the function is using. 382 uint16_t ProfileFlags{PF_NONE}; 383 384 /// For functions with mismatched profile we store all call profile 385 /// information at a function level (as opposed to tying it to 386 /// specific call sites). 387 IndirectCallSiteProfile AllCallSites; 388 389 /// Score of the function (estimated number of instructions executed, 390 /// according to profile data). -1 if the score has not been calculated yet. 391 mutable int64_t FunctionScore{-1}; 392 393 /// Original LSDA address for the function. 394 uint64_t LSDAAddress{0}; 395 396 /// Containing compilation unit for the function. 397 DWARFUnit *DwarfUnit{nullptr}; 398 399 /// Last computed hash value. Note that the value could be recomputed using 400 /// different parameters by every pass. 401 mutable uint64_t Hash{0}; 402 403 /// For PLT functions it contains a symbol associated with a function 404 /// reference. It is nullptr for non-PLT functions. 405 const MCSymbol *PLTSymbol{nullptr}; 406 407 /// Function order for streaming into the destination binary. 408 uint32_t Index{-1U}; 409 410 /// Get basic block index assuming it belongs to this function. 411 unsigned getIndex(const BinaryBasicBlock *BB) const { 412 assert(BB->getIndex() < BasicBlocks.size()); 413 return BB->getIndex(); 414 } 415 416 /// Return basic block that originally contained offset \p Offset 417 /// from the function start. 418 BinaryBasicBlock *getBasicBlockContainingOffset(uint64_t Offset); 419 420 const BinaryBasicBlock *getBasicBlockContainingOffset(uint64_t Offset) const { 421 return const_cast<BinaryFunction *>(this)->getBasicBlockContainingOffset( 422 Offset); 423 } 424 425 /// Return basic block that started at offset \p Offset. 426 BinaryBasicBlock *getBasicBlockAtOffset(uint64_t Offset) { 427 BinaryBasicBlock *BB = getBasicBlockContainingOffset(Offset); 428 return BB && BB->getOffset() == Offset ? BB : nullptr; 429 } 430 431 /// Release memory taken by the list. 432 template <typename T> BinaryFunction &clearList(T &List) { 433 T TempList; 434 TempList.swap(List); 435 return *this; 436 } 437 438 /// Update the indices of all the basic blocks starting at StartIndex. 439 void updateBBIndices(const unsigned StartIndex); 440 441 /// Annotate each basic block entry with its current CFI state. This is 442 /// run right after the construction of CFG while basic blocks are in their 443 /// original order. 444 void annotateCFIState(); 445 446 /// Associate DW_CFA_GNU_args_size info with invoke instructions 447 /// (call instructions with non-empty landing pad). 448 void propagateGnuArgsSizeInfo(MCPlusBuilder::AllocatorIdTy AllocId); 449 450 /// Synchronize branch instructions with CFG. 451 void postProcessBranches(); 452 453 /// The address offset where we emitted the constant island, that is, the 454 /// chunk of data in the function code area (AArch only) 455 int64_t OutputDataOffset{0}; 456 int64_t OutputColdDataOffset{0}; 457 458 /// Map labels to corresponding basic blocks. 459 DenseMap<const MCSymbol *, BinaryBasicBlock *> LabelToBB; 460 461 using BranchListType = SmallVector<std::pair<uint32_t, uint32_t>, 0>; 462 BranchListType TakenBranches; /// All local taken branches. 463 BranchListType IgnoredBranches; /// Branches ignored by CFG purposes. 464 465 /// Map offset in the function to a label. 466 /// Labels are used for building CFG for simple functions. For non-simple 467 /// function in relocation mode we need to emit them for relocations 468 /// referencing function internals to work (e.g. jump tables). 469 using LabelsMapType = std::map<uint32_t, MCSymbol *>; 470 LabelsMapType Labels; 471 472 /// Temporary holder of instructions before CFG is constructed. 473 /// Map offset in the function to MCInst. 474 using InstrMapType = std::map<uint32_t, MCInst>; 475 InstrMapType Instructions; 476 477 /// We don't decode Call Frame Info encoded in DWARF program state 478 /// machine. Instead we define a "CFI State" - a frame information that 479 /// is a result of executing FDE CFI program up to a given point. The 480 /// program consists of opaque Call Frame Instructions: 481 /// 482 /// CFI #0 483 /// CFI #1 484 /// .... 485 /// CFI #N 486 /// 487 /// When we refer to "CFI State K" - it corresponds to a row in an abstract 488 /// Call Frame Info table. This row is reached right before executing CFI #K. 489 /// 490 /// At any point of execution in a function we are in any one of (N + 2) 491 /// states described in the original FDE program. We can't have more states 492 /// without intelligent processing of CFIs. 493 /// 494 /// When the final layout of basic blocks is known, and we finalize CFG, 495 /// we modify the original program to make sure the same state could be 496 /// reached even when basic blocks containing CFI instructions are executed 497 /// in a different order. 498 CFIInstrMapType FrameInstructions; 499 500 /// A map of restore state CFI instructions to their equivalent CFI 501 /// instructions that produce the same state, in order to eliminate 502 /// remember-restore CFI instructions when rewriting CFI. 503 DenseMap<int32_t, SmallVector<int32_t, 4>> FrameRestoreEquivalents; 504 505 // For tracking exception handling ranges. 506 CallSitesType CallSites; 507 CallSitesType ColdCallSites; 508 509 /// Binary blobs representing action, type, and type index tables for this 510 /// function' LSDA (exception handling). 511 ArrayRef<uint8_t> LSDAActionTable; 512 ArrayRef<uint8_t> LSDATypeIndexTable; 513 514 /// Vector of addresses of types referenced by LSDA. 515 LSDATypeTableTy LSDATypeTable; 516 517 /// Vector of addresses of entries in LSDATypeTable used for indirect 518 /// addressing. 519 LSDATypeTableTy LSDATypeAddressTable; 520 521 /// Marking for the beginning of language-specific data area for the function. 522 MCSymbol *LSDASymbol{nullptr}; 523 MCSymbol *ColdLSDASymbol{nullptr}; 524 525 /// Map to discover which CFIs are attached to a given instruction offset. 526 /// Maps an instruction offset into a FrameInstructions offset. 527 /// This is only relevant to the buildCFG phase and is discarded afterwards. 528 std::multimap<uint32_t, uint32_t> OffsetToCFI; 529 530 /// List of CFI instructions associated with the CIE (common to more than one 531 /// function and that apply before the entry basic block). 532 CFIInstrMapType CIEFrameInstructions; 533 534 /// All compound jump tables for this function. This duplicates what's stored 535 /// in the BinaryContext, but additionally it gives quick access for all 536 /// jump tables used by this function. 537 /// 538 /// <OriginalAddress> -> <JumpTable *> 539 std::map<uint64_t, JumpTable *> JumpTables; 540 541 /// All jump table sites in the function before CFG is built. 542 SmallVector<std::pair<uint64_t, uint64_t>, 0> JTSites; 543 544 /// List of relocations in this function. 545 std::map<uint64_t, Relocation> Relocations; 546 547 /// Information on function constant islands. 548 std::unique_ptr<IslandInfo> Islands; 549 550 // Blocks are kept sorted in the layout order. If we need to change the 551 // layout (if BasicBlocksLayout stores a different order than BasicBlocks), 552 // the terminating instructions need to be modified. 553 using BasicBlockListType = SmallVector<BinaryBasicBlock *, 0>; 554 BasicBlockListType BasicBlocks; 555 BasicBlockListType DeletedBasicBlocks; 556 BasicBlockOrderType BasicBlocksLayout; 557 /// Previous layout replaced by modifyLayout 558 BasicBlockOrderType BasicBlocksPreviousLayout; 559 bool ModifiedLayout{false}; 560 561 /// BasicBlockOffsets are used during CFG construction to map from code 562 /// offsets to BinaryBasicBlocks. Any modifications made to the CFG 563 /// after initial construction are not reflected in this data structure. 564 using BasicBlockOffset = std::pair<uint64_t, BinaryBasicBlock *>; 565 struct CompareBasicBlockOffsets { 566 bool operator()(const BasicBlockOffset &A, 567 const BasicBlockOffset &B) const { 568 return A.first < B.first; 569 } 570 }; 571 SmallVector<BasicBlockOffset, 0> BasicBlockOffsets; 572 573 MCSymbol *ColdSymbol{nullptr}; 574 575 /// Symbol at the end of the function. 576 mutable MCSymbol *FunctionEndLabel{nullptr}; 577 578 /// Symbol at the end of the cold part of split function. 579 mutable MCSymbol *FunctionColdEndLabel{nullptr}; 580 581 /// Unique number associated with the function. 582 uint64_t FunctionNumber; 583 584 /// Count the number of functions created. 585 static uint64_t Count; 586 587 /// Map offsets of special instructions to addresses in the output. 588 InputOffsetToAddressMapTy InputOffsetToAddressMap; 589 590 /// Register alternative function name. 591 void addAlternativeName(std::string NewName) { 592 Aliases.push_back(std::move(NewName)); 593 } 594 595 /// Return a label at a given \p Address in the function. If the label does 596 /// not exist - create it. Assert if the \p Address does not belong to 597 /// the function. If \p CreatePastEnd is true, then return the function 598 /// end label when the \p Address points immediately past the last byte 599 /// of the function. 600 /// NOTE: the function always returns a local (temp) symbol, even if there's 601 /// a global symbol that corresponds to an entry at this address. 602 MCSymbol *getOrCreateLocalLabel(uint64_t Address, bool CreatePastEnd = false); 603 604 /// Register an data entry at a given \p Offset into the function. 605 void markDataAtOffset(uint64_t Offset) { 606 if (!Islands) 607 Islands = std::make_unique<IslandInfo>(); 608 Islands->DataOffsets.emplace(Offset); 609 } 610 611 /// Register an entry point at a given \p Offset into the function. 612 void markCodeAtOffset(uint64_t Offset) { 613 if (!Islands) 614 Islands = std::make_unique<IslandInfo>(); 615 Islands->CodeOffsets.emplace(Offset); 616 } 617 618 /// Register secondary entry point at a given \p Offset into the function. 619 /// Return global symbol for use by extern function references. 620 MCSymbol *addEntryPointAtOffset(uint64_t Offset); 621 622 /// Register an internal offset in a function referenced from outside. 623 void registerReferencedOffset(uint64_t Offset) { 624 ExternallyReferencedOffsets.emplace(Offset); 625 } 626 627 /// True if there are references to internals of this function from data, 628 /// e.g. from jump tables. 629 bool hasInternalReference() const { 630 return !ExternallyReferencedOffsets.empty(); 631 } 632 633 /// Return an entry ID corresponding to a symbol known to belong to 634 /// the function. 635 /// 636 /// Prefer to use BinaryContext::getFunctionForSymbol(EntrySymbol, &ID) 637 /// instead of calling this function directly. 638 uint64_t getEntryIDForSymbol(const MCSymbol *EntrySymbol) const; 639 640 /// If the function represents a secondary split function fragment, set its 641 /// parent fragment to \p BF. 642 void addParentFragment(BinaryFunction &BF) { 643 assert(this != &BF); 644 assert(IsFragment && "function must be a fragment to have a parent"); 645 ParentFragments.insert(&BF); 646 } 647 648 /// Register a child fragment for the main fragment of a split function. 649 void addFragment(BinaryFunction &BF) { 650 assert(this != &BF); 651 Fragments.insert(&BF); 652 } 653 654 void addInstruction(uint64_t Offset, MCInst &&Instruction) { 655 Instructions.emplace(Offset, std::forward<MCInst>(Instruction)); 656 } 657 658 /// Convert CFI instructions to a standard form (remove remember/restore). 659 void normalizeCFIState(); 660 661 /// Analyze and process indirect branch \p Instruction before it is 662 /// added to Instructions list. 663 IndirectBranchType processIndirectBranch(MCInst &Instruction, unsigned Size, 664 uint64_t Offset, 665 uint64_t &TargetAddress); 666 667 DenseMap<const MCInst *, SmallVector<MCInst *, 4>> 668 computeLocalUDChain(const MCInst *CurInstr); 669 670 BinaryFunction &operator=(const BinaryFunction &) = delete; 671 BinaryFunction(const BinaryFunction &) = delete; 672 673 friend class MachORewriteInstance; 674 friend class RewriteInstance; 675 friend class BinaryContext; 676 friend class DataReader; 677 friend class DataAggregator; 678 679 static std::string buildCodeSectionName(StringRef Name, 680 const BinaryContext &BC); 681 static std::string buildColdCodeSectionName(StringRef Name, 682 const BinaryContext &BC); 683 684 /// Creation should be handled by RewriteInstance or BinaryContext 685 BinaryFunction(const std::string &Name, BinarySection &Section, 686 uint64_t Address, uint64_t Size, BinaryContext &BC) 687 : OriginSection(&Section), Address(Address), Size(Size), BC(BC), 688 CodeSectionName(buildCodeSectionName(Name, BC)), 689 ColdCodeSectionName(buildColdCodeSectionName(Name, BC)), 690 FunctionNumber(++Count) { 691 Symbols.push_back(BC.Ctx->getOrCreateSymbol(Name)); 692 } 693 694 /// This constructor is used to create an injected function 695 BinaryFunction(const std::string &Name, BinaryContext &BC, bool IsSimple) 696 : Address(0), Size(0), BC(BC), IsSimple(IsSimple), 697 CodeSectionName(buildCodeSectionName(Name, BC)), 698 ColdCodeSectionName(buildColdCodeSectionName(Name, BC)), 699 FunctionNumber(++Count) { 700 Symbols.push_back(BC.Ctx->getOrCreateSymbol(Name)); 701 IsInjected = true; 702 } 703 704 /// Clear state of the function that could not be disassembled or if its 705 /// disassembled state was later invalidated. 706 void clearDisasmState(); 707 708 /// Release memory allocated for CFG and instructions. 709 /// We still keep basic blocks for address translation/mapping purposes. 710 void releaseCFG() { 711 for (BinaryBasicBlock *BB : BasicBlocks) 712 BB->releaseCFG(); 713 for (BinaryBasicBlock *BB : DeletedBasicBlocks) 714 BB->releaseCFG(); 715 716 clearList(CallSites); 717 clearList(ColdCallSites); 718 clearList(LSDATypeTable); 719 clearList(LSDATypeAddressTable); 720 721 clearList(LabelToBB); 722 723 if (!isMultiEntry()) 724 clearList(Labels); 725 726 clearList(FrameInstructions); 727 clearList(FrameRestoreEquivalents); 728 } 729 730 public: 731 BinaryFunction(BinaryFunction &&) = default; 732 733 using iterator = pointee_iterator<BasicBlockListType::iterator>; 734 using const_iterator = pointee_iterator<BasicBlockListType::const_iterator>; 735 using reverse_iterator = 736 pointee_iterator<BasicBlockListType::reverse_iterator>; 737 using const_reverse_iterator = 738 pointee_iterator<BasicBlockListType::const_reverse_iterator>; 739 740 typedef BasicBlockOrderType::iterator order_iterator; 741 typedef BasicBlockOrderType::const_iterator const_order_iterator; 742 typedef BasicBlockOrderType::reverse_iterator reverse_order_iterator; 743 typedef BasicBlockOrderType::const_reverse_iterator 744 const_reverse_order_iterator; 745 746 // CFG iterators. 747 iterator begin() { return BasicBlocks.begin(); } 748 const_iterator begin() const { return BasicBlocks.begin(); } 749 iterator end () { return BasicBlocks.end(); } 750 const_iterator end () const { return BasicBlocks.end(); } 751 752 reverse_iterator rbegin() { return BasicBlocks.rbegin(); } 753 const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); } 754 reverse_iterator rend () { return BasicBlocks.rend(); } 755 const_reverse_iterator rend () const { return BasicBlocks.rend(); } 756 757 size_t size() const { return BasicBlocks.size();} 758 bool empty() const { return BasicBlocks.empty(); } 759 const BinaryBasicBlock &front() const { return *BasicBlocks.front(); } 760 BinaryBasicBlock &front() { return *BasicBlocks.front(); } 761 const BinaryBasicBlock & back() const { return *BasicBlocks.back(); } 762 BinaryBasicBlock & back() { return *BasicBlocks.back(); } 763 inline iterator_range<iterator> blocks() { 764 return iterator_range<iterator>(begin(), end()); 765 } 766 inline iterator_range<const_iterator> blocks() const { 767 return iterator_range<const_iterator>(begin(), end()); 768 } 769 770 // Iterators by pointer. 771 BasicBlockListType::iterator pbegin() { return BasicBlocks.begin(); } 772 BasicBlockListType::iterator pend() { return BasicBlocks.end(); } 773 774 order_iterator layout_begin() { return BasicBlocksLayout.begin(); } 775 const_order_iterator layout_begin() const 776 { return BasicBlocksLayout.begin(); } 777 order_iterator layout_end() { return BasicBlocksLayout.end(); } 778 const_order_iterator layout_end() const 779 { return BasicBlocksLayout.end(); } 780 reverse_order_iterator layout_rbegin() 781 { return BasicBlocksLayout.rbegin(); } 782 const_reverse_order_iterator layout_rbegin() const 783 { return BasicBlocksLayout.rbegin(); } 784 reverse_order_iterator layout_rend() 785 { return BasicBlocksLayout.rend(); } 786 const_reverse_order_iterator layout_rend() const 787 { return BasicBlocksLayout.rend(); } 788 size_t layout_size() const { return BasicBlocksLayout.size(); } 789 bool layout_empty() const { return BasicBlocksLayout.empty(); } 790 const BinaryBasicBlock *layout_front() const 791 { return BasicBlocksLayout.front(); } 792 BinaryBasicBlock *layout_front() { return BasicBlocksLayout.front(); } 793 const BinaryBasicBlock *layout_back() const 794 { return BasicBlocksLayout.back(); } 795 BinaryBasicBlock *layout_back() { return BasicBlocksLayout.back(); } 796 797 inline iterator_range<order_iterator> layout() { 798 return iterator_range<order_iterator>(BasicBlocksLayout.begin(), 799 BasicBlocksLayout.end()); 800 } 801 802 inline iterator_range<const_order_iterator> layout() const { 803 return iterator_range<const_order_iterator>(BasicBlocksLayout.begin(), 804 BasicBlocksLayout.end()); 805 } 806 807 inline iterator_range<reverse_order_iterator> rlayout() { 808 return iterator_range<reverse_order_iterator>(BasicBlocksLayout.rbegin(), 809 BasicBlocksLayout.rend()); 810 } 811 812 inline iterator_range<const_reverse_order_iterator> rlayout() const { 813 return iterator_range<const_reverse_order_iterator>( 814 BasicBlocksLayout.rbegin(), BasicBlocksLayout.rend()); 815 } 816 817 cfi_iterator cie_begin() { return CIEFrameInstructions.begin(); } 818 const_cfi_iterator cie_begin() const { return CIEFrameInstructions.begin(); } 819 cfi_iterator cie_end() { return CIEFrameInstructions.end(); } 820 const_cfi_iterator cie_end() const { return CIEFrameInstructions.end(); } 821 bool cie_empty() const { return CIEFrameInstructions.empty(); } 822 823 inline iterator_range<cfi_iterator> cie() { 824 return iterator_range<cfi_iterator>(cie_begin(), cie_end()); 825 } 826 inline iterator_range<const_cfi_iterator> cie() const { 827 return iterator_range<const_cfi_iterator>(cie_begin(), cie_end()); 828 } 829 830 /// Iterate over all jump tables associated with this function. 831 iterator_range<std::map<uint64_t, JumpTable *>::const_iterator> 832 jumpTables() const { 833 return make_range(JumpTables.begin(), JumpTables.end()); 834 } 835 836 /// Returns the raw binary encoding of this function. 837 ErrorOr<ArrayRef<uint8_t>> getData() const; 838 839 BinaryFunction &updateState(BinaryFunction::State State) { 840 CurrentState = State; 841 return *this; 842 } 843 844 /// Update layout of basic blocks used for output. 845 void updateBasicBlockLayout(BasicBlockOrderType &NewLayout) { 846 BasicBlocksPreviousLayout = BasicBlocksLayout; 847 848 if (NewLayout != BasicBlocksLayout) { 849 ModifiedLayout = true; 850 BasicBlocksLayout.clear(); 851 BasicBlocksLayout.swap(NewLayout); 852 } 853 } 854 855 /// Recompute landing pad information for the function and all its blocks. 856 void recomputeLandingPads(); 857 858 /// Return current basic block layout. 859 const BasicBlockOrderType &getLayout() const { return BasicBlocksLayout; } 860 861 /// Return a list of basic blocks sorted using DFS and update layout indices 862 /// using the same order. Does not modify the current layout. 863 BasicBlockOrderType dfs() const; 864 865 /// Find the loops in the CFG of the function and store information about 866 /// them. 867 void calculateLoopInfo(); 868 869 /// Calculate missed macro-fusion opportunities and update BinaryContext 870 /// stats. 871 void calculateMacroOpFusionStats(); 872 873 /// Returns if loop detection has been run for this function. 874 bool hasLoopInfo() const { return BLI != nullptr; } 875 876 const BinaryLoopInfo &getLoopInfo() { return *BLI.get(); } 877 878 bool isLoopFree() { 879 if (!hasLoopInfo()) 880 calculateLoopInfo(); 881 return BLI->empty(); 882 } 883 884 /// Print loop information about the function. 885 void printLoopInfo(raw_ostream &OS) const; 886 887 /// View CFG in graphviz program 888 void viewGraph() const; 889 890 /// Dump CFG in graphviz format 891 void dumpGraph(raw_ostream &OS) const; 892 893 /// Dump CFG in graphviz format to file. 894 void dumpGraphToFile(std::string Filename) const; 895 896 /// Dump CFG in graphviz format to a file with a filename that is derived 897 /// from the function name and Annotation strings. Useful for dumping the 898 /// CFG after an optimization pass. 899 void dumpGraphForPass(std::string Annotation = "") const; 900 901 /// Return BinaryContext for the function. 902 const BinaryContext &getBinaryContext() const { return BC; } 903 904 /// Return BinaryContext for the function. 905 BinaryContext &getBinaryContext() { return BC; } 906 907 /// Attempt to validate CFG invariants. 908 bool validateCFG() const; 909 910 BinaryBasicBlock *getBasicBlockForLabel(const MCSymbol *Label) { 911 auto I = LabelToBB.find(Label); 912 return I == LabelToBB.end() ? nullptr : I->second; 913 } 914 915 const BinaryBasicBlock *getBasicBlockForLabel(const MCSymbol *Label) const { 916 auto I = LabelToBB.find(Label); 917 return I == LabelToBB.end() ? nullptr : I->second; 918 } 919 920 /// Returns the basic block after the given basic block in the layout or 921 /// nullptr the last basic block is given. 922 const BinaryBasicBlock *getBasicBlockAfter(const BinaryBasicBlock *BB, 923 bool IgnoreSplits = true) const { 924 return const_cast<BinaryFunction *>(this)->getBasicBlockAfter(BB, 925 IgnoreSplits); 926 } 927 928 BinaryBasicBlock *getBasicBlockAfter(const BinaryBasicBlock *BB, 929 bool IgnoreSplits = true) { 930 for (auto I = layout_begin(), E = layout_end(); I != E; ++I) { 931 auto Next = std::next(I); 932 if (*I == BB && Next != E) { 933 return (IgnoreSplits || (*I)->isCold() == (*Next)->isCold()) ? *Next 934 : nullptr; 935 } 936 } 937 return nullptr; 938 } 939 940 /// Retrieve the landing pad BB associated with invoke instruction \p Invoke 941 /// that is in \p BB. Return nullptr if none exists 942 BinaryBasicBlock *getLandingPadBBFor(const BinaryBasicBlock &BB, 943 const MCInst &InvokeInst) const { 944 assert(BC.MIB->isInvoke(InvokeInst) && "must be invoke instruction"); 945 const Optional<MCPlus::MCLandingPad> LP = BC.MIB->getEHInfo(InvokeInst); 946 if (LP && LP->first) { 947 BinaryBasicBlock *LBB = BB.getLandingPad(LP->first); 948 assert(LBB && "Landing pad should be defined"); 949 return LBB; 950 } 951 return nullptr; 952 } 953 954 /// Return instruction at a given offset in the function. Valid before 955 /// CFG is constructed or while instruction offsets are available in CFG. 956 MCInst *getInstructionAtOffset(uint64_t Offset); 957 958 const MCInst *getInstructionAtOffset(uint64_t Offset) const { 959 return const_cast<BinaryFunction *>(this)->getInstructionAtOffset(Offset); 960 } 961 962 /// Return jump table that covers a given \p Address in memory. 963 JumpTable *getJumpTableContainingAddress(uint64_t Address) { 964 auto JTI = JumpTables.upper_bound(Address); 965 if (JTI == JumpTables.begin()) 966 return nullptr; 967 --JTI; 968 if (JTI->first + JTI->second->getSize() > Address) 969 return JTI->second; 970 if (JTI->second->getSize() == 0 && JTI->first == Address) 971 return JTI->second; 972 return nullptr; 973 } 974 975 const JumpTable *getJumpTableContainingAddress(uint64_t Address) const { 976 return const_cast<BinaryFunction *>(this)->getJumpTableContainingAddress( 977 Address); 978 } 979 980 /// Return the name of the function if the function has just one name. 981 /// If the function has multiple names - return one followed 982 /// by "(*#<numnames>)". 983 /// 984 /// We should use getPrintName() for diagnostics and use 985 /// hasName() to match function name against a given string. 986 /// 987 /// NOTE: for disambiguating names of local symbols we use the following 988 /// naming schemes: 989 /// primary: <function>/<id> 990 /// alternative: <function>/<file>/<id2> 991 std::string getPrintName() const { 992 const size_t NumNames = Symbols.size() + Aliases.size(); 993 return NumNames == 1 994 ? getOneName().str() 995 : (getOneName().str() + "(*" + std::to_string(NumNames) + ")"); 996 } 997 998 /// The function may have many names. For that reason, we avoid having 999 /// getName() method as most of the time the user needs a different 1000 /// interface, such as forEachName(), hasName(), hasNameRegex(), etc. 1001 /// In some cases though, we need just a name uniquely identifying 1002 /// the function, and that's what this method is for. 1003 StringRef getOneName() const { return Symbols[0]->getName(); } 1004 1005 /// Return the name of the function as getPrintName(), but also trying 1006 /// to demangle it. 1007 std::string getDemangledName() const; 1008 1009 /// Call \p Callback for every name of this function as long as the Callback 1010 /// returns false. Stop if Callback returns true or all names have been used. 1011 /// Return the name for which the Callback returned true if any. 1012 template <typename FType> 1013 Optional<StringRef> forEachName(FType Callback) const { 1014 for (MCSymbol *Symbol : Symbols) 1015 if (Callback(Symbol->getName())) 1016 return Symbol->getName(); 1017 1018 for (const std::string &Name : Aliases) 1019 if (Callback(StringRef(Name))) 1020 return StringRef(Name); 1021 1022 return NoneType(); 1023 } 1024 1025 /// Check if (possibly one out of many) function name matches the given 1026 /// string. Use this member function instead of direct name comparison. 1027 bool hasName(const std::string &FunctionName) const { 1028 auto Res = 1029 forEachName([&](StringRef Name) { return Name == FunctionName; }); 1030 return Res.hasValue(); 1031 } 1032 1033 /// Check if any of function names matches the given regex. 1034 Optional<StringRef> hasNameRegex(const StringRef NameRegex) const; 1035 1036 /// Check if any of restored function names matches the given regex. 1037 /// Restored name means stripping BOLT-added suffixes like "/1", 1038 Optional<StringRef> hasRestoredNameRegex(const StringRef NameRegex) const; 1039 1040 /// Return a vector of all possible names for the function. 1041 const std::vector<StringRef> getNames() const { 1042 std::vector<StringRef> AllNames; 1043 forEachName([&AllNames](StringRef Name) { 1044 AllNames.push_back(Name); 1045 return false; 1046 }); 1047 1048 return AllNames; 1049 } 1050 1051 /// Return a state the function is in (see BinaryFunction::State definition 1052 /// for description). 1053 State getState() const { return CurrentState; } 1054 1055 /// Return true if function has a control flow graph available. 1056 bool hasCFG() const { 1057 return getState() == State::CFG || getState() == State::CFG_Finalized || 1058 getState() == State::EmittedCFG; 1059 } 1060 1061 /// Return true if the function state implies that it includes instructions. 1062 bool hasInstructions() const { 1063 return getState() == State::Disassembled || hasCFG(); 1064 } 1065 1066 bool isEmitted() const { 1067 return getState() == State::EmittedCFG || getState() == State::Emitted; 1068 } 1069 1070 /// Return the section in the input binary this function originated from or 1071 /// nullptr if the function did not originate from the file. 1072 BinarySection *getOriginSection() const { return OriginSection; } 1073 1074 void setOriginSection(BinarySection *Section) { OriginSection = Section; } 1075 1076 /// Return true if the function did not originate from the primary input file. 1077 bool isInjected() const { return IsInjected; } 1078 1079 /// Return original address of the function (or offset from base for PIC). 1080 uint64_t getAddress() const { return Address; } 1081 1082 uint64_t getOutputAddress() const { return OutputAddress; } 1083 1084 uint64_t getOutputSize() const { return OutputSize; } 1085 1086 /// Does this function have a valid streaming order index? 1087 bool hasValidIndex() const { return Index != -1U; } 1088 1089 /// Get the streaming order index for this function. 1090 uint32_t getIndex() const { return Index; } 1091 1092 /// Set the streaming order index for this function. 1093 void setIndex(uint32_t Idx) { 1094 assert(!hasValidIndex()); 1095 Index = Idx; 1096 } 1097 1098 /// Return offset of the function body in the binary file. 1099 uint64_t getFileOffset() const { return FileOffset; } 1100 1101 /// Return (original) byte size of the function. 1102 uint64_t getSize() const { return Size; } 1103 1104 /// Return the maximum size the body of the function could have. 1105 uint64_t getMaxSize() const { return MaxSize; } 1106 1107 /// Return the number of emitted instructions for this function. 1108 uint32_t getNumNonPseudos() const { 1109 uint32_t N = 0; 1110 for (BinaryBasicBlock *const &BB : layout()) 1111 N += BB->getNumNonPseudos(); 1112 return N; 1113 } 1114 1115 /// Return MC symbol associated with the function. 1116 /// All references to the function should use this symbol. 1117 MCSymbol *getSymbol() { return Symbols[0]; } 1118 1119 /// Return MC symbol associated with the function (const version). 1120 /// All references to the function should use this symbol. 1121 const MCSymbol *getSymbol() const { return Symbols[0]; } 1122 1123 /// Return a list of symbols associated with the main entry of the function. 1124 SymbolListTy &getSymbols() { return Symbols; } 1125 const SymbolListTy &getSymbols() const { return Symbols; } 1126 1127 /// If a local symbol \p BBLabel corresponds to a basic block that is a 1128 /// secondary entry point into the function, then return a global symbol 1129 /// that represents the secondary entry point. Otherwise return nullptr. 1130 MCSymbol *getSecondaryEntryPointSymbol(const MCSymbol *BBLabel) const { 1131 auto I = SecondaryEntryPoints.find(BBLabel); 1132 if (I == SecondaryEntryPoints.end()) 1133 return nullptr; 1134 1135 return I->second; 1136 } 1137 1138 /// If the basic block serves as a secondary entry point to the function, 1139 /// return a global symbol representing the entry. Otherwise return nullptr. 1140 MCSymbol *getSecondaryEntryPointSymbol(const BinaryBasicBlock &BB) const { 1141 return getSecondaryEntryPointSymbol(BB.getLabel()); 1142 } 1143 1144 /// Return true if the basic block is an entry point into the function 1145 /// (either primary or secondary). 1146 bool isEntryPoint(const BinaryBasicBlock &BB) const { 1147 if (&BB == BasicBlocks.front()) 1148 return true; 1149 return getSecondaryEntryPointSymbol(BB); 1150 } 1151 1152 /// Return MC symbol corresponding to an enumerated entry for multiple-entry 1153 /// functions. 1154 MCSymbol *getSymbolForEntryID(uint64_t EntryNum); 1155 const MCSymbol *getSymbolForEntryID(uint64_t EntryNum) const { 1156 return const_cast<BinaryFunction *>(this)->getSymbolForEntryID(EntryNum); 1157 } 1158 1159 using EntryPointCallbackTy = function_ref<bool(uint64_t, const MCSymbol *)>; 1160 1161 /// Invoke \p Callback function for every entry point in the function starting 1162 /// with the main entry and using entries in the ascending address order. 1163 /// Stop calling the function after false is returned by the callback. 1164 /// 1165 /// Pass an offset of the entry point in the input binary and a corresponding 1166 /// global symbol to the callback function. 1167 /// 1168 /// Return true of all callbacks returned true, false otherwise. 1169 bool forEachEntryPoint(EntryPointCallbackTy Callback) const; 1170 1171 MCSymbol *getColdSymbol() { 1172 if (ColdSymbol) 1173 return ColdSymbol; 1174 1175 ColdSymbol = BC.Ctx->getOrCreateSymbol( 1176 NameResolver::append(getSymbol()->getName(), ".cold.0")); 1177 1178 return ColdSymbol; 1179 } 1180 1181 /// Return MC symbol associated with the end of the function. 1182 MCSymbol *getFunctionEndLabel() const { 1183 assert(BC.Ctx && "cannot be called with empty context"); 1184 if (!FunctionEndLabel) { 1185 std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex); 1186 FunctionEndLabel = BC.Ctx->createNamedTempSymbol("func_end"); 1187 } 1188 return FunctionEndLabel; 1189 } 1190 1191 /// Return MC symbol associated with the end of the cold part of the function. 1192 MCSymbol *getFunctionColdEndLabel() const { 1193 if (!FunctionColdEndLabel) { 1194 std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex); 1195 FunctionColdEndLabel = BC.Ctx->createNamedTempSymbol("func_cold_end"); 1196 } 1197 return FunctionColdEndLabel; 1198 } 1199 1200 /// Return a label used to identify where the constant island was emitted 1201 /// (AArch only). This is used to update the symbol table accordingly, 1202 /// emitting data marker symbols as required by the ABI. 1203 MCSymbol *getFunctionConstantIslandLabel() const { 1204 assert(Islands && "function expected to have constant islands"); 1205 1206 if (!Islands->FunctionConstantIslandLabel) { 1207 Islands->FunctionConstantIslandLabel = 1208 BC.Ctx->createNamedTempSymbol("func_const_island"); 1209 } 1210 return Islands->FunctionConstantIslandLabel; 1211 } 1212 1213 MCSymbol *getFunctionColdConstantIslandLabel() const { 1214 assert(Islands && "function expected to have constant islands"); 1215 1216 if (!Islands->FunctionColdConstantIslandLabel) { 1217 Islands->FunctionColdConstantIslandLabel = 1218 BC.Ctx->createNamedTempSymbol("func_cold_const_island"); 1219 } 1220 return Islands->FunctionColdConstantIslandLabel; 1221 } 1222 1223 /// Return true if this is a function representing a PLT entry. 1224 bool isPLTFunction() const { return PLTSymbol != nullptr; } 1225 1226 /// Return PLT function reference symbol for PLT functions and nullptr for 1227 /// non-PLT functions. 1228 const MCSymbol *getPLTSymbol() const { return PLTSymbol; } 1229 1230 /// Set function PLT reference symbol for PLT functions. 1231 void setPLTSymbol(const MCSymbol *Symbol) { 1232 assert(Size == 0 && "function size should be 0 for PLT functions"); 1233 PLTSymbol = Symbol; 1234 IsPseudo = true; 1235 } 1236 1237 /// Update output values of the function based on the final \p Layout. 1238 void updateOutputValues(const MCAsmLayout &Layout); 1239 1240 /// Return mapping of input to output addresses. Most users should call 1241 /// translateInputToOutputAddress() for address translation. 1242 InputOffsetToAddressMapTy &getInputOffsetToAddressMap() { 1243 assert(isEmitted() && "cannot use address mapping before code emission"); 1244 return InputOffsetToAddressMap; 1245 } 1246 1247 void addRelocationAArch64(uint64_t Offset, MCSymbol *Symbol, uint64_t RelType, 1248 uint64_t Addend, uint64_t Value, bool IsCI) { 1249 std::map<uint64_t, Relocation> &Rels = 1250 (IsCI) ? Islands->Relocations : Relocations; 1251 switch (RelType) { 1252 case ELF::R_AARCH64_ABS64: 1253 case ELF::R_AARCH64_ABS32: 1254 case ELF::R_AARCH64_ABS16: 1255 case ELF::R_AARCH64_ADD_ABS_LO12_NC: 1256 case ELF::R_AARCH64_ADR_GOT_PAGE: 1257 case ELF::R_AARCH64_ADR_PREL_LO21: 1258 case ELF::R_AARCH64_ADR_PREL_PG_HI21: 1259 case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: 1260 case ELF::R_AARCH64_LD64_GOT_LO12_NC: 1261 case ELF::R_AARCH64_LDST8_ABS_LO12_NC: 1262 case ELF::R_AARCH64_LDST16_ABS_LO12_NC: 1263 case ELF::R_AARCH64_LDST32_ABS_LO12_NC: 1264 case ELF::R_AARCH64_LDST64_ABS_LO12_NC: 1265 case ELF::R_AARCH64_LDST128_ABS_LO12_NC: 1266 case ELF::R_AARCH64_TLSDESC_ADD_LO12: 1267 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 1268 case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 1269 case ELF::R_AARCH64_TLSDESC_LD64_LO12: 1270 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 1271 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 1272 case ELF::R_AARCH64_MOVW_UABS_G0: 1273 case ELF::R_AARCH64_MOVW_UABS_G0_NC: 1274 case ELF::R_AARCH64_MOVW_UABS_G1: 1275 case ELF::R_AARCH64_MOVW_UABS_G1_NC: 1276 case ELF::R_AARCH64_MOVW_UABS_G2: 1277 case ELF::R_AARCH64_MOVW_UABS_G2_NC: 1278 case ELF::R_AARCH64_MOVW_UABS_G3: 1279 Rels[Offset] = Relocation{Offset, Symbol, RelType, Addend, Value}; 1280 return; 1281 case ELF::R_AARCH64_CALL26: 1282 case ELF::R_AARCH64_JUMP26: 1283 case ELF::R_AARCH64_TSTBR14: 1284 case ELF::R_AARCH64_CONDBR19: 1285 case ELF::R_AARCH64_TLSDESC_CALL: 1286 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 1287 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 1288 return; 1289 default: 1290 llvm_unreachable("Unexpected AArch64 relocation type in code"); 1291 } 1292 } 1293 1294 void addRelocationX86(uint64_t Offset, MCSymbol *Symbol, uint64_t RelType, 1295 uint64_t Addend, uint64_t Value) { 1296 switch (RelType) { 1297 case ELF::R_X86_64_8: 1298 case ELF::R_X86_64_16: 1299 case ELF::R_X86_64_32: 1300 case ELF::R_X86_64_32S: 1301 case ELF::R_X86_64_64: 1302 case ELF::R_X86_64_PC8: 1303 case ELF::R_X86_64_PC32: 1304 case ELF::R_X86_64_PC64: 1305 Relocations[Offset] = Relocation{Offset, Symbol, RelType, Addend, Value}; 1306 return; 1307 case ELF::R_X86_64_PLT32: 1308 case ELF::R_X86_64_GOTPCRELX: 1309 case ELF::R_X86_64_REX_GOTPCRELX: 1310 case ELF::R_X86_64_GOTPCREL: 1311 case ELF::R_X86_64_TPOFF32: 1312 case ELF::R_X86_64_GOTTPOFF: 1313 return; 1314 default: 1315 llvm_unreachable("Unexpected x86 relocation type in code"); 1316 } 1317 } 1318 1319 /// Register relocation type \p RelType at a given \p Address in the function 1320 /// against \p Symbol. 1321 /// Assert if the \p Address is not inside this function. 1322 void addRelocation(uint64_t Address, MCSymbol *Symbol, uint64_t RelType, 1323 uint64_t Addend, uint64_t Value) { 1324 assert(Address >= getAddress() && Address < getAddress() + getMaxSize() && 1325 "address is outside of the function"); 1326 uint64_t Offset = Address - getAddress(); 1327 if (BC.isAArch64()) { 1328 return addRelocationAArch64(Offset, Symbol, RelType, Addend, Value, 1329 isInConstantIsland(Address)); 1330 } 1331 1332 return addRelocationX86(Offset, Symbol, RelType, Addend, Value); 1333 } 1334 1335 /// Return the name of the section this function originated from. 1336 Optional<StringRef> getOriginSectionName() const { 1337 if (!OriginSection) 1338 return NoneType(); 1339 return OriginSection->getName(); 1340 } 1341 1342 /// Return internal section name for this function. 1343 StringRef getCodeSectionName() const { return StringRef(CodeSectionName); } 1344 1345 /// Assign a code section name to the function. 1346 void setCodeSectionName(StringRef Name) { 1347 CodeSectionName = std::string(Name); 1348 } 1349 1350 /// Get output code section. 1351 ErrorOr<BinarySection &> getCodeSection() const { 1352 return BC.getUniqueSectionByName(getCodeSectionName()); 1353 } 1354 1355 /// Return cold code section name for the function. 1356 StringRef getColdCodeSectionName() const { 1357 return StringRef(ColdCodeSectionName); 1358 } 1359 1360 /// Assign a section name for the cold part of the function. 1361 void setColdCodeSectionName(StringRef Name) { 1362 ColdCodeSectionName = std::string(Name); 1363 } 1364 1365 /// Get output code section for cold code of this function. 1366 ErrorOr<BinarySection &> getColdCodeSection() const { 1367 return BC.getUniqueSectionByName(getColdCodeSectionName()); 1368 } 1369 1370 /// Return true iif the function will halt execution on entry. 1371 bool trapsOnEntry() const { return TrapsOnEntry; } 1372 1373 /// Make the function always trap on entry. Other than the trap instruction, 1374 /// the function body will be empty. 1375 void setTrapOnEntry(); 1376 1377 /// Return true if the function could be correctly processed. 1378 bool isSimple() const { return IsSimple; } 1379 1380 /// Return true if the function should be ignored for optimization purposes. 1381 bool isIgnored() const { return IsIgnored; } 1382 1383 /// Return true if the function should not be disassembled, emitted, or 1384 /// otherwise processed. 1385 bool isPseudo() const { return IsPseudo; } 1386 1387 /// Return true if the function contains a jump table with entries pointing 1388 /// to split fragments. 1389 bool hasSplitJumpTable() const { return HasSplitJumpTable; } 1390 1391 /// Return true if all CFG edges have local successors. 1392 bool hasCanonicalCFG() const { return HasCanonicalCFG; } 1393 1394 /// Return true if the original function code has all necessary relocations 1395 /// to track addresses of functions emitted to new locations. 1396 bool hasExternalRefRelocations() const { return HasExternalRefRelocations; } 1397 1398 /// Return true if the function has instruction(s) with unknown control flow. 1399 bool hasUnknownControlFlow() const { return HasUnknownControlFlow; } 1400 1401 /// Return true if the function body is non-contiguous. 1402 bool isSplit() const { 1403 return isSimple() && layout_size() && 1404 layout_front()->isCold() != layout_back()->isCold(); 1405 } 1406 1407 bool shouldPreserveNops() const { return PreserveNops; } 1408 1409 /// Return true if the function has exception handling tables. 1410 bool hasEHRanges() const { return HasEHRanges; } 1411 1412 /// Return true if the function uses DW_CFA_GNU_args_size CFIs. 1413 bool usesGnuArgsSize() const { return UsesGnuArgsSize; } 1414 1415 /// Return true if the function has more than one entry point. 1416 bool isMultiEntry() const { return !SecondaryEntryPoints.empty(); } 1417 1418 /// Return true if the function might have a profile available externally, 1419 /// but not yet populated into the function. 1420 bool hasProfileAvailable() const { return HasProfileAvailable; } 1421 1422 bool hasMemoryProfile() const { return HasMemoryProfile; } 1423 1424 /// Return true if the body of the function was merged into another function. 1425 bool isFolded() const { return FoldedIntoFunction != nullptr; } 1426 1427 /// If this function was folded, return the function it was folded into. 1428 BinaryFunction *getFoldedIntoFunction() const { return FoldedIntoFunction; } 1429 1430 /// Return true if the function uses jump tables. 1431 bool hasJumpTables() const { return !JumpTables.empty(); } 1432 1433 /// Return true if the function has SDT marker 1434 bool hasSDTMarker() const { return HasSDTMarker; } 1435 1436 /// Return true if the function has Pseudo Probe 1437 bool hasPseudoProbe() const { return HasPseudoProbe; } 1438 1439 /// Return true if the original entry point was patched. 1440 bool isPatched() const { return IsPatched; } 1441 1442 const JumpTable *getJumpTable(const MCInst &Inst) const { 1443 const uint64_t Address = BC.MIB->getJumpTable(Inst); 1444 return getJumpTableContainingAddress(Address); 1445 } 1446 1447 JumpTable *getJumpTable(const MCInst &Inst) { 1448 const uint64_t Address = BC.MIB->getJumpTable(Inst); 1449 return getJumpTableContainingAddress(Address); 1450 } 1451 1452 const MCSymbol *getPersonalityFunction() const { return PersonalityFunction; } 1453 1454 uint8_t getPersonalityEncoding() const { return PersonalityEncoding; } 1455 1456 const CallSitesType &getCallSites() const { return CallSites; } 1457 1458 const CallSitesType &getColdCallSites() const { return ColdCallSites; } 1459 1460 const ArrayRef<uint8_t> getLSDAActionTable() const { return LSDAActionTable; } 1461 1462 const LSDATypeTableTy &getLSDATypeTable() const { return LSDATypeTable; } 1463 1464 const LSDATypeTableTy &getLSDATypeAddressTable() const { 1465 return LSDATypeAddressTable; 1466 } 1467 1468 const ArrayRef<uint8_t> getLSDATypeIndexTable() const { 1469 return LSDATypeIndexTable; 1470 } 1471 1472 const LabelsMapType &getLabels() const { return Labels; } 1473 1474 IslandInfo &getIslandInfo() { 1475 assert(Islands && "function expected to have constant islands"); 1476 return *Islands; 1477 } 1478 1479 const IslandInfo &getIslandInfo() const { 1480 assert(Islands && "function expected to have constant islands"); 1481 return *Islands; 1482 } 1483 1484 /// Return true if the function has CFI instructions 1485 bool hasCFI() const { 1486 return !FrameInstructions.empty() || !CIEFrameInstructions.empty(); 1487 } 1488 1489 /// Return unique number associated with the function. 1490 uint64_t getFunctionNumber() const { return FunctionNumber; } 1491 1492 /// Return true if the given address \p PC is inside the function body. 1493 bool containsAddress(uint64_t PC, bool UseMaxSize = false) const { 1494 if (UseMaxSize) 1495 return Address <= PC && PC < Address + MaxSize; 1496 return Address <= PC && PC < Address + Size; 1497 } 1498 1499 /// Create a basic block at a given \p Offset in the 1500 /// function. 1501 /// If \p DeriveAlignment is true, set the alignment of the block based 1502 /// on the alignment of the existing offset. 1503 /// The new block is not inserted into the CFG. The client must 1504 /// use insertBasicBlocks to add any new blocks to the CFG. 1505 std::unique_ptr<BinaryBasicBlock> 1506 createBasicBlock(uint64_t Offset, MCSymbol *Label = nullptr, 1507 bool DeriveAlignment = false) { 1508 assert(BC.Ctx && "cannot be called with empty context"); 1509 if (!Label) { 1510 std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex); 1511 Label = BC.Ctx->createNamedTempSymbol("BB"); 1512 } 1513 auto BB = std::unique_ptr<BinaryBasicBlock>( 1514 new BinaryBasicBlock(this, Label, Offset)); 1515 1516 if (DeriveAlignment) { 1517 uint64_t DerivedAlignment = Offset & (1 + ~Offset); 1518 BB->setAlignment(std::min(DerivedAlignment, uint64_t(32))); 1519 } 1520 1521 LabelToBB[Label] = BB.get(); 1522 1523 return BB; 1524 } 1525 1526 /// Create a basic block at a given \p Offset in the 1527 /// function and append it to the end of list of blocks. 1528 /// If \p DeriveAlignment is true, set the alignment of the block based 1529 /// on the alignment of the existing offset. 1530 /// 1531 /// Returns NULL if basic block already exists at the \p Offset. 1532 BinaryBasicBlock *addBasicBlock(uint64_t Offset, MCSymbol *Label = nullptr, 1533 bool DeriveAlignment = false) { 1534 assert((CurrentState == State::CFG || !getBasicBlockAtOffset(Offset)) && 1535 "basic block already exists in pre-CFG state"); 1536 1537 if (!Label) { 1538 std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex); 1539 Label = BC.Ctx->createNamedTempSymbol("BB"); 1540 } 1541 std::unique_ptr<BinaryBasicBlock> BBPtr = 1542 createBasicBlock(Offset, Label, DeriveAlignment); 1543 BasicBlocks.emplace_back(BBPtr.release()); 1544 1545 BinaryBasicBlock *BB = BasicBlocks.back(); 1546 BB->setIndex(BasicBlocks.size() - 1); 1547 1548 if (CurrentState == State::Disassembled) { 1549 BasicBlockOffsets.emplace_back(Offset, BB); 1550 } else if (CurrentState == State::CFG) { 1551 BB->setLayoutIndex(layout_size()); 1552 BasicBlocksLayout.emplace_back(BB); 1553 } 1554 1555 assert(CurrentState == State::CFG || 1556 (std::is_sorted(BasicBlockOffsets.begin(), BasicBlockOffsets.end(), 1557 CompareBasicBlockOffsets()) && 1558 std::is_sorted(begin(), end()))); 1559 1560 return BB; 1561 } 1562 1563 /// Add basic block \BB as an entry point to the function. Return global 1564 /// symbol associated with the entry. 1565 MCSymbol *addEntryPoint(const BinaryBasicBlock &BB); 1566 1567 /// Mark all blocks that are unreachable from a root (entry point 1568 /// or landing pad) as invalid. 1569 void markUnreachableBlocks(); 1570 1571 /// Rebuilds BBs layout, ignoring dead BBs. Returns the number of removed 1572 /// BBs and the removed number of bytes of code. 1573 std::pair<unsigned, uint64_t> eraseInvalidBBs(); 1574 1575 /// Get the relative order between two basic blocks in the original 1576 /// layout. The result is > 0 if B occurs before A and < 0 if B 1577 /// occurs after A. If A and B are the same block, the result is 0. 1578 signed getOriginalLayoutRelativeOrder(const BinaryBasicBlock *A, 1579 const BinaryBasicBlock *B) const { 1580 return getIndex(A) - getIndex(B); 1581 } 1582 1583 /// Insert the BBs contained in NewBBs into the basic blocks for this 1584 /// function. Update the associated state of all blocks as needed, i.e. 1585 /// BB offsets and BB indices. The new BBs are inserted after Start. 1586 /// This operation could affect fallthrough branches for Start. 1587 /// 1588 void 1589 insertBasicBlocks(BinaryBasicBlock *Start, 1590 std::vector<std::unique_ptr<BinaryBasicBlock>> &&NewBBs, 1591 const bool UpdateLayout = true, 1592 const bool UpdateCFIState = true, 1593 const bool RecomputeLandingPads = true); 1594 1595 iterator insertBasicBlocks( 1596 iterator StartBB, std::vector<std::unique_ptr<BinaryBasicBlock>> &&NewBBs, 1597 const bool UpdateLayout = true, const bool UpdateCFIState = true, 1598 const bool RecomputeLandingPads = true); 1599 1600 /// Update the basic block layout for this function. The BBs from 1601 /// [Start->Index, Start->Index + NumNewBlocks) are inserted into the 1602 /// layout after the BB indicated by Start. 1603 void updateLayout(BinaryBasicBlock *Start, const unsigned NumNewBlocks); 1604 1605 /// Make sure basic blocks' indices match the current layout. 1606 void updateLayoutIndices() const { 1607 unsigned Index = 0; 1608 for (BinaryBasicBlock *BB : layout()) 1609 BB->setLayoutIndex(Index++); 1610 } 1611 1612 /// Recompute the CFI state for NumNewBlocks following Start after inserting 1613 /// new blocks into the CFG. This must be called after updateLayout. 1614 void updateCFIState(BinaryBasicBlock *Start, const unsigned NumNewBlocks); 1615 1616 /// Return true if we detected ambiguous jump tables in this function, which 1617 /// happen when one JT is used in more than one indirect jumps. This precludes 1618 /// us from splitting edges for this JT unless we duplicate the JT (see 1619 /// disambiguateJumpTables). 1620 bool checkForAmbiguousJumpTables(); 1621 1622 /// Detect when two distinct indirect jumps are using the same jump table and 1623 /// duplicate it, allocating a separate JT for each indirect branch. This is 1624 /// necessary for code transformations on the CFG that change an edge induced 1625 /// by an indirect branch, e.g.: instrumentation or shrink wrapping. However, 1626 /// this is only possible if we are not updating jump tables in place, but are 1627 /// writing it to a new location (moving them). 1628 void disambiguateJumpTables(MCPlusBuilder::AllocatorIdTy AllocId); 1629 1630 /// Change \p OrigDest to \p NewDest in the jump table used at the end of 1631 /// \p BB. Returns false if \p OrigDest couldn't be find as a valid target 1632 /// and no replacement took place. 1633 bool replaceJumpTableEntryIn(BinaryBasicBlock *BB, BinaryBasicBlock *OldDest, 1634 BinaryBasicBlock *NewDest); 1635 1636 /// Split the CFG edge <From, To> by inserting an intermediate basic block. 1637 /// Returns a pointer to this new intermediate basic block. BB "From" will be 1638 /// updated to jump to the intermediate block, which in turn will have an 1639 /// unconditional branch to BB "To". 1640 /// User needs to manually call fixBranches(). This function only creates the 1641 /// correct CFG edges. 1642 BinaryBasicBlock *splitEdge(BinaryBasicBlock *From, BinaryBasicBlock *To); 1643 1644 /// We may have built an overly conservative CFG for functions with calls 1645 /// to functions that the compiler knows will never return. In this case, 1646 /// clear all successors from these blocks. 1647 void deleteConservativeEdges(); 1648 1649 /// Determine direction of the branch based on the current layout. 1650 /// Callee is responsible of updating basic block indices prior to using 1651 /// this function (e.g. by calling BinaryFunction::updateLayoutIndices()). 1652 static bool isForwardBranch(const BinaryBasicBlock *From, 1653 const BinaryBasicBlock *To) { 1654 assert(From->getFunction() == To->getFunction() && 1655 "basic blocks should be in the same function"); 1656 return To->getLayoutIndex() > From->getLayoutIndex(); 1657 } 1658 1659 /// Determine direction of the call to callee symbol relative to the start 1660 /// of this function. 1661 /// Note: this doesn't take function splitting into account. 1662 bool isForwardCall(const MCSymbol *CalleeSymbol) const; 1663 1664 /// Dump function information to debug output. If \p PrintInstructions 1665 /// is true - include instruction disassembly. 1666 void dump(bool PrintInstructions = true) const; 1667 1668 /// Print function information to the \p OS stream. 1669 void print(raw_ostream &OS, std::string Annotation = "", 1670 bool PrintInstructions = true) const; 1671 1672 /// Print all relocations between \p Offset and \p Offset + \p Size in 1673 /// this function. 1674 void printRelocations(raw_ostream &OS, uint64_t Offset, uint64_t Size) const; 1675 1676 /// Return true if function has a profile, even if the profile does not 1677 /// match CFG 100%. 1678 bool hasProfile() const { return ExecutionCount != COUNT_NO_PROFILE; } 1679 1680 /// Return true if function profile is present and accurate. 1681 bool hasValidProfile() const { 1682 return ExecutionCount != COUNT_NO_PROFILE && ProfileMatchRatio == 1.0f; 1683 } 1684 1685 /// Mark this function as having a valid profile. 1686 void markProfiled(uint16_t Flags) { 1687 if (ExecutionCount == COUNT_NO_PROFILE) 1688 ExecutionCount = 0; 1689 ProfileFlags = Flags; 1690 ProfileMatchRatio = 1.0f; 1691 } 1692 1693 /// Return flags describing a profile for this function. 1694 uint16_t getProfileFlags() const { return ProfileFlags; } 1695 1696 void addCFIInstruction(uint64_t Offset, MCCFIInstruction &&Inst) { 1697 assert(!Instructions.empty()); 1698 1699 // Fix CFI instructions skipping NOPs. We need to fix this because changing 1700 // CFI state after a NOP, besides being wrong and inaccurate, makes it 1701 // harder for us to recover this information, since we can create empty BBs 1702 // with NOPs and then reorder it away. 1703 // We fix this by moving the CFI instruction just before any NOPs. 1704 auto I = Instructions.lower_bound(Offset); 1705 if (Offset == getSize()) { 1706 assert(I == Instructions.end() && "unexpected iterator value"); 1707 // Sometimes compiler issues restore_state after all instructions 1708 // in the function (even after nop). 1709 --I; 1710 Offset = I->first; 1711 } 1712 assert(I->first == Offset && "CFI pointing to unknown instruction"); 1713 if (I == Instructions.begin()) { 1714 CIEFrameInstructions.emplace_back(std::forward<MCCFIInstruction>(Inst)); 1715 return; 1716 } 1717 1718 --I; 1719 while (I != Instructions.begin() && BC.MIB->isNoop(I->second)) { 1720 Offset = I->first; 1721 --I; 1722 } 1723 OffsetToCFI.emplace(Offset, FrameInstructions.size()); 1724 FrameInstructions.emplace_back(std::forward<MCCFIInstruction>(Inst)); 1725 return; 1726 } 1727 1728 BinaryBasicBlock::iterator addCFIInstruction(BinaryBasicBlock *BB, 1729 BinaryBasicBlock::iterator Pos, 1730 MCCFIInstruction &&Inst) { 1731 size_t Idx = FrameInstructions.size(); 1732 FrameInstructions.emplace_back(std::forward<MCCFIInstruction>(Inst)); 1733 return addCFIPseudo(BB, Pos, Idx); 1734 } 1735 1736 /// Insert a CFI pseudo instruction in a basic block. This pseudo instruction 1737 /// is a placeholder that refers to a real MCCFIInstruction object kept by 1738 /// this function that will be emitted at that position. 1739 BinaryBasicBlock::iterator addCFIPseudo(BinaryBasicBlock *BB, 1740 BinaryBasicBlock::iterator Pos, 1741 uint32_t Offset) { 1742 MCInst CFIPseudo; 1743 BC.MIB->createCFI(CFIPseudo, Offset); 1744 return BB->insertPseudoInstr(Pos, CFIPseudo); 1745 } 1746 1747 /// Retrieve the MCCFIInstruction object associated with a CFI pseudo. 1748 const MCCFIInstruction *getCFIFor(const MCInst &Instr) const { 1749 if (!BC.MIB->isCFI(Instr)) 1750 return nullptr; 1751 uint32_t Offset = Instr.getOperand(0).getImm(); 1752 assert(Offset < FrameInstructions.size() && "Invalid CFI offset"); 1753 return &FrameInstructions[Offset]; 1754 } 1755 1756 void setCFIFor(const MCInst &Instr, MCCFIInstruction &&CFIInst) { 1757 assert(BC.MIB->isCFI(Instr) && 1758 "attempting to change CFI in a non-CFI inst"); 1759 uint32_t Offset = Instr.getOperand(0).getImm(); 1760 assert(Offset < FrameInstructions.size() && "Invalid CFI offset"); 1761 FrameInstructions[Offset] = std::move(CFIInst); 1762 } 1763 1764 void mutateCFIRegisterFor(const MCInst &Instr, MCPhysReg NewReg); 1765 1766 const MCCFIInstruction *mutateCFIOffsetFor(const MCInst &Instr, 1767 int64_t NewOffset); 1768 1769 BinaryFunction &setFileOffset(uint64_t Offset) { 1770 FileOffset = Offset; 1771 return *this; 1772 } 1773 1774 BinaryFunction &setSize(uint64_t S) { 1775 Size = S; 1776 return *this; 1777 } 1778 1779 BinaryFunction &setMaxSize(uint64_t Size) { 1780 MaxSize = Size; 1781 return *this; 1782 } 1783 1784 BinaryFunction &setOutputAddress(uint64_t Address) { 1785 OutputAddress = Address; 1786 return *this; 1787 } 1788 1789 BinaryFunction &setOutputSize(uint64_t Size) { 1790 OutputSize = Size; 1791 return *this; 1792 } 1793 1794 BinaryFunction &setSimple(bool Simple) { 1795 IsSimple = Simple; 1796 return *this; 1797 } 1798 1799 void setPseudo(bool Pseudo) { IsPseudo = Pseudo; } 1800 1801 BinaryFunction &setUsesGnuArgsSize(bool Uses = true) { 1802 UsesGnuArgsSize = Uses; 1803 return *this; 1804 } 1805 1806 BinaryFunction &setHasProfileAvailable(bool V = true) { 1807 HasProfileAvailable = V; 1808 return *this; 1809 } 1810 1811 /// Mark function that should not be emitted. 1812 void setIgnored(); 1813 1814 void setIsPatched(bool V) { IsPatched = V; } 1815 1816 void setHasSplitJumpTable(bool V) { HasSplitJumpTable = V; } 1817 1818 void setHasCanonicalCFG(bool V) { HasCanonicalCFG = V; } 1819 1820 void setFolded(BinaryFunction *BF) { FoldedIntoFunction = BF; } 1821 1822 BinaryFunction &setPersonalityFunction(uint64_t Addr) { 1823 assert(!PersonalityFunction && "can't set personality function twice"); 1824 PersonalityFunction = BC.getOrCreateGlobalSymbol(Addr, "FUNCat"); 1825 return *this; 1826 } 1827 1828 BinaryFunction &setPersonalityEncoding(uint8_t Encoding) { 1829 PersonalityEncoding = Encoding; 1830 return *this; 1831 } 1832 1833 BinaryFunction &setAlignment(uint16_t Align) { 1834 Alignment = Align; 1835 return *this; 1836 } 1837 1838 uint16_t getAlignment() const { return Alignment; } 1839 1840 BinaryFunction &setMaxAlignmentBytes(uint16_t MaxAlignBytes) { 1841 MaxAlignmentBytes = MaxAlignBytes; 1842 return *this; 1843 } 1844 1845 uint16_t getMaxAlignmentBytes() const { return MaxAlignmentBytes; } 1846 1847 BinaryFunction &setMaxColdAlignmentBytes(uint16_t MaxAlignBytes) { 1848 MaxColdAlignmentBytes = MaxAlignBytes; 1849 return *this; 1850 } 1851 1852 uint16_t getMaxColdAlignmentBytes() const { return MaxColdAlignmentBytes; } 1853 1854 BinaryFunction &setImageAddress(uint64_t Address) { 1855 ImageAddress = Address; 1856 return *this; 1857 } 1858 1859 /// Return the address of this function' image in memory. 1860 uint64_t getImageAddress() const { return ImageAddress; } 1861 1862 BinaryFunction &setImageSize(uint64_t Size) { 1863 ImageSize = Size; 1864 return *this; 1865 } 1866 1867 /// Return the size of this function' image in memory. 1868 uint64_t getImageSize() const { return ImageSize; } 1869 1870 /// Return true if the function is a secondary fragment of another function. 1871 bool isFragment() const { return IsFragment; } 1872 1873 /// Returns if the given function is a parent fragment of this function. 1874 bool isParentFragment(BinaryFunction *Parent) const { 1875 return ParentFragments.count(Parent); 1876 } 1877 1878 /// Set the profile data for the number of times the function was called. 1879 BinaryFunction &setExecutionCount(uint64_t Count) { 1880 ExecutionCount = Count; 1881 return *this; 1882 } 1883 1884 /// Adjust execution count for the function by a given \p Count. The value 1885 /// \p Count will be subtracted from the current function count. 1886 /// 1887 /// The function will proportionally adjust execution count for all 1888 /// basic blocks and edges in the control flow graph. 1889 void adjustExecutionCount(uint64_t Count); 1890 1891 /// Set LSDA address for the function. 1892 BinaryFunction &setLSDAAddress(uint64_t Address) { 1893 LSDAAddress = Address; 1894 return *this; 1895 } 1896 1897 /// Set LSDA symbol for the function. 1898 BinaryFunction &setLSDASymbol(MCSymbol *Symbol) { 1899 LSDASymbol = Symbol; 1900 return *this; 1901 } 1902 1903 /// Return the profile information about the number of times 1904 /// the function was executed. 1905 /// 1906 /// Return COUNT_NO_PROFILE if there's no profile info. 1907 uint64_t getExecutionCount() const { return ExecutionCount; } 1908 1909 /// Return the raw profile information about the number of branch 1910 /// executions corresponding to this function. 1911 uint64_t getRawBranchCount() const { return RawBranchCount; } 1912 1913 /// Return the execution count for functions with known profile. 1914 /// Return 0 if the function has no profile. 1915 uint64_t getKnownExecutionCount() const { 1916 return ExecutionCount == COUNT_NO_PROFILE ? 0 : ExecutionCount; 1917 } 1918 1919 /// Return original LSDA address for the function or NULL. 1920 uint64_t getLSDAAddress() const { return LSDAAddress; } 1921 1922 /// Return symbol pointing to function's LSDA. 1923 MCSymbol *getLSDASymbol() { 1924 if (LSDASymbol) 1925 return LSDASymbol; 1926 if (CallSites.empty()) 1927 return nullptr; 1928 1929 LSDASymbol = BC.Ctx->getOrCreateSymbol( 1930 Twine("GCC_except_table") + Twine::utohexstr(getFunctionNumber())); 1931 1932 return LSDASymbol; 1933 } 1934 1935 /// Return symbol pointing to function's LSDA for the cold part. 1936 MCSymbol *getColdLSDASymbol() { 1937 if (ColdLSDASymbol) 1938 return ColdLSDASymbol; 1939 if (ColdCallSites.empty()) 1940 return nullptr; 1941 1942 ColdLSDASymbol = BC.Ctx->getOrCreateSymbol( 1943 Twine("GCC_cold_except_table") + Twine::utohexstr(getFunctionNumber())); 1944 1945 return ColdLSDASymbol; 1946 } 1947 1948 /// True if the symbol is a mapping symbol used in AArch64 to delimit 1949 /// data inside code section. 1950 bool isDataMarker(const SymbolRef &Symbol, uint64_t SymbolSize) const; 1951 bool isCodeMarker(const SymbolRef &Symbol, uint64_t SymbolSize) const; 1952 1953 void setOutputDataAddress(uint64_t Address) { OutputDataOffset = Address; } 1954 1955 uint64_t getOutputDataAddress() const { return OutputDataOffset; } 1956 1957 void setOutputColdDataAddress(uint64_t Address) { 1958 OutputColdDataOffset = Address; 1959 } 1960 1961 uint64_t getOutputColdDataAddress() const { return OutputColdDataOffset; } 1962 1963 /// If \p Address represents an access to a constant island managed by this 1964 /// function, return a symbol so code can safely refer to it. Otherwise, 1965 /// return nullptr. First return value is the symbol for reference in the 1966 /// hot code area while the second return value is the symbol for reference 1967 /// in the cold code area, as when the function is split the islands are 1968 /// duplicated. 1969 MCSymbol *getOrCreateIslandAccess(uint64_t Address) { 1970 if (!Islands) 1971 return nullptr; 1972 1973 MCSymbol *Symbol; 1974 if (!isInConstantIsland(Address)) 1975 return nullptr; 1976 1977 // Register our island at global namespace 1978 Symbol = BC.getOrCreateGlobalSymbol(Address, "ISLANDat"); 1979 1980 // Internal bookkeeping 1981 const uint64_t Offset = Address - getAddress(); 1982 assert((!Islands->Offsets.count(Offset) || 1983 Islands->Offsets[Offset] == Symbol) && 1984 "Inconsistent island symbol management"); 1985 if (!Islands->Offsets.count(Offset)) { 1986 Islands->Offsets[Offset] = Symbol; 1987 Islands->Symbols.insert(Symbol); 1988 } 1989 return Symbol; 1990 } 1991 1992 /// Called by an external function which wishes to emit references to constant 1993 /// island symbols of this function. We create a proxy for it, so we emit 1994 /// separate symbols when emitting our constant island on behalf of this other 1995 /// function. 1996 MCSymbol *getOrCreateProxyIslandAccess(uint64_t Address, 1997 BinaryFunction &Referrer) { 1998 MCSymbol *Symbol = getOrCreateIslandAccess(Address); 1999 if (!Symbol) 2000 return nullptr; 2001 2002 MCSymbol *Proxy; 2003 if (!Islands->Proxies[&Referrer].count(Symbol)) { 2004 Proxy = BC.Ctx->getOrCreateSymbol(Symbol->getName() + ".proxy.for." + 2005 Referrer.getPrintName()); 2006 Islands->Proxies[&Referrer][Symbol] = Proxy; 2007 Islands->Proxies[&Referrer][Proxy] = Symbol; 2008 } 2009 Proxy = Islands->Proxies[&Referrer][Symbol]; 2010 return Proxy; 2011 } 2012 2013 /// Make this function depend on \p BF because we have a reference to its 2014 /// constant island. When emitting this function, we will also emit 2015 // \p BF's constants. This only happens in custom AArch64 assembly code. 2016 void createIslandDependency(MCSymbol *Island, BinaryFunction *BF) { 2017 if (!Islands) 2018 Islands = std::make_unique<IslandInfo>(); 2019 2020 Islands->Dependency.insert(BF); 2021 Islands->ProxySymbols[Island] = BF; 2022 } 2023 2024 /// Detects whether \p Address is inside a data region in this function 2025 /// (constant islands). 2026 bool isInConstantIsland(uint64_t Address) const { 2027 if (!Islands) 2028 return false; 2029 2030 if (Address < getAddress()) 2031 return false; 2032 2033 uint64_t Offset = Address - getAddress(); 2034 2035 if (Offset >= getMaxSize()) 2036 return false; 2037 2038 auto DataIter = Islands->DataOffsets.upper_bound(Offset); 2039 if (DataIter == Islands->DataOffsets.begin()) 2040 return false; 2041 DataIter = std::prev(DataIter); 2042 2043 auto CodeIter = Islands->CodeOffsets.upper_bound(Offset); 2044 if (CodeIter == Islands->CodeOffsets.begin()) 2045 return true; 2046 2047 return *std::prev(CodeIter) <= *DataIter; 2048 } 2049 2050 uint64_t 2051 estimateConstantIslandSize(const BinaryFunction *OnBehalfOf = nullptr) const { 2052 if (!Islands) 2053 return 0; 2054 2055 uint64_t Size = 0; 2056 for (auto DataIter = Islands->DataOffsets.begin(); 2057 DataIter != Islands->DataOffsets.end(); ++DataIter) { 2058 auto NextData = std::next(DataIter); 2059 auto CodeIter = Islands->CodeOffsets.lower_bound(*DataIter); 2060 if (CodeIter == Islands->CodeOffsets.end() && 2061 NextData == Islands->DataOffsets.end()) { 2062 Size += getMaxSize() - *DataIter; 2063 continue; 2064 } 2065 2066 uint64_t NextMarker; 2067 if (CodeIter == Islands->CodeOffsets.end()) 2068 NextMarker = *NextData; 2069 else if (NextData == Islands->DataOffsets.end()) 2070 NextMarker = *CodeIter; 2071 else 2072 NextMarker = (*CodeIter > *NextData) ? *NextData : *CodeIter; 2073 2074 Size += NextMarker - *DataIter; 2075 } 2076 2077 if (!OnBehalfOf) 2078 for (BinaryFunction *ExternalFunc : Islands->Dependency) 2079 Size += ExternalFunc->estimateConstantIslandSize(this); 2080 return Size; 2081 } 2082 2083 bool hasIslandsInfo() const { return !!Islands; } 2084 2085 bool hasConstantIsland() const { 2086 return Islands && !Islands->DataOffsets.empty(); 2087 } 2088 2089 /// Return true iff the symbol could be seen inside this function otherwise 2090 /// it is probably another function. 2091 bool isSymbolValidInScope(const SymbolRef &Symbol, uint64_t SymbolSize) const; 2092 2093 /// Disassemble function from raw data. 2094 /// If successful, this function will populate the list of instructions 2095 /// for this function together with offsets from the function start 2096 /// in the input. It will also populate Labels with destinations for 2097 /// local branches, and TakenBranches with [from, to] info. 2098 /// 2099 /// The Function should be properly initialized before this function 2100 /// is called. I.e. function address and size should be set. 2101 /// 2102 /// Returns true on successful disassembly, and updates the current 2103 /// state to State:Disassembled. 2104 /// 2105 /// Returns false if disassembly failed. 2106 bool disassemble(); 2107 2108 /// Scan function for references to other functions. In relocation mode, 2109 /// add relocations for external references. 2110 /// 2111 /// Return true on success. 2112 bool scanExternalRefs(); 2113 2114 /// Return the size of a data object located at \p Offset in the function. 2115 /// Return 0 if there is no data object at the \p Offset. 2116 size_t getSizeOfDataInCodeAt(uint64_t Offset) const; 2117 2118 /// Verify that starting at \p Offset function contents are filled with 2119 /// zero-value bytes. 2120 bool isZeroPaddingAt(uint64_t Offset) const; 2121 2122 /// Check that entry points have an associated instruction at their 2123 /// offsets after disassembly. 2124 void postProcessEntryPoints(); 2125 2126 /// Post-processing for jump tables after disassembly. Since their 2127 /// boundaries are not known until all call sites are seen, we need this 2128 /// extra pass to perform any final adjustments. 2129 void postProcessJumpTables(); 2130 2131 /// Builds a list of basic blocks with successor and predecessor info. 2132 /// 2133 /// The function should in Disassembled state prior to call. 2134 /// 2135 /// Returns true on success and update the current function state to 2136 /// State::CFG. Returns false if CFG cannot be built. 2137 bool buildCFG(MCPlusBuilder::AllocatorIdTy); 2138 2139 /// Perform post-processing of the CFG. 2140 void postProcessCFG(); 2141 2142 /// Verify that any assumptions we've made about indirect branches were 2143 /// correct and also make any necessary changes to unknown indirect branches. 2144 /// 2145 /// Catch-22: we need to know indirect branch targets to build CFG, and 2146 /// in order to determine the value for indirect branches we need to know CFG. 2147 /// 2148 /// As such, the process of decoding indirect branches is broken into 2 steps: 2149 /// first we make our best guess about a branch without knowing the CFG, 2150 /// and later after we have the CFG for the function, we verify our earlier 2151 /// assumptions and also do our best at processing unknown indirect branches. 2152 /// 2153 /// Return true upon successful processing, or false if the control flow 2154 /// cannot be statically evaluated for any given indirect branch. 2155 bool postProcessIndirectBranches(MCPlusBuilder::AllocatorIdTy AllocId); 2156 2157 /// Return all call site profile info for this function. 2158 IndirectCallSiteProfile &getAllCallSites() { return AllCallSites; } 2159 2160 const IndirectCallSiteProfile &getAllCallSites() const { 2161 return AllCallSites; 2162 } 2163 2164 /// Walks the list of basic blocks filling in missing information about 2165 /// edge frequency for fall-throughs. 2166 /// 2167 /// Assumes the CFG has been built and edge frequency for taken branches 2168 /// has been filled with LBR data. 2169 void inferFallThroughCounts(); 2170 2171 /// Clear execution profile of the function. 2172 void clearProfile(); 2173 2174 /// Converts conditional tail calls to unconditional tail calls. We do this to 2175 /// handle conditional tail calls correctly and to give a chance to the 2176 /// simplify conditional tail call pass to decide whether to re-optimize them 2177 /// using profile information. 2178 void removeConditionalTailCalls(); 2179 2180 // Convert COUNT_NO_PROFILE to 0 2181 void removeTagsFromProfile(); 2182 2183 /// Computes a function hotness score: the sum of the products of BB frequency 2184 /// and size. 2185 uint64_t getFunctionScore() const; 2186 2187 /// Return true if the layout has been changed by basic block reordering, 2188 /// false otherwise. 2189 bool hasLayoutChanged() const; 2190 2191 /// Get the edit distance of the new layout with respect to the previous 2192 /// layout after basic block reordering. 2193 uint64_t getEditDistance() const; 2194 2195 /// Get the number of instructions within this function. 2196 uint64_t getInstructionCount() const; 2197 2198 const CFIInstrMapType &getFDEProgram() const { return FrameInstructions; } 2199 2200 void moveRememberRestorePair(BinaryBasicBlock *BB); 2201 2202 bool replayCFIInstrs(int32_t FromState, int32_t ToState, 2203 BinaryBasicBlock *InBB, 2204 BinaryBasicBlock::iterator InsertIt); 2205 2206 /// unwindCFIState is used to unwind from a higher to a lower state number 2207 /// without using remember-restore instructions. We do that by keeping track 2208 /// of what values have been changed from state A to B and emitting 2209 /// instructions that undo this change. 2210 SmallVector<int32_t, 4> unwindCFIState(int32_t FromState, int32_t ToState, 2211 BinaryBasicBlock *InBB, 2212 BinaryBasicBlock::iterator &InsertIt); 2213 2214 /// After reordering, this function checks the state of CFI and fixes it if it 2215 /// is corrupted. If it is unable to fix it, it returns false. 2216 bool finalizeCFIState(); 2217 2218 /// Return true if this function needs an address-transaltion table after 2219 /// its code emission. 2220 bool requiresAddressTranslation() const; 2221 2222 /// Adjust branch instructions to match the CFG. 2223 /// 2224 /// As it comes to internal branches, the CFG represents "the ultimate source 2225 /// of truth". Transformations on functions and blocks have to update the CFG 2226 /// and fixBranches() would make sure the correct branch instructions are 2227 /// inserted at the end of basic blocks. 2228 /// 2229 /// We do require a conditional branch at the end of the basic block if 2230 /// the block has 2 successors as CFG currently lacks the conditional 2231 /// code support (it will probably stay that way). We only use this 2232 /// branch instruction for its conditional code, the destination is 2233 /// determined by CFG - first successor representing true/taken branch, 2234 /// while the second successor - false/fall-through branch. 2235 /// 2236 /// When we reverse the branch condition, the CFG is updated accordingly. 2237 void fixBranches(); 2238 2239 /// Mark function as finalized. No further optimizations are permitted. 2240 void setFinalized() { CurrentState = State::CFG_Finalized; } 2241 2242 void setEmitted(bool KeepCFG = false) { 2243 CurrentState = State::EmittedCFG; 2244 if (!KeepCFG) { 2245 releaseCFG(); 2246 CurrentState = State::Emitted; 2247 } 2248 } 2249 2250 /// Process LSDA information for the function. 2251 void parseLSDA(ArrayRef<uint8_t> LSDAData, uint64_t LSDAAddress); 2252 2253 /// Update exception handling ranges for the function. 2254 void updateEHRanges(); 2255 2256 /// Traverse cold basic blocks and replace references to constants in islands 2257 /// with a proxy symbol for the duplicated constant island that is going to be 2258 /// emitted in the cold region. 2259 void duplicateConstantIslands(); 2260 2261 /// Merge profile data of this function into those of the given 2262 /// function. The functions should have been proven identical with 2263 /// isIdenticalWith. 2264 void mergeProfileDataInto(BinaryFunction &BF) const; 2265 2266 /// Returns the last computed hash value of the function. 2267 size_t getHash() const { return Hash; } 2268 2269 using OperandHashFuncTy = 2270 function_ref<typename std::string(const MCOperand &)>; 2271 2272 /// Compute the hash value of the function based on its contents. 2273 /// 2274 /// If \p UseDFS is set, process basic blocks in DFS order. Otherwise, use 2275 /// the existing layout order. 2276 /// 2277 /// By default, instruction operands are ignored while calculating the hash. 2278 /// The caller can change this via passing \p OperandHashFunc function. 2279 /// The return result of this function will be mixed with internal hash. 2280 size_t computeHash( 2281 bool UseDFS = false, 2282 OperandHashFuncTy OperandHashFunc = [](const MCOperand &) { 2283 return std::string(); 2284 }) const; 2285 2286 void setDWARFUnit(DWARFUnit *Unit) { DwarfUnit = Unit; } 2287 2288 /// Return DWARF compile unit for this function. 2289 DWARFUnit *getDWARFUnit() const { return DwarfUnit; } 2290 2291 /// Return line info table for this function. 2292 const DWARFDebugLine::LineTable *getDWARFLineTable() const { 2293 return getDWARFUnit() ? BC.DwCtx->getLineTableForUnit(getDWARFUnit()) 2294 : nullptr; 2295 } 2296 2297 /// Finalize profile for the function. 2298 void postProcessProfile(); 2299 2300 /// Returns an estimate of the function's hot part after splitting. 2301 /// This is a very rough estimate, as with C++ exceptions there are 2302 /// blocks we don't move, and it makes no attempt at estimating the size 2303 /// of the added/removed branch instructions. 2304 /// Note that this size is optimistic and the actual size may increase 2305 /// after relaxation. 2306 size_t estimateHotSize(const bool UseSplitSize = true) const { 2307 size_t Estimate = 0; 2308 if (UseSplitSize && isSplit()) { 2309 for (const BinaryBasicBlock *BB : BasicBlocksLayout) 2310 if (!BB->isCold()) 2311 Estimate += BC.computeCodeSize(BB->begin(), BB->end()); 2312 } else { 2313 for (const BinaryBasicBlock *BB : BasicBlocksLayout) 2314 if (BB->getKnownExecutionCount() != 0) 2315 Estimate += BC.computeCodeSize(BB->begin(), BB->end()); 2316 } 2317 return Estimate; 2318 } 2319 2320 size_t estimateColdSize() const { 2321 if (!isSplit()) 2322 return estimateSize(); 2323 size_t Estimate = 0; 2324 for (const BinaryBasicBlock *BB : BasicBlocksLayout) 2325 if (BB->isCold()) 2326 Estimate += BC.computeCodeSize(BB->begin(), BB->end()); 2327 return Estimate; 2328 } 2329 2330 size_t estimateSize() const { 2331 size_t Estimate = 0; 2332 for (const BinaryBasicBlock *BB : BasicBlocksLayout) 2333 Estimate += BC.computeCodeSize(BB->begin(), BB->end()); 2334 return Estimate; 2335 } 2336 2337 /// Return output address ranges for a function. 2338 DebugAddressRangesVector getOutputAddressRanges() const; 2339 2340 /// Given an address corresponding to an instruction in the input binary, 2341 /// return an address of this instruction in output binary. 2342 /// 2343 /// Return 0 if no matching address could be found or the instruction was 2344 /// removed. 2345 uint64_t translateInputToOutputAddress(uint64_t Address) const; 2346 2347 /// Take address ranges corresponding to the input binary and translate 2348 /// them to address ranges in the output binary. 2349 DebugAddressRangesVector translateInputToOutputRanges( 2350 const DWARFAddressRangesVector &InputRanges) const; 2351 2352 /// Similar to translateInputToOutputRanges() but operates on location lists 2353 /// and moves associated data to output location lists. 2354 DebugLocationsVector 2355 translateInputToOutputLocationList(const DebugLocationsVector &InputLL) const; 2356 2357 /// Return true if the function is an AArch64 linker inserted veneer 2358 bool isAArch64Veneer() const; 2359 2360 virtual ~BinaryFunction(); 2361 2362 /// Info for fragmented functions. 2363 class FragmentInfo { 2364 private: 2365 uint64_t Address{0}; 2366 uint64_t ImageAddress{0}; 2367 uint64_t ImageSize{0}; 2368 uint64_t FileOffset{0}; 2369 2370 public: 2371 uint64_t getAddress() const { return Address; } 2372 uint64_t getImageAddress() const { return ImageAddress; } 2373 uint64_t getImageSize() const { return ImageSize; } 2374 uint64_t getFileOffset() const { return FileOffset; } 2375 2376 void setAddress(uint64_t VAddress) { Address = VAddress; } 2377 void setImageAddress(uint64_t Address) { ImageAddress = Address; } 2378 void setImageSize(uint64_t Size) { ImageSize = Size; } 2379 void setFileOffset(uint64_t Offset) { FileOffset = Offset; } 2380 }; 2381 2382 /// Cold fragment of the function. 2383 FragmentInfo ColdFragment; 2384 2385 FragmentInfo &cold() { return ColdFragment; } 2386 2387 const FragmentInfo &cold() const { return ColdFragment; } 2388 }; 2389 2390 inline raw_ostream &operator<<(raw_ostream &OS, 2391 const BinaryFunction &Function) { 2392 OS << Function.getPrintName(); 2393 return OS; 2394 } 2395 2396 } // namespace bolt 2397 2398 // GraphTraits specializations for function basic block graphs (CFGs) 2399 template <> 2400 struct GraphTraits<bolt::BinaryFunction *> 2401 : public GraphTraits<bolt::BinaryBasicBlock *> { 2402 static NodeRef getEntryNode(bolt::BinaryFunction *F) { 2403 return *F->layout_begin(); 2404 } 2405 2406 using nodes_iterator = pointer_iterator<bolt::BinaryFunction::iterator>; 2407 2408 static nodes_iterator nodes_begin(bolt::BinaryFunction *F) { 2409 llvm_unreachable("Not implemented"); 2410 return nodes_iterator(F->begin()); 2411 } 2412 static nodes_iterator nodes_end(bolt::BinaryFunction *F) { 2413 llvm_unreachable("Not implemented"); 2414 return nodes_iterator(F->end()); 2415 } 2416 static size_t size(bolt::BinaryFunction *F) { return F->size(); } 2417 }; 2418 2419 template <> 2420 struct GraphTraits<const bolt::BinaryFunction *> 2421 : public GraphTraits<const bolt::BinaryBasicBlock *> { 2422 static NodeRef getEntryNode(const bolt::BinaryFunction *F) { 2423 return *F->layout_begin(); 2424 } 2425 2426 using nodes_iterator = pointer_iterator<bolt::BinaryFunction::const_iterator>; 2427 2428 static nodes_iterator nodes_begin(const bolt::BinaryFunction *F) { 2429 llvm_unreachable("Not implemented"); 2430 return nodes_iterator(F->begin()); 2431 } 2432 static nodes_iterator nodes_end(const bolt::BinaryFunction *F) { 2433 llvm_unreachable("Not implemented"); 2434 return nodes_iterator(F->end()); 2435 } 2436 static size_t size(const bolt::BinaryFunction *F) { return F->size(); } 2437 }; 2438 2439 template <> 2440 struct GraphTraits<Inverse<bolt::BinaryFunction *>> 2441 : public GraphTraits<Inverse<bolt::BinaryBasicBlock *>> { 2442 static NodeRef getEntryNode(Inverse<bolt::BinaryFunction *> G) { 2443 return *G.Graph->layout_begin(); 2444 } 2445 }; 2446 2447 template <> 2448 struct GraphTraits<Inverse<const bolt::BinaryFunction *>> 2449 : public GraphTraits<Inverse<const bolt::BinaryBasicBlock *>> { 2450 static NodeRef getEntryNode(Inverse<const bolt::BinaryFunction *> G) { 2451 return *G.Graph->layout_begin(); 2452 } 2453 }; 2454 2455 } // namespace llvm 2456 2457 #endif 2458