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