Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:18

0001 //===- ELFTypes.h - Endian specific types for ELF ---------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_OBJECT_ELFTYPES_H
0010 #define LLVM_OBJECT_ELFTYPES_H
0011 
0012 #include "llvm/ADT/ArrayRef.h"
0013 #include "llvm/ADT/StringRef.h"
0014 #include "llvm/BinaryFormat/ELF.h"
0015 #include "llvm/Object/Error.h"
0016 #include "llvm/Support/BlockFrequency.h"
0017 #include "llvm/Support/BranchProbability.h"
0018 #include "llvm/Support/Endian.h"
0019 #include "llvm/Support/Error.h"
0020 #include "llvm/Support/MathExtras.h"
0021 #include <cassert>
0022 #include <cstdint>
0023 #include <cstring>
0024 #include <type_traits>
0025 
0026 namespace llvm {
0027 namespace object {
0028 
0029 template <class ELFT> struct Elf_Ehdr_Impl;
0030 template <class ELFT> struct Elf_Shdr_Impl;
0031 template <class ELFT> struct Elf_Sym_Impl;
0032 template <class ELFT> struct Elf_Dyn_Impl;
0033 template <class ELFT> struct Elf_Phdr_Impl;
0034 template <class ELFT, bool isRela> struct Elf_Rel_Impl;
0035 template <bool Is64> struct Elf_Crel_Impl;
0036 template <class ELFT> struct Elf_Verdef_Impl;
0037 template <class ELFT> struct Elf_Verdaux_Impl;
0038 template <class ELFT> struct Elf_Verneed_Impl;
0039 template <class ELFT> struct Elf_Vernaux_Impl;
0040 template <class ELFT> struct Elf_Versym_Impl;
0041 template <class ELFT> struct Elf_Hash_Impl;
0042 template <class ELFT> struct Elf_GnuHash_Impl;
0043 template <class ELFT> struct Elf_Chdr_Impl;
0044 template <class ELFT> struct Elf_Nhdr_Impl;
0045 template <class ELFT> class Elf_Note_Impl;
0046 template <class ELFT> class Elf_Note_Iterator_Impl;
0047 template <class ELFT> struct Elf_CGProfile_Impl;
0048 
0049 template <endianness E, bool Is64> struct ELFType {
0050 private:
0051   template <typename Ty>
0052   using packed = support::detail::packed_endian_specific_integral<Ty, E, 1>;
0053 
0054 public:
0055   static const endianness Endianness = E;
0056   static const bool Is64Bits = Is64;
0057 
0058   using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
0059   using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
0060   using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
0061   using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
0062   using Dyn = Elf_Dyn_Impl<ELFType<E, Is64>>;
0063   using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
0064   using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
0065   using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
0066   using Crel = Elf_Crel_Impl<Is64>;
0067   using Relr = packed<uint>;
0068   using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
0069   using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
0070   using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
0071   using Vernaux = Elf_Vernaux_Impl<ELFType<E, Is64>>;
0072   using Versym = Elf_Versym_Impl<ELFType<E, Is64>>;
0073   using Hash = Elf_Hash_Impl<ELFType<E, Is64>>;
0074   using GnuHash = Elf_GnuHash_Impl<ELFType<E, Is64>>;
0075   using Chdr = Elf_Chdr_Impl<ELFType<E, Is64>>;
0076   using Nhdr = Elf_Nhdr_Impl<ELFType<E, Is64>>;
0077   using Note = Elf_Note_Impl<ELFType<E, Is64>>;
0078   using NoteIterator = Elf_Note_Iterator_Impl<ELFType<E, Is64>>;
0079   using CGProfile = Elf_CGProfile_Impl<ELFType<E, Is64>>;
0080   using DynRange = ArrayRef<Dyn>;
0081   using ShdrRange = ArrayRef<Shdr>;
0082   using SymRange = ArrayRef<Sym>;
0083   using RelRange = ArrayRef<Rel>;
0084   using RelaRange = ArrayRef<Rela>;
0085   using RelrRange = ArrayRef<Relr>;
0086   using PhdrRange = ArrayRef<Phdr>;
0087 
0088   using Half = packed<uint16_t>;
0089   using Word = packed<uint32_t>;
0090   using Sword = packed<int32_t>;
0091   using Xword = packed<uint64_t>;
0092   using Sxword = packed<int64_t>;
0093   using Addr = packed<uint>;
0094   using Off = packed<uint>;
0095 };
0096 
0097 using ELF32LE = ELFType<llvm::endianness::little, false>;
0098 using ELF32BE = ELFType<llvm::endianness::big, false>;
0099 using ELF64LE = ELFType<llvm::endianness::little, true>;
0100 using ELF64BE = ELFType<llvm::endianness::big, true>;
0101 
0102 // Use an alignment of 2 for the typedefs since that is the worst case for
0103 // ELF files in archives.
0104 
0105 // I really don't like doing this, but the alternative is copypasta.
0106 #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)                                       \
0107   using Elf_Addr = typename ELFT::Addr;                                        \
0108   using Elf_Off = typename ELFT::Off;                                          \
0109   using Elf_Half = typename ELFT::Half;                                        \
0110   using Elf_Word = typename ELFT::Word;                                        \
0111   using Elf_Sword = typename ELFT::Sword;                                      \
0112   using Elf_Xword = typename ELFT::Xword;                                      \
0113   using Elf_Sxword = typename ELFT::Sxword;                                    \
0114   using uintX_t = typename ELFT::uint;                                         \
0115   using Elf_Ehdr = typename ELFT::Ehdr;                                        \
0116   using Elf_Shdr = typename ELFT::Shdr;                                        \
0117   using Elf_Sym = typename ELFT::Sym;                                          \
0118   using Elf_Dyn = typename ELFT::Dyn;                                          \
0119   using Elf_Phdr = typename ELFT::Phdr;                                        \
0120   using Elf_Rel = typename ELFT::Rel;                                          \
0121   using Elf_Rela = typename ELFT::Rela;                                        \
0122   using Elf_Crel = typename ELFT::Crel;                                        \
0123   using Elf_Relr = typename ELFT::Relr;                                        \
0124   using Elf_Verdef = typename ELFT::Verdef;                                    \
0125   using Elf_Verdaux = typename ELFT::Verdaux;                                  \
0126   using Elf_Verneed = typename ELFT::Verneed;                                  \
0127   using Elf_Vernaux = typename ELFT::Vernaux;                                  \
0128   using Elf_Versym = typename ELFT::Versym;                                    \
0129   using Elf_Hash = typename ELFT::Hash;                                        \
0130   using Elf_GnuHash = typename ELFT::GnuHash;                                  \
0131   using Elf_Chdr = typename ELFT::Chdr;                                        \
0132   using Elf_Nhdr = typename ELFT::Nhdr;                                        \
0133   using Elf_Note = typename ELFT::Note;                                        \
0134   using Elf_Note_Iterator = typename ELFT::NoteIterator;                       \
0135   using Elf_CGProfile = typename ELFT::CGProfile;                              \
0136   using Elf_Dyn_Range = typename ELFT::DynRange;                               \
0137   using Elf_Shdr_Range = typename ELFT::ShdrRange;                             \
0138   using Elf_Sym_Range = typename ELFT::SymRange;                               \
0139   using Elf_Rel_Range = typename ELFT::RelRange;                               \
0140   using Elf_Rela_Range = typename ELFT::RelaRange;                             \
0141   using Elf_Relr_Range = typename ELFT::RelrRange;                             \
0142   using Elf_Phdr_Range = typename ELFT::PhdrRange;
0143 
0144 #define LLVM_ELF_COMMA ,
0145 #define LLVM_ELF_IMPORT_TYPES(E, W)                                            \
0146   LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
0147 
0148 // Section header.
0149 template <class ELFT> struct Elf_Shdr_Base;
0150 
0151 template <endianness Endianness>
0152 struct Elf_Shdr_Base<ELFType<Endianness, false>> {
0153   LLVM_ELF_IMPORT_TYPES(Endianness, false)
0154   Elf_Word sh_name;      // Section name (index into string table)
0155   Elf_Word sh_type;      // Section type (SHT_*)
0156   Elf_Word sh_flags;     // Section flags (SHF_*)
0157   Elf_Addr sh_addr;      // Address where section is to be loaded
0158   Elf_Off sh_offset;     // File offset of section data, in bytes
0159   Elf_Word sh_size;      // Size of section, in bytes
0160   Elf_Word sh_link;      // Section type-specific header table index link
0161   Elf_Word sh_info;      // Section type-specific extra information
0162   Elf_Word sh_addralign; // Section address alignment
0163   Elf_Word sh_entsize;   // Size of records contained within the section
0164 };
0165 
0166 template <endianness Endianness>
0167 struct Elf_Shdr_Base<ELFType<Endianness, true>> {
0168   LLVM_ELF_IMPORT_TYPES(Endianness, true)
0169   Elf_Word sh_name;       // Section name (index into string table)
0170   Elf_Word sh_type;       // Section type (SHT_*)
0171   Elf_Xword sh_flags;     // Section flags (SHF_*)
0172   Elf_Addr sh_addr;       // Address where section is to be loaded
0173   Elf_Off sh_offset;      // File offset of section data, in bytes
0174   Elf_Xword sh_size;      // Size of section, in bytes
0175   Elf_Word sh_link;       // Section type-specific header table index link
0176   Elf_Word sh_info;       // Section type-specific extra information
0177   Elf_Xword sh_addralign; // Section address alignment
0178   Elf_Xword sh_entsize;   // Size of records contained within the section
0179 };
0180 
0181 template <class ELFT>
0182 struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
0183   using Elf_Shdr_Base<ELFT>::sh_entsize;
0184   using Elf_Shdr_Base<ELFT>::sh_size;
0185 
0186   /// Get the number of entities this section contains if it has any.
0187   unsigned getEntityCount() const {
0188     if (sh_entsize == 0)
0189       return 0;
0190     return sh_size / sh_entsize;
0191   }
0192 };
0193 
0194 template <class ELFT> struct Elf_Sym_Base;
0195 
0196 template <endianness Endianness>
0197 struct Elf_Sym_Base<ELFType<Endianness, false>> {
0198   LLVM_ELF_IMPORT_TYPES(Endianness, false)
0199   Elf_Word st_name;       // Symbol name (index into string table)
0200   Elf_Addr st_value;      // Value or address associated with the symbol
0201   Elf_Word st_size;       // Size of the symbol
0202   unsigned char st_info;  // Symbol's type and binding attributes
0203   unsigned char st_other; // Must be zero; reserved
0204   Elf_Half st_shndx;      // Which section (header table index) it's defined in
0205 };
0206 
0207 template <endianness Endianness>
0208 struct Elf_Sym_Base<ELFType<Endianness, true>> {
0209   LLVM_ELF_IMPORT_TYPES(Endianness, true)
0210   Elf_Word st_name;       // Symbol name (index into string table)
0211   unsigned char st_info;  // Symbol's type and binding attributes
0212   unsigned char st_other; // Must be zero; reserved
0213   Elf_Half st_shndx;      // Which section (header table index) it's defined in
0214   Elf_Addr st_value;      // Value or address associated with the symbol
0215   Elf_Xword st_size;      // Size of the symbol
0216 };
0217 
0218 template <class ELFT>
0219 struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
0220   using Elf_Sym_Base<ELFT>::st_info;
0221   using Elf_Sym_Base<ELFT>::st_shndx;
0222   using Elf_Sym_Base<ELFT>::st_other;
0223   using Elf_Sym_Base<ELFT>::st_value;
0224 
0225   // These accessors and mutators correspond to the ELF32_ST_BIND,
0226   // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
0227   unsigned char getBinding() const { return st_info >> 4; }
0228   unsigned char getType() const { return st_info & 0x0f; }
0229   uint64_t getValue() const { return st_value; }
0230   void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
0231   void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
0232 
0233   void setBindingAndType(unsigned char b, unsigned char t) {
0234     st_info = (b << 4) + (t & 0x0f);
0235   }
0236 
0237   /// Access to the STV_xxx flag stored in the first two bits of st_other.
0238   /// STV_DEFAULT: 0
0239   /// STV_INTERNAL: 1
0240   /// STV_HIDDEN: 2
0241   /// STV_PROTECTED: 3
0242   unsigned char getVisibility() const { return st_other & 0x3; }
0243   void setVisibility(unsigned char v) {
0244     assert(v < 4 && "Invalid value for visibility");
0245     st_other = (st_other & ~0x3) | v;
0246   }
0247 
0248   bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
0249 
0250   bool isCommon() const {
0251     return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
0252   }
0253 
0254   bool isDefined() const { return !isUndefined(); }
0255 
0256   bool isProcessorSpecific() const {
0257     return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
0258   }
0259 
0260   bool isOSSpecific() const {
0261     return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
0262   }
0263 
0264   bool isReserved() const {
0265     // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
0266     // true and some compilers warn about it.
0267     return st_shndx >= ELF::SHN_LORESERVE;
0268   }
0269 
0270   bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
0271 
0272   bool isExternal() const {
0273     return getBinding() != ELF::STB_LOCAL;
0274   }
0275 
0276   Expected<StringRef> getName(StringRef StrTab) const;
0277 };
0278 
0279 template <class ELFT>
0280 Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
0281   uint32_t Offset = this->st_name;
0282   if (Offset >= StrTab.size())
0283     return createStringError(object_error::parse_failed,
0284                              "st_name (0x%" PRIx32
0285                              ") is past the end of the string table"
0286                              " of size 0x%zx",
0287                              Offset, StrTab.size());
0288   return StringRef(StrTab.data() + Offset);
0289 }
0290 
0291 /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
0292 /// (.gnu.version). This structure is identical for ELF32 and ELF64.
0293 template <class ELFT>
0294 struct Elf_Versym_Impl {
0295   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0296   Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
0297 };
0298 
0299 /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
0300 /// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
0301 template <class ELFT>
0302 struct Elf_Verdef_Impl {
0303   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0304   Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
0305   Elf_Half vd_flags;   // Bitwise flags (VER_DEF_*)
0306   Elf_Half vd_ndx;     // Version index, used in .gnu.version entries
0307   Elf_Half vd_cnt;     // Number of Verdaux entries
0308   Elf_Word vd_hash;    // Hash of name
0309   Elf_Word vd_aux;     // Offset to the first Verdaux entry (in bytes)
0310   Elf_Word vd_next;    // Offset to the next Verdef entry (in bytes)
0311 
0312   /// Get the first Verdaux entry for this Verdef.
0313   const Elf_Verdaux *getAux() const {
0314     return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
0315   }
0316 };
0317 
0318 /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
0319 /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
0320 template <class ELFT>
0321 struct Elf_Verdaux_Impl {
0322   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0323   Elf_Word vda_name; // Version name (offset in string table)
0324   Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
0325 };
0326 
0327 /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
0328 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
0329 template <class ELFT>
0330 struct Elf_Verneed_Impl {
0331   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0332   Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
0333   Elf_Half vn_cnt;     // Number of associated Vernaux entries
0334   Elf_Word vn_file;    // Library name (string table offset)
0335   Elf_Word vn_aux;     // Offset to first Vernaux entry (in bytes)
0336   Elf_Word vn_next;    // Offset to next Verneed entry (in bytes)
0337 };
0338 
0339 /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
0340 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
0341 template <class ELFT>
0342 struct Elf_Vernaux_Impl {
0343   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0344   Elf_Word vna_hash;  // Hash of dependency name
0345   Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
0346   Elf_Half vna_other; // Version index, used in .gnu.version entries
0347   Elf_Word vna_name;  // Dependency name
0348   Elf_Word vna_next;  // Offset to next Vernaux entry (in bytes)
0349 };
0350 
0351 /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
0352 ///               table section (.dynamic) look like.
0353 template <class ELFT> struct Elf_Dyn_Base;
0354 
0355 template <endianness Endianness>
0356 struct Elf_Dyn_Base<ELFType<Endianness, false>> {
0357   LLVM_ELF_IMPORT_TYPES(Endianness, false)
0358   Elf_Sword d_tag;
0359   union {
0360     Elf_Word d_val;
0361     Elf_Addr d_ptr;
0362   } d_un;
0363 };
0364 
0365 template <endianness Endianness>
0366 struct Elf_Dyn_Base<ELFType<Endianness, true>> {
0367   LLVM_ELF_IMPORT_TYPES(Endianness, true)
0368   Elf_Sxword d_tag;
0369   union {
0370     Elf_Xword d_val;
0371     Elf_Addr d_ptr;
0372   } d_un;
0373 };
0374 
0375 /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
0376 template <class ELFT>
0377 struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
0378   using Elf_Dyn_Base<ELFT>::d_tag;
0379   using Elf_Dyn_Base<ELFT>::d_un;
0380   using intX_t = std::conditional_t<ELFT::Is64Bits, int64_t, int32_t>;
0381   using uintX_t = std::conditional_t<ELFT::Is64Bits, uint64_t, uint32_t>;
0382   intX_t getTag() const { return d_tag; }
0383   uintX_t getVal() const { return d_un.d_val; }
0384   uintX_t getPtr() const { return d_un.d_ptr; }
0385 };
0386 
0387 template <endianness Endianness>
0388 struct Elf_Rel_Impl<ELFType<Endianness, false>, false> {
0389   LLVM_ELF_IMPORT_TYPES(Endianness, false)
0390   static const bool HasAddend = false;
0391   static const bool IsCrel = false;
0392   Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
0393   Elf_Word r_info;   // Symbol table index and type of relocation to apply
0394 
0395   uint32_t getRInfo(bool isMips64EL) const {
0396     assert(!isMips64EL);
0397     return r_info;
0398   }
0399   void setRInfo(uint32_t R, bool IsMips64EL) {
0400     assert(!IsMips64EL);
0401     r_info = R;
0402   }
0403 
0404   // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
0405   // and ELF32_R_INFO macros defined in the ELF specification:
0406   uint32_t getSymbol(bool isMips64EL) const {
0407     return this->getRInfo(isMips64EL) >> 8;
0408   }
0409   unsigned char getType(bool isMips64EL) const {
0410     return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
0411   }
0412   void setSymbol(uint32_t s, bool IsMips64EL) {
0413     setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
0414   }
0415   void setType(unsigned char t, bool IsMips64EL) {
0416     setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
0417   }
0418   void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
0419     this->setRInfo((s << 8) + t, IsMips64EL);
0420   }
0421 };
0422 
0423 template <endianness Endianness>
0424 struct Elf_Rel_Impl<ELFType<Endianness, false>, true>
0425     : public Elf_Rel_Impl<ELFType<Endianness, false>, false> {
0426   LLVM_ELF_IMPORT_TYPES(Endianness, false)
0427   static const bool HasAddend = true;
0428   static const bool IsCrel = false;
0429   Elf_Sword r_addend; // Compute value for relocatable field by adding this
0430 };
0431 
0432 template <endianness Endianness>
0433 struct Elf_Rel_Impl<ELFType<Endianness, true>, false> {
0434   LLVM_ELF_IMPORT_TYPES(Endianness, true)
0435   static const bool HasAddend = false;
0436   static const bool IsCrel = false;
0437   Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
0438   Elf_Xword r_info;  // Symbol table index and type of relocation to apply
0439 
0440   uint64_t getRInfo(bool isMips64EL) const {
0441     uint64_t t = r_info;
0442     if (!isMips64EL)
0443       return t;
0444     // Mips64 little endian has a "special" encoding of r_info. Instead of one
0445     // 64 bit little endian number, it is a little endian 32 bit number followed
0446     // by a 32 bit big endian number.
0447     return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
0448            ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
0449   }
0450 
0451   void setRInfo(uint64_t R, bool IsMips64EL) {
0452     if (IsMips64EL)
0453       r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
0454                ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
0455     else
0456       r_info = R;
0457   }
0458 
0459   // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
0460   // and ELF64_R_INFO macros defined in the ELF specification:
0461   uint32_t getSymbol(bool isMips64EL) const {
0462     return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
0463   }
0464   uint32_t getType(bool isMips64EL) const {
0465     return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
0466   }
0467   void setSymbol(uint32_t s, bool IsMips64EL) {
0468     setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
0469   }
0470   void setType(uint32_t t, bool IsMips64EL) {
0471     setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
0472   }
0473   void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) {
0474     this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
0475   }
0476 };
0477 
0478 template <endianness Endianness>
0479 struct Elf_Rel_Impl<ELFType<Endianness, true>, true>
0480     : public Elf_Rel_Impl<ELFType<Endianness, true>, false> {
0481   LLVM_ELF_IMPORT_TYPES(Endianness, true)
0482   static const bool HasAddend = true;
0483   static const bool IsCrel = false;
0484   Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
0485 };
0486 
0487 // In-memory representation. The serialized representation uses LEB128.
0488 template <bool Is64> struct Elf_Crel_Impl {
0489   using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
0490   static const bool HasAddend = true;
0491   static const bool IsCrel = true;
0492   uint r_offset;
0493   uint32_t r_symidx;
0494   uint32_t r_type;
0495   std::conditional_t<Is64, int64_t, int32_t> r_addend;
0496 
0497   // Dummy bool parameter is for compatibility with Elf_Rel_Impl.
0498   uint32_t getType(bool) const { return r_type; }
0499   uint32_t getSymbol(bool) const { return r_symidx; }
0500   void setSymbolAndType(uint32_t s, unsigned char t, bool) {
0501     r_symidx = s;
0502     r_type = t;
0503   }
0504 };
0505 
0506 template <class ELFT>
0507 struct Elf_Ehdr_Impl {
0508   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0509   unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
0510   Elf_Half e_type;                       // Type of file (see ET_*)
0511   Elf_Half e_machine;   // Required architecture for this file (see EM_*)
0512   Elf_Word e_version;   // Must be equal to 1
0513   Elf_Addr e_entry;     // Address to jump to in order to start program
0514   Elf_Off e_phoff;      // Program header table's file offset, in bytes
0515   Elf_Off e_shoff;      // Section header table's file offset, in bytes
0516   Elf_Word e_flags;     // Processor-specific flags
0517   Elf_Half e_ehsize;    // Size of ELF header, in bytes
0518   Elf_Half e_phentsize; // Size of an entry in the program header table
0519   Elf_Half e_phnum;     // Number of entries in the program header table
0520   Elf_Half e_shentsize; // Size of an entry in the section header table
0521   Elf_Half e_shnum;     // Number of entries in the section header table
0522   Elf_Half e_shstrndx;  // Section header table index of section name
0523                         // string table
0524 
0525   bool checkMagic() const {
0526     return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
0527   }
0528 
0529   unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
0530   unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
0531 };
0532 
0533 template <endianness Endianness>
0534 struct Elf_Phdr_Impl<ELFType<Endianness, false>> {
0535   LLVM_ELF_IMPORT_TYPES(Endianness, false)
0536   Elf_Word p_type;   // Type of segment
0537   Elf_Off p_offset;  // FileOffset where segment is located, in bytes
0538   Elf_Addr p_vaddr;  // Virtual Address of beginning of segment
0539   Elf_Addr p_paddr;  // Physical address of beginning of segment (OS-specific)
0540   Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
0541   Elf_Word p_memsz;  // Num. of bytes in mem image of segment (may be zero)
0542   Elf_Word p_flags;  // Segment flags
0543   Elf_Word p_align;  // Segment alignment constraint
0544 };
0545 
0546 template <endianness Endianness>
0547 struct Elf_Phdr_Impl<ELFType<Endianness, true>> {
0548   LLVM_ELF_IMPORT_TYPES(Endianness, true)
0549   Elf_Word p_type;    // Type of segment
0550   Elf_Word p_flags;   // Segment flags
0551   Elf_Off p_offset;   // FileOffset where segment is located, in bytes
0552   Elf_Addr p_vaddr;   // Virtual Address of beginning of segment
0553   Elf_Addr p_paddr;   // Physical address of beginning of segment (OS-specific)
0554   Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
0555   Elf_Xword p_memsz;  // Num. of bytes in mem image of segment (may be zero)
0556   Elf_Xword p_align;  // Segment alignment constraint
0557 };
0558 
0559 // ELFT needed for endianness.
0560 template <class ELFT>
0561 struct Elf_Hash_Impl {
0562   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0563   Elf_Word nbucket;
0564   Elf_Word nchain;
0565 
0566   ArrayRef<Elf_Word> buckets() const {
0567     return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
0568   }
0569 
0570   ArrayRef<Elf_Word> chains() const {
0571     return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
0572                               &nbucket + 2 + nbucket + nchain);
0573   }
0574 };
0575 
0576 // .gnu.hash section
0577 template <class ELFT>
0578 struct Elf_GnuHash_Impl {
0579   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0580   Elf_Word nbuckets;
0581   Elf_Word symndx;
0582   Elf_Word maskwords;
0583   Elf_Word shift2;
0584 
0585   ArrayRef<Elf_Off> filter() const {
0586     return ArrayRef<Elf_Off>(reinterpret_cast<const Elf_Off *>(&shift2 + 1),
0587                              maskwords);
0588   }
0589 
0590   ArrayRef<Elf_Word> buckets() const {
0591     return ArrayRef<Elf_Word>(
0592         reinterpret_cast<const Elf_Word *>(filter().end()), nbuckets);
0593   }
0594 
0595   ArrayRef<Elf_Word> values(unsigned DynamicSymCount) const {
0596     assert(DynamicSymCount >= symndx);
0597     return ArrayRef<Elf_Word>(buckets().end(), DynamicSymCount - symndx);
0598   }
0599 };
0600 
0601 // Compressed section headers.
0602 // http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
0603 template <endianness Endianness>
0604 struct Elf_Chdr_Impl<ELFType<Endianness, false>> {
0605   LLVM_ELF_IMPORT_TYPES(Endianness, false)
0606   Elf_Word ch_type;
0607   Elf_Word ch_size;
0608   Elf_Word ch_addralign;
0609 };
0610 
0611 template <endianness Endianness>
0612 struct Elf_Chdr_Impl<ELFType<Endianness, true>> {
0613   LLVM_ELF_IMPORT_TYPES(Endianness, true)
0614   Elf_Word ch_type;
0615   Elf_Word ch_reserved;
0616   Elf_Xword ch_size;
0617   Elf_Xword ch_addralign;
0618 };
0619 
0620 /// Note header
0621 template <class ELFT>
0622 struct Elf_Nhdr_Impl {
0623   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0624   Elf_Word n_namesz;
0625   Elf_Word n_descsz;
0626   Elf_Word n_type;
0627 
0628   /// Get the size of the note, including name, descriptor, and padding. Both
0629   /// the start and the end of the descriptor are aligned by the section
0630   /// alignment. In practice many 64-bit systems deviate from the generic ABI by
0631   /// using sh_addralign=4.
0632   size_t getSize(size_t Align) const {
0633     return alignToPowerOf2(sizeof(*this) + n_namesz, Align) +
0634            alignToPowerOf2(n_descsz, Align);
0635   }
0636 };
0637 
0638 /// An ELF note.
0639 ///
0640 /// Wraps a note header, providing methods for accessing the name and
0641 /// descriptor safely.
0642 template <class ELFT>
0643 class Elf_Note_Impl {
0644   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0645 
0646   const Elf_Nhdr_Impl<ELFT> &Nhdr;
0647 
0648   template <class NoteIteratorELFT> friend class Elf_Note_Iterator_Impl;
0649 
0650 public:
0651   Elf_Note_Impl(const Elf_Nhdr_Impl<ELFT> &Nhdr) : Nhdr(Nhdr) {}
0652 
0653   /// Get the note's name, excluding the terminating null byte.
0654   StringRef getName() const {
0655     if (!Nhdr.n_namesz)
0656       return StringRef();
0657     return StringRef(reinterpret_cast<const char *>(&Nhdr) + sizeof(Nhdr),
0658                      Nhdr.n_namesz - 1);
0659   }
0660 
0661   /// Get the note's descriptor.
0662   ArrayRef<uint8_t> getDesc(size_t Align) const {
0663     if (!Nhdr.n_descsz)
0664       return ArrayRef<uint8_t>();
0665     return ArrayRef<uint8_t>(
0666         reinterpret_cast<const uint8_t *>(&Nhdr) +
0667             alignToPowerOf2(sizeof(Nhdr) + Nhdr.n_namesz, Align),
0668         Nhdr.n_descsz);
0669   }
0670 
0671   /// Get the note's descriptor as StringRef
0672   StringRef getDescAsStringRef(size_t Align) const {
0673     ArrayRef<uint8_t> Desc = getDesc(Align);
0674     return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
0675   }
0676 
0677   /// Get the note's type.
0678   Elf_Word getType() const { return Nhdr.n_type; }
0679 };
0680 
0681 template <class ELFT> class Elf_Note_Iterator_Impl {
0682 public:
0683   using iterator_category = std::forward_iterator_tag;
0684   using value_type = Elf_Note_Impl<ELFT>;
0685   using difference_type = std::ptrdiff_t;
0686   using pointer = value_type *;
0687   using reference = value_type &;
0688 
0689 private:
0690   // Nhdr being a nullptr marks the end of iteration.
0691   const Elf_Nhdr_Impl<ELFT> *Nhdr = nullptr;
0692   size_t RemainingSize = 0u;
0693   size_t Align = 0;
0694   Error *Err = nullptr;
0695 
0696   template <class ELFFileELFT> friend class ELFFile;
0697 
0698   // Stop iteration and indicate an overflow.
0699   void stopWithOverflowError() {
0700     Nhdr = nullptr;
0701     *Err = make_error<StringError>("ELF note overflows container",
0702                                    object_error::parse_failed);
0703   }
0704 
0705   // Advance Nhdr by NoteSize bytes, starting from NhdrPos.
0706   //
0707   // Assumes NoteSize <= RemainingSize. Ensures Nhdr->getSize() <= RemainingSize
0708   // upon returning. Handles stopping iteration when reaching the end of the
0709   // container, either cleanly or with an overflow error.
0710   void advanceNhdr(const uint8_t *NhdrPos, size_t NoteSize) {
0711     RemainingSize -= NoteSize;
0712     if (RemainingSize == 0u) {
0713       // Ensure that if the iterator walks to the end, the error is checked
0714       // afterwards.
0715       *Err = Error::success();
0716       Nhdr = nullptr;
0717     } else if (sizeof(*Nhdr) > RemainingSize)
0718       stopWithOverflowError();
0719     else {
0720       Nhdr = reinterpret_cast<const Elf_Nhdr_Impl<ELFT> *>(NhdrPos + NoteSize);
0721       if (Nhdr->getSize(Align) > RemainingSize)
0722         stopWithOverflowError();
0723       else
0724         *Err = Error::success();
0725     }
0726   }
0727 
0728   Elf_Note_Iterator_Impl() = default;
0729   explicit Elf_Note_Iterator_Impl(Error &Err) : Err(&Err) {}
0730   Elf_Note_Iterator_Impl(const uint8_t *Start, size_t Size, size_t Align,
0731                          Error &Err)
0732       : RemainingSize(Size), Align(Align), Err(&Err) {
0733     consumeError(std::move(Err));
0734     assert(Start && "ELF note iterator starting at NULL");
0735     advanceNhdr(Start, 0u);
0736   }
0737 
0738 public:
0739   Elf_Note_Iterator_Impl &operator++() {
0740     assert(Nhdr && "incremented ELF note end iterator");
0741     const uint8_t *NhdrPos = reinterpret_cast<const uint8_t *>(Nhdr);
0742     size_t NoteSize = Nhdr->getSize(Align);
0743     advanceNhdr(NhdrPos, NoteSize);
0744     return *this;
0745   }
0746   bool operator==(Elf_Note_Iterator_Impl Other) const {
0747     if (!Nhdr && Other.Err)
0748       (void)(bool)(*Other.Err);
0749     if (!Other.Nhdr && Err)
0750       (void)(bool)(*Err);
0751     return Nhdr == Other.Nhdr;
0752   }
0753   bool operator!=(Elf_Note_Iterator_Impl Other) const {
0754     return !(*this == Other);
0755   }
0756   Elf_Note_Impl<ELFT> operator*() const {
0757     assert(Nhdr && "dereferenced ELF note end iterator");
0758     return Elf_Note_Impl<ELFT>(*Nhdr);
0759   }
0760 };
0761 
0762 template <class ELFT> struct Elf_CGProfile_Impl {
0763   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0764   Elf_Xword cgp_weight;
0765 };
0766 
0767 // MIPS .reginfo section
0768 template <class ELFT>
0769 struct Elf_Mips_RegInfo;
0770 
0771 template <llvm::endianness Endianness>
0772 struct Elf_Mips_RegInfo<ELFType<Endianness, false>> {
0773   LLVM_ELF_IMPORT_TYPES(Endianness, false)
0774   Elf_Word ri_gprmask;     // bit-mask of used general registers
0775   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
0776   Elf_Addr ri_gp_value;    // gp register value
0777 };
0778 
0779 template <llvm::endianness Endianness>
0780 struct Elf_Mips_RegInfo<ELFType<Endianness, true>> {
0781   LLVM_ELF_IMPORT_TYPES(Endianness, true)
0782   Elf_Word ri_gprmask;     // bit-mask of used general registers
0783   Elf_Word ri_pad;         // unused padding field
0784   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
0785   Elf_Addr ri_gp_value;    // gp register value
0786 };
0787 
0788 // .MIPS.options section
0789 template <class ELFT> struct Elf_Mips_Options {
0790   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0791   uint8_t kind;     // Determines interpretation of variable part of descriptor
0792   uint8_t size;     // Byte size of descriptor, including this header
0793   Elf_Half section; // Section header index of section affected,
0794                     // or 0 for global options
0795   Elf_Word info;    // Kind-specific information
0796 
0797   Elf_Mips_RegInfo<ELFT> &getRegInfo() {
0798     assert(kind == ELF::ODK_REGINFO);
0799     return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
0800         (uint8_t *)this + sizeof(Elf_Mips_Options));
0801   }
0802   const Elf_Mips_RegInfo<ELFT> &getRegInfo() const {
0803     return const_cast<Elf_Mips_Options *>(this)->getRegInfo();
0804   }
0805 };
0806 
0807 // .MIPS.abiflags section content
0808 template <class ELFT> struct Elf_Mips_ABIFlags {
0809   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
0810   Elf_Half version;  // Version of the structure
0811   uint8_t isa_level; // ISA level: 1-5, 32, and 64
0812   uint8_t isa_rev;   // ISA revision (0 for MIPS I - MIPS V)
0813   uint8_t gpr_size;  // General purpose registers size
0814   uint8_t cpr1_size; // Co-processor 1 registers size
0815   uint8_t cpr2_size; // Co-processor 2 registers size
0816   uint8_t fp_abi;    // Floating-point ABI flag
0817   Elf_Word isa_ext;  // Processor-specific extension
0818   Elf_Word ases;     // ASEs flags
0819   Elf_Word flags1;   // General flags
0820   Elf_Word flags2;   // General flags
0821 };
0822 
0823 // Struct representing the BBAddrMap for one function.
0824 struct BBAddrMap {
0825 
0826   // Bitfield of optional features to control the extra information
0827   // emitted/encoded in the the section.
0828   struct Features {
0829     bool FuncEntryCount : 1;
0830     bool BBFreq : 1;
0831     bool BrProb : 1;
0832     bool MultiBBRange : 1;
0833     bool OmitBBEntries : 1;
0834 
0835     bool hasPGOAnalysis() const { return FuncEntryCount || BBFreq || BrProb; }
0836 
0837     bool hasPGOAnalysisBBData() const { return BBFreq || BrProb; }
0838 
0839     // Encodes to minimum bit width representation.
0840     uint8_t encode() const {
0841       return (static_cast<uint8_t>(FuncEntryCount) << 0) |
0842              (static_cast<uint8_t>(BBFreq) << 1) |
0843              (static_cast<uint8_t>(BrProb) << 2) |
0844              (static_cast<uint8_t>(MultiBBRange) << 3) |
0845              (static_cast<uint8_t>(OmitBBEntries) << 4);
0846     }
0847 
0848     // Decodes from minimum bit width representation and validates no
0849     // unnecessary bits are used.
0850     static Expected<Features> decode(uint8_t Val) {
0851       Features Feat{
0852           static_cast<bool>(Val & (1 << 0)), static_cast<bool>(Val & (1 << 1)),
0853           static_cast<bool>(Val & (1 << 2)), static_cast<bool>(Val & (1 << 3)),
0854           static_cast<bool>(Val & (1 << 4))};
0855       if (Feat.encode() != Val)
0856         return createStringError(
0857             std::error_code(), "invalid encoding for BBAddrMap::Features: 0x%x",
0858             Val);
0859       return Feat;
0860     }
0861 
0862     bool operator==(const Features &Other) const {
0863       return std::tie(FuncEntryCount, BBFreq, BrProb, MultiBBRange,
0864                       OmitBBEntries) ==
0865              std::tie(Other.FuncEntryCount, Other.BBFreq, Other.BrProb,
0866                       Other.MultiBBRange, Other.OmitBBEntries);
0867     }
0868   };
0869 
0870   // Struct representing the BBAddrMap information for one basic block.
0871   struct BBEntry {
0872     struct Metadata {
0873       bool HasReturn : 1;         // If this block ends with a return (or tail
0874                                   // call).
0875       bool HasTailCall : 1;       // If this block ends with a tail call.
0876       bool IsEHPad : 1;           // If this is an exception handling block.
0877       bool CanFallThrough : 1;    // If this block can fall through to its next.
0878       bool HasIndirectBranch : 1; // If this block ends with an indirect branch
0879                                   // (branch via a register).
0880 
0881       bool operator==(const Metadata &Other) const {
0882         return HasReturn == Other.HasReturn &&
0883                HasTailCall == Other.HasTailCall && IsEHPad == Other.IsEHPad &&
0884                CanFallThrough == Other.CanFallThrough &&
0885                HasIndirectBranch == Other.HasIndirectBranch;
0886       }
0887 
0888       // Encodes this struct as a uint32_t value.
0889       uint32_t encode() const {
0890         return static_cast<uint32_t>(HasReturn) |
0891                (static_cast<uint32_t>(HasTailCall) << 1) |
0892                (static_cast<uint32_t>(IsEHPad) << 2) |
0893                (static_cast<uint32_t>(CanFallThrough) << 3) |
0894                (static_cast<uint32_t>(HasIndirectBranch) << 4);
0895       }
0896 
0897       // Decodes and returns a Metadata struct from a uint32_t value.
0898       static Expected<Metadata> decode(uint32_t V) {
0899         Metadata MD{/*HasReturn=*/static_cast<bool>(V & 1),
0900                     /*HasTailCall=*/static_cast<bool>(V & (1 << 1)),
0901                     /*IsEHPad=*/static_cast<bool>(V & (1 << 2)),
0902                     /*CanFallThrough=*/static_cast<bool>(V & (1 << 3)),
0903                     /*HasIndirectBranch=*/static_cast<bool>(V & (1 << 4))};
0904         if (MD.encode() != V)
0905           return createStringError(
0906               std::error_code(), "invalid encoding for BBEntry::Metadata: 0x%x",
0907               V);
0908         return MD;
0909       }
0910     };
0911 
0912     uint32_t ID = 0;     // Unique ID of this basic block.
0913     uint32_t Offset = 0; // Offset of basic block relative to the base address.
0914     uint32_t Size = 0;   // Size of the basic block.
0915     Metadata MD = {false, false, false, false,
0916                    false}; // Metdata for this basic block.
0917 
0918     BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD)
0919         : ID(ID), Offset(Offset), Size(Size), MD(MD){};
0920 
0921     bool operator==(const BBEntry &Other) const {
0922       return ID == Other.ID && Offset == Other.Offset && Size == Other.Size &&
0923              MD == Other.MD;
0924     }
0925 
0926     bool hasReturn() const { return MD.HasReturn; }
0927     bool hasTailCall() const { return MD.HasTailCall; }
0928     bool isEHPad() const { return MD.IsEHPad; }
0929     bool canFallThrough() const { return MD.CanFallThrough; }
0930     bool hasIndirectBranch() const { return MD.HasIndirectBranch; }
0931   };
0932 
0933   // Struct representing the BBAddrMap information for a contiguous range of
0934   // basic blocks (a function or a basic block section).
0935   struct BBRangeEntry {
0936     uint64_t BaseAddress = 0;       // Base address of the range.
0937     std::vector<BBEntry> BBEntries; // Basic block entries for this range.
0938 
0939     // Equality operator for unit testing.
0940     bool operator==(const BBRangeEntry &Other) const {
0941       return BaseAddress == Other.BaseAddress &&
0942              std::equal(BBEntries.begin(), BBEntries.end(),
0943                         Other.BBEntries.begin());
0944     }
0945   };
0946 
0947   // All ranges for this function. Cannot be empty. The first range always
0948   // corresponds to the function entry.
0949   std::vector<BBRangeEntry> BBRanges;
0950 
0951   // Returns the function address associated with this BBAddrMap, which is
0952   // stored as the `BaseAddress` of its first BBRangeEntry.
0953   uint64_t getFunctionAddress() const {
0954     assert(!BBRanges.empty());
0955     return BBRanges.front().BaseAddress;
0956   }
0957 
0958   // Returns the total number of bb entries in all bb ranges.
0959   size_t getNumBBEntries() const {
0960     size_t NumBBEntries = 0;
0961     for (const auto &BBR : BBRanges)
0962       NumBBEntries += BBR.BBEntries.size();
0963     return NumBBEntries;
0964   }
0965 
0966   // Returns the index of the bb range with the given base address, or
0967   // `std::nullopt` if no such range exists.
0968   std::optional<size_t>
0969   getBBRangeIndexForBaseAddress(uint64_t BaseAddress) const {
0970     for (size_t I = 0; I < BBRanges.size(); ++I)
0971       if (BBRanges[I].BaseAddress == BaseAddress)
0972         return I;
0973     return {};
0974   }
0975 
0976   // Returns bb entries in the first range.
0977   const std::vector<BBEntry> &getBBEntries() const {
0978     return BBRanges.front().BBEntries;
0979   }
0980 
0981   const std::vector<BBRangeEntry> &getBBRanges() const { return BBRanges; }
0982 
0983   // Equality operator for unit testing.
0984   bool operator==(const BBAddrMap &Other) const {
0985     return std::equal(BBRanges.begin(), BBRanges.end(), Other.BBRanges.begin());
0986   }
0987 };
0988 
0989 /// A feature extension of BBAddrMap that holds information relevant to PGO.
0990 struct PGOAnalysisMap {
0991   /// Extra basic block data with fields for block frequency and branch
0992   /// probability.
0993   struct PGOBBEntry {
0994     /// Single successor of a given basic block that contains the tag and branch
0995     /// probability associated with it.
0996     struct SuccessorEntry {
0997       /// Unique ID of this successor basic block.
0998       uint32_t ID;
0999       /// Branch Probability of the edge to this successor taken from MBPI.
1000       BranchProbability Prob;
1001 
1002       bool operator==(const SuccessorEntry &Other) const {
1003         return std::tie(ID, Prob) == std::tie(Other.ID, Other.Prob);
1004       }
1005     };
1006 
1007     /// Block frequency taken from MBFI
1008     BlockFrequency BlockFreq;
1009     /// List of successors of the current block
1010     llvm::SmallVector<SuccessorEntry, 2> Successors;
1011 
1012     bool operator==(const PGOBBEntry &Other) const {
1013       return std::tie(BlockFreq, Successors) ==
1014              std::tie(Other.BlockFreq, Other.Successors);
1015     }
1016   };
1017 
1018   uint64_t FuncEntryCount;           // Prof count from IR function
1019   std::vector<PGOBBEntry> BBEntries; // Extended basic block entries
1020 
1021   // Flags to indicate if each PGO related info was enabled in this function
1022   BBAddrMap::Features FeatEnable;
1023 
1024   bool operator==(const PGOAnalysisMap &Other) const {
1025     return std::tie(FuncEntryCount, BBEntries, FeatEnable) ==
1026            std::tie(Other.FuncEntryCount, Other.BBEntries, Other.FeatEnable);
1027   }
1028 };
1029 
1030 } // end namespace object.
1031 } // end namespace llvm.
1032 
1033 #endif // LLVM_OBJECT_ELFTYPES_H