brintos

brintos / llvm-project-archived public Read only

0
0
Text · 316.8 KiB · 2b5bc63 Raw
8696 lines · cpp
1//===- ELFDumper.cpp - ELF-specific dumper --------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file implements the ELF-specific dumper for llvm-readobj.11///12//===----------------------------------------------------------------------===//13 14#include "ARMEHABIPrinter.h"15#include "DwarfCFIEHPrinter.h"16#include "ObjDumper.h"17#include "StackMapPrinter.h"18#include "llvm-readobj.h"19#include "llvm/ADT/ArrayRef.h"20#include "llvm/ADT/BitVector.h"21#include "llvm/ADT/DenseMap.h"22#include "llvm/ADT/DenseSet.h"23#include "llvm/ADT/MapVector.h"24#include "llvm/ADT/STLExtras.h"25#include "llvm/ADT/SmallString.h"26#include "llvm/ADT/SmallVector.h"27#include "llvm/ADT/StringExtras.h"28#include "llvm/ADT/StringRef.h"29#include "llvm/ADT/Twine.h"30#include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h"31#include "llvm/BinaryFormat/ELF.h"32#include "llvm/BinaryFormat/MsgPackDocument.h"33#include "llvm/BinaryFormat/SFrame.h"34#include "llvm/Demangle/Demangle.h"35#include "llvm/Object/Archive.h"36#include "llvm/Object/ELF.h"37#include "llvm/Object/ELFObjectFile.h"38#include "llvm/Object/ELFTypes.h"39#include "llvm/Object/Error.h"40#include "llvm/Object/ObjectFile.h"41#include "llvm/Object/RelocationResolver.h"42#include "llvm/Object/SFrameParser.h"43#include "llvm/Object/StackMapParser.h"44#include "llvm/Support/AArch64AttributeParser.h"45#include "llvm/Support/AMDGPUMetadata.h"46#include "llvm/Support/ARMAttributeParser.h"47#include "llvm/Support/ARMBuildAttributes.h"48#include "llvm/Support/Casting.h"49#include "llvm/Support/Compiler.h"50#include "llvm/Support/Endian.h"51#include "llvm/Support/ErrorHandling.h"52#include "llvm/Support/Format.h"53#include "llvm/Support/FormatVariadic.h"54#include "llvm/Support/FormattedStream.h"55#include "llvm/Support/HexagonAttributeParser.h"56#include "llvm/Support/LEB128.h"57#include "llvm/Support/MSP430AttributeParser.h"58#include "llvm/Support/MSP430Attributes.h"59#include "llvm/Support/MathExtras.h"60#include "llvm/Support/MipsABIFlags.h"61#include "llvm/Support/RISCVAttributeParser.h"62#include "llvm/Support/RISCVAttributes.h"63#include "llvm/Support/ScopedPrinter.h"64#include "llvm/Support/raw_ostream.h"65#include <algorithm>66#include <array>67#include <cinttypes>68#include <cstddef>69#include <cstdint>70#include <cstdlib>71#include <iterator>72#include <memory>73#include <optional>74#include <string>75#include <system_error>76#include <vector>77 78using namespace llvm;79using namespace llvm::object;80using namespace llvm::support;81using namespace ELF;82 83#define LLVM_READOBJ_ENUM_CASE(ns, enum)                                       \84  case ns::enum:                                                               \85    return #enum;86 87#define ENUM_ENT(enum, altName)                                                \88  { #enum, altName, ELF::enum }89 90#define ENUM_ENT_1(enum)                                                       \91  { #enum, #enum, ELF::enum }92 93namespace {94 95template <class ELFT> struct RelSymbol {96  RelSymbol(const typename ELFT::Sym *S, StringRef N)97      : Sym(S), Name(N.str()) {}98  const typename ELFT::Sym *Sym;99  std::string Name;100};101 102/// Represents a contiguous uniform range in the file. We cannot just create a103/// range directly because when creating one of these from the .dynamic table104/// the size, entity size and virtual address are different entries in arbitrary105/// order (DT_REL, DT_RELSZ, DT_RELENT for example).106struct DynRegionInfo {107  DynRegionInfo(const Binary &Owner, const ObjDumper &D)108      : Obj(&Owner), Dumper(&D) {}109  DynRegionInfo(const Binary &Owner, const ObjDumper &D, const uint8_t *A,110                uint64_t S, uint64_t ES)111      : Addr(A), Size(S), EntSize(ES), Obj(&Owner), Dumper(&D) {}112 113  /// Address in current address space.114  const uint8_t *Addr = nullptr;115  /// Size in bytes of the region.116  uint64_t Size = 0;117  /// Size of each entity in the region.118  uint64_t EntSize = 0;119 120  /// Owner object. Used for error reporting.121  const Binary *Obj;122  /// Dumper used for error reporting.123  const ObjDumper *Dumper;124  /// Error prefix. Used for error reporting to provide more information.125  std::string Context;126  /// Region size name. Used for error reporting.127  StringRef SizePrintName = "size";128  /// Entry size name. Used for error reporting. If this field is empty, errors129  /// will not mention the entry size.130  StringRef EntSizePrintName = "entry size";131 132  template <typename Type> ArrayRef<Type> getAsArrayRef() const {133    const Type *Start = reinterpret_cast<const Type *>(Addr);134    if (!Start)135      return {Start, Start};136 137    const uint64_t Offset =138        Addr - (const uint8_t *)Obj->getMemoryBufferRef().getBufferStart();139    const uint64_t ObjSize = Obj->getMemoryBufferRef().getBufferSize();140 141    if (Size > ObjSize - Offset) {142      Dumper->reportUniqueWarning(143          "unable to read data at 0x" + Twine::utohexstr(Offset) +144          " of size 0x" + Twine::utohexstr(Size) + " (" + SizePrintName +145          "): it goes past the end of the file of size 0x" +146          Twine::utohexstr(ObjSize));147      return {Start, Start};148    }149 150    if (EntSize == sizeof(Type) && (Size % EntSize == 0))151      return {Start, Start + (Size / EntSize)};152 153    std::string Msg;154    if (!Context.empty())155      Msg += Context + " has ";156 157    Msg += ("invalid " + SizePrintName + " (0x" + Twine::utohexstr(Size) + ")")158               .str();159    if (!EntSizePrintName.empty())160      Msg +=161          (" or " + EntSizePrintName + " (0x" + Twine::utohexstr(EntSize) + ")")162              .str();163 164    Dumper->reportUniqueWarning(Msg);165    return {Start, Start};166  }167};168 169struct GroupMember {170  StringRef Name;171  uint64_t Index;172};173 174struct GroupSection {175  StringRef Name;176  std::string Signature;177  uint64_t ShName;178  uint64_t Index;179  uint32_t Link;180  uint32_t Info;181  uint32_t Type;182  std::vector<GroupMember> Members;183};184 185namespace {186 187struct NoteType {188  uint32_t ID;189  StringRef Name;190};191 192} // namespace193 194template <class ELFT> class Relocation {195public:196  Relocation(const typename ELFT::Rel &R, bool IsMips64EL)197      : Type(R.getType(IsMips64EL)), Symbol(R.getSymbol(IsMips64EL)),198        Offset(R.r_offset), Info(R.r_info) {}199 200  Relocation(const typename ELFT::Rela &R, bool IsMips64EL)201      : Relocation((const typename ELFT::Rel &)R, IsMips64EL) {202    Addend = R.r_addend;203  }204 205  uint32_t Type;206  uint32_t Symbol;207  typename ELFT::uint Offset;208  typename ELFT::uint Info;209  std::optional<int64_t> Addend;210};211 212template <class ELFT> class MipsGOTParser;213 214template <typename ELFT> class ELFDumper : public ObjDumper {215  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)216 217public:218  ELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer);219 220  void printUnwindInfo() override;221  void printNeededLibraries() override;222  void printHashTable() override;223  void printGnuHashTable() override;224  void printLoadName() override;225  void printVersionInfo() override;226  void printArchSpecificInfo() override;227  void printStackMap() const override;228  void printMemtag() override;229  void printSectionsAsSFrame(ArrayRef<std::string> Sections) override;230 231  ArrayRef<uint8_t> getMemtagGlobalsSectionContents(uint64_t ExpectedAddr);232 233  // Hash histogram shows statistics of how efficient the hash was for the234  // dynamic symbol table. The table shows the number of hash buckets for235  // different lengths of chains as an absolute number and percentage of the236  // total buckets, and the cumulative coverage of symbols for each set of237  // buckets.238  void printHashHistograms() override;239 240  const object::ELFObjectFile<ELFT> &getElfObject() const { return ObjF; };241 242  std::string describe(const Elf_Shdr &Sec) const;243 244  unsigned getHashTableEntSize() const {245    // EM_S390 and ELF::EM_ALPHA platforms use 8-bytes entries in SHT_HASH246    // sections. This violates the ELF specification.247    if (Obj.getHeader().e_machine == ELF::EM_S390 ||248        Obj.getHeader().e_machine == ELF::EM_ALPHA)249      return 8;250    return 4;251  }252 253  std::vector<EnumEntry<unsigned>>254  getOtherFlagsFromSymbol(const Elf_Ehdr &Header, const Elf_Sym &Symbol) const;255 256  Elf_Dyn_Range dynamic_table() const {257    // A valid .dynamic section contains an array of entries terminated258    // with a DT_NULL entry. However, sometimes the section content may259    // continue past the DT_NULL entry, so to dump the section correctly,260    // we first find the end of the entries by iterating over them.261    Elf_Dyn_Range Table = DynamicTable.template getAsArrayRef<Elf_Dyn>();262 263    size_t Size = 0;264    while (Size < Table.size())265      if (Table[Size++].getTag() == DT_NULL)266        break;267 268    return Table.slice(0, Size);269  }270 271  Elf_Sym_Range dynamic_symbols() const {272    if (!DynSymRegion)273      return Elf_Sym_Range();274    return DynSymRegion->template getAsArrayRef<Elf_Sym>();275  }276 277  const Elf_Shdr *findSectionByName(StringRef Name) const;278 279  StringRef getDynamicStringTable() const { return DynamicStringTable; }280 281protected:282  virtual void printVersionSymbolSection(const Elf_Shdr *Sec) = 0;283  virtual void printVersionDefinitionSection(const Elf_Shdr *Sec) = 0;284  virtual void printVersionDependencySection(const Elf_Shdr *Sec) = 0;285 286  void287  printDependentLibsHelper(function_ref<void(const Elf_Shdr &)> OnSectionStart,288                           function_ref<void(StringRef, uint64_t)> OnLibEntry);289 290  virtual void printRelRelaReloc(const Relocation<ELFT> &R,291                                 const RelSymbol<ELFT> &RelSym) = 0;292  virtual void printDynamicRelocHeader(unsigned Type, StringRef Name,293                                       const DynRegionInfo &Reg) {}294  void printReloc(const Relocation<ELFT> &R, unsigned RelIndex,295                  const Elf_Shdr &Sec, const Elf_Shdr *SymTab);296  void printDynamicReloc(const Relocation<ELFT> &R);297  void printDynamicRelocationsHelper();298  void printRelocationsHelper(const Elf_Shdr &Sec);299  void forEachRelocationDo(300      const Elf_Shdr &Sec,301      llvm::function_ref<void(const Relocation<ELFT> &, unsigned,302                              const Elf_Shdr &, const Elf_Shdr *)>303          RelRelaFn);304 305  virtual void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset,306                                  bool NonVisibilityBitsUsed,307                                  bool ExtraSymInfo) const {};308  virtual void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,309                           DataRegion<Elf_Word> ShndxTable,310                           std::optional<StringRef> StrTable, bool IsDynamic,311                           bool NonVisibilityBitsUsed,312                           bool ExtraSymInfo) const = 0;313 314  virtual void printMipsABIFlags() = 0;315  virtual void printMipsGOT(const MipsGOTParser<ELFT> &Parser) = 0;316  virtual void printMipsPLT(const MipsGOTParser<ELFT> &Parser) = 0;317 318  virtual void printMemtag(319      const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,320      const ArrayRef<uint8_t> AndroidNoteDesc,321      const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) = 0;322 323  virtual void printHashHistogram(const Elf_Hash &HashTable) const;324  virtual void printGnuHashHistogram(const Elf_GnuHash &GnuHashTable) const;325  virtual void printHashHistogramStats(size_t NBucket, size_t MaxChain,326                                       size_t TotalSyms, ArrayRef<size_t> Count,327                                       bool IsGnu) const = 0;328 329  Expected<ArrayRef<Elf_Versym>>330  getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,331                  StringRef *StrTab, const Elf_Shdr **SymTabSec) const;332  StringRef getPrintableSectionName(const Elf_Shdr &Sec) const;333 334  std::vector<GroupSection> getGroups();335 336  // Returns the function symbol index for the given address. Matches the337  // symbol's section with FunctionSec when specified.338  // Returns std::nullopt if no function symbol can be found for the address or339  // in case it is not defined in the specified section.340  SmallVector<uint32_t> getSymbolIndexesForFunctionAddress(341      uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec);342  bool printFunctionStackSize(uint64_t SymValue,343                              std::optional<const Elf_Shdr *> FunctionSec,344                              const Elf_Shdr &StackSizeSec, DataExtractor Data,345                              uint64_t *Offset);346  void printStackSize(const Relocation<ELFT> &R, const Elf_Shdr &RelocSec,347                      unsigned Ndx, const Elf_Shdr *SymTab,348                      const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec,349                      const RelocationResolver &Resolver, DataExtractor Data);350  virtual void printStackSizeEntry(uint64_t Size,351                                   ArrayRef<std::string> FuncNames) = 0;352 353  void printRelocatableStackSizes(std::function<void()> PrintHeader);354  void printNonRelocatableStackSizes(std::function<void()> PrintHeader);355 356  const object::ELFObjectFile<ELFT> &ObjF;357  const ELFFile<ELFT> &Obj;358  StringRef FileName;359 360  Expected<DynRegionInfo> createDRI(uint64_t Offset, uint64_t Size,361                                    uint64_t EntSize) {362    if (Offset + Size < Offset || Offset + Size > Obj.getBufSize())363      return createError("offset (0x" + Twine::utohexstr(Offset) +364                         ") + size (0x" + Twine::utohexstr(Size) +365                         ") is greater than the file size (0x" +366                         Twine::utohexstr(Obj.getBufSize()) + ")");367    return DynRegionInfo(ObjF, *this, Obj.base() + Offset, Size, EntSize);368  }369 370  void printAttributes(unsigned, std::unique_ptr<ELFAttributeParser>,371                       llvm::endianness);372  void printMipsReginfo();373  void printMipsOptions();374 375  std::pair<const Elf_Phdr *, const Elf_Shdr *> findDynamic();376  void loadDynamicTable();377  void parseDynamicTable();378 379  Expected<StringRef> getSymbolVersion(const Elf_Sym &Sym,380                                       bool &IsDefault) const;381  Expected<SmallVector<std::optional<VersionEntry>, 0> *> getVersionMap() const;382 383  DynRegionInfo DynRelRegion;384  DynRegionInfo DynRelaRegion;385  DynRegionInfo DynCrelRegion;386  DynRegionInfo DynRelrRegion;387  DynRegionInfo DynPLTRelRegion;388  std::optional<DynRegionInfo> DynSymRegion;389  DynRegionInfo DynSymTabShndxRegion;390  DynRegionInfo DynamicTable;391  StringRef DynamicStringTable;392  const Elf_Hash *HashTable = nullptr;393  const Elf_GnuHash *GnuHashTable = nullptr;394  const Elf_Shdr *DotSymtabSec = nullptr;395  const Elf_Shdr *DotDynsymSec = nullptr;396  const Elf_Shdr *DotAddrsigSec = nullptr;397  DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;398  std::optional<uint64_t> SONameOffset;399  std::optional<DenseMap<uint64_t, std::vector<uint32_t>>> AddressToIndexMap;400 401  const Elf_Shdr *SymbolVersionSection = nullptr;   // .gnu.version402  const Elf_Shdr *SymbolVersionNeedSection = nullptr; // .gnu.version_r403  const Elf_Shdr *SymbolVersionDefSection = nullptr; // .gnu.version_d404 405  std::string getFullSymbolName(const Elf_Sym &Symbol, unsigned SymIndex,406                                DataRegion<Elf_Word> ShndxTable,407                                std::optional<StringRef> StrTable,408                                bool IsDynamic) const;409  Expected<unsigned>410  getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex,411                        DataRegion<Elf_Word> ShndxTable) const;412  Expected<StringRef> getSymbolSectionName(const Elf_Sym &Symbol,413                                           unsigned SectionIndex) const;414  std::string getStaticSymbolName(uint32_t Index) const;415  StringRef getDynamicString(uint64_t Value) const;416 417  std::pair<Elf_Sym_Range, std::optional<StringRef>> getSymtabAndStrtab() const;418  void printSymbolsHelper(bool IsDynamic, bool ExtraSymInfo) const;419  std::string getDynamicEntry(uint64_t Type, uint64_t Value) const;420 421  Expected<RelSymbol<ELFT>> getRelocationTarget(const Relocation<ELFT> &R,422                                                const Elf_Shdr *SymTab) const;423 424  ArrayRef<Elf_Word> getShndxTable(const Elf_Shdr *Symtab) const;425 426  void printSFrameHeader(const SFrameParser<ELFT::Endianness> &Parser);427  void printSFrameFDEs(const SFrameParser<ELFT::Endianness> &Parser,428                       ArrayRef<Relocation<ELFT>> Relocations,429                       const Elf_Shdr *RelocSymTab);430  uint64_t getAndPrintSFrameFDEStartAddress(431      const SFrameParser<ELFT::Endianness> &Parser,432      const typename SFrameParser<ELFT::Endianness>::FDERange::iterator FDE,433      ArrayRef<Relocation<ELFT>> Relocations, const Elf_Shdr *RelocSymTab);434 435private:436  mutable SmallVector<std::optional<VersionEntry>, 0> VersionMap;437};438 439template <class ELFT>440std::string ELFDumper<ELFT>::describe(const Elf_Shdr &Sec) const {441  return ::describe(Obj, Sec);442}443 444namespace {445 446template <class ELFT> struct SymtabLink {447  typename ELFT::SymRange Symbols;448  StringRef StringTable;449  const typename ELFT::Shdr *SymTab;450};451 452// Returns the linked symbol table, symbols and associated string table for a453// given section.454template <class ELFT>455Expected<SymtabLink<ELFT>> getLinkAsSymtab(const ELFFile<ELFT> &Obj,456                                           const typename ELFT::Shdr &Sec,457                                           unsigned ExpectedType) {458  Expected<const typename ELFT::Shdr *> SymtabOrErr =459      Obj.getSection(Sec.sh_link);460  if (!SymtabOrErr)461    return createError("invalid section linked to " + describe(Obj, Sec) +462                       ": " + toString(SymtabOrErr.takeError()));463 464  if ((*SymtabOrErr)->sh_type != ExpectedType)465    return createError(466        "invalid section linked to " + describe(Obj, Sec) + ": expected " +467        object::getELFSectionTypeName(Obj.getHeader().e_machine, ExpectedType) +468        ", but got " +469        object::getELFSectionTypeName(Obj.getHeader().e_machine,470                                      (*SymtabOrErr)->sh_type));471 472  Expected<StringRef> StrTabOrErr = Obj.getLinkAsStrtab(**SymtabOrErr);473  if (!StrTabOrErr)474    return createError(475        "can't get a string table for the symbol table linked to " +476        describe(Obj, Sec) + ": " + toString(StrTabOrErr.takeError()));477 478  Expected<typename ELFT::SymRange> SymsOrErr = Obj.symbols(*SymtabOrErr);479  if (!SymsOrErr)480    return createError("unable to read symbols from the " + describe(Obj, Sec) +481                       ": " + toString(SymsOrErr.takeError()));482 483  return SymtabLink<ELFT>{*SymsOrErr, *StrTabOrErr, *SymtabOrErr};484}485 486} // namespace487 488template <class ELFT>489Expected<ArrayRef<typename ELFT::Versym>>490ELFDumper<ELFT>::getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,491                                 StringRef *StrTab,492                                 const Elf_Shdr **SymTabSec) const {493  assert((!SymTab && !StrTab && !SymTabSec) || (SymTab && StrTab && SymTabSec));494  if (reinterpret_cast<uintptr_t>(Obj.base() + Sec.sh_offset) %495          sizeof(uint16_t) !=496      0)497    return createError("the " + describe(Sec) + " is misaligned");498 499  Expected<ArrayRef<Elf_Versym>> VersionsOrErr =500      Obj.template getSectionContentsAsArray<Elf_Versym>(Sec);501  if (!VersionsOrErr)502    return createError("cannot read content of " + describe(Sec) + ": " +503                       toString(VersionsOrErr.takeError()));504 505  Expected<SymtabLink<ELFT>> SymTabOrErr =506      getLinkAsSymtab(Obj, Sec, SHT_DYNSYM);507  if (!SymTabOrErr) {508    reportUniqueWarning(SymTabOrErr.takeError());509    return *VersionsOrErr;510  }511 512  if (SymTabOrErr->Symbols.size() != VersionsOrErr->size())513    reportUniqueWarning(describe(Sec) + ": the number of entries (" +514                        Twine(VersionsOrErr->size()) +515                        ") does not match the number of symbols (" +516                        Twine(SymTabOrErr->Symbols.size()) +517                        ") in the symbol table with index " +518                        Twine(Sec.sh_link));519 520  if (SymTab) {521    *SymTab = SymTabOrErr->Symbols;522    *StrTab = SymTabOrErr->StringTable;523    *SymTabSec = SymTabOrErr->SymTab;524  }525  return *VersionsOrErr;526}527 528template <class ELFT>529std::pair<typename ELFDumper<ELFT>::Elf_Sym_Range, std::optional<StringRef>>530ELFDumper<ELFT>::getSymtabAndStrtab() const {531  assert(DotSymtabSec);532  Elf_Sym_Range Syms(nullptr, nullptr);533  std::optional<StringRef> StrTable;534  if (Expected<StringRef> StrTableOrErr =535          Obj.getStringTableForSymtab(*DotSymtabSec))536    StrTable = *StrTableOrErr;537  else538    reportUniqueWarning(539        "unable to get the string table for the SHT_SYMTAB section: " +540        toString(StrTableOrErr.takeError()));541 542  if (Expected<Elf_Sym_Range> SymsOrErr = Obj.symbols(DotSymtabSec))543    Syms = *SymsOrErr;544  else545    reportUniqueWarning("unable to read symbols from the SHT_SYMTAB section: " +546                        toString(SymsOrErr.takeError()));547  return {Syms, StrTable};548}549 550template <class ELFT>551void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic,552                                         bool ExtraSymInfo) const {553  std::optional<StringRef> StrTable;554  size_t Entries = 0;555  Elf_Sym_Range Syms(nullptr, nullptr);556  const Elf_Shdr *SymtabSec = IsDynamic ? DotDynsymSec : DotSymtabSec;557 558  if (IsDynamic) {559    StrTable = DynamicStringTable;560    Syms = dynamic_symbols();561    Entries = Syms.size();562  } else if (DotSymtabSec) {563    std::tie(Syms, StrTable) = getSymtabAndStrtab();564    Entries = DotSymtabSec->getEntityCount();565  }566  if (Syms.empty())567    return;568 569  // The st_other field has 2 logical parts. The first two bits hold the symbol570  // visibility (STV_*) and the remainder hold other platform-specific values.571  bool NonVisibilityBitsUsed =572      llvm::any_of(Syms, [](const Elf_Sym &S) { return S.st_other & ~0x3; });573 574  DataRegion<Elf_Word> ShndxTable =575      IsDynamic ? DataRegion<Elf_Word>(576                      (const Elf_Word *)this->DynSymTabShndxRegion.Addr,577                      this->getElfObject().getELFFile().end())578                : DataRegion<Elf_Word>(this->getShndxTable(SymtabSec));579 580  printSymtabMessage(SymtabSec, Entries, NonVisibilityBitsUsed, ExtraSymInfo);581  for (const Elf_Sym &Sym : Syms)582    printSymbol(Sym, &Sym - Syms.begin(), ShndxTable, StrTable, IsDynamic,583                NonVisibilityBitsUsed, ExtraSymInfo);584}585 586template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {587  formatted_raw_ostream &OS;588 589public:590  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)591 592  GNUELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)593      : ELFDumper<ELFT>(ObjF, Writer),594        OS(static_cast<formatted_raw_ostream &>(Writer.getOStream())) {595    assert(&this->W.getOStream() == &llvm::fouts());596  }597 598  void printFileSummary(StringRef FileStr, ObjectFile &Obj,599                        ArrayRef<std::string> InputFilenames,600                        const Archive *A) override;601  void printFileHeaders() override;602  void printGroupSections() override;603  void printRelocations() override;604  void printSectionHeaders() override;605  void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,606                    bool ExtraSymInfo) override;607  void printHashSymbols() override;608  void printSectionDetails() override;609  void printDependentLibs() override;610  void printDynamicTable() override;611  void printDynamicRelocations() override;612  void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset,613                          bool NonVisibilityBitsUsed,614                          bool ExtraSymInfo) const override;615  void printProgramHeaders(bool PrintProgramHeaders,616                           cl::boolOrDefault PrintSectionMapping) override;617  void printVersionSymbolSection(const Elf_Shdr *Sec) override;618  void printVersionDefinitionSection(const Elf_Shdr *Sec) override;619  void printVersionDependencySection(const Elf_Shdr *Sec) override;620  void printCGProfile() override;621  void printBBAddrMaps(bool PrettyPGOAnalysis) override;622  void printAddrsig() override;623  void printNotes() override;624  void printELFLinkerOptions() override;625  void printStackSizes() override;626  void printMemtag(627      const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,628      const ArrayRef<uint8_t> AndroidNoteDesc,629      const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) override;630  void printHashHistogramStats(size_t NBucket, size_t MaxChain,631                               size_t TotalSyms, ArrayRef<size_t> Count,632                               bool IsGnu) const override;633 634private:635  void printHashTableSymbols(const Elf_Hash &HashTable);636  void printGnuHashTableSymbols(const Elf_GnuHash &GnuHashTable);637 638  struct Field {639    std::string Str;640    unsigned Column;641 642    Field(StringRef S, unsigned Col) : Str(std::string(S)), Column(Col) {}643    Field(unsigned Col) : Column(Col) {}644  };645 646  template <typename T, typename TEnum>647  std::string printFlags(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues,648                         TEnum EnumMask1 = {}, TEnum EnumMask2 = {},649                         TEnum EnumMask3 = {}) const {650    std::string Str;651    for (const EnumEntry<TEnum> &Flag : EnumValues) {652      if (Flag.Value == 0)653        continue;654 655      TEnum EnumMask{};656      if (Flag.Value & EnumMask1)657        EnumMask = EnumMask1;658      else if (Flag.Value & EnumMask2)659        EnumMask = EnumMask2;660      else if (Flag.Value & EnumMask3)661        EnumMask = EnumMask3;662      bool IsEnum = (Flag.Value & EnumMask) != 0;663      if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||664          (IsEnum && (Value & EnumMask) == Flag.Value)) {665        if (!Str.empty())666          Str += ", ";667        Str += Flag.AltName;668      }669    }670    return Str;671  }672 673  formatted_raw_ostream &printField(struct Field F) const {674    if (F.Column != 0)675      OS.PadToColumn(F.Column);676    OS << F.Str;677    OS.flush();678    return OS;679  }680  void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex,681                         DataRegion<Elf_Word> ShndxTable, StringRef StrTable,682                         uint32_t Bucket);683  void printRelr(const Elf_Shdr &Sec);684  void printRelRelaReloc(const Relocation<ELFT> &R,685                         const RelSymbol<ELFT> &RelSym) override;686  void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,687                   DataRegion<Elf_Word> ShndxTable,688                   std::optional<StringRef> StrTable, bool IsDynamic,689                   bool NonVisibilityBitsUsed,690                   bool ExtraSymInfo) const override;691  void printDynamicRelocHeader(unsigned Type, StringRef Name,692                               const DynRegionInfo &Reg) override;693 694  std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex,695                                  DataRegion<Elf_Word> ShndxTable,696                                  bool ExtraSymInfo = false) const;697  void printProgramHeaders() override;698  void printSectionMapping() override;699  void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec,700                                    const Twine &Label, unsigned EntriesNum);701 702  void printStackSizeEntry(uint64_t Size,703                           ArrayRef<std::string> FuncNames) override;704 705  void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;706  void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;707  void printMipsABIFlags() override;708};709 710template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {711public:712  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)713 714  LLVMELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)715      : ELFDumper<ELFT>(ObjF, Writer), W(Writer) {}716 717  void printFileHeaders() override;718  void printGroupSections() override;719  void printRelocations() override;720  void printSectionHeaders() override;721  void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,722                    bool ExtraSymInfo) override;723  void printDependentLibs() override;724  void printDynamicTable() override;725  void printDynamicRelocations() override;726  void printProgramHeaders(bool PrintProgramHeaders,727                           cl::boolOrDefault PrintSectionMapping) override;728  void printVersionSymbolSection(const Elf_Shdr *Sec) override;729  void printVersionDefinitionSection(const Elf_Shdr *Sec) override;730  void printVersionDependencySection(const Elf_Shdr *Sec) override;731  void printCGProfile() override;732  void printBBAddrMaps(bool PrettyPGOAnalysis) override;733  void printAddrsig() override;734  void printNotes() override;735  void printELFLinkerOptions() override;736  void printStackSizes() override;737  void printMemtag(738      const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,739      const ArrayRef<uint8_t> AndroidNoteDesc,740      const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) override;741  void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex,742                          DataRegion<Elf_Word> ShndxTable) const;743  void printHashHistogramStats(size_t NBucket, size_t MaxChain,744                               size_t TotalSyms, ArrayRef<size_t> Count,745                               bool IsGnu) const override;746 747private:748  void printRelRelaReloc(const Relocation<ELFT> &R,749                         const RelSymbol<ELFT> &RelSym) override;750 751  void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,752                   DataRegion<Elf_Word> ShndxTable,753                   std::optional<StringRef> StrTable, bool IsDynamic,754                   bool /*NonVisibilityBitsUsed*/,755                   bool /*ExtraSymInfo*/) const override;756  void printProgramHeaders() override;757  void printSectionMapping() override {}758  void printStackSizeEntry(uint64_t Size,759                           ArrayRef<std::string> FuncNames) override;760 761  void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;762  void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;763  void printMipsABIFlags() override;764  virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const;765 766protected:767  virtual std::string getGroupSectionHeaderName() const;768  void printSymbolOtherField(const Elf_Sym &Symbol) const;769  virtual void printExpandedRelRelaReloc(const Relocation<ELFT> &R,770                                         StringRef SymbolName,771                                         StringRef RelocName);772  virtual void printDefaultRelRelaReloc(const Relocation<ELFT> &R,773                                        StringRef SymbolName,774                                        StringRef RelocName);775  virtual void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name,776                                          const unsigned SecNdx);777  virtual void printSectionGroupMembers(StringRef Name, uint64_t Idx) const;778  virtual void printEmptyGroupMessage() const;779 780  ScopedPrinter &W;781};782 783// JSONELFDumper shares most of the same implementation as LLVMELFDumper except784// it uses a JSONScopedPrinter.785template <typename ELFT> class JSONELFDumper : public LLVMELFDumper<ELFT> {786public:787  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)788 789  JSONELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)790      : LLVMELFDumper<ELFT>(ObjF, Writer) {}791 792  std::string getGroupSectionHeaderName() const override;793 794  void printFileSummary(StringRef FileStr, ObjectFile &Obj,795                        ArrayRef<std::string> InputFilenames,796                        const Archive *A) override;797  void printZeroSymbolOtherField(const Elf_Sym &Symbol) const override;798 799  void printDefaultRelRelaReloc(const Relocation<ELFT> &R,800                                StringRef SymbolName,801                                StringRef RelocName) override;802 803  void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name,804                                  const unsigned SecNdx) override;805 806  void printSectionGroupMembers(StringRef Name, uint64_t Idx) const override;807 808  void printEmptyGroupMessage() const override;809 810  void printDynamicTable() override;811 812private:813  void printAuxillaryDynamicTableEntryInfo(const Elf_Dyn &Entry);814 815  std::unique_ptr<DictScope> FileScope;816};817 818} // end anonymous namespace819 820namespace llvm {821 822template <class ELFT>823static std::unique_ptr<ObjDumper>824createELFDumper(const ELFObjectFile<ELFT> &Obj, ScopedPrinter &Writer) {825  if (opts::Output == opts::GNU)826    return std::make_unique<GNUELFDumper<ELFT>>(Obj, Writer);827  else if (opts::Output == opts::JSON)828    return std::make_unique<JSONELFDumper<ELFT>>(Obj, Writer);829  return std::make_unique<LLVMELFDumper<ELFT>>(Obj, Writer);830}831 832std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj,833                                           ScopedPrinter &Writer) {834  // Little-endian 32-bit835  if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(&Obj))836    return createELFDumper(*ELFObj, Writer);837 838  // Big-endian 32-bit839  if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(&Obj))840    return createELFDumper(*ELFObj, Writer);841 842  // Little-endian 64-bit843  if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(&Obj))844    return createELFDumper(*ELFObj, Writer);845 846  // Big-endian 64-bit847  return createELFDumper(*cast<ELF64BEObjectFile>(&Obj), Writer);848}849 850} // end namespace llvm851 852template <class ELFT>853Expected<SmallVector<std::optional<VersionEntry>, 0> *>854ELFDumper<ELFT>::getVersionMap() const {855  // If the VersionMap has already been loaded or if there is no dynamic symtab856  // or version table, there is nothing to do.857  if (!VersionMap.empty() || !DynSymRegion || !SymbolVersionSection)858    return &VersionMap;859 860  Expected<SmallVector<std::optional<VersionEntry>, 0>> MapOrErr =861      Obj.loadVersionMap(SymbolVersionNeedSection, SymbolVersionDefSection);862  if (MapOrErr)863    VersionMap = *MapOrErr;864  else865    return MapOrErr.takeError();866 867  return &VersionMap;868}869 870template <typename ELFT>871Expected<StringRef> ELFDumper<ELFT>::getSymbolVersion(const Elf_Sym &Sym,872                                                      bool &IsDefault) const {873  // This is a dynamic symbol. Look in the GNU symbol version table.874  if (!SymbolVersionSection) {875    // No version table.876    IsDefault = false;877    return "";878  }879 880  assert(DynSymRegion && "DynSymRegion has not been initialised");881  // Determine the position in the symbol table of this entry.882  size_t EntryIndex = (reinterpret_cast<uintptr_t>(&Sym) -883                       reinterpret_cast<uintptr_t>(DynSymRegion->Addr)) /884                      sizeof(Elf_Sym);885 886  // Get the corresponding version index entry.887  Expected<const Elf_Versym *> EntryOrErr =888      Obj.template getEntry<Elf_Versym>(*SymbolVersionSection, EntryIndex);889  if (!EntryOrErr)890    return EntryOrErr.takeError();891 892  unsigned Version = (*EntryOrErr)->vs_index;893  if (Version == VER_NDX_LOCAL || Version == VER_NDX_GLOBAL) {894    IsDefault = false;895    return "";896  }897 898  Expected<SmallVector<std::optional<VersionEntry>, 0> *> MapOrErr =899      getVersionMap();900  if (!MapOrErr)901    return MapOrErr.takeError();902 903  return Obj.getSymbolVersionByIndex(Version, IsDefault, **MapOrErr,904                                     Sym.st_shndx == ELF::SHN_UNDEF);905}906 907template <typename ELFT>908Expected<RelSymbol<ELFT>>909ELFDumper<ELFT>::getRelocationTarget(const Relocation<ELFT> &R,910                                     const Elf_Shdr *SymTab) const {911  if (R.Symbol == 0)912    return RelSymbol<ELFT>(nullptr, "");913 914  Expected<const Elf_Sym *> SymOrErr =915      Obj.template getEntry<Elf_Sym>(*SymTab, R.Symbol);916  if (!SymOrErr)917    return createError("unable to read an entry with index " + Twine(R.Symbol) +918                       " from " + describe(*SymTab) + ": " +919                       toString(SymOrErr.takeError()));920  const Elf_Sym *Sym = *SymOrErr;921  if (!Sym)922    return RelSymbol<ELFT>(nullptr, "");923 924  Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(*SymTab);925  if (!StrTableOrErr)926    return StrTableOrErr.takeError();927 928  const Elf_Sym *FirstSym =929      cantFail(Obj.template getEntry<Elf_Sym>(*SymTab, 0));930  std::string SymbolName =931      getFullSymbolName(*Sym, Sym - FirstSym, getShndxTable(SymTab),932                        *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM);933  return RelSymbol<ELFT>(Sym, SymbolName);934}935 936template <typename ELFT>937ArrayRef<typename ELFT::Word>938ELFDumper<ELFT>::getShndxTable(const Elf_Shdr *Symtab) const {939  if (Symtab) {940    auto It = ShndxTables.find(Symtab);941    if (It != ShndxTables.end())942      return It->second;943  }944  return {};945}946 947static std::string maybeDemangle(StringRef Name) {948  return opts::Demangle ? demangle(Name) : Name.str();949}950 951template <typename ELFT>952std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {953  auto Warn = [&](Error E) -> std::string {954    reportUniqueWarning("unable to read the name of symbol with index " +955                        Twine(Index) + ": " + toString(std::move(E)));956    return "<?>";957  };958 959  Expected<const typename ELFT::Sym *> SymOrErr =960      Obj.getSymbol(DotSymtabSec, Index);961  if (!SymOrErr)962    return Warn(SymOrErr.takeError());963 964  Expected<StringRef> StrTabOrErr = Obj.getStringTableForSymtab(*DotSymtabSec);965  if (!StrTabOrErr)966    return Warn(StrTabOrErr.takeError());967 968  Expected<StringRef> NameOrErr = (*SymOrErr)->getName(*StrTabOrErr);969  if (!NameOrErr)970    return Warn(NameOrErr.takeError());971  return maybeDemangle(*NameOrErr);972}973 974template <typename ELFT>975std::string ELFDumper<ELFT>::getFullSymbolName(976    const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable,977    std::optional<StringRef> StrTable, bool IsDynamic) const {978  if (!StrTable)979    return "<?>";980 981  std::string SymbolName;982  if (Expected<StringRef> NameOrErr = Symbol.getName(*StrTable)) {983    SymbolName = maybeDemangle(*NameOrErr);984  } else {985    reportUniqueWarning(NameOrErr.takeError());986    return "<?>";987  }988 989  if (SymbolName.empty() && Symbol.getType() == ELF::STT_SECTION) {990    Expected<unsigned> SectionIndex =991        getSymbolSectionIndex(Symbol, SymIndex, ShndxTable);992    if (!SectionIndex) {993      reportUniqueWarning(SectionIndex.takeError());994      return "<?>";995    }996    Expected<StringRef> NameOrErr = getSymbolSectionName(Symbol, *SectionIndex);997    if (!NameOrErr) {998      reportUniqueWarning(NameOrErr.takeError());999      return ("<section " + Twine(*SectionIndex) + ">").str();1000    }1001    return std::string(*NameOrErr);1002  }1003 1004  if (!IsDynamic)1005    return SymbolName;1006 1007  bool IsDefault;1008  Expected<StringRef> VersionOrErr = getSymbolVersion(Symbol, IsDefault);1009  if (!VersionOrErr) {1010    reportUniqueWarning(VersionOrErr.takeError());1011    return SymbolName + "@<corrupt>";1012  }1013 1014  if (!VersionOrErr->empty()) {1015    SymbolName += (IsDefault ? "@@" : "@");1016    SymbolName += *VersionOrErr;1017  }1018  return SymbolName;1019}1020 1021template <typename ELFT>1022Expected<unsigned>1023ELFDumper<ELFT>::getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex,1024                                       DataRegion<Elf_Word> ShndxTable) const {1025  unsigned Ndx = Symbol.st_shndx;1026  if (Ndx == SHN_XINDEX)1027    return object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex,1028                                                     ShndxTable);1029  if (Ndx != SHN_UNDEF && Ndx < SHN_LORESERVE)1030    return Ndx;1031 1032  auto CreateErr = [&](const Twine &Name,1033                       std::optional<unsigned> Offset = std::nullopt) {1034    std::string Desc;1035    if (Offset)1036      Desc = (Name + "+0x" + Twine::utohexstr(*Offset)).str();1037    else1038      Desc = Name.str();1039    return createError(1040        "unable to get section index for symbol with st_shndx = 0x" +1041        Twine::utohexstr(Ndx) + " (" + Desc + ")");1042  };1043 1044  if (Ndx >= ELF::SHN_LOPROC && Ndx <= ELF::SHN_HIPROC)1045    return CreateErr("SHN_LOPROC", Ndx - ELF::SHN_LOPROC);1046  if (Ndx >= ELF::SHN_LOOS && Ndx <= ELF::SHN_HIOS)1047    return CreateErr("SHN_LOOS", Ndx - ELF::SHN_LOOS);1048  if (Ndx == ELF::SHN_UNDEF)1049    return CreateErr("SHN_UNDEF");1050  if (Ndx == ELF::SHN_ABS)1051    return CreateErr("SHN_ABS");1052  if (Ndx == ELF::SHN_COMMON)1053    return CreateErr("SHN_COMMON");1054  return CreateErr("SHN_LORESERVE", Ndx - SHN_LORESERVE);1055}1056 1057template <typename ELFT>1058Expected<StringRef>1059ELFDumper<ELFT>::getSymbolSectionName(const Elf_Sym &Symbol,1060                                      unsigned SectionIndex) const {1061  Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(SectionIndex);1062  if (!SecOrErr)1063    return SecOrErr.takeError();1064  return Obj.getSectionName(**SecOrErr);1065}1066 1067template <class ELFO>1068static const typename ELFO::Elf_Shdr *1069findNotEmptySectionByAddress(const ELFO &Obj, StringRef FileName,1070                             uint64_t Addr) {1071  for (const typename ELFO::Elf_Shdr &Shdr : cantFail(Obj.sections()))1072    if (Shdr.sh_addr == Addr && Shdr.sh_size > 0)1073      return &Shdr;1074  return nullptr;1075}1076 1077const EnumEntry<unsigned> ElfClass[] = {1078  {"None",   "none",   ELF::ELFCLASSNONE},1079  {"32-bit", "ELF32",  ELF::ELFCLASS32},1080  {"64-bit", "ELF64",  ELF::ELFCLASS64},1081};1082 1083const EnumEntry<unsigned> ElfDataEncoding[] = {1084  {"None",         "none",                          ELF::ELFDATANONE},1085  {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB},1086  {"BigEndian",    "2's complement, big endian",    ELF::ELFDATA2MSB},1087};1088 1089const EnumEntry<unsigned> ElfObjectFileType[] = {1090  {"None",         "NONE (none)",              ELF::ET_NONE},1091  {"Relocatable",  "REL (Relocatable file)",   ELF::ET_REL},1092  {"Executable",   "EXEC (Executable file)",   ELF::ET_EXEC},1093  {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN},1094  {"Core",         "CORE (Core file)",         ELF::ET_CORE},1095};1096 1097const EnumEntry<unsigned> ElfOSABI[] = {1098    {"SystemV", "UNIX - System V", ELF::ELFOSABI_NONE},1099    {"HPUX", "UNIX - HP-UX", ELF::ELFOSABI_HPUX},1100    {"NetBSD", "UNIX - NetBSD", ELF::ELFOSABI_NETBSD},1101    {"GNU/Linux", "UNIX - GNU", ELF::ELFOSABI_LINUX},1102    {"GNU/Hurd", "GNU/Hurd", ELF::ELFOSABI_HURD},1103    {"Solaris", "UNIX - Solaris", ELF::ELFOSABI_SOLARIS},1104    {"AIX", "UNIX - AIX", ELF::ELFOSABI_AIX},1105    {"IRIX", "UNIX - IRIX", ELF::ELFOSABI_IRIX},1106    {"FreeBSD", "UNIX - FreeBSD", ELF::ELFOSABI_FREEBSD},1107    {"TRU64", "UNIX - TRU64", ELF::ELFOSABI_TRU64},1108    {"Modesto", "Novell - Modesto", ELF::ELFOSABI_MODESTO},1109    {"OpenBSD", "UNIX - OpenBSD", ELF::ELFOSABI_OPENBSD},1110    {"OpenVMS", "VMS - OpenVMS", ELF::ELFOSABI_OPENVMS},1111    {"NSK", "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK},1112    {"AROS", "AROS", ELF::ELFOSABI_AROS},1113    {"FenixOS", "FenixOS", ELF::ELFOSABI_FENIXOS},1114    {"CloudABI", "CloudABI", ELF::ELFOSABI_CLOUDABI},1115    {"CUDA", "NVIDIA - CUDA", ELF::ELFOSABI_CUDA},1116    {"CUDA", "NVIDIA - CUDA", ELF::ELFOSABI_CUDA_V2},1117    {"Standalone", "Standalone App", ELF::ELFOSABI_STANDALONE}};1118 1119const EnumEntry<unsigned> AMDGPUElfOSABI[] = {1120  {"AMDGPU_HSA",    "AMDGPU - HSA",    ELF::ELFOSABI_AMDGPU_HSA},1121  {"AMDGPU_PAL",    "AMDGPU - PAL",    ELF::ELFOSABI_AMDGPU_PAL},1122  {"AMDGPU_MESA3D", "AMDGPU - MESA3D", ELF::ELFOSABI_AMDGPU_MESA3D}1123};1124 1125const EnumEntry<unsigned> ARMElfOSABI[] = {1126    {"ARM", "ARM", ELF::ELFOSABI_ARM},1127    {"ARM FDPIC", "ARM FDPIC", ELF::ELFOSABI_ARM_FDPIC},1128};1129 1130const EnumEntry<unsigned> C6000ElfOSABI[] = {1131  {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI},1132  {"C6000_LINUX",  "Linux C6000",      ELF::ELFOSABI_C6000_LINUX}1133};1134 1135// clang-format off1136const EnumEntry<unsigned> ElfMachineType[] = {1137  ENUM_ENT(EM_NONE,          "None"),1138  ENUM_ENT(EM_M32,           "WE32100"),1139  ENUM_ENT(EM_SPARC,         "Sparc"),1140  ENUM_ENT(EM_386,           "Intel 80386"),1141  ENUM_ENT(EM_68K,           "MC68000"),1142  ENUM_ENT(EM_88K,           "MC88000"),1143  ENUM_ENT(EM_IAMCU,         "EM_IAMCU"),1144  ENUM_ENT(EM_860,           "Intel 80860"),1145  ENUM_ENT(EM_MIPS,          "MIPS R3000"),1146  ENUM_ENT(EM_S370,          "IBM System/370"),1147  ENUM_ENT(EM_MIPS_RS3_LE,   "MIPS R3000 little-endian"),1148  ENUM_ENT(EM_PARISC,        "HPPA"),1149  ENUM_ENT(EM_VPP500,        "Fujitsu VPP500"),1150  ENUM_ENT(EM_SPARC32PLUS,   "Sparc v8+"),1151  ENUM_ENT(EM_960,           "Intel 80960"),1152  ENUM_ENT(EM_PPC,           "PowerPC"),1153  ENUM_ENT(EM_PPC64,         "PowerPC64"),1154  ENUM_ENT(EM_S390,          "IBM S/390"),1155  ENUM_ENT(EM_SPU,           "SPU"),1156  ENUM_ENT(EM_V800,          "NEC V800 series"),1157  ENUM_ENT(EM_FR20,          "Fujistsu FR20"),1158  ENUM_ENT(EM_RH32,          "TRW RH-32"),1159  ENUM_ENT(EM_RCE,           "Motorola RCE"),1160  ENUM_ENT(EM_ARM,           "ARM"),1161  ENUM_ENT(EM_ALPHA,         "EM_ALPHA"),1162  ENUM_ENT(EM_SH,            "Hitachi SH"),1163  ENUM_ENT(EM_SPARCV9,       "Sparc v9"),1164  ENUM_ENT(EM_TRICORE,       "Siemens Tricore"),1165  ENUM_ENT(EM_ARC,           "ARC"),1166  ENUM_ENT(EM_H8_300,        "Hitachi H8/300"),1167  ENUM_ENT(EM_H8_300H,       "Hitachi H8/300H"),1168  ENUM_ENT(EM_H8S,           "Hitachi H8S"),1169  ENUM_ENT(EM_H8_500,        "Hitachi H8/500"),1170  ENUM_ENT(EM_IA_64,         "Intel IA-64"),1171  ENUM_ENT(EM_MIPS_X,        "Stanford MIPS-X"),1172  ENUM_ENT(EM_COLDFIRE,      "Motorola Coldfire"),1173  ENUM_ENT(EM_68HC12,        "Motorola MC68HC12 Microcontroller"),1174  ENUM_ENT(EM_MMA,           "Fujitsu Multimedia Accelerator"),1175  ENUM_ENT(EM_PCP,           "Siemens PCP"),1176  ENUM_ENT(EM_NCPU,          "Sony nCPU embedded RISC processor"),1177  ENUM_ENT(EM_NDR1,          "Denso NDR1 microprocesspr"),1178  ENUM_ENT(EM_STARCORE,      "Motorola Star*Core processor"),1179  ENUM_ENT(EM_ME16,          "Toyota ME16 processor"),1180  ENUM_ENT(EM_ST100,         "STMicroelectronics ST100 processor"),1181  ENUM_ENT(EM_TINYJ,         "Advanced Logic Corp. TinyJ embedded processor"),1182  ENUM_ENT(EM_X86_64,        "Advanced Micro Devices X86-64"),1183  ENUM_ENT(EM_PDSP,          "Sony DSP processor"),1184  ENUM_ENT(EM_PDP10,         "Digital Equipment Corp. PDP-10"),1185  ENUM_ENT(EM_PDP11,         "Digital Equipment Corp. PDP-11"),1186  ENUM_ENT(EM_FX66,          "Siemens FX66 microcontroller"),1187  ENUM_ENT(EM_ST9PLUS,       "STMicroelectronics ST9+ 8/16 bit microcontroller"),1188  ENUM_ENT(EM_ST7,           "STMicroelectronics ST7 8-bit microcontroller"),1189  ENUM_ENT(EM_68HC16,        "Motorola MC68HC16 Microcontroller"),1190  ENUM_ENT(EM_68HC11,        "Motorola MC68HC11 Microcontroller"),1191  ENUM_ENT(EM_68HC08,        "Motorola MC68HC08 Microcontroller"),1192  ENUM_ENT(EM_68HC05,        "Motorola MC68HC05 Microcontroller"),1193  ENUM_ENT(EM_SVX,           "Silicon Graphics SVx"),1194  ENUM_ENT(EM_ST19,          "STMicroelectronics ST19 8-bit microcontroller"),1195  ENUM_ENT(EM_VAX,           "Digital VAX"),1196  ENUM_ENT(EM_CRIS,          "Axis Communications 32-bit embedded processor"),1197  ENUM_ENT(EM_JAVELIN,       "Infineon Technologies 32-bit embedded cpu"),1198  ENUM_ENT(EM_FIREPATH,      "Element 14 64-bit DSP processor"),1199  ENUM_ENT(EM_ZSP,           "LSI Logic's 16-bit DSP processor"),1200  ENUM_ENT(EM_MMIX,          "Donald Knuth's educational 64-bit processor"),1201  ENUM_ENT(EM_HUANY,         "Harvard Universitys's machine-independent object format"),1202  ENUM_ENT(EM_PRISM,         "Vitesse Prism"),1203  ENUM_ENT(EM_AVR,           "Atmel AVR 8-bit microcontroller"),1204  ENUM_ENT(EM_FR30,          "Fujitsu FR30"),1205  ENUM_ENT(EM_D10V,          "Mitsubishi D10V"),1206  ENUM_ENT(EM_D30V,          "Mitsubishi D30V"),1207  ENUM_ENT(EM_V850,          "NEC v850"),1208  ENUM_ENT(EM_M32R,          "Renesas M32R (formerly Mitsubishi M32r)"),1209  ENUM_ENT(EM_MN10300,       "Matsushita MN10300"),1210  ENUM_ENT(EM_MN10200,       "Matsushita MN10200"),1211  ENUM_ENT(EM_PJ,            "picoJava"),1212  ENUM_ENT(EM_OPENRISC,      "OpenRISC 32-bit embedded processor"),1213  ENUM_ENT(EM_ARC_COMPACT,   "EM_ARC_COMPACT"),1214  ENUM_ENT(EM_XTENSA,        "Tensilica Xtensa Processor"),1215  ENUM_ENT(EM_VIDEOCORE,     "Alphamosaic VideoCore processor"),1216  ENUM_ENT(EM_TMM_GPP,       "Thompson Multimedia General Purpose Processor"),1217  ENUM_ENT(EM_NS32K,         "National Semiconductor 32000 series"),1218  ENUM_ENT(EM_TPC,           "Tenor Network TPC processor"),1219  ENUM_ENT(EM_SNP1K,         "EM_SNP1K"),1220  ENUM_ENT(EM_ST200,         "STMicroelectronics ST200 microcontroller"),1221  ENUM_ENT(EM_IP2K,          "Ubicom IP2xxx 8-bit microcontrollers"),1222  ENUM_ENT(EM_MAX,           "MAX Processor"),1223  ENUM_ENT(EM_CR,            "National Semiconductor CompactRISC"),1224  ENUM_ENT(EM_F2MC16,        "Fujitsu F2MC16"),1225  ENUM_ENT(EM_MSP430,        "Texas Instruments msp430 microcontroller"),1226  ENUM_ENT(EM_BLACKFIN,      "Analog Devices Blackfin"),1227  ENUM_ENT(EM_SE_C33,        "S1C33 Family of Seiko Epson processors"),1228  ENUM_ENT(EM_SEP,           "Sharp embedded microprocessor"),1229  ENUM_ENT(EM_ARCA,          "Arca RISC microprocessor"),1230  ENUM_ENT(EM_UNICORE,       "Unicore"),1231  ENUM_ENT(EM_EXCESS,        "eXcess 16/32/64-bit configurable embedded CPU"),1232  ENUM_ENT(EM_DXP,           "Icera Semiconductor Inc. Deep Execution Processor"),1233  ENUM_ENT(EM_ALTERA_NIOS2,  "Altera Nios"),1234  ENUM_ENT(EM_CRX,           "National Semiconductor CRX microprocessor"),1235  ENUM_ENT(EM_XGATE,         "Motorola XGATE embedded processor"),1236  ENUM_ENT(EM_C166,          "Infineon Technologies xc16x"),1237  ENUM_ENT(EM_M16C,          "Renesas M16C"),1238  ENUM_ENT(EM_DSPIC30F,      "Microchip Technology dsPIC30F Digital Signal Controller"),1239  ENUM_ENT(EM_CE,            "Freescale Communication Engine RISC core"),1240  ENUM_ENT(EM_M32C,          "Renesas M32C"),1241  ENUM_ENT(EM_TSK3000,       "Altium TSK3000 core"),1242  ENUM_ENT(EM_RS08,          "Freescale RS08 embedded processor"),1243  ENUM_ENT(EM_SHARC,         "EM_SHARC"),1244  ENUM_ENT(EM_ECOG2,         "Cyan Technology eCOG2 microprocessor"),1245  ENUM_ENT(EM_SCORE7,        "SUNPLUS S+Core"),1246  ENUM_ENT(EM_DSP24,         "New Japan Radio (NJR) 24-bit DSP Processor"),1247  ENUM_ENT(EM_VIDEOCORE3,    "Broadcom VideoCore III processor"),1248  ENUM_ENT(EM_LATTICEMICO32, "Lattice Mico32"),1249  ENUM_ENT(EM_SE_C17,        "Seiko Epson C17 family"),1250  ENUM_ENT(EM_TI_C6000,      "Texas Instruments TMS320C6000 DSP family"),1251  ENUM_ENT(EM_TI_C2000,      "Texas Instruments TMS320C2000 DSP family"),1252  ENUM_ENT(EM_TI_C5500,      "Texas Instruments TMS320C55x DSP family"),1253  ENUM_ENT(EM_MMDSP_PLUS,    "STMicroelectronics 64bit VLIW Data Signal Processor"),1254  ENUM_ENT(EM_CYPRESS_M8C,   "Cypress M8C microprocessor"),1255  ENUM_ENT(EM_R32C,          "Renesas R32C series microprocessors"),1256  ENUM_ENT(EM_TRIMEDIA,      "NXP Semiconductors TriMedia architecture family"),1257  ENUM_ENT(EM_HEXAGON,       "Qualcomm Hexagon"),1258  ENUM_ENT(EM_8051,          "Intel 8051 and variants"),1259  ENUM_ENT(EM_STXP7X,        "STMicroelectronics STxP7x family"),1260  ENUM_ENT(EM_NDS32,         "Andes Technology compact code size embedded RISC processor family"),1261  ENUM_ENT(EM_ECOG1,         "Cyan Technology eCOG1 microprocessor"),1262  // FIXME: Following EM_ECOG1X definitions is dead code since EM_ECOG1X has1263  //        an identical number to EM_ECOG1.1264  ENUM_ENT(EM_ECOG1X,        "Cyan Technology eCOG1X family"),1265  ENUM_ENT(EM_MAXQ30,        "Dallas Semiconductor MAXQ30 Core microcontrollers"),1266  ENUM_ENT(EM_XIMO16,        "New Japan Radio (NJR) 16-bit DSP Processor"),1267  ENUM_ENT(EM_MANIK,         "M2000 Reconfigurable RISC Microprocessor"),1268  ENUM_ENT(EM_CRAYNV2,       "Cray Inc. NV2 vector architecture"),1269  ENUM_ENT(EM_RX,            "Renesas RX"),1270  ENUM_ENT(EM_METAG,         "Imagination Technologies Meta processor architecture"),1271  ENUM_ENT(EM_MCST_ELBRUS,   "MCST Elbrus general purpose hardware architecture"),1272  ENUM_ENT(EM_ECOG16,        "Cyan Technology eCOG16 family"),1273  ENUM_ENT(EM_CR16,          "National Semiconductor CompactRISC 16-bit processor"),1274  ENUM_ENT(EM_ETPU,          "Freescale Extended Time Processing Unit"),1275  ENUM_ENT(EM_SLE9X,         "Infineon Technologies SLE9X core"),1276  ENUM_ENT(EM_L10M,          "EM_L10M"),1277  ENUM_ENT(EM_K10M,          "EM_K10M"),1278  ENUM_ENT(EM_AARCH64,       "AArch64"),1279  ENUM_ENT(EM_AVR32,         "Atmel Corporation 32-bit microprocessor family"),1280  ENUM_ENT(EM_STM8,          "STMicroeletronics STM8 8-bit microcontroller"),1281  ENUM_ENT(EM_TILE64,        "Tilera TILE64 multicore architecture family"),1282  ENUM_ENT(EM_TILEPRO,       "Tilera TILEPro multicore architecture family"),1283  ENUM_ENT(EM_MICROBLAZE,    "Xilinx MicroBlaze 32-bit RISC soft processor core"),1284  ENUM_ENT(EM_CUDA,          "NVIDIA CUDA architecture"),1285  ENUM_ENT(EM_TILEGX,        "Tilera TILE-Gx multicore architecture family"),1286  ENUM_ENT(EM_CLOUDSHIELD,   "EM_CLOUDSHIELD"),1287  ENUM_ENT(EM_COREA_1ST,     "EM_COREA_1ST"),1288  ENUM_ENT(EM_COREA_2ND,     "EM_COREA_2ND"),1289  ENUM_ENT(EM_ARC_COMPACT2,  "EM_ARC_COMPACT2"),1290  ENUM_ENT(EM_OPEN8,         "EM_OPEN8"),1291  ENUM_ENT(EM_RL78,          "Renesas RL78"),1292  ENUM_ENT(EM_VIDEOCORE5,    "Broadcom VideoCore V processor"),1293  ENUM_ENT(EM_78KOR,         "EM_78KOR"),1294  ENUM_ENT(EM_56800EX,       "EM_56800EX"),1295  ENUM_ENT(EM_AMDGPU,        "EM_AMDGPU"),1296  ENUM_ENT(EM_RISCV,         "RISC-V"),1297  ENUM_ENT(EM_LANAI,         "EM_LANAI"),1298  ENUM_ENT(EM_BPF,           "EM_BPF"),1299  ENUM_ENT(EM_VE,            "NEC SX-Aurora Vector Engine"),1300  ENUM_ENT(EM_LOONGARCH,     "LoongArch"),1301  ENUM_ENT(EM_INTELGT,       "Intel Graphics Technology"),1302};1303// clang-format on1304 1305const EnumEntry<unsigned> ElfSymbolBindings[] = {1306    {"Local",  "LOCAL",  ELF::STB_LOCAL},1307    {"Global", "GLOBAL", ELF::STB_GLOBAL},1308    {"Weak",   "WEAK",   ELF::STB_WEAK},1309    {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE}};1310 1311const EnumEntry<unsigned> ElfSymbolVisibilities[] = {1312    {"DEFAULT",   "DEFAULT",   ELF::STV_DEFAULT},1313    {"INTERNAL",  "INTERNAL",  ELF::STV_INTERNAL},1314    {"HIDDEN",    "HIDDEN",    ELF::STV_HIDDEN},1315    {"PROTECTED", "PROTECTED", ELF::STV_PROTECTED}};1316 1317const EnumEntry<unsigned> AMDGPUSymbolTypes[] = {1318  { "AMDGPU_HSA_KERNEL",            ELF::STT_AMDGPU_HSA_KERNEL }1319};1320 1321static const char *getGroupType(uint32_t Flag) {1322  if (Flag & ELF::GRP_COMDAT)1323    return "COMDAT";1324  else1325    return "(unknown)";1326}1327 1328const EnumEntry<unsigned> ElfSectionFlags[] = {1329  ENUM_ENT(SHF_WRITE,            "W"),1330  ENUM_ENT(SHF_ALLOC,            "A"),1331  ENUM_ENT(SHF_EXECINSTR,        "X"),1332  ENUM_ENT(SHF_MERGE,            "M"),1333  ENUM_ENT(SHF_STRINGS,          "S"),1334  ENUM_ENT(SHF_INFO_LINK,        "I"),1335  ENUM_ENT(SHF_LINK_ORDER,       "L"),1336  ENUM_ENT(SHF_OS_NONCONFORMING, "O"),1337  ENUM_ENT(SHF_GROUP,            "G"),1338  ENUM_ENT(SHF_TLS,              "T"),1339  ENUM_ENT(SHF_COMPRESSED,       "C"),1340  ENUM_ENT(SHF_EXCLUDE,          "E"),1341};1342 1343const EnumEntry<unsigned> ElfGNUSectionFlags[] = {1344  ENUM_ENT(SHF_GNU_RETAIN, "R")1345};1346 1347const EnumEntry<unsigned> ElfSolarisSectionFlags[] = {1348  ENUM_ENT(SHF_SUNW_NODISCARD, "R")1349};1350 1351const EnumEntry<unsigned> ElfXCoreSectionFlags[] = {1352  ENUM_ENT(XCORE_SHF_CP_SECTION, ""),1353  ENUM_ENT(XCORE_SHF_DP_SECTION, "")1354};1355 1356const EnumEntry<unsigned> ElfAArch64SectionFlags[] = {1357  ENUM_ENT(SHF_AARCH64_PURECODE, "y")1358};1359 1360const EnumEntry<unsigned> ElfARMSectionFlags[] = {1361  ENUM_ENT(SHF_ARM_PURECODE, "y")1362};1363 1364const EnumEntry<unsigned> ElfHexagonSectionFlags[] = {1365  ENUM_ENT(SHF_HEX_GPREL, "")1366};1367 1368const EnumEntry<unsigned> ElfMipsSectionFlags[] = {1369  ENUM_ENT(SHF_MIPS_NODUPES, ""),1370  ENUM_ENT(SHF_MIPS_NAMES,   ""),1371  ENUM_ENT(SHF_MIPS_LOCAL,   ""),1372  ENUM_ENT(SHF_MIPS_NOSTRIP, ""),1373  ENUM_ENT(SHF_MIPS_GPREL,   ""),1374  ENUM_ENT(SHF_MIPS_MERGE,   ""),1375  ENUM_ENT(SHF_MIPS_ADDR,    ""),1376  ENUM_ENT(SHF_MIPS_STRING,  "")1377};1378 1379const EnumEntry<unsigned> ElfX86_64SectionFlags[] = {1380  ENUM_ENT(SHF_X86_64_LARGE, "l")1381};1382 1383static std::vector<EnumEntry<unsigned>>1384getSectionFlagsForTarget(unsigned EOSAbi, unsigned EMachine) {1385  std::vector<EnumEntry<unsigned>> Ret(std::begin(ElfSectionFlags),1386                                       std::end(ElfSectionFlags));1387  switch (EOSAbi) {1388  case ELFOSABI_SOLARIS:1389    llvm::append_range(Ret, ElfSolarisSectionFlags);1390    break;1391  default:1392    llvm::append_range(Ret, ElfGNUSectionFlags);1393    break;1394  }1395  switch (EMachine) {1396  case EM_AARCH64:1397    llvm::append_range(Ret, ElfAArch64SectionFlags);1398    break;1399  case EM_ARM:1400    llvm::append_range(Ret, ElfARMSectionFlags);1401    break;1402  case EM_HEXAGON:1403    llvm::append_range(Ret, ElfHexagonSectionFlags);1404    break;1405  case EM_MIPS:1406    llvm::append_range(Ret, ElfMipsSectionFlags);1407    break;1408  case EM_X86_64:1409    llvm::append_range(Ret, ElfX86_64SectionFlags);1410    break;1411  case EM_XCORE:1412    llvm::append_range(Ret, ElfXCoreSectionFlags);1413    break;1414  default:1415    break;1416  }1417  return Ret;1418}1419 1420static std::string getGNUFlags(unsigned EOSAbi, unsigned EMachine,1421                               uint64_t Flags) {1422  // Here we are trying to build the flags string in the same way as GNU does.1423  // It is not that straightforward. Imagine we have sh_flags == 0x90000000.1424  // SHF_EXCLUDE ("E") has a value of 0x80000000 and SHF_MASKPROC is 0xf0000000.1425  // GNU readelf will not print "E" or "Ep" in this case, but will print just1426  // "p". It only will print "E" when no other processor flag is set.1427  std::string Str;1428  bool HasUnknownFlag = false;1429  bool HasOSFlag = false;1430  bool HasProcFlag = false;1431  std::vector<EnumEntry<unsigned>> FlagsList =1432      getSectionFlagsForTarget(EOSAbi, EMachine);1433  while (Flags) {1434    // Take the least significant bit as a flag.1435    uint64_t Flag = Flags & -Flags;1436    Flags -= Flag;1437 1438    // Find the flag in the known flags list.1439    auto I = llvm::find_if(FlagsList, [=](const EnumEntry<unsigned> &E) {1440      // Flags with empty names are not printed in GNU style output.1441      return E.Value == Flag && !E.AltName.empty();1442    });1443    if (I != FlagsList.end()) {1444      Str += I->AltName;1445      continue;1446    }1447 1448    // If we did not find a matching regular flag, then we deal with an OS1449    // specific flag, processor specific flag or an unknown flag.1450    if (Flag & ELF::SHF_MASKOS) {1451      HasOSFlag = true;1452      Flags &= ~ELF::SHF_MASKOS;1453    } else if (Flag & ELF::SHF_MASKPROC) {1454      HasProcFlag = true;1455      // Mask off all the processor-specific bits. This removes the SHF_EXCLUDE1456      // bit if set so that it doesn't also get printed.1457      Flags &= ~ELF::SHF_MASKPROC;1458    } else {1459      HasUnknownFlag = true;1460    }1461  }1462 1463  // "o", "p" and "x" are printed last.1464  if (HasOSFlag)1465    Str += "o";1466  if (HasProcFlag)1467    Str += "p";1468  if (HasUnknownFlag)1469    Str += "x";1470  return Str;1471}1472 1473static StringRef segmentTypeToString(unsigned Arch, unsigned Type) {1474  // Check potentially overlapped processor-specific program header type.1475  switch (Arch) {1476  case ELF::EM_ARM:1477    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); }1478    break;1479  case ELF::EM_MIPS:1480  case ELF::EM_MIPS_RS3_LE:1481    switch (Type) {1482      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);1483      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);1484      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);1485      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);1486    }1487    break;1488  case ELF::EM_RISCV:1489    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_RISCV_ATTRIBUTES); }1490  }1491 1492  switch (Type) {1493    LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL);1494    LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD);1495    LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);1496    LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP);1497    LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE);1498    LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB);1499    LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR);1500    LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS);1501 1502    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);1503    LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);1504 1505    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);1506    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);1507    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_PROPERTY);1508    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_SFRAME);1509 1510    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_MUTABLE);1511    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE);1512    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED);1513    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_NOBTCFI);1514    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_SYSCALLS);1515    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA);1516  default:1517    return "";1518  }1519}1520 1521static std::string getGNUPtType(unsigned Arch, unsigned Type) {1522  StringRef Seg = segmentTypeToString(Arch, Type);1523  if (Seg.empty())1524    return std::string("<unknown>: ") + to_string(format_hex(Type, 1));1525 1526  // E.g. "PT_ARM_EXIDX" -> "EXIDX".1527  if (Seg.consume_front("PT_ARM_"))1528    return Seg.str();1529 1530  // E.g. "PT_MIPS_REGINFO" -> "REGINFO".1531  if (Seg.consume_front("PT_MIPS_"))1532    return Seg.str();1533 1534  // E.g. "PT_RISCV_ATTRIBUTES"1535  if (Seg.consume_front("PT_RISCV_"))1536    return Seg.str();1537 1538  // E.g. "PT_LOAD" -> "LOAD".1539  assert(Seg.starts_with("PT_"));1540  return Seg.drop_front(3).str();1541}1542 1543const EnumEntry<unsigned> ElfSegmentFlags[] = {1544  LLVM_READOBJ_ENUM_ENT(ELF, PF_X),1545  LLVM_READOBJ_ENUM_ENT(ELF, PF_W),1546  LLVM_READOBJ_ENUM_ENT(ELF, PF_R)1547};1548 1549const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {1550  ENUM_ENT(EF_MIPS_NOREORDER, "noreorder"),1551  ENUM_ENT(EF_MIPS_PIC, "pic"),1552  ENUM_ENT(EF_MIPS_CPIC, "cpic"),1553  ENUM_ENT(EF_MIPS_ABI2, "abi2"),1554  ENUM_ENT(EF_MIPS_32BITMODE, "32bitmode"),1555  ENUM_ENT(EF_MIPS_FP64, "fp64"),1556  ENUM_ENT(EF_MIPS_NAN2008, "nan2008"),1557  ENUM_ENT(EF_MIPS_ABI_O32, "o32"),1558  ENUM_ENT(EF_MIPS_ABI_O64, "o64"),1559  ENUM_ENT(EF_MIPS_ABI_EABI32, "eabi32"),1560  ENUM_ENT(EF_MIPS_ABI_EABI64, "eabi64"),1561  ENUM_ENT(EF_MIPS_MACH_3900, "3900"),1562  ENUM_ENT(EF_MIPS_MACH_4010, "4010"),1563  ENUM_ENT(EF_MIPS_MACH_4100, "4100"),1564  ENUM_ENT(EF_MIPS_MACH_4650, "4650"),1565  ENUM_ENT(EF_MIPS_MACH_4120, "4120"),1566  ENUM_ENT(EF_MIPS_MACH_4111, "4111"),1567  ENUM_ENT(EF_MIPS_MACH_SB1, "sb1"),1568  ENUM_ENT(EF_MIPS_MACH_OCTEON, "octeon"),1569  ENUM_ENT(EF_MIPS_MACH_XLR, "xlr"),1570  ENUM_ENT(EF_MIPS_MACH_OCTEON2, "octeon2"),1571  ENUM_ENT(EF_MIPS_MACH_OCTEON3, "octeon3"),1572  ENUM_ENT(EF_MIPS_MACH_5400, "5400"),1573  ENUM_ENT(EF_MIPS_MACH_5900, "5900"),1574  ENUM_ENT(EF_MIPS_MACH_5500, "5500"),1575  ENUM_ENT(EF_MIPS_MACH_9000, "9000"),1576  ENUM_ENT(EF_MIPS_MACH_LS2E, "loongson-2e"),1577  ENUM_ENT(EF_MIPS_MACH_LS2F, "loongson-2f"),1578  ENUM_ENT(EF_MIPS_MACH_LS3A, "loongson-3a"),1579  ENUM_ENT(EF_MIPS_MICROMIPS, "micromips"),1580  ENUM_ENT(EF_MIPS_ARCH_ASE_M16, "mips16"),1581  ENUM_ENT(EF_MIPS_ARCH_ASE_MDMX, "mdmx"),1582  ENUM_ENT(EF_MIPS_ARCH_1, "mips1"),1583  ENUM_ENT(EF_MIPS_ARCH_2, "mips2"),1584  ENUM_ENT(EF_MIPS_ARCH_3, "mips3"),1585  ENUM_ENT(EF_MIPS_ARCH_4, "mips4"),1586  ENUM_ENT(EF_MIPS_ARCH_5, "mips5"),1587  ENUM_ENT(EF_MIPS_ARCH_32, "mips32"),1588  ENUM_ENT(EF_MIPS_ARCH_64, "mips64"),1589  ENUM_ENT(EF_MIPS_ARCH_32R2, "mips32r2"),1590  ENUM_ENT(EF_MIPS_ARCH_64R2, "mips64r2"),1591  ENUM_ENT(EF_MIPS_ARCH_32R6, "mips32r6"),1592  ENUM_ENT(EF_MIPS_ARCH_64R6, "mips64r6")1593};1594 1595// clang-format off1596#define AMDGPU_MACH_ENUM_ENTS                                                  \1597  ENUM_ENT(EF_AMDGPU_MACH_NONE, "none"),                                       \1598  ENUM_ENT(EF_AMDGPU_MACH_R600_R600, "r600"),                                  \1599  ENUM_ENT(EF_AMDGPU_MACH_R600_R630, "r630"),                                  \1600  ENUM_ENT(EF_AMDGPU_MACH_R600_RS880, "rs880"),                                \1601  ENUM_ENT(EF_AMDGPU_MACH_R600_RV670, "rv670"),                                \1602  ENUM_ENT(EF_AMDGPU_MACH_R600_RV710, "rv710"),                                \1603  ENUM_ENT(EF_AMDGPU_MACH_R600_RV730, "rv730"),                                \1604  ENUM_ENT(EF_AMDGPU_MACH_R600_RV770, "rv770"),                                \1605  ENUM_ENT(EF_AMDGPU_MACH_R600_CEDAR, "cedar"),                                \1606  ENUM_ENT(EF_AMDGPU_MACH_R600_CYPRESS, "cypress"),                            \1607  ENUM_ENT(EF_AMDGPU_MACH_R600_JUNIPER, "juniper"),                            \1608  ENUM_ENT(EF_AMDGPU_MACH_R600_REDWOOD, "redwood"),                            \1609  ENUM_ENT(EF_AMDGPU_MACH_R600_SUMO, "sumo"),                                  \1610  ENUM_ENT(EF_AMDGPU_MACH_R600_BARTS, "barts"),                                \1611  ENUM_ENT(EF_AMDGPU_MACH_R600_CAICOS, "caicos"),                              \1612  ENUM_ENT(EF_AMDGPU_MACH_R600_CAYMAN, "cayman"),                              \1613  ENUM_ENT(EF_AMDGPU_MACH_R600_TURKS, "turks"),                                \1614  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600"),                            \1615  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601"),                            \1616  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602"),                            \1617  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700"),                            \1618  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701"),                            \1619  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702"),                            \1620  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703"),                            \1621  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704"),                            \1622  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705"),                            \1623  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801"),                            \1624  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802"),                            \1625  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803"),                            \1626  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805"),                            \1627  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810"),                            \1628  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900"),                            \1629  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902"),                            \1630  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904"),                            \1631  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906"),                            \1632  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908"),                            \1633  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909"),                            \1634  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a"),                            \1635  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c"),                            \1636  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX942, "gfx942"),                            \1637  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX950, "gfx950"),                            \1638  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010"),                          \1639  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011"),                          \1640  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012"),                          \1641  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013"),                          \1642  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030"),                          \1643  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031"),                          \1644  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032"),                          \1645  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033"),                          \1646  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034"),                          \1647  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035"),                          \1648  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036"),                          \1649  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100"),                          \1650  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101"),                          \1651  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102"),                          \1652  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1103, "gfx1103"),                          \1653  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1150, "gfx1150"),                          \1654  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1151, "gfx1151"),                          \1655  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1152, "gfx1152"),                          \1656  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1153, "gfx1153"),                          \1657  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1200, "gfx1200"),                          \1658  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1201, "gfx1201"),                          \1659  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1250, "gfx1250"),                          \1660  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1251, "gfx1251"),                          \1661  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC, "gfx9-generic"),                \1662  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC, "gfx9-4-generic"),            \1663  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC, "gfx10-1-generic"),          \1664  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC, "gfx10-3-generic"),          \1665  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC, "gfx11-generic"),              \1666  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC, "gfx12-generic")1667// clang-format on1668 1669const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion3[] = {1670    AMDGPU_MACH_ENUM_ENTS,1671    ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_V3, "xnack"),1672    ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_V3, "sramecc"),1673};1674 1675const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion4[] = {1676    AMDGPU_MACH_ENUM_ENTS,1677    ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_ANY_V4, "xnack"),1678    ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_OFF_V4, "xnack-"),1679    ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_ON_V4, "xnack+"),1680    ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_ANY_V4, "sramecc"),1681    ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_OFF_V4, "sramecc-"),1682    ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_ON_V4, "sramecc+"),1683};1684 1685const EnumEntry<unsigned> ElfHeaderNVPTXFlags[] = {1686    ENUM_ENT(EF_CUDA_SM20, "sm_20"),1687    ENUM_ENT(EF_CUDA_SM21, "sm_21"),1688    ENUM_ENT(EF_CUDA_SM30, "sm_30"),1689    ENUM_ENT(EF_CUDA_SM32, "sm_32"),1690    ENUM_ENT(EF_CUDA_SM35, "sm_35"),1691    ENUM_ENT(EF_CUDA_SM37, "sm_37"),1692    ENUM_ENT(EF_CUDA_SM50, "sm_50"),1693    ENUM_ENT(EF_CUDA_SM52, "sm_52"),1694    ENUM_ENT(EF_CUDA_SM53, "sm_53"),1695    ENUM_ENT(EF_CUDA_SM60, "sm_60"),1696    ENUM_ENT(EF_CUDA_SM61, "sm_61"),1697    ENUM_ENT(EF_CUDA_SM62, "sm_62"),1698    ENUM_ENT(EF_CUDA_SM70, "sm_70"),1699    ENUM_ENT(EF_CUDA_SM72, "sm_72"),1700    ENUM_ENT(EF_CUDA_SM75, "sm_75"),1701    ENUM_ENT(EF_CUDA_SM80, "sm_80"),1702    ENUM_ENT(EF_CUDA_SM86, "sm_86"),1703    ENUM_ENT(EF_CUDA_SM87, "sm_87"),1704    ENUM_ENT(EF_CUDA_SM88, "sm_88"),1705    ENUM_ENT(EF_CUDA_SM89, "sm_89"),1706    ENUM_ENT(EF_CUDA_SM90, "sm_90"),1707    ENUM_ENT(EF_CUDA_SM100, "sm_100"),1708    ENUM_ENT(EF_CUDA_SM101, "sm_101"),1709    ENUM_ENT(EF_CUDA_SM103, "sm_103"),1710    ENUM_ENT(EF_CUDA_SM110, "sm_110"),1711    ENUM_ENT(EF_CUDA_SM120, "sm_120"),1712    ENUM_ENT(EF_CUDA_SM121, "sm_121"),1713    ENUM_ENT(EF_CUDA_SM20 << EF_CUDA_SM_OFFSET, "sm_20"),1714    ENUM_ENT(EF_CUDA_SM21 << EF_CUDA_SM_OFFSET, "sm_21"),1715    ENUM_ENT(EF_CUDA_SM30 << EF_CUDA_SM_OFFSET, "sm_30"),1716    ENUM_ENT(EF_CUDA_SM32 << EF_CUDA_SM_OFFSET, "sm_32"),1717    ENUM_ENT(EF_CUDA_SM35 << EF_CUDA_SM_OFFSET, "sm_35"),1718    ENUM_ENT(EF_CUDA_SM37 << EF_CUDA_SM_OFFSET, "sm_37"),1719    ENUM_ENT(EF_CUDA_SM50 << EF_CUDA_SM_OFFSET, "sm_50"),1720    ENUM_ENT(EF_CUDA_SM52 << EF_CUDA_SM_OFFSET, "sm_52"),1721    ENUM_ENT(EF_CUDA_SM53 << EF_CUDA_SM_OFFSET, "sm_53"),1722    ENUM_ENT(EF_CUDA_SM60 << EF_CUDA_SM_OFFSET, "sm_60"),1723    ENUM_ENT(EF_CUDA_SM61 << EF_CUDA_SM_OFFSET, "sm_61"),1724    ENUM_ENT(EF_CUDA_SM62 << EF_CUDA_SM_OFFSET, "sm_62"),1725    ENUM_ENT(EF_CUDA_SM70 << EF_CUDA_SM_OFFSET, "sm_70"),1726    ENUM_ENT(EF_CUDA_SM72 << EF_CUDA_SM_OFFSET, "sm_72"),1727    ENUM_ENT(EF_CUDA_SM75 << EF_CUDA_SM_OFFSET, "sm_75"),1728    ENUM_ENT(EF_CUDA_SM80 << EF_CUDA_SM_OFFSET, "sm_80"),1729    ENUM_ENT(EF_CUDA_SM86 << EF_CUDA_SM_OFFSET, "sm_86"),1730    ENUM_ENT(EF_CUDA_SM87 << EF_CUDA_SM_OFFSET, "sm_87"),1731    ENUM_ENT(EF_CUDA_SM88 << EF_CUDA_SM_OFFSET, "sm_88"),1732    ENUM_ENT(EF_CUDA_SM89 << EF_CUDA_SM_OFFSET, "sm_89"),1733    ENUM_ENT(EF_CUDA_SM90 << EF_CUDA_SM_OFFSET, "sm_90"),1734    ENUM_ENT(EF_CUDA_SM100 << EF_CUDA_SM_OFFSET, "sm_100"),1735    ENUM_ENT(EF_CUDA_SM101 << EF_CUDA_SM_OFFSET, "sm_101"),1736    ENUM_ENT(EF_CUDA_SM103 << EF_CUDA_SM_OFFSET, "sm_103"),1737    ENUM_ENT(EF_CUDA_SM110 << EF_CUDA_SM_OFFSET, "sm_110"),1738    ENUM_ENT(EF_CUDA_SM120 << EF_CUDA_SM_OFFSET, "sm_120"),1739    ENUM_ENT(EF_CUDA_SM121 << EF_CUDA_SM_OFFSET, "sm_121"),1740};1741 1742const EnumEntry<unsigned> ElfHeaderRISCVFlags[] = {1743  ENUM_ENT(EF_RISCV_RVC, "RVC"),1744  ENUM_ENT(EF_RISCV_FLOAT_ABI_SINGLE, "single-float ABI"),1745  ENUM_ENT(EF_RISCV_FLOAT_ABI_DOUBLE, "double-float ABI"),1746  ENUM_ENT(EF_RISCV_FLOAT_ABI_QUAD, "quad-float ABI"),1747  ENUM_ENT(EF_RISCV_RVE, "RVE"),1748  ENUM_ENT(EF_RISCV_TSO, "TSO"),1749};1750 1751const EnumEntry<unsigned> ElfHeaderSPARCFlags[] = {1752    ENUM_ENT(EF_SPARC_32PLUS, "V8+ ABI"),1753    ENUM_ENT(EF_SPARC_SUN_US1, "Sun UltraSPARC I extensions"),1754    ENUM_ENT(EF_SPARC_HAL_R1, "HAL/Fujitsu R1 extensions"),1755    ENUM_ENT(EF_SPARC_SUN_US3, "Sun UltraSPARC III extensions"),1756    ENUM_ENT(EF_SPARCV9_TSO, "Total Store Ordering"),1757    ENUM_ENT(EF_SPARCV9_PSO, "Partial Store Ordering"),1758    ENUM_ENT(EF_SPARCV9_RMO, "Relaxed Memory Ordering"),1759};1760 1761const EnumEntry<unsigned> ElfHeaderAVRFlags[] = {1762  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR1),1763  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR2),1764  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR25),1765  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR3),1766  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR31),1767  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR35),1768  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR4),1769  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR5),1770  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR51),1771  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR6),1772  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVRTINY),1773  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA1),1774  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA2),1775  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA3),1776  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA4),1777  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA5),1778  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA6),1779  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA7),1780  ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"),1781};1782 1783const EnumEntry<unsigned> ElfHeaderLoongArchFlags[] = {1784  ENUM_ENT(EF_LOONGARCH_ABI_SOFT_FLOAT, "SOFT-FLOAT"),1785  ENUM_ENT(EF_LOONGARCH_ABI_SINGLE_FLOAT, "SINGLE-FLOAT"),1786  ENUM_ENT(EF_LOONGARCH_ABI_DOUBLE_FLOAT, "DOUBLE-FLOAT"),1787  ENUM_ENT(EF_LOONGARCH_OBJABI_V0, "OBJ-v0"),1788  ENUM_ENT(EF_LOONGARCH_OBJABI_V1, "OBJ-v1"),1789};1790 1791static const EnumEntry<unsigned> ElfHeaderXtensaFlags[] = {1792  LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_MACH_NONE),1793  LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_INSN),1794  LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_LIT)1795};1796 1797const EnumEntry<unsigned> ElfSymOtherFlags[] = {1798  LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL),1799  LLVM_READOBJ_ENUM_ENT(ELF, STV_HIDDEN),1800  LLVM_READOBJ_ENUM_ENT(ELF, STV_PROTECTED)1801};1802 1803const EnumEntry<unsigned> ElfMipsSymOtherFlags[] = {1804  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),1805  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),1806  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PIC),1807  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MICROMIPS)1808};1809 1810const EnumEntry<unsigned> ElfAArch64SymOtherFlags[] = {1811  LLVM_READOBJ_ENUM_ENT(ELF, STO_AARCH64_VARIANT_PCS)1812};1813 1814const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = {1815  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),1816  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),1817  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16)1818};1819 1820const EnumEntry<unsigned> ElfRISCVSymOtherFlags[] = {1821    LLVM_READOBJ_ENUM_ENT(ELF, STO_RISCV_VARIANT_CC)};1822 1823static const char *getElfMipsOptionsOdkType(unsigned Odk) {1824  switch (Odk) {1825  LLVM_READOBJ_ENUM_CASE(ELF, ODK_NULL);1826  LLVM_READOBJ_ENUM_CASE(ELF, ODK_REGINFO);1827  LLVM_READOBJ_ENUM_CASE(ELF, ODK_EXCEPTIONS);1828  LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAD);1829  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWPATCH);1830  LLVM_READOBJ_ENUM_CASE(ELF, ODK_FILL);1831  LLVM_READOBJ_ENUM_CASE(ELF, ODK_TAGS);1832  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWAND);1833  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWOR);1834  LLVM_READOBJ_ENUM_CASE(ELF, ODK_GP_GROUP);1835  LLVM_READOBJ_ENUM_CASE(ELF, ODK_IDENT);1836  LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAGESIZE);1837  default:1838    return "Unknown";1839  }1840}1841 1842template <typename ELFT>1843std::pair<const typename ELFT::Phdr *, const typename ELFT::Shdr *>1844ELFDumper<ELFT>::findDynamic() {1845  // Try to locate the PT_DYNAMIC header.1846  const Elf_Phdr *DynamicPhdr = nullptr;1847  if (Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = Obj.program_headers()) {1848    for (const Elf_Phdr &Phdr : *PhdrsOrErr) {1849      if (Phdr.p_type != ELF::PT_DYNAMIC)1850        continue;1851      DynamicPhdr = &Phdr;1852      break;1853    }1854  } else {1855    reportUniqueWarning(1856        "unable to read program headers to locate the PT_DYNAMIC segment: " +1857        toString(PhdrsOrErr.takeError()));1858  }1859 1860  // Try to locate the .dynamic section in the sections header table.1861  const Elf_Shdr *DynamicSec = nullptr;1862  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {1863    if (Sec.sh_type != ELF::SHT_DYNAMIC)1864      continue;1865    DynamicSec = &Sec;1866    break;1867  }1868 1869  if (DynamicPhdr && ((DynamicPhdr->p_offset + DynamicPhdr->p_filesz >1870                       ObjF.getMemoryBufferRef().getBufferSize()) ||1871                      (DynamicPhdr->p_offset + DynamicPhdr->p_filesz <1872                       DynamicPhdr->p_offset))) {1873    reportUniqueWarning(1874        "PT_DYNAMIC segment offset (0x" +1875        Twine::utohexstr(DynamicPhdr->p_offset) + ") + file size (0x" +1876        Twine::utohexstr(DynamicPhdr->p_filesz) +1877        ") exceeds the size of the file (0x" +1878        Twine::utohexstr(ObjF.getMemoryBufferRef().getBufferSize()) + ")");1879    // Don't use the broken dynamic header.1880    DynamicPhdr = nullptr;1881  }1882 1883  if (DynamicPhdr && DynamicSec) {1884    if (DynamicSec->sh_addr + DynamicSec->sh_size >1885            DynamicPhdr->p_vaddr + DynamicPhdr->p_memsz ||1886        DynamicSec->sh_addr < DynamicPhdr->p_vaddr)1887      reportUniqueWarning(describe(*DynamicSec) +1888                          " is not contained within the "1889                          "PT_DYNAMIC segment");1890 1891    if (DynamicSec->sh_addr != DynamicPhdr->p_vaddr)1892      reportUniqueWarning(describe(*DynamicSec) + " is not at the start of "1893                                                  "PT_DYNAMIC segment");1894  }1895 1896  return std::make_pair(DynamicPhdr, DynamicSec);1897}1898 1899template <typename ELFT>1900void ELFDumper<ELFT>::loadDynamicTable() {1901  const Elf_Phdr *DynamicPhdr;1902  const Elf_Shdr *DynamicSec;1903  std::tie(DynamicPhdr, DynamicSec) = findDynamic();1904  if (!DynamicPhdr && !DynamicSec)1905    return;1906 1907  DynRegionInfo FromPhdr(ObjF, *this);1908  bool IsPhdrTableValid = false;1909  if (DynamicPhdr) {1910    // Use cantFail(), because p_offset/p_filesz fields of a PT_DYNAMIC are1911    // validated in findDynamic() and so createDRI() is not expected to fail.1912    FromPhdr = cantFail(createDRI(DynamicPhdr->p_offset, DynamicPhdr->p_filesz,1913                                  sizeof(Elf_Dyn)));1914    FromPhdr.SizePrintName = "PT_DYNAMIC size";1915    FromPhdr.EntSizePrintName = "";1916    IsPhdrTableValid = !FromPhdr.template getAsArrayRef<Elf_Dyn>().empty();1917  }1918 1919  // Locate the dynamic table described in a section header.1920  // Ignore sh_entsize and use the expected value for entry size explicitly.1921  // This allows us to dump dynamic sections with a broken sh_entsize1922  // field.1923  DynRegionInfo FromSec(ObjF, *this);1924  bool IsSecTableValid = false;1925  if (DynamicSec) {1926    Expected<DynRegionInfo> RegOrErr =1927        createDRI(DynamicSec->sh_offset, DynamicSec->sh_size, sizeof(Elf_Dyn));1928    if (RegOrErr) {1929      FromSec = *RegOrErr;1930      FromSec.Context = describe(*DynamicSec);1931      FromSec.EntSizePrintName = "";1932      IsSecTableValid = !FromSec.template getAsArrayRef<Elf_Dyn>().empty();1933    } else {1934      reportUniqueWarning("unable to read the dynamic table from " +1935                          describe(*DynamicSec) + ": " +1936                          toString(RegOrErr.takeError()));1937    }1938  }1939 1940  // When we only have information from one of the SHT_DYNAMIC section header or1941  // PT_DYNAMIC program header, just use that.1942  if (!DynamicPhdr || !DynamicSec) {1943    if ((DynamicPhdr && IsPhdrTableValid) || (DynamicSec && IsSecTableValid)) {1944      DynamicTable = DynamicPhdr ? FromPhdr : FromSec;1945      parseDynamicTable();1946    } else {1947      reportUniqueWarning("no valid dynamic table was found");1948    }1949    return;1950  }1951 1952  // At this point we have tables found from the section header and from the1953  // dynamic segment. Usually they match, but we have to do sanity checks to1954  // verify that.1955 1956  if (FromPhdr.Addr != FromSec.Addr)1957    reportUniqueWarning("SHT_DYNAMIC section header and PT_DYNAMIC "1958                        "program header disagree about "1959                        "the location of the dynamic table");1960 1961  if (!IsPhdrTableValid && !IsSecTableValid) {1962    reportUniqueWarning("no valid dynamic table was found");1963    return;1964  }1965 1966  // Information in the PT_DYNAMIC program header has priority over the1967  // information in a section header.1968  if (IsPhdrTableValid) {1969    if (!IsSecTableValid)1970      reportUniqueWarning(1971          "SHT_DYNAMIC dynamic table is invalid: PT_DYNAMIC will be used");1972    DynamicTable = FromPhdr;1973  } else {1974    reportUniqueWarning(1975        "PT_DYNAMIC dynamic table is invalid: SHT_DYNAMIC will be used");1976    DynamicTable = FromSec;1977  }1978 1979  parseDynamicTable();1980}1981 1982template <typename ELFT>1983ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> &O,1984                           ScopedPrinter &Writer)1985    : ObjDumper(Writer, O.getFileName()), ObjF(O), Obj(O.getELFFile()),1986      FileName(O.getFileName()), DynRelRegion(O, *this),1987      DynRelaRegion(O, *this), DynCrelRegion(O, *this), DynRelrRegion(O, *this),1988      DynPLTRelRegion(O, *this), DynSymTabShndxRegion(O, *this),1989      DynamicTable(O, *this) {1990  if (!O.IsContentValid())1991    return;1992 1993  typename ELFT::ShdrRange Sections = cantFail(Obj.sections());1994  for (const Elf_Shdr &Sec : Sections) {1995    switch (Sec.sh_type) {1996    case ELF::SHT_SYMTAB:1997      if (!DotSymtabSec)1998        DotSymtabSec = &Sec;1999      break;2000    case ELF::SHT_DYNSYM:2001      if (!DotDynsymSec)2002        DotDynsymSec = &Sec;2003 2004      if (!DynSymRegion) {2005        Expected<DynRegionInfo> RegOrErr =2006            createDRI(Sec.sh_offset, Sec.sh_size, Sec.sh_entsize);2007        if (RegOrErr) {2008          DynSymRegion = *RegOrErr;2009          DynSymRegion->Context = describe(Sec);2010 2011          if (Expected<StringRef> E = Obj.getStringTableForSymtab(Sec))2012            DynamicStringTable = *E;2013          else2014            reportUniqueWarning("unable to get the string table for the " +2015                                describe(Sec) + ": " + toString(E.takeError()));2016        } else {2017          reportUniqueWarning("unable to read dynamic symbols from " +2018                              describe(Sec) + ": " +2019                              toString(RegOrErr.takeError()));2020        }2021      }2022      break;2023    case ELF::SHT_SYMTAB_SHNDX: {2024      uint32_t SymtabNdx = Sec.sh_link;2025      if (SymtabNdx >= Sections.size()) {2026        reportUniqueWarning(2027            "unable to get the associated symbol table for " + describe(Sec) +2028            ": sh_link (" + Twine(SymtabNdx) +2029            ") is greater than or equal to the total number of sections (" +2030            Twine(Sections.size()) + ")");2031        continue;2032      }2033 2034      if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =2035              Obj.getSHNDXTable(Sec)) {2036        if (!ShndxTables.insert({&Sections[SymtabNdx], *ShndxTableOrErr})2037                 .second)2038          reportUniqueWarning(2039              "multiple SHT_SYMTAB_SHNDX sections are linked to " +2040              describe(Sec));2041      } else {2042        reportUniqueWarning(ShndxTableOrErr.takeError());2043      }2044      break;2045    }2046    case ELF::SHT_GNU_versym:2047      if (!SymbolVersionSection)2048        SymbolVersionSection = &Sec;2049      break;2050    case ELF::SHT_GNU_verdef:2051      if (!SymbolVersionDefSection)2052        SymbolVersionDefSection = &Sec;2053      break;2054    case ELF::SHT_GNU_verneed:2055      if (!SymbolVersionNeedSection)2056        SymbolVersionNeedSection = &Sec;2057      break;2058    case ELF::SHT_LLVM_ADDRSIG:2059      if (!DotAddrsigSec)2060        DotAddrsigSec = &Sec;2061      break;2062    }2063  }2064 2065  loadDynamicTable();2066}2067 2068template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() {2069  auto toMappedAddr = [&](uint64_t Tag, uint64_t VAddr) -> const uint8_t * {2070    auto MappedAddrOrError = Obj.toMappedAddr(VAddr, [&](const Twine &Msg) {2071      this->reportUniqueWarning(Msg);2072      return Error::success();2073    });2074    if (!MappedAddrOrError) {2075      this->reportUniqueWarning("unable to parse DT_" +2076                                Obj.getDynamicTagAsString(Tag) + ": " +2077                                llvm::toString(MappedAddrOrError.takeError()));2078      return nullptr;2079    }2080    return MappedAddrOrError.get();2081  };2082 2083  const char *StringTableBegin = nullptr;2084  uint64_t StringTableSize = 0;2085  std::optional<DynRegionInfo> DynSymFromTable;2086  for (const Elf_Dyn &Dyn : dynamic_table()) {2087    if (Obj.getHeader().e_machine == EM_AARCH64) {2088      switch (Dyn.d_tag) {2089      case ELF::DT_AARCH64_AUTH_RELRSZ:2090        DynRelrRegion.Size = Dyn.getVal();2091        DynRelrRegion.SizePrintName = "DT_AARCH64_AUTH_RELRSZ value";2092        continue;2093      case ELF::DT_AARCH64_AUTH_RELRENT:2094        DynRelrRegion.EntSize = Dyn.getVal();2095        DynRelrRegion.EntSizePrintName = "DT_AARCH64_AUTH_RELRENT value";2096        continue;2097      }2098    }2099    switch (Dyn.d_tag) {2100    case ELF::DT_HASH:2101      HashTable = reinterpret_cast<const Elf_Hash *>(2102          toMappedAddr(Dyn.getTag(), Dyn.getPtr()));2103      break;2104    case ELF::DT_GNU_HASH:2105      GnuHashTable = reinterpret_cast<const Elf_GnuHash *>(2106          toMappedAddr(Dyn.getTag(), Dyn.getPtr()));2107      break;2108    case ELF::DT_STRTAB:2109      StringTableBegin = reinterpret_cast<const char *>(2110          toMappedAddr(Dyn.getTag(), Dyn.getPtr()));2111      break;2112    case ELF::DT_STRSZ:2113      StringTableSize = Dyn.getVal();2114      break;2115    case ELF::DT_SYMTAB: {2116      // If we can't map the DT_SYMTAB value to an address (e.g. when there are2117      // no program headers), we ignore its value.2118      if (const uint8_t *VA = toMappedAddr(Dyn.getTag(), Dyn.getPtr())) {2119        DynSymFromTable.emplace(ObjF, *this);2120        DynSymFromTable->Addr = VA;2121        DynSymFromTable->EntSize = sizeof(Elf_Sym);2122        DynSymFromTable->EntSizePrintName = "";2123      }2124      break;2125    }2126    case ELF::DT_SYMENT: {2127      uint64_t Val = Dyn.getVal();2128      if (Val != sizeof(Elf_Sym))2129        this->reportUniqueWarning("DT_SYMENT value of 0x" +2130                                  Twine::utohexstr(Val) +2131                                  " is not the size of a symbol (0x" +2132                                  Twine::utohexstr(sizeof(Elf_Sym)) + ")");2133      break;2134    }2135    case ELF::DT_RELA:2136      DynRelaRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());2137      break;2138    case ELF::DT_RELASZ:2139      DynRelaRegion.Size = Dyn.getVal();2140      DynRelaRegion.SizePrintName = "DT_RELASZ value";2141      break;2142    case ELF::DT_RELAENT:2143      DynRelaRegion.EntSize = Dyn.getVal();2144      DynRelaRegion.EntSizePrintName = "DT_RELAENT value";2145      break;2146    case ELF::DT_CREL:2147      DynCrelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());2148      break;2149    case ELF::DT_SONAME:2150      SONameOffset = Dyn.getVal();2151      break;2152    case ELF::DT_REL:2153      DynRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());2154      break;2155    case ELF::DT_RELSZ:2156      DynRelRegion.Size = Dyn.getVal();2157      DynRelRegion.SizePrintName = "DT_RELSZ value";2158      break;2159    case ELF::DT_RELENT:2160      DynRelRegion.EntSize = Dyn.getVal();2161      DynRelRegion.EntSizePrintName = "DT_RELENT value";2162      break;2163    case ELF::DT_RELR:2164    case ELF::DT_ANDROID_RELR:2165    case ELF::DT_AARCH64_AUTH_RELR:2166      DynRelrRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());2167      break;2168    case ELF::DT_RELRSZ:2169    case ELF::DT_ANDROID_RELRSZ:2170    case ELF::DT_AARCH64_AUTH_RELRSZ:2171      DynRelrRegion.Size = Dyn.getVal();2172      DynRelrRegion.SizePrintName = Dyn.d_tag == ELF::DT_RELRSZ2173                                        ? "DT_RELRSZ value"2174                                        : "DT_ANDROID_RELRSZ value";2175      break;2176    case ELF::DT_RELRENT:2177    case ELF::DT_ANDROID_RELRENT:2178    case ELF::DT_AARCH64_AUTH_RELRENT:2179      DynRelrRegion.EntSize = Dyn.getVal();2180      DynRelrRegion.EntSizePrintName = Dyn.d_tag == ELF::DT_RELRENT2181                                           ? "DT_RELRENT value"2182                                           : "DT_ANDROID_RELRENT value";2183      break;2184    case ELF::DT_PLTREL:2185      if (Dyn.getVal() == DT_REL)2186        DynPLTRelRegion.EntSize = sizeof(Elf_Rel);2187      else if (Dyn.getVal() == DT_RELA)2188        DynPLTRelRegion.EntSize = sizeof(Elf_Rela);2189      else if (Dyn.getVal() == DT_CREL)2190        DynPLTRelRegion.EntSize = 1;2191      else2192        reportUniqueWarning(Twine("unknown DT_PLTREL value of ") +2193                            Twine((uint64_t)Dyn.getVal()));2194      DynPLTRelRegion.EntSizePrintName = "PLTREL entry size";2195      break;2196    case ELF::DT_JMPREL:2197      DynPLTRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());2198      break;2199    case ELF::DT_PLTRELSZ:2200      DynPLTRelRegion.Size = Dyn.getVal();2201      DynPLTRelRegion.SizePrintName = "DT_PLTRELSZ value";2202      break;2203    case ELF::DT_SYMTAB_SHNDX:2204      DynSymTabShndxRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());2205      DynSymTabShndxRegion.EntSize = sizeof(Elf_Word);2206      break;2207    }2208  }2209 2210  if (StringTableBegin) {2211    const uint64_t FileSize = Obj.getBufSize();2212    const uint64_t Offset = (const uint8_t *)StringTableBegin - Obj.base();2213    if (StringTableSize > FileSize - Offset)2214      reportUniqueWarning(2215          "the dynamic string table at 0x" + Twine::utohexstr(Offset) +2216          " goes past the end of the file (0x" + Twine::utohexstr(FileSize) +2217          ") with DT_STRSZ = 0x" + Twine::utohexstr(StringTableSize));2218    else2219      DynamicStringTable = StringRef(StringTableBegin, StringTableSize);2220  }2221 2222  const bool IsHashTableSupported = getHashTableEntSize() == 4;2223  if (DynSymRegion) {2224    // Often we find the information about the dynamic symbol table2225    // location in the SHT_DYNSYM section header. However, the value in2226    // DT_SYMTAB has priority, because it is used by dynamic loaders to2227    // locate .dynsym at runtime. The location we find in the section header2228    // and the location we find here should match.2229    if (DynSymFromTable && DynSymFromTable->Addr != DynSymRegion->Addr)2230      reportUniqueWarning(2231          createError("SHT_DYNSYM section header and DT_SYMTAB disagree about "2232                      "the location of the dynamic symbol table"));2233 2234    // According to the ELF gABI: "The number of symbol table entries should2235    // equal nchain". Check to see if the DT_HASH hash table nchain value2236    // conflicts with the number of symbols in the dynamic symbol table2237    // according to the section header.2238    if (HashTable && IsHashTableSupported) {2239      if (DynSymRegion->EntSize == 0)2240        reportUniqueWarning("SHT_DYNSYM section has sh_entsize == 0");2241      else if (HashTable->nchain != DynSymRegion->Size / DynSymRegion->EntSize)2242        reportUniqueWarning(2243            "hash table nchain (" + Twine(HashTable->nchain) +2244            ") differs from symbol count derived from SHT_DYNSYM section "2245            "header (" +2246            Twine(DynSymRegion->Size / DynSymRegion->EntSize) + ")");2247    }2248  }2249 2250  // Delay the creation of the actual dynamic symbol table until now, so that2251  // checks can always be made against the section header-based properties,2252  // without worrying about tag order.2253  if (DynSymFromTable) {2254    if (!DynSymRegion) {2255      DynSymRegion = DynSymFromTable;2256    } else {2257      DynSymRegion->Addr = DynSymFromTable->Addr;2258      DynSymRegion->EntSize = DynSymFromTable->EntSize;2259      DynSymRegion->EntSizePrintName = DynSymFromTable->EntSizePrintName;2260    }2261  }2262 2263  // Derive the dynamic symbol table size from the DT_HASH hash table, if2264  // present.2265  if (HashTable && IsHashTableSupported && DynSymRegion) {2266    const uint64_t FileSize = Obj.getBufSize();2267    const uint64_t DerivedSize =2268        (uint64_t)HashTable->nchain * DynSymRegion->EntSize;2269    const uint64_t Offset = DynSymRegion->Addr - Obj.base();2270    if (DerivedSize > FileSize - Offset)2271      reportUniqueWarning(2272          "the size (0x" + Twine::utohexstr(DerivedSize) +2273          ") of the dynamic symbol table at 0x" + Twine::utohexstr(Offset) +2274          ", derived from the hash table, goes past the end of the file (0x" +2275          Twine::utohexstr(FileSize) + ") and will be ignored");2276    else2277      DynSymRegion->Size = HashTable->nchain * DynSymRegion->EntSize;2278  }2279}2280 2281template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {2282  // Dump version symbol section.2283  printVersionSymbolSection(SymbolVersionSection);2284 2285  // Dump version definition section.2286  printVersionDefinitionSection(SymbolVersionDefSection);2287 2288  // Dump version dependency section.2289  printVersionDependencySection(SymbolVersionNeedSection);2290}2291 2292#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum)                                 \2293  { #enum, prefix##_##enum }2294 2295const EnumEntry<unsigned> ElfDynamicDTFlags[] = {2296  LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),2297  LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),2298  LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),2299  LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),2300  LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)2301};2302 2303const EnumEntry<unsigned> ElfDynamicDTFlags1[] = {2304  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW),2305  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL),2306  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP),2307  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE),2308  LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR),2309  LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST),2310  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN),2311  LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN),2312  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT),2313  LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS),2314  LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE),2315  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB),2316  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP),2317  LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT),2318  LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE),2319  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE),2320  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELPND),2321  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT),2322  LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF),2323  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS),2324  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR),2325  LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED),2326  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC),2327  LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE),2328  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT),2329  LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON),2330  LLVM_READOBJ_DT_FLAG_ENT(DF_1, PIE),2331};2332 2333const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {2334  LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),2335  LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),2336  LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),2337  LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),2338  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),2339  LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),2340  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),2341  LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),2342  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),2343  LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),2344  LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),2345  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),2346  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),2347  LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),2348  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),2349  LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)2350};2351 2352#undef LLVM_READOBJ_DT_FLAG_ENT2353 2354template <typename T, typename TFlag>2355void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {2356  SmallVector<EnumEntry<TFlag>, 10> SetFlags;2357  for (const EnumEntry<TFlag> &Flag : Flags)2358    if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value)2359      SetFlags.push_back(Flag);2360 2361  for (const EnumEntry<TFlag> &Flag : SetFlags)2362    OS << Flag.Name << " ";2363}2364 2365template <class ELFT>2366const typename ELFT::Shdr *2367ELFDumper<ELFT>::findSectionByName(StringRef Name) const {2368  for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) {2369    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Shdr)) {2370      if (*NameOrErr == Name)2371        return &Shdr;2372    } else {2373      reportUniqueWarning("unable to read the name of " + describe(Shdr) +2374                          ": " + toString(NameOrErr.takeError()));2375    }2376  }2377  return nullptr;2378}2379 2380template <class ELFT>2381std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type,2382                                             uint64_t Value) const {2383  auto FormatHexValue = [](uint64_t V) {2384    std::string Str;2385    raw_string_ostream OS(Str);2386    const char *ConvChar =2387        (opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64;2388    OS << format(ConvChar, V);2389    return Str;2390  };2391 2392  auto FormatFlags = [](uint64_t V,2393                        llvm::ArrayRef<llvm::EnumEntry<unsigned int>> Array) {2394    std::string Str;2395    raw_string_ostream OS(Str);2396    printFlags(V, Array, OS);2397    return Str;2398  };2399 2400  // Handle custom printing of architecture specific tags2401  switch (Obj.getHeader().e_machine) {2402  case EM_AARCH64:2403    switch (Type) {2404    case DT_AARCH64_BTI_PLT:2405    case DT_AARCH64_PAC_PLT:2406    case DT_AARCH64_VARIANT_PCS:2407    case DT_AARCH64_MEMTAG_GLOBALSSZ:2408      return std::to_string(Value);2409    case DT_AARCH64_MEMTAG_MODE:2410      switch (Value) {2411        case 0:2412          return "Synchronous (0)";2413        case 1:2414          return "Asynchronous (1)";2415        default:2416          return (Twine("Unknown (") + Twine(Value) + ")").str();2417      }2418    case DT_AARCH64_MEMTAG_HEAP:2419    case DT_AARCH64_MEMTAG_STACK:2420      switch (Value) {2421        case 0:2422          return "Disabled (0)";2423        case 1:2424          return "Enabled (1)";2425        default:2426          return (Twine("Unknown (") + Twine(Value) + ")").str();2427      }2428    case DT_AARCH64_MEMTAG_GLOBALS:2429      return (Twine("0x") + utohexstr(Value, /*LowerCase=*/true)).str();2430    default:2431      break;2432    }2433    break;2434  case EM_HEXAGON:2435    switch (Type) {2436    case DT_HEXAGON_VER:2437      return std::to_string(Value);2438    case DT_HEXAGON_SYMSZ:2439    case DT_HEXAGON_PLT:2440      return FormatHexValue(Value);2441    default:2442      break;2443    }2444    break;2445  case EM_MIPS:2446    switch (Type) {2447    case DT_MIPS_RLD_VERSION:2448    case DT_MIPS_LOCAL_GOTNO:2449    case DT_MIPS_SYMTABNO:2450    case DT_MIPS_UNREFEXTNO:2451      return std::to_string(Value);2452    case DT_MIPS_TIME_STAMP:2453    case DT_MIPS_ICHECKSUM:2454    case DT_MIPS_IVERSION:2455    case DT_MIPS_BASE_ADDRESS:2456    case DT_MIPS_MSYM:2457    case DT_MIPS_CONFLICT:2458    case DT_MIPS_LIBLIST:2459    case DT_MIPS_CONFLICTNO:2460    case DT_MIPS_LIBLISTNO:2461    case DT_MIPS_GOTSYM:2462    case DT_MIPS_HIPAGENO:2463    case DT_MIPS_RLD_MAP:2464    case DT_MIPS_DELTA_CLASS:2465    case DT_MIPS_DELTA_CLASS_NO:2466    case DT_MIPS_DELTA_INSTANCE:2467    case DT_MIPS_DELTA_RELOC:2468    case DT_MIPS_DELTA_RELOC_NO:2469    case DT_MIPS_DELTA_SYM:2470    case DT_MIPS_DELTA_SYM_NO:2471    case DT_MIPS_DELTA_CLASSSYM:2472    case DT_MIPS_DELTA_CLASSSYM_NO:2473    case DT_MIPS_CXX_FLAGS:2474    case DT_MIPS_PIXIE_INIT:2475    case DT_MIPS_SYMBOL_LIB:2476    case DT_MIPS_LOCALPAGE_GOTIDX:2477    case DT_MIPS_LOCAL_GOTIDX:2478    case DT_MIPS_HIDDEN_GOTIDX:2479    case DT_MIPS_PROTECTED_GOTIDX:2480    case DT_MIPS_OPTIONS:2481    case DT_MIPS_INTERFACE:2482    case DT_MIPS_DYNSTR_ALIGN:2483    case DT_MIPS_INTERFACE_SIZE:2484    case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:2485    case DT_MIPS_PERF_SUFFIX:2486    case DT_MIPS_COMPACT_SIZE:2487    case DT_MIPS_GP_VALUE:2488    case DT_MIPS_AUX_DYNAMIC:2489    case DT_MIPS_PLTGOT:2490    case DT_MIPS_RWPLT:2491    case DT_MIPS_RLD_MAP_REL:2492    case DT_MIPS_XHASH:2493      return FormatHexValue(Value);2494    case DT_MIPS_FLAGS:2495      return FormatFlags(Value, ArrayRef(ElfDynamicDTMipsFlags));2496    default:2497      break;2498    }2499    break;2500  default:2501    break;2502  }2503 2504  switch (Type) {2505  case DT_PLTREL:2506    if (Value == DT_REL)2507      return "REL";2508    if (Value == DT_RELA)2509      return "RELA";2510    if (Value == DT_CREL)2511      return "CREL";2512    [[fallthrough]];2513  case DT_PLTGOT:2514  case DT_HASH:2515  case DT_STRTAB:2516  case DT_SYMTAB:2517  case DT_RELA:2518  case DT_INIT:2519  case DT_FINI:2520  case DT_REL:2521  case DT_JMPREL:2522  case DT_INIT_ARRAY:2523  case DT_FINI_ARRAY:2524  case DT_PREINIT_ARRAY:2525  case DT_DEBUG:2526  case DT_CREL:2527  case DT_VERDEF:2528  case DT_VERNEED:2529  case DT_VERSYM:2530  case DT_GNU_HASH:2531  case DT_NULL:2532    return FormatHexValue(Value);2533  case DT_RELACOUNT:2534  case DT_RELCOUNT:2535  case DT_VERDEFNUM:2536  case DT_VERNEEDNUM:2537    return std::to_string(Value);2538  case DT_PLTRELSZ:2539  case DT_RELASZ:2540  case DT_RELAENT:2541  case DT_STRSZ:2542  case DT_SYMENT:2543  case DT_RELSZ:2544  case DT_RELENT:2545  case DT_INIT_ARRAYSZ:2546  case DT_FINI_ARRAYSZ:2547  case DT_PREINIT_ARRAYSZ:2548  case DT_RELRSZ:2549  case DT_RELRENT:2550  case DT_AARCH64_AUTH_RELRSZ:2551  case DT_AARCH64_AUTH_RELRENT:2552  case DT_ANDROID_RELSZ:2553  case DT_ANDROID_RELASZ:2554    return std::to_string(Value) + " (bytes)";2555  case DT_NEEDED:2556  case DT_SONAME:2557  case DT_AUXILIARY:2558  case DT_USED:2559  case DT_FILTER:2560  case DT_RPATH:2561  case DT_RUNPATH: {2562    const std::map<uint64_t, const char *> TagNames = {2563        {DT_NEEDED, "Shared library"},       {DT_SONAME, "Library soname"},2564        {DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"},2565        {DT_FILTER, "Filter library"},       {DT_RPATH, "Library rpath"},2566        {DT_RUNPATH, "Library runpath"},2567    };2568 2569    return (Twine(TagNames.at(Type)) + ": [" + getDynamicString(Value) + "]")2570        .str();2571  }2572  case DT_FLAGS:2573    return FormatFlags(Value, ArrayRef(ElfDynamicDTFlags));2574  case DT_FLAGS_1:2575    return FormatFlags(Value, ArrayRef(ElfDynamicDTFlags1));2576  default:2577    return FormatHexValue(Value);2578  }2579}2580 2581template <class ELFT>2582StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {2583  if (DynamicStringTable.empty() && !DynamicStringTable.data()) {2584    reportUniqueWarning("string table was not found");2585    return "<?>";2586  }2587 2588  auto WarnAndReturn = [this](const Twine &Msg, uint64_t Offset) {2589    reportUniqueWarning("string table at offset 0x" + Twine::utohexstr(Offset) +2590                        Msg);2591    return "<?>";2592  };2593 2594  const uint64_t FileSize = Obj.getBufSize();2595  const uint64_t Offset =2596      (const uint8_t *)DynamicStringTable.data() - Obj.base();2597  if (DynamicStringTable.size() > FileSize - Offset)2598    return WarnAndReturn(" with size 0x" +2599                             Twine::utohexstr(DynamicStringTable.size()) +2600                             " goes past the end of the file (0x" +2601                             Twine::utohexstr(FileSize) + ")",2602                         Offset);2603 2604  if (Value >= DynamicStringTable.size())2605    return WarnAndReturn(2606        ": unable to read the string at 0x" + Twine::utohexstr(Offset + Value) +2607            ": it goes past the end of the table (0x" +2608            Twine::utohexstr(Offset + DynamicStringTable.size()) + ")",2609        Offset);2610 2611  if (DynamicStringTable.back() != '\0')2612    return WarnAndReturn(": unable to read the string at 0x" +2613                             Twine::utohexstr(Offset + Value) +2614                             ": the string table is not null-terminated",2615                         Offset);2616 2617  return DynamicStringTable.data() + Value;2618}2619 2620template <class ELFT> void ELFDumper<ELFT>::printUnwindInfo() {2621  DwarfCFIEH::PrinterContext<ELFT> Ctx(W, ObjF);2622  Ctx.printUnwindInformation();2623}2624 2625// The namespace is needed to fix the compilation with GCC older than 7.0+.2626namespace {2627template <> void ELFDumper<ELF32LE>::printUnwindInfo() {2628  if (Obj.getHeader().e_machine == EM_ARM) {2629    ARM::EHABI::PrinterContext<ELF32LE> Ctx(W, Obj, ObjF.getFileName(),2630                                            DotSymtabSec);2631    Ctx.PrintUnwindInformation();2632  }2633  DwarfCFIEH::PrinterContext<ELF32LE> Ctx(W, ObjF);2634  Ctx.printUnwindInformation();2635}2636} // namespace2637 2638template <class ELFT> void ELFDumper<ELFT>::printNeededLibraries() {2639  ListScope D(W, "NeededLibraries");2640 2641  std::vector<StringRef> Libs;2642  for (const auto &Entry : dynamic_table())2643    if (Entry.d_tag == ELF::DT_NEEDED)2644      Libs.push_back(getDynamicString(Entry.d_un.d_val));2645 2646  llvm::sort(Libs);2647 2648  for (StringRef L : Libs)2649    W.printString(L);2650}2651 2652template <class ELFT>2653static Error checkHashTable(const ELFDumper<ELFT> &Dumper,2654                            const typename ELFT::Hash *H,2655                            bool *IsHeaderValid = nullptr) {2656  const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();2657  const uint64_t SecOffset = (const uint8_t *)H - Obj.base();2658  if (Dumper.getHashTableEntSize() == 8) {2659    auto It = llvm::find_if(ElfMachineType, [&](const EnumEntry<unsigned> &E) {2660      return E.Value == Obj.getHeader().e_machine;2661    });2662    if (IsHeaderValid)2663      *IsHeaderValid = false;2664    return createError("the hash table at 0x" + Twine::utohexstr(SecOffset) +2665                       " is not supported: it contains non-standard 8 "2666                       "byte entries on " +2667                       It->AltName + " platform");2668  }2669 2670  auto MakeError = [&](const Twine &Msg = "") {2671    return createError("the hash table at offset 0x" +2672                       Twine::utohexstr(SecOffset) +2673                       " goes past the end of the file (0x" +2674                       Twine::utohexstr(Obj.getBufSize()) + ")" + Msg);2675  };2676 2677  // Each SHT_HASH section starts from two 32-bit fields: nbucket and nchain.2678  const unsigned HeaderSize = 2 * sizeof(typename ELFT::Word);2679 2680  if (IsHeaderValid)2681    *IsHeaderValid = Obj.getBufSize() - SecOffset >= HeaderSize;2682 2683  if (Obj.getBufSize() - SecOffset < HeaderSize)2684    return MakeError();2685 2686  if (Obj.getBufSize() - SecOffset - HeaderSize <2687      ((uint64_t)H->nbucket + H->nchain) * sizeof(typename ELFT::Word))2688    return MakeError(", nbucket = " + Twine(H->nbucket) +2689                     ", nchain = " + Twine(H->nchain));2690  return Error::success();2691}2692 2693template <class ELFT>2694static Error checkGNUHashTable(const ELFFile<ELFT> &Obj,2695                               const typename ELFT::GnuHash *GnuHashTable,2696                               bool *IsHeaderValid = nullptr) {2697  const uint8_t *TableData = reinterpret_cast<const uint8_t *>(GnuHashTable);2698  assert(TableData >= Obj.base() && TableData < Obj.base() + Obj.getBufSize() &&2699         "GnuHashTable must always point to a location inside the file");2700 2701  uint64_t TableOffset = TableData - Obj.base();2702  if (IsHeaderValid)2703    *IsHeaderValid = TableOffset + /*Header size:*/ 16 < Obj.getBufSize();2704  if (TableOffset + 16 + (uint64_t)GnuHashTable->nbuckets * 4 +2705          (uint64_t)GnuHashTable->maskwords * sizeof(typename ELFT::Off) >=2706      Obj.getBufSize())2707    return createError("unable to dump the SHT_GNU_HASH "2708                       "section at 0x" +2709                       Twine::utohexstr(TableOffset) +2710                       ": it goes past the end of the file");2711  return Error::success();2712}2713 2714template <typename ELFT> void ELFDumper<ELFT>::printHashTable() {2715  DictScope D(W, "HashTable");2716  if (!HashTable)2717    return;2718 2719  bool IsHeaderValid;2720  Error Err = checkHashTable(*this, HashTable, &IsHeaderValid);2721  if (IsHeaderValid) {2722    W.printNumber("Num Buckets", HashTable->nbucket);2723    W.printNumber("Num Chains", HashTable->nchain);2724  }2725 2726  if (Err) {2727    reportUniqueWarning(std::move(Err));2728    return;2729  }2730 2731  W.printList("Buckets", HashTable->buckets());2732  W.printList("Chains", HashTable->chains());2733}2734 2735template <class ELFT>2736static Expected<ArrayRef<typename ELFT::Word>>2737getGnuHashTableChains(std::optional<DynRegionInfo> DynSymRegion,2738                      const typename ELFT::GnuHash *GnuHashTable) {2739  if (!DynSymRegion)2740    return createError("no dynamic symbol table found");2741 2742  ArrayRef<typename ELFT::Sym> DynSymTable =2743      DynSymRegion->template getAsArrayRef<typename ELFT::Sym>();2744  size_t NumSyms = DynSymTable.size();2745  if (!NumSyms)2746    return createError("the dynamic symbol table is empty");2747 2748  if (GnuHashTable->symndx < NumSyms)2749    return GnuHashTable->values(NumSyms);2750 2751  // A normal empty GNU hash table section produced by linker might have2752  // symndx set to the number of dynamic symbols + 1 (for the zero symbol)2753  // and have dummy null values in the Bloom filter and in the buckets2754  // vector (or no values at all). It happens because the value of symndx is not2755  // important for dynamic loaders when the GNU hash table is empty. They just2756  // skip the whole object during symbol lookup. In such cases, the symndx value2757  // is irrelevant and we should not report a warning.2758  ArrayRef<typename ELFT::Word> Buckets = GnuHashTable->buckets();2759  if (!llvm::all_of(Buckets, [](typename ELFT::Word V) { return V == 0; }))2760    return createError(2761        "the first hashed symbol index (" + Twine(GnuHashTable->symndx) +2762        ") is greater than or equal to the number of dynamic symbols (" +2763        Twine(NumSyms) + ")");2764  // There is no way to represent an array of (dynamic symbols count - symndx)2765  // length.2766  return ArrayRef<typename ELFT::Word>();2767}2768 2769template <typename ELFT>2770void ELFDumper<ELFT>::printGnuHashTable() {2771  DictScope D(W, "GnuHashTable");2772  if (!GnuHashTable)2773    return;2774 2775  bool IsHeaderValid;2776  Error Err = checkGNUHashTable<ELFT>(Obj, GnuHashTable, &IsHeaderValid);2777  if (IsHeaderValid) {2778    W.printNumber("Num Buckets", GnuHashTable->nbuckets);2779    W.printNumber("First Hashed Symbol Index", GnuHashTable->symndx);2780    W.printNumber("Num Mask Words", GnuHashTable->maskwords);2781    W.printNumber("Shift Count", GnuHashTable->shift2);2782  }2783 2784  if (Err) {2785    reportUniqueWarning(std::move(Err));2786    return;2787  }2788 2789  ArrayRef<typename ELFT::Off> BloomFilter = GnuHashTable->filter();2790  W.printHexList("Bloom Filter", BloomFilter);2791 2792  ArrayRef<Elf_Word> Buckets = GnuHashTable->buckets();2793  W.printList("Buckets", Buckets);2794 2795  Expected<ArrayRef<Elf_Word>> Chains =2796      getGnuHashTableChains<ELFT>(DynSymRegion, GnuHashTable);2797  if (!Chains) {2798    reportUniqueWarning("unable to dump 'Values' for the SHT_GNU_HASH "2799                        "section: " +2800                        toString(Chains.takeError()));2801    return;2802  }2803 2804  W.printHexList("Values", *Chains);2805}2806 2807template <typename ELFT> void ELFDumper<ELFT>::printHashHistograms() {2808  // Print histogram for the .hash section.2809  if (this->HashTable) {2810    if (Error E = checkHashTable<ELFT>(*this, this->HashTable))2811      this->reportUniqueWarning(std::move(E));2812    else2813      printHashHistogram(*this->HashTable);2814  }2815 2816  // Print histogram for the .gnu.hash section.2817  if (this->GnuHashTable) {2818    if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable))2819      this->reportUniqueWarning(std::move(E));2820    else2821      printGnuHashHistogram(*this->GnuHashTable);2822  }2823}2824 2825template <typename ELFT>2826void ELFDumper<ELFT>::printHashHistogram(const Elf_Hash &HashTable) const {2827  size_t NBucket = HashTable.nbucket;2828  size_t NChain = HashTable.nchain;2829  ArrayRef<Elf_Word> Buckets = HashTable.buckets();2830  ArrayRef<Elf_Word> Chains = HashTable.chains();2831  size_t TotalSyms = 0;2832  // If hash table is correct, we have at least chains with 0 length.2833  size_t MaxChain = 1;2834 2835  if (NChain == 0 || NBucket == 0)2836    return;2837 2838  std::vector<size_t> ChainLen(NBucket, 0);2839  // Go over all buckets and note chain lengths of each bucket (total2840  // unique chain lengths).2841  for (size_t B = 0; B < NBucket; ++B) {2842    BitVector Visited(NChain);2843    for (size_t C = Buckets[B]; C < NChain; C = Chains[C]) {2844      if (C == ELF::STN_UNDEF)2845          break;2846      if (Visited[C]) {2847          this->reportUniqueWarning(2848              ".hash section is invalid: bucket " + Twine(C) +2849              ": a cycle was detected in the linked chain");2850          break;2851      }2852      Visited[C] = true;2853      if (MaxChain <= ++ChainLen[B])2854          ++MaxChain;2855    }2856    TotalSyms += ChainLen[B];2857  }2858 2859  if (!TotalSyms)2860    return;2861 2862  std::vector<size_t> Count(MaxChain, 0);2863  // Count how long is the chain for each bucket.2864  for (size_t B = 0; B < NBucket; B++)2865    ++Count[ChainLen[B]];2866  // Print Number of buckets with each chain lengths and their cumulative2867  // coverage of the symbols.2868  printHashHistogramStats(NBucket, MaxChain, TotalSyms, Count, /*IsGnu=*/false);2869}2870 2871template <class ELFT>2872void ELFDumper<ELFT>::printGnuHashHistogram(2873    const Elf_GnuHash &GnuHashTable) const {2874  Expected<ArrayRef<Elf_Word>> ChainsOrErr =2875      getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHashTable);2876  if (!ChainsOrErr) {2877    this->reportUniqueWarning("unable to print the GNU hash table histogram: " +2878                              toString(ChainsOrErr.takeError()));2879    return;2880  }2881 2882  ArrayRef<Elf_Word> Chains = *ChainsOrErr;2883  size_t Symndx = GnuHashTable.symndx;2884  size_t TotalSyms = 0;2885  size_t MaxChain = 1;2886 2887  size_t NBucket = GnuHashTable.nbuckets;2888  if (Chains.empty() || NBucket == 0)2889    return;2890 2891  ArrayRef<Elf_Word> Buckets = GnuHashTable.buckets();2892  std::vector<size_t> ChainLen(NBucket, 0);2893  for (size_t B = 0; B < NBucket; ++B) {2894    if (!Buckets[B])2895      continue;2896    size_t Len = 1;2897    for (size_t C = Buckets[B] - Symndx;2898         C < Chains.size() && (Chains[C] & 1) == 0; ++C)2899      if (MaxChain < ++Len)2900          ++MaxChain;2901    ChainLen[B] = Len;2902    TotalSyms += Len;2903  }2904  ++MaxChain;2905 2906  if (!TotalSyms)2907    return;2908 2909  std::vector<size_t> Count(MaxChain, 0);2910  for (size_t B = 0; B < NBucket; ++B)2911    ++Count[ChainLen[B]];2912  // Print Number of buckets with each chain lengths and their cumulative2913  // coverage of the symbols.2914  printHashHistogramStats(NBucket, MaxChain, TotalSyms, Count, /*IsGnu=*/true);2915}2916 2917template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {2918  StringRef SOName = "<Not found>";2919  if (SONameOffset)2920    SOName = getDynamicString(*SONameOffset);2921  W.printString("LoadName", SOName);2922}2923 2924template <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() {2925  switch (Obj.getHeader().e_machine) {2926  case EM_HEXAGON:2927    printAttributes(ELF::SHT_HEXAGON_ATTRIBUTES,2928                    std::make_unique<HexagonAttributeParser>(&W),2929                    llvm::endianness::little);2930    break;2931  case EM_ARM:2932    printAttributes(2933        ELF::SHT_ARM_ATTRIBUTES, std::make_unique<ARMAttributeParser>(&W),2934        Obj.isLE() ? llvm::endianness::little : llvm::endianness::big);2935    break;2936  case EM_AARCH64:2937    printAttributes(ELF::SHT_AARCH64_ATTRIBUTES,2938                    std::make_unique<AArch64AttributeParser>(&W),2939                    Obj.isLE() ? llvm::endianness::little2940                               : llvm::endianness::big);2941    break;2942  case EM_RISCV:2943    if (Obj.isLE())2944      printAttributes(ELF::SHT_RISCV_ATTRIBUTES,2945                      std::make_unique<RISCVAttributeParser>(&W),2946                      llvm::endianness::little);2947    else2948      reportUniqueWarning("attribute printing not implemented for big-endian "2949                          "RISC-V objects");2950    break;2951  case EM_MSP430:2952    printAttributes(ELF::SHT_MSP430_ATTRIBUTES,2953                    std::make_unique<MSP430AttributeParser>(&W),2954                    llvm::endianness::little);2955    break;2956  case EM_MIPS: {2957    printMipsABIFlags();2958    printMipsOptions();2959    printMipsReginfo();2960    MipsGOTParser<ELFT> Parser(*this);2961    if (Error E = Parser.findGOT(dynamic_table(), dynamic_symbols()))2962      reportUniqueWarning(std::move(E));2963    else if (!Parser.isGotEmpty())2964      printMipsGOT(Parser);2965 2966    if (Error E = Parser.findPLT(dynamic_table()))2967      reportUniqueWarning(std::move(E));2968    else if (!Parser.isPltEmpty())2969      printMipsPLT(Parser);2970    break;2971  }2972  default:2973    break;2974  }2975}2976 2977template <class ELFT>2978void ELFDumper<ELFT>::printAttributes(2979    unsigned AttrShType, std::unique_ptr<ELFAttributeParser> AttrParser,2980    llvm::endianness Endianness) {2981  assert((AttrShType != ELF::SHT_NULL) && AttrParser &&2982         "Incomplete ELF attribute implementation");2983  DictScope BA(W, "BuildAttributes");2984  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {2985    if (Sec.sh_type != AttrShType)2986      continue;2987 2988    ArrayRef<uint8_t> Contents;2989    if (Expected<ArrayRef<uint8_t>> ContentOrErr =2990            Obj.getSectionContents(Sec)) {2991      Contents = *ContentOrErr;2992      if (Contents.empty()) {2993        reportUniqueWarning("the " + describe(Sec) + " is empty");2994        continue;2995      }2996    } else {2997      reportUniqueWarning("unable to read the content of the " + describe(Sec) +2998                          ": " + toString(ContentOrErr.takeError()));2999      continue;3000    }3001 3002    W.printHex("FormatVersion", Contents[0]);3003 3004    if (Error E = AttrParser->parse(Contents, Endianness))3005      reportUniqueWarning("unable to dump attributes from the " +3006                          describe(Sec) + ": " + toString(std::move(E)));3007  }3008}3009 3010namespace {3011 3012template <class ELFT> class MipsGOTParser {3013public:3014  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)3015  using Entry = typename ELFT::Addr;3016  using Entries = ArrayRef<Entry>;3017 3018  const bool IsStatic;3019  const ELFFile<ELFT> &Obj;3020  const ELFDumper<ELFT> &Dumper;3021 3022  MipsGOTParser(const ELFDumper<ELFT> &D);3023  Error findGOT(Elf_Dyn_Range DynTable, Elf_Sym_Range DynSyms);3024  Error findPLT(Elf_Dyn_Range DynTable);3025 3026  bool isGotEmpty() const { return GotEntries.empty(); }3027  bool isPltEmpty() const { return PltEntries.empty(); }3028 3029  uint64_t getGp() const;3030 3031  const Entry *getGotLazyResolver() const;3032  const Entry *getGotModulePointer() const;3033  const Entry *getPltLazyResolver() const;3034  const Entry *getPltModulePointer() const;3035 3036  Entries getLocalEntries() const;3037  Entries getGlobalEntries() const;3038  Entries getOtherEntries() const;3039  Entries getPltEntries() const;3040 3041  uint64_t getGotAddress(const Entry * E) const;3042  int64_t getGotOffset(const Entry * E) const;3043  const Elf_Sym *getGotSym(const Entry *E) const;3044 3045  uint64_t getPltAddress(const Entry * E) const;3046  const Elf_Sym *getPltSym(const Entry *E) const;3047 3048  StringRef getPltStrTable() const { return PltStrTable; }3049  const Elf_Shdr *getPltSymTable() const { return PltSymTable; }3050 3051private:3052  const Elf_Shdr *GotSec;3053  size_t LocalNum;3054  size_t GlobalNum;3055 3056  const Elf_Shdr *PltSec;3057  const Elf_Shdr *PltRelSec;3058  const Elf_Shdr *PltSymTable;3059  StringRef FileName;3060 3061  Elf_Sym_Range GotDynSyms;3062  StringRef PltStrTable;3063 3064  Entries GotEntries;3065  Entries PltEntries;3066};3067 3068} // end anonymous namespace3069 3070template <class ELFT>3071MipsGOTParser<ELFT>::MipsGOTParser(const ELFDumper<ELFT> &D)3072    : IsStatic(D.dynamic_table().empty()), Obj(D.getElfObject().getELFFile()),3073      Dumper(D), GotSec(nullptr), LocalNum(0), GlobalNum(0), PltSec(nullptr),3074      PltRelSec(nullptr), PltSymTable(nullptr),3075      FileName(D.getElfObject().getFileName()) {}3076 3077template <class ELFT>3078Error MipsGOTParser<ELFT>::findGOT(Elf_Dyn_Range DynTable,3079                                   Elf_Sym_Range DynSyms) {3080  // See "Global Offset Table" in Chapter 5 in the following document3081  // for detailed GOT description.3082  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf3083 3084  // Find static GOT secton.3085  if (IsStatic) {3086    GotSec = Dumper.findSectionByName(".got");3087    if (!GotSec)3088      return Error::success();3089 3090    ArrayRef<uint8_t> Content =3091        unwrapOrError(FileName, Obj.getSectionContents(*GotSec));3092    GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),3093                         Content.size() / sizeof(Entry));3094    LocalNum = GotEntries.size();3095    return Error::success();3096  }3097 3098  // Lookup dynamic table tags which define the GOT layout.3099  std::optional<uint64_t> DtPltGot;3100  std::optional<uint64_t> DtLocalGotNum;3101  std::optional<uint64_t> DtGotSym;3102  for (const auto &Entry : DynTable) {3103    switch (Entry.getTag()) {3104    case ELF::DT_PLTGOT:3105      DtPltGot = Entry.getVal();3106      break;3107    case ELF::DT_MIPS_LOCAL_GOTNO:3108      DtLocalGotNum = Entry.getVal();3109      break;3110    case ELF::DT_MIPS_GOTSYM:3111      DtGotSym = Entry.getVal();3112      break;3113    }3114  }3115 3116  if (!DtPltGot && !DtLocalGotNum && !DtGotSym)3117    return Error::success();3118 3119  if (!DtPltGot)3120    return createError("cannot find PLTGOT dynamic tag");3121  if (!DtLocalGotNum)3122    return createError("cannot find MIPS_LOCAL_GOTNO dynamic tag");3123  if (!DtGotSym)3124    return createError("cannot find MIPS_GOTSYM dynamic tag");3125 3126  size_t DynSymTotal = DynSyms.size();3127  if (*DtGotSym > DynSymTotal)3128    return createError("DT_MIPS_GOTSYM value (" + Twine(*DtGotSym) +3129                       ") exceeds the number of dynamic symbols (" +3130                       Twine(DynSymTotal) + ")");3131 3132  GotSec = findNotEmptySectionByAddress(Obj, FileName, *DtPltGot);3133  if (!GotSec)3134    return createError("there is no non-empty GOT section at 0x" +3135                       Twine::utohexstr(*DtPltGot));3136 3137  LocalNum = *DtLocalGotNum;3138  GlobalNum = DynSymTotal - *DtGotSym;3139 3140  ArrayRef<uint8_t> Content =3141      unwrapOrError(FileName, Obj.getSectionContents(*GotSec));3142  GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),3143                       Content.size() / sizeof(Entry));3144  GotDynSyms = DynSyms.drop_front(*DtGotSym);3145 3146  return Error::success();3147}3148 3149template <class ELFT>3150Error MipsGOTParser<ELFT>::findPLT(Elf_Dyn_Range DynTable) {3151  // Lookup dynamic table tags which define the PLT layout.3152  std::optional<uint64_t> DtMipsPltGot;3153  std::optional<uint64_t> DtJmpRel;3154  for (const auto &Entry : DynTable) {3155    switch (Entry.getTag()) {3156    case ELF::DT_MIPS_PLTGOT:3157      DtMipsPltGot = Entry.getVal();3158      break;3159    case ELF::DT_JMPREL:3160      DtJmpRel = Entry.getVal();3161      break;3162    }3163  }3164 3165  if (!DtMipsPltGot && !DtJmpRel)3166    return Error::success();3167 3168  // Find PLT section.3169  if (!DtMipsPltGot)3170    return createError("cannot find MIPS_PLTGOT dynamic tag");3171  if (!DtJmpRel)3172    return createError("cannot find JMPREL dynamic tag");3173 3174  PltSec = findNotEmptySectionByAddress(Obj, FileName, *DtMipsPltGot);3175  if (!PltSec)3176    return createError("there is no non-empty PLTGOT section at 0x" +3177                       Twine::utohexstr(*DtMipsPltGot));3178 3179  PltRelSec = findNotEmptySectionByAddress(Obj, FileName, *DtJmpRel);3180  if (!PltRelSec)3181    return createError("there is no non-empty RELPLT section at 0x" +3182                       Twine::utohexstr(*DtJmpRel));3183 3184  if (Expected<ArrayRef<uint8_t>> PltContentOrErr =3185          Obj.getSectionContents(*PltSec))3186    PltEntries =3187        Entries(reinterpret_cast<const Entry *>(PltContentOrErr->data()),3188                PltContentOrErr->size() / sizeof(Entry));3189  else3190    return createError("unable to read PLTGOT section content: " +3191                       toString(PltContentOrErr.takeError()));3192 3193  if (Expected<const Elf_Shdr *> PltSymTableOrErr =3194          Obj.getSection(PltRelSec->sh_link))3195    PltSymTable = *PltSymTableOrErr;3196  else3197    return createError("unable to get a symbol table linked to the " +3198                       describe(Obj, *PltRelSec) + ": " +3199                       toString(PltSymTableOrErr.takeError()));3200 3201  if (Expected<StringRef> StrTabOrErr =3202          Obj.getStringTableForSymtab(*PltSymTable))3203    PltStrTable = *StrTabOrErr;3204  else3205    return createError("unable to get a string table for the " +3206                       describe(Obj, *PltSymTable) + ": " +3207                       toString(StrTabOrErr.takeError()));3208 3209  return Error::success();3210}3211 3212template <class ELFT> uint64_t MipsGOTParser<ELFT>::getGp() const {3213  return GotSec->sh_addr + 0x7ff0;3214}3215 3216template <class ELFT>3217const typename MipsGOTParser<ELFT>::Entry *3218MipsGOTParser<ELFT>::getGotLazyResolver() const {3219  return LocalNum > 0 ? &GotEntries[0] : nullptr;3220}3221 3222template <class ELFT>3223const typename MipsGOTParser<ELFT>::Entry *3224MipsGOTParser<ELFT>::getGotModulePointer() const {3225  if (LocalNum < 2)3226    return nullptr;3227  const Entry &E = GotEntries[1];3228  if ((E >> (sizeof(Entry) * 8 - 1)) == 0)3229    return nullptr;3230  return &E;3231}3232 3233template <class ELFT>3234typename MipsGOTParser<ELFT>::Entries3235MipsGOTParser<ELFT>::getLocalEntries() const {3236  size_t Skip = getGotModulePointer() ? 2 : 1;3237  if (LocalNum - Skip <= 0)3238    return Entries();3239  return GotEntries.slice(Skip, LocalNum - Skip);3240}3241 3242template <class ELFT>3243typename MipsGOTParser<ELFT>::Entries3244MipsGOTParser<ELFT>::getGlobalEntries() const {3245  if (GlobalNum == 0)3246    return Entries();3247  return GotEntries.slice(LocalNum, GlobalNum);3248}3249 3250template <class ELFT>3251typename MipsGOTParser<ELFT>::Entries3252MipsGOTParser<ELFT>::getOtherEntries() const {3253  size_t OtherNum = GotEntries.size() - LocalNum - GlobalNum;3254  if (OtherNum == 0)3255    return Entries();3256  return GotEntries.slice(LocalNum + GlobalNum, OtherNum);3257}3258 3259template <class ELFT>3260uint64_t MipsGOTParser<ELFT>::getGotAddress(const Entry *E) const {3261  int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);3262  return GotSec->sh_addr + Offset;3263}3264 3265template <class ELFT>3266int64_t MipsGOTParser<ELFT>::getGotOffset(const Entry *E) const {3267  int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);3268  return Offset - 0x7ff0;3269}3270 3271template <class ELFT>3272const typename MipsGOTParser<ELFT>::Elf_Sym *3273MipsGOTParser<ELFT>::getGotSym(const Entry *E) const {3274  int64_t Offset = std::distance(GotEntries.data(), E);3275  return &GotDynSyms[Offset - LocalNum];3276}3277 3278template <class ELFT>3279const typename MipsGOTParser<ELFT>::Entry *3280MipsGOTParser<ELFT>::getPltLazyResolver() const {3281  return PltEntries.empty() ? nullptr : &PltEntries[0];3282}3283 3284template <class ELFT>3285const typename MipsGOTParser<ELFT>::Entry *3286MipsGOTParser<ELFT>::getPltModulePointer() const {3287  return PltEntries.size() < 2 ? nullptr : &PltEntries[1];3288}3289 3290template <class ELFT>3291typename MipsGOTParser<ELFT>::Entries3292MipsGOTParser<ELFT>::getPltEntries() const {3293  if (PltEntries.size() <= 2)3294    return Entries();3295  return PltEntries.slice(2, PltEntries.size() - 2);3296}3297 3298template <class ELFT>3299uint64_t MipsGOTParser<ELFT>::getPltAddress(const Entry *E) const {3300  int64_t Offset = std::distance(PltEntries.data(), E) * sizeof(Entry);3301  return PltSec->sh_addr + Offset;3302}3303 3304template <class ELFT>3305const typename MipsGOTParser<ELFT>::Elf_Sym *3306MipsGOTParser<ELFT>::getPltSym(const Entry *E) const {3307  int64_t Offset = std::distance(getPltEntries().data(), E);3308  if (PltRelSec->sh_type == ELF::SHT_REL) {3309    Elf_Rel_Range Rels = unwrapOrError(FileName, Obj.rels(*PltRelSec));3310    return unwrapOrError(FileName,3311                         Obj.getRelocationSymbol(Rels[Offset], PltSymTable));3312  } else {3313    Elf_Rela_Range Rels = unwrapOrError(FileName, Obj.relas(*PltRelSec));3314    return unwrapOrError(FileName,3315                         Obj.getRelocationSymbol(Rels[Offset], PltSymTable));3316  }3317}3318 3319const EnumEntry<unsigned> ElfMipsISAExtType[] = {3320  {"None",                    Mips::AFL_EXT_NONE},3321  {"Broadcom SB-1",           Mips::AFL_EXT_SB1},3322  {"Cavium Networks Octeon",  Mips::AFL_EXT_OCTEON},3323  {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2},3324  {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP},3325  {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3},3326  {"LSI R4010",               Mips::AFL_EXT_4010},3327  {"Loongson 2E",             Mips::AFL_EXT_LOONGSON_2E},3328  {"Loongson 2F",             Mips::AFL_EXT_LOONGSON_2F},3329  {"Loongson 3A",             Mips::AFL_EXT_LOONGSON_3A},3330  {"MIPS R4650",              Mips::AFL_EXT_4650},3331  {"MIPS R5900",              Mips::AFL_EXT_5900},3332  {"MIPS R10000",             Mips::AFL_EXT_10000},3333  {"NEC VR4100",              Mips::AFL_EXT_4100},3334  {"NEC VR4111/VR4181",       Mips::AFL_EXT_4111},3335  {"NEC VR4120",              Mips::AFL_EXT_4120},3336  {"NEC VR5400",              Mips::AFL_EXT_5400},3337  {"NEC VR5500",              Mips::AFL_EXT_5500},3338  {"RMI Xlr",                 Mips::AFL_EXT_XLR},3339  {"Toshiba R3900",           Mips::AFL_EXT_3900}3340};3341 3342const EnumEntry<unsigned> ElfMipsASEFlags[] = {3343  {"DSP",                Mips::AFL_ASE_DSP},3344  {"DSPR2",              Mips::AFL_ASE_DSPR2},3345  {"Enhanced VA Scheme", Mips::AFL_ASE_EVA},3346  {"MCU",                Mips::AFL_ASE_MCU},3347  {"MDMX",               Mips::AFL_ASE_MDMX},3348  {"MIPS-3D",            Mips::AFL_ASE_MIPS3D},3349  {"MT",                 Mips::AFL_ASE_MT},3350  {"SmartMIPS",          Mips::AFL_ASE_SMARTMIPS},3351  {"VZ",                 Mips::AFL_ASE_VIRT},3352  {"MSA",                Mips::AFL_ASE_MSA},3353  {"MIPS16",             Mips::AFL_ASE_MIPS16},3354  {"microMIPS",          Mips::AFL_ASE_MICROMIPS},3355  {"XPA",                Mips::AFL_ASE_XPA},3356  {"CRC",                Mips::AFL_ASE_CRC},3357  {"GINV",               Mips::AFL_ASE_GINV},3358};3359 3360const EnumEntry<unsigned> ElfMipsFpABIType[] = {3361  {"Hard or soft float",                  Mips::Val_GNU_MIPS_ABI_FP_ANY},3362  {"Hard float (double precision)",       Mips::Val_GNU_MIPS_ABI_FP_DOUBLE},3363  {"Hard float (single precision)",       Mips::Val_GNU_MIPS_ABI_FP_SINGLE},3364  {"Soft float",                          Mips::Val_GNU_MIPS_ABI_FP_SOFT},3365  {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)",3366   Mips::Val_GNU_MIPS_ABI_FP_OLD_64},3367  {"Hard float (32-bit CPU, Any FPU)",    Mips::Val_GNU_MIPS_ABI_FP_XX},3368  {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64},3369  {"Hard float compat (32-bit CPU, 64-bit FPU)",3370   Mips::Val_GNU_MIPS_ABI_FP_64A}3371};3372 3373static const EnumEntry<unsigned> ElfMipsFlags1[] {3374  {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG},3375};3376 3377static int getMipsRegisterSize(uint8_t Flag) {3378  switch (Flag) {3379  case Mips::AFL_REG_NONE:3380    return 0;3381  case Mips::AFL_REG_32:3382    return 32;3383  case Mips::AFL_REG_64:3384    return 64;3385  case Mips::AFL_REG_128:3386    return 128;3387  default:3388    return -1;3389  }3390}3391 3392template <class ELFT>3393static void printMipsReginfoData(ScopedPrinter &W,3394                                 const Elf_Mips_RegInfo<ELFT> &Reginfo) {3395  W.printHex("GP", Reginfo.ri_gp_value);3396  W.printHex("General Mask", Reginfo.ri_gprmask);3397  W.printHex("Co-Proc Mask0", Reginfo.ri_cprmask[0]);3398  W.printHex("Co-Proc Mask1", Reginfo.ri_cprmask[1]);3399  W.printHex("Co-Proc Mask2", Reginfo.ri_cprmask[2]);3400  W.printHex("Co-Proc Mask3", Reginfo.ri_cprmask[3]);3401}3402 3403template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {3404  const Elf_Shdr *RegInfoSec = findSectionByName(".reginfo");3405  if (!RegInfoSec) {3406    W.startLine() << "There is no .reginfo section in the file.\n";3407    return;3408  }3409 3410  Expected<ArrayRef<uint8_t>> ContentsOrErr =3411      Obj.getSectionContents(*RegInfoSec);3412  if (!ContentsOrErr) {3413    this->reportUniqueWarning(3414        "unable to read the content of the .reginfo section (" +3415        describe(*RegInfoSec) + "): " + toString(ContentsOrErr.takeError()));3416    return;3417  }3418 3419  if (ContentsOrErr->size() < sizeof(Elf_Mips_RegInfo<ELFT>)) {3420    this->reportUniqueWarning("the .reginfo section has an invalid size (0x" +3421                              Twine::utohexstr(ContentsOrErr->size()) + ")");3422    return;3423  }3424 3425  DictScope GS(W, "MIPS RegInfo");3426  printMipsReginfoData(W, *reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(3427                              ContentsOrErr->data()));3428}3429 3430template <class ELFT>3431static Expected<const Elf_Mips_Options<ELFT> *>3432readMipsOptions(const uint8_t *SecBegin, ArrayRef<uint8_t> &SecData,3433                bool &IsSupported) {3434  if (SecData.size() < sizeof(Elf_Mips_Options<ELFT>))3435    return createError("the .MIPS.options section has an invalid size (0x" +3436                       Twine::utohexstr(SecData.size()) + ")");3437 3438  const Elf_Mips_Options<ELFT> *O =3439      reinterpret_cast<const Elf_Mips_Options<ELFT> *>(SecData.data());3440  const uint8_t Size = O->size;3441  if (Size > SecData.size()) {3442    const uint64_t Offset = SecData.data() - SecBegin;3443    const uint64_t SecSize = Offset + SecData.size();3444    return createError("a descriptor of size 0x" + Twine::utohexstr(Size) +3445                       " at offset 0x" + Twine::utohexstr(Offset) +3446                       " goes past the end of the .MIPS.options "3447                       "section of size 0x" +3448                       Twine::utohexstr(SecSize));3449  }3450 3451  IsSupported = O->kind == ODK_REGINFO;3452  const size_t ExpectedSize =3453      sizeof(Elf_Mips_Options<ELFT>) + sizeof(Elf_Mips_RegInfo<ELFT>);3454 3455  if (IsSupported)3456    if (Size < ExpectedSize)3457      return createError(3458          "a .MIPS.options entry of kind " +3459          Twine(getElfMipsOptionsOdkType(O->kind)) +3460          " has an invalid size (0x" + Twine::utohexstr(Size) +3461          "), the expected size is 0x" + Twine::utohexstr(ExpectedSize));3462 3463  SecData = SecData.drop_front(Size);3464  return O;3465}3466 3467template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {3468  const Elf_Shdr *MipsOpts = findSectionByName(".MIPS.options");3469  if (!MipsOpts) {3470    W.startLine() << "There is no .MIPS.options section in the file.\n";3471    return;3472  }3473 3474  DictScope GS(W, "MIPS Options");3475 3476  ArrayRef<uint8_t> Data =3477      unwrapOrError(ObjF.getFileName(), Obj.getSectionContents(*MipsOpts));3478  const uint8_t *const SecBegin = Data.begin();3479  while (!Data.empty()) {3480    bool IsSupported;3481    Expected<const Elf_Mips_Options<ELFT> *> OptsOrErr =3482        readMipsOptions<ELFT>(SecBegin, Data, IsSupported);3483    if (!OptsOrErr) {3484      reportUniqueWarning(OptsOrErr.takeError());3485      break;3486    }3487 3488    unsigned Kind = (*OptsOrErr)->kind;3489    const char *Type = getElfMipsOptionsOdkType(Kind);3490    if (!IsSupported) {3491      W.startLine() << "Unsupported MIPS options tag: " << Type << " (" << Kind3492                    << ")\n";3493      continue;3494    }3495 3496    DictScope GS(W, Type);3497    if (Kind == ODK_REGINFO)3498      printMipsReginfoData(W, (*OptsOrErr)->getRegInfo());3499    else3500      llvm_unreachable("unexpected .MIPS.options section descriptor kind");3501  }3502}3503 3504template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {3505  const Elf_Shdr *StackMapSection = findSectionByName(".llvm_stackmaps");3506  if (!StackMapSection)3507    return;3508 3509  auto Warn = [&](Error &&E) {3510    this->reportUniqueWarning("unable to read the stack map from " +3511                              describe(*StackMapSection) + ": " +3512                              toString(std::move(E)));3513  };3514 3515  Expected<ArrayRef<uint8_t>> ContentOrErr =3516      Obj.getSectionContents(*StackMapSection);3517  if (!ContentOrErr) {3518    Warn(ContentOrErr.takeError());3519    return;3520  }3521 3522  if (Error E =3523          StackMapParser<ELFT::Endianness>::validateHeader(*ContentOrErr)) {3524    Warn(std::move(E));3525    return;3526  }3527 3528  prettyPrintStackMap(W, StackMapParser<ELFT::Endianness>(*ContentOrErr));3529}3530 3531template <class ELFT>3532void ELFDumper<ELFT>::printReloc(const Relocation<ELFT> &R, unsigned RelIndex,3533                                 const Elf_Shdr &Sec, const Elf_Shdr *SymTab) {3534  Expected<RelSymbol<ELFT>> Target = getRelocationTarget(R, SymTab);3535  if (!Target)3536    reportUniqueWarning("unable to print relocation " + Twine(RelIndex) +3537                        " in " + describe(Sec) + ": " +3538                        toString(Target.takeError()));3539  else3540    printRelRelaReloc(R, *Target);3541}3542 3543template <class ELFT>3544std::vector<EnumEntry<unsigned>>3545ELFDumper<ELFT>::getOtherFlagsFromSymbol(const Elf_Ehdr &Header,3546                                         const Elf_Sym &Symbol) const {3547  std::vector<EnumEntry<unsigned>> SymOtherFlags(std::begin(ElfSymOtherFlags),3548                                                 std::end(ElfSymOtherFlags));3549  if (Header.e_machine == EM_MIPS) {3550    // Someone in their infinite wisdom decided to make STO_MIPS_MIPS163551    // flag overlap with other ST_MIPS_xxx flags. So consider both3552    // cases separately.3553    if ((Symbol.st_other & STO_MIPS_MIPS16) == STO_MIPS_MIPS16)3554      llvm::append_range(SymOtherFlags, ElfMips16SymOtherFlags);3555    else3556      llvm::append_range(SymOtherFlags, ElfMipsSymOtherFlags);3557  } else if (Header.e_machine == EM_AARCH64) {3558    llvm::append_range(SymOtherFlags, ElfAArch64SymOtherFlags);3559  } else if (Header.e_machine == EM_RISCV) {3560    llvm::append_range(SymOtherFlags, ElfRISCVSymOtherFlags);3561  }3562  return SymOtherFlags;3563}3564 3565static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,3566                               StringRef Str2) {3567  OS.PadToColumn(2u);3568  OS << Str1;3569  OS.PadToColumn(37u);3570  OS << Str2 << "\n";3571  OS.flush();3572}3573 3574template <class ELFT>3575static std::string getSectionHeadersNumString(const ELFFile<ELFT> &Obj,3576                                              StringRef FileName) {3577  const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();3578  if (ElfHeader.e_shnum != 0)3579    return to_string(ElfHeader.e_shnum);3580 3581  Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();3582  if (!ArrOrErr) {3583    // In this case we can ignore an error, because we have already reported a3584    // warning about the broken section header table earlier.3585    consumeError(ArrOrErr.takeError());3586    return "<?>";3587  }3588 3589  if (ArrOrErr->empty())3590    return "0";3591  return "0 (" + to_string((*ArrOrErr)[0].sh_size) + ")";3592}3593 3594template <class ELFT>3595static std::string getSectionHeaderTableIndexString(const ELFFile<ELFT> &Obj,3596                                                    StringRef FileName) {3597  const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();3598  if (ElfHeader.e_shstrndx != SHN_XINDEX)3599    return to_string(ElfHeader.e_shstrndx);3600 3601  Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();3602  if (!ArrOrErr) {3603    // In this case we can ignore an error, because we have already reported a3604    // warning about the broken section header table earlier.3605    consumeError(ArrOrErr.takeError());3606    return "<?>";3607  }3608 3609  if (ArrOrErr->empty())3610    return "65535 (corrupt: out of range)";3611  return to_string(ElfHeader.e_shstrndx) + " (" +3612         to_string((*ArrOrErr)[0].sh_link) + ")";3613}3614 3615static const EnumEntry<unsigned> *getObjectFileEnumEntry(unsigned Type) {3616  auto It = llvm::find_if(ElfObjectFileType, [&](const EnumEntry<unsigned> &E) {3617    return E.Value == Type;3618  });3619  if (It != ArrayRef(ElfObjectFileType).end())3620    return It;3621  return nullptr;3622}3623 3624template <class ELFT>3625void GNUELFDumper<ELFT>::printFileSummary(StringRef FileStr, ObjectFile &Obj,3626                                          ArrayRef<std::string> InputFilenames,3627                                          const Archive *A) {3628  if (InputFilenames.size() > 1 || A) {3629    this->W.startLine() << "\n";3630    this->W.printString("File", FileStr);3631  }3632}3633 3634template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() {3635  const Elf_Ehdr &e = this->Obj.getHeader();3636  OS << "ELF Header:\n";3637  OS << "  Magic:  ";3638  std::string Str;3639  for (int i = 0; i < ELF::EI_NIDENT; i++)3640    OS << format(" %02x", static_cast<int>(e.e_ident[i]));3641  OS << "\n";3642  Str = enumToString(e.e_ident[ELF::EI_CLASS], ArrayRef(ElfClass));3643  printFields(OS, "Class:", Str);3644  Str = enumToString(e.e_ident[ELF::EI_DATA], ArrayRef(ElfDataEncoding));3645  printFields(OS, "Data:", Str);3646  OS.PadToColumn(2u);3647  OS << "Version:";3648  OS.PadToColumn(37u);3649  OS << utohexstr(e.e_ident[ELF::EI_VERSION], /*LowerCase=*/true);3650  if (e.e_version == ELF::EV_CURRENT)3651    OS << " (current)";3652  OS << "\n";3653  auto OSABI = ArrayRef(ElfOSABI);3654  if (e.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH &&3655      e.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) {3656    switch (e.e_machine) {3657    case ELF::EM_ARM:3658      OSABI = ArrayRef(ARMElfOSABI);3659      break;3660    case ELF::EM_AMDGPU:3661      OSABI = ArrayRef(AMDGPUElfOSABI);3662      break;3663    default:3664      break;3665    }3666  }3667  Str = enumToString(e.e_ident[ELF::EI_OSABI], OSABI);3668  printFields(OS, "OS/ABI:", Str);3669  printFields(OS,3670              "ABI Version:", std::to_string(e.e_ident[ELF::EI_ABIVERSION]));3671 3672  if (const EnumEntry<unsigned> *E = getObjectFileEnumEntry(e.e_type)) {3673    Str = E->AltName.str();3674  } else {3675    if (e.e_type >= ET_LOPROC)3676      Str = "Processor Specific: (" + utohexstr(e.e_type, /*LowerCase=*/true) + ")";3677    else if (e.e_type >= ET_LOOS)3678      Str = "OS Specific: (" + utohexstr(e.e_type, /*LowerCase=*/true) + ")";3679    else3680      Str = "<unknown>: " + utohexstr(e.e_type, /*LowerCase=*/true);3681  }3682  printFields(OS, "Type:", Str);3683 3684  Str = enumToString(e.e_machine, ArrayRef(ElfMachineType));3685  printFields(OS, "Machine:", Str);3686  Str = "0x" + utohexstr(e.e_version, /*LowerCase=*/true);3687  printFields(OS, "Version:", Str);3688  Str = "0x" + utohexstr(e.e_entry, /*LowerCase=*/true);3689  printFields(OS, "Entry point address:", Str);3690  Str = to_string(e.e_phoff) + " (bytes into file)";3691  printFields(OS, "Start of program headers:", Str);3692  Str = to_string(e.e_shoff) + " (bytes into file)";3693  printFields(OS, "Start of section headers:", Str);3694  std::string ElfFlags;3695  if (e.e_machine == EM_MIPS)3696    ElfFlags = printFlags(3697        e.e_flags, ArrayRef(ElfHeaderMipsFlags), unsigned(ELF::EF_MIPS_ARCH),3698        unsigned(ELF::EF_MIPS_ABI), unsigned(ELF::EF_MIPS_MACH));3699  else if (e.e_machine == EM_RISCV)3700    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderRISCVFlags));3701  else if (e.e_machine == EM_SPARC32PLUS || e.e_machine == EM_SPARCV9)3702    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderSPARCFlags),3703                          unsigned(ELF::EF_SPARCV9_MM));3704  else if (e.e_machine == EM_AVR)3705    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderAVRFlags),3706                          unsigned(ELF::EF_AVR_ARCH_MASK));3707  else if (e.e_machine == EM_LOONGARCH)3708    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderLoongArchFlags),3709                          unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK),3710                          unsigned(ELF::EF_LOONGARCH_OBJABI_MASK));3711  else if (e.e_machine == EM_XTENSA)3712    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderXtensaFlags),3713                          unsigned(ELF::EF_XTENSA_MACH));3714  else if (e.e_machine == EM_CUDA) {3715    unsigned Mask = e.e_ident[ELF::EI_ABIVERSION] == ELF::ELFABIVERSION_CUDA_V13716                        ? ELF::EF_CUDA_SM3717                        : ELF::EF_CUDA_SM_MASK;3718    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderNVPTXFlags), Mask);3719    if (e.e_ident[ELF::EI_ABIVERSION] == ELF::ELFABIVERSION_CUDA_V1 &&3720        (e.e_flags & ELF::EF_CUDA_ACCELERATORS_V1))3721      ElfFlags += "a";3722    else if (e.e_ident[ELF::EI_ABIVERSION] == ELF::ELFABIVERSION_CUDA_V2 &&3723             (e.e_flags & ELF::EF_CUDA_ACCELERATORS))3724      ElfFlags += "a";3725  } else if (e.e_machine == EM_AMDGPU) {3726    switch (e.e_ident[ELF::EI_ABIVERSION]) {3727    default:3728      break;3729    case 0:3730      // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags.3731      [[fallthrough]];3732    case ELF::ELFABIVERSION_AMDGPU_HSA_V3:3733      ElfFlags =3734          printFlags(e.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion3),3735                     unsigned(ELF::EF_AMDGPU_MACH));3736      break;3737    case ELF::ELFABIVERSION_AMDGPU_HSA_V4:3738    case ELF::ELFABIVERSION_AMDGPU_HSA_V5:3739      ElfFlags =3740          printFlags(e.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),3741                     unsigned(ELF::EF_AMDGPU_MACH),3742                     unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),3743                     unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4));3744      break;3745    case ELF::ELFABIVERSION_AMDGPU_HSA_V6: {3746      ElfFlags =3747          printFlags(e.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),3748                     unsigned(ELF::EF_AMDGPU_MACH),3749                     unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),3750                     unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4));3751      if (auto GenericV = e.e_flags & ELF::EF_AMDGPU_GENERIC_VERSION) {3752        ElfFlags +=3753            ", generic_v" +3754            to_string(GenericV >> ELF::EF_AMDGPU_GENERIC_VERSION_OFFSET);3755      }3756    } break;3757    }3758  }3759  Str = "0x" + utohexstr(e.e_flags, /*LowerCase=*/true);3760  if (!ElfFlags.empty())3761    Str = Str + ", " + ElfFlags;3762  printFields(OS, "Flags:", Str);3763  Str = to_string(e.e_ehsize) + " (bytes)";3764  printFields(OS, "Size of this header:", Str);3765  Str = to_string(e.e_phentsize) + " (bytes)";3766  printFields(OS, "Size of program headers:", Str);3767  Str = to_string(e.e_phnum);3768  printFields(OS, "Number of program headers:", Str);3769  Str = to_string(e.e_shentsize) + " (bytes)";3770  printFields(OS, "Size of section headers:", Str);3771  Str = getSectionHeadersNumString(this->Obj, this->FileName);3772  printFields(OS, "Number of section headers:", Str);3773  Str = getSectionHeaderTableIndexString(this->Obj, this->FileName);3774  printFields(OS, "Section header string table index:", Str);3775}3776 3777template <class ELFT> std::vector<GroupSection> ELFDumper<ELFT>::getGroups() {3778  auto GetSignature = [&](const Elf_Sym &Sym, unsigned SymNdx,3779                          const Elf_Shdr &Symtab) -> StringRef {3780    Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(Symtab);3781    if (!StrTableOrErr) {3782      reportUniqueWarning("unable to get the string table for " +3783                          describe(Symtab) + ": " +3784                          toString(StrTableOrErr.takeError()));3785      return "<?>";3786    }3787 3788    StringRef Strings = *StrTableOrErr;3789    if (Sym.st_name >= Strings.size()) {3790      reportUniqueWarning("unable to get the name of the symbol with index " +3791                          Twine(SymNdx) + ": st_name (0x" +3792                          Twine::utohexstr(Sym.st_name) +3793                          ") is past the end of the string table of size 0x" +3794                          Twine::utohexstr(Strings.size()));3795      return "<?>";3796    }3797 3798    return StrTableOrErr->data() + Sym.st_name;3799  };3800 3801  std::vector<GroupSection> Ret;3802  uint64_t I = 0;3803  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {3804    ++I;3805    if (Sec.sh_type != ELF::SHT_GROUP)3806      continue;3807 3808    StringRef Signature = "<?>";3809    if (Expected<const Elf_Shdr *> SymtabOrErr = Obj.getSection(Sec.sh_link)) {3810      if (Expected<const Elf_Sym *> SymOrErr =3811              Obj.template getEntry<Elf_Sym>(**SymtabOrErr, Sec.sh_info))3812        Signature = GetSignature(**SymOrErr, Sec.sh_info, **SymtabOrErr);3813      else3814        reportUniqueWarning("unable to get the signature symbol for " +3815                            describe(Sec) + ": " +3816                            toString(SymOrErr.takeError()));3817    } else {3818      reportUniqueWarning("unable to get the symbol table for " +3819                          describe(Sec) + ": " +3820                          toString(SymtabOrErr.takeError()));3821    }3822 3823    ArrayRef<Elf_Word> Data;3824    if (Expected<ArrayRef<Elf_Word>> ContentsOrErr =3825            Obj.template getSectionContentsAsArray<Elf_Word>(Sec)) {3826      if (ContentsOrErr->empty())3827        reportUniqueWarning("unable to read the section group flag from the " +3828                            describe(Sec) + ": the section is empty");3829      else3830        Data = *ContentsOrErr;3831    } else {3832      reportUniqueWarning("unable to get the content of the " + describe(Sec) +3833                          ": " + toString(ContentsOrErr.takeError()));3834    }3835 3836    Ret.push_back({getPrintableSectionName(Sec),3837                   maybeDemangle(Signature),3838                   Sec.sh_name,3839                   I - 1,3840                   Sec.sh_link,3841                   Sec.sh_info,3842                   Data.empty() ? Elf_Word(0) : Data[0],3843                   {}});3844 3845    if (Data.empty())3846      continue;3847 3848    std::vector<GroupMember> &GM = Ret.back().Members;3849    for (uint32_t Ndx : Data.slice(1)) {3850      if (Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(Ndx)) {3851        GM.push_back({getPrintableSectionName(**SecOrErr), Ndx});3852      } else {3853        reportUniqueWarning("unable to get the section with index " +3854                            Twine(Ndx) + " when dumping the " + describe(Sec) +3855                            ": " + toString(SecOrErr.takeError()));3856        GM.push_back({"<?>", Ndx});3857      }3858    }3859  }3860  return Ret;3861}3862 3863static DenseMap<uint64_t, const GroupSection *>3864mapSectionsToGroups(ArrayRef<GroupSection> Groups) {3865  DenseMap<uint64_t, const GroupSection *> Ret;3866  for (const GroupSection &G : Groups)3867    for (const GroupMember &GM : G.Members)3868      Ret.insert({GM.Index, &G});3869  return Ret;3870}3871 3872template <class ELFT> void GNUELFDumper<ELFT>::printGroupSections() {3873  std::vector<GroupSection> V = this->getGroups();3874  DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);3875  for (const GroupSection &G : V) {3876    OS << "\n"3877       << getGroupType(G.Type) << " group section ["3878       << format_decimal(G.Index, 5) << "] `" << G.Name << "' [" << G.Signature3879       << "] contains " << G.Members.size() << " sections:\n"3880       << "   [Index]    Name\n";3881    for (const GroupMember &GM : G.Members) {3882      const GroupSection *MainGroup = Map[GM.Index];3883      if (MainGroup != &G)3884        this->reportUniqueWarning(3885            "section with index " + Twine(GM.Index) +3886            ", included in the group section with index " +3887            Twine(MainGroup->Index) +3888            ", was also found in the group section with index " +3889            Twine(G.Index));3890      OS << "   [" << format_decimal(GM.Index, 5) << "]   " << GM.Name << "\n";3891    }3892  }3893 3894  if (V.empty())3895    OS << "There are no section groups in this file.\n";3896}3897 3898template <class ELFT>3899void GNUELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,3900                                           const RelSymbol<ELFT> &RelSym) {3901  // First two fields are bit width dependent. The rest of them are fixed width.3902  unsigned Bias = ELFT::Is64Bits ? 8 : 0;3903  Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};3904  unsigned Width = ELFT::Is64Bits ? 16 : 8;3905 3906  Fields[0].Str = to_string(format_hex_no_prefix(R.Offset, Width));3907  Fields[1].Str = to_string(format_hex_no_prefix(R.Info, Width));3908 3909  SmallString<32> RelocName;3910  this->Obj.getRelocationTypeName(R.Type, RelocName);3911  Fields[2].Str = RelocName.c_str();3912 3913  if (RelSym.Sym)3914    Fields[3].Str =3915        to_string(format_hex_no_prefix(RelSym.Sym->getValue(), Width));3916  if (RelSym.Sym && RelSym.Name.empty())3917    Fields[4].Str = "<null>";3918  else3919    Fields[4].Str = std::string(RelSym.Name);3920 3921  for (const Field &F : Fields)3922    printField(F);3923 3924  std::string Addend;3925  if (std::optional<int64_t> A = R.Addend) {3926    int64_t RelAddend = *A;3927    if (!Fields[4].Str.empty()) {3928      if (RelAddend < 0) {3929        Addend = " - ";3930        RelAddend = -static_cast<uint64_t>(RelAddend);3931      } else {3932        Addend = " + ";3933      }3934    }3935    Addend += utohexstr(RelAddend, /*LowerCase=*/true);3936  }3937  OS << Addend << "\n";3938}3939 3940template <class ELFT>3941static void printRelocHeaderFields(formatted_raw_ostream &OS, unsigned SType,3942                                   const typename ELFT::Ehdr &EHeader,3943                                   uint64_t CrelHdr = 0) {3944  bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA;3945  if (ELFT::Is64Bits)3946    OS << "    Offset             Info             Type               Symbol's "3947          "Value  Symbol's Name";3948  else3949    OS << " Offset     Info    Type                Sym. Value  Symbol's Name";3950  if (IsRela || (SType == ELF::SHT_CREL && (CrelHdr & CREL_HDR_ADDEND)))3951    OS << " + Addend";3952  OS << "\n";3953}3954 3955template <class ELFT>3956void GNUELFDumper<ELFT>::printDynamicRelocHeader(unsigned Type, StringRef Name,3957                                                 const DynRegionInfo &Reg) {3958  uint64_t Offset = Reg.Addr - this->Obj.base();3959  OS << "\n'" << Name.str().c_str() << "' relocation section at offset 0x"3960     << utohexstr(Offset, /*LowerCase=*/true);3961  if (Type != ELF::SHT_CREL)3962    OS << " contains " << Reg.Size << " bytes";3963  OS << ":\n";3964  printRelocHeaderFields<ELFT>(OS, Type, this->Obj.getHeader());3965}3966 3967template <class ELFT>3968static bool isRelocationSec(const typename ELFT::Shdr &Sec,3969                            const typename ELFT::Ehdr &EHeader) {3970  return Sec.sh_type == ELF::SHT_REL || Sec.sh_type == ELF::SHT_RELA ||3971         Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_CREL ||3972         Sec.sh_type == ELF::SHT_ANDROID_REL ||3973         Sec.sh_type == ELF::SHT_ANDROID_RELA ||3974         Sec.sh_type == ELF::SHT_ANDROID_RELR ||3975         (EHeader.e_machine == EM_AARCH64 &&3976          Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR);3977}3978 3979template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {3980  auto PrintAsRelr = [&](const Elf_Shdr &Sec) {3981    return Sec.sh_type == ELF::SHT_RELR ||3982           Sec.sh_type == ELF::SHT_ANDROID_RELR ||3983           (this->Obj.getHeader().e_machine == EM_AARCH64 &&3984            Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR);3985  };3986  auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected<size_t> {3987    // Android's packed relocation section needs to be unpacked first3988    // to get the actual number of entries.3989    if (Sec.sh_type == ELF::SHT_ANDROID_REL ||3990        Sec.sh_type == ELF::SHT_ANDROID_RELA) {3991      Expected<std::vector<typename ELFT::Rela>> RelasOrErr =3992          this->Obj.android_relas(Sec);3993      if (!RelasOrErr)3994        return RelasOrErr.takeError();3995      return RelasOrErr->size();3996    }3997 3998    if (Sec.sh_type == ELF::SHT_CREL) {3999      Expected<ArrayRef<uint8_t>> ContentsOrErr =4000          this->Obj.getSectionContents(Sec);4001      if (!ContentsOrErr)4002        return ContentsOrErr.takeError();4003      auto NumOrErr = this->Obj.getCrelHeader(*ContentsOrErr);4004      if (!NumOrErr)4005        return NumOrErr.takeError();4006      return *NumOrErr / 8;4007    }4008 4009    if (PrintAsRelr(Sec)) {4010      Expected<Elf_Relr_Range> RelrsOrErr = this->Obj.relrs(Sec);4011      if (!RelrsOrErr)4012        return RelrsOrErr.takeError();4013      return this->Obj.decode_relrs(*RelrsOrErr).size();4014    }4015 4016    return Sec.getEntityCount();4017  };4018 4019  bool HasRelocSections = false;4020  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {4021    if (!isRelocationSec<ELFT>(Sec, this->Obj.getHeader()))4022      continue;4023    HasRelocSections = true;4024 4025    std::string EntriesNum = "<?>";4026    if (Expected<size_t> NumOrErr = GetEntriesNum(Sec))4027      EntriesNum = std::to_string(*NumOrErr);4028    else4029      this->reportUniqueWarning("unable to get the number of relocations in " +4030                                this->describe(Sec) + ": " +4031                                toString(NumOrErr.takeError()));4032 4033    uintX_t Offset = Sec.sh_offset;4034    StringRef Name = this->getPrintableSectionName(Sec);4035    OS << "\nRelocation section '" << Name << "' at offset 0x"4036       << utohexstr(Offset, /*LowerCase=*/true) << " contains " << EntriesNum4037       << " entries:\n";4038 4039    if (PrintAsRelr(Sec)) {4040      printRelr(Sec);4041    } else {4042      uint64_t CrelHdr = 0;4043      // For CREL, read the header and call printRelocationsHelper only if4044      // GetEntriesNum(Sec) succeeded.4045      if (Sec.sh_type == ELF::SHT_CREL && EntriesNum != "<?>") {4046        CrelHdr = cantFail(this->Obj.getCrelHeader(4047            cantFail(this->Obj.getSectionContents(Sec))));4048      }4049      printRelocHeaderFields<ELFT>(OS, Sec.sh_type, this->Obj.getHeader(),4050                                   CrelHdr);4051      if (Sec.sh_type != ELF::SHT_CREL || EntriesNum != "<?>")4052        this->printRelocationsHelper(Sec);4053    }4054  }4055  if (!HasRelocSections)4056    OS << "\nThere are no relocations in this file.\n";4057}4058 4059template <class ELFT> void GNUELFDumper<ELFT>::printRelr(const Elf_Shdr &Sec) {4060  Expected<Elf_Relr_Range> RangeOrErr = this->Obj.relrs(Sec);4061  if (!RangeOrErr) {4062    this->reportUniqueWarning("unable to read relocations from " +4063                              this->describe(Sec) + ": " +4064                              toString(RangeOrErr.takeError()));4065    return;4066  }4067  if (ELFT::Is64Bits)4068    OS << "Index: Entry            Address           Symbolic Address\n";4069  else4070    OS << "Index: Entry    Address   Symbolic Address\n";4071 4072  // If .symtab is available, collect its defined symbols and sort them by4073  // st_value.4074  SmallVector<std::pair<uint64_t, std::string>, 0> Syms;4075  if (this->DotSymtabSec) {4076    Elf_Sym_Range Symtab;4077    std::optional<StringRef> Strtab;4078    std::tie(Symtab, Strtab) = this->getSymtabAndStrtab();4079    if (Symtab.size() && Strtab) {4080      for (auto [I, Sym] : enumerate(Symtab)) {4081        if (!Sym.st_shndx)4082          continue;4083        Syms.emplace_back(Sym.st_value,4084                          this->getFullSymbolName(Sym, I, ArrayRef<Elf_Word>(),4085                                                  *Strtab, false));4086      }4087    }4088  }4089  llvm::stable_sort(Syms);4090 4091  typename ELFT::uint Base = 0;4092  size_t I = 0;4093  auto Print = [&](uint64_t Where) {4094    OS << format_hex_no_prefix(Where, ELFT::Is64Bits ? 16 : 8);4095    for (; I < Syms.size() && Syms[I].first <= Where; ++I)4096      ;4097    // Try symbolizing the address. Find the nearest symbol before or at the4098    // address and print the symbol and the address difference.4099    if (I) {4100      OS << "  " << Syms[I - 1].second;4101      if (Syms[I - 1].first < Where)4102        OS << " + 0x" << Twine::utohexstr(Where - Syms[I - 1].first);4103    }4104    OS << '\n';4105  };4106  for (auto [Index, R] : enumerate(*RangeOrErr)) {4107    typename ELFT::uint Entry = R;4108    OS << formatv("{0:4}:  ", Index)4109       << format_hex_no_prefix(Entry, ELFT::Is64Bits ? 16 : 8) << ' ';4110    if ((Entry & 1) == 0) {4111      Print(Entry);4112      Base = Entry + sizeof(typename ELFT::uint);4113    } else {4114      bool First = true;4115      for (auto Where = Base; Entry >>= 1;4116           Where += sizeof(typename ELFT::uint)) {4117        if (Entry & 1) {4118          if (First)4119            First = false;4120          else4121            OS.indent(ELFT::Is64Bits ? 24 : 16);4122          Print(Where);4123        }4124      }4125      Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(typename ELFT::uint);4126    }4127  }4128}4129 4130// Print the offset of a particular section from anyone of the ranges:4131// [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].4132// If 'Type' does not fall within any of those ranges, then a string is4133// returned as '<unknown>' followed by the type value.4134static std::string getSectionTypeOffsetString(unsigned Type) {4135  if (Type >= SHT_LOOS && Type <= SHT_HIOS)4136    return "LOOS+0x" + utohexstr(Type - SHT_LOOS, /*LowerCase=*/true);4137  else if (Type >= SHT_LOPROC && Type <= SHT_HIPROC)4138    return "LOPROC+0x" + utohexstr(Type - SHT_LOPROC, /*LowerCase=*/true);4139  else if (Type >= SHT_LOUSER && Type <= SHT_HIUSER)4140    return "LOUSER+0x" + utohexstr(Type - SHT_LOUSER, /*LowerCase=*/true);4141  return "0x" + utohexstr(Type, /*LowerCase=*/true) + ": <unknown>";4142}4143 4144static std::string getSectionTypeString(unsigned Machine, unsigned Type) {4145  StringRef Name = getELFSectionTypeName(Machine, Type);4146 4147  // Handle SHT_GNU_* type names.4148  if (Name.consume_front("SHT_GNU_")) {4149    if (Name == "HASH")4150      return "GNU_HASH";4151    // E.g. SHT_GNU_verneed -> VERNEED.4152    return Name.upper();4153  }4154 4155  if (Name == "SHT_SYMTAB_SHNDX")4156    return "SYMTAB SECTION INDICES";4157 4158  if (Name.consume_front("SHT_"))4159    return Name.str();4160  return getSectionTypeOffsetString(Type);4161}4162 4163static void printSectionDescription(formatted_raw_ostream &OS,4164                                    unsigned EMachine) {4165  OS << "Key to Flags:\n";4166  OS << "  W (write), A (alloc), X (execute), M (merge), S (strings), I "4167        "(info),\n";4168  OS << "  L (link order), O (extra OS processing required), G (group), T "4169        "(TLS),\n";4170  OS << "  C (compressed), x (unknown), o (OS specific), E (exclude),\n";4171  OS << "  R (retain)";4172 4173  if (EMachine == EM_X86_64)4174    OS << ", l (large)";4175  else if (EMachine == EM_ARM || EMachine == EM_AARCH64)4176    OS << ", y (purecode)";4177 4178  OS << ", p (processor specific)\n";4179}4180 4181template <class ELFT> void GNUELFDumper<ELFT>::printSectionHeaders() {4182  ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections());4183  if (Sections.empty()) {4184    OS << "\nThere are no sections in this file.\n";4185    Expected<StringRef> SecStrTableOrErr =4186        this->Obj.getSectionStringTable(Sections, this->WarningHandler);4187    if (!SecStrTableOrErr)4188      this->reportUniqueWarning(SecStrTableOrErr.takeError());4189    return;4190  }4191  unsigned Bias = ELFT::Is64Bits ? 0 : 8;4192  OS << "There are " << to_string(Sections.size())4193     << " section headers, starting at offset "4194     << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n";4195  OS << "Section Headers:\n";4196  Field Fields[11] = {4197      {"[Nr]", 2},        {"Name", 7},        {"Type", 25},4198      {"Address", 41},    {"Off", 58 - Bias}, {"Size", 65 - Bias},4199      {"ES", 72 - Bias},  {"Flg", 75 - Bias}, {"Lk", 79 - Bias},4200      {"Inf", 82 - Bias}, {"Al", 86 - Bias}};4201  for (const Field &F : Fields)4202    printField(F);4203  OS << "\n";4204 4205  StringRef SecStrTable;4206  if (Expected<StringRef> SecStrTableOrErr =4207          this->Obj.getSectionStringTable(Sections, this->WarningHandler))4208    SecStrTable = *SecStrTableOrErr;4209  else4210    this->reportUniqueWarning(SecStrTableOrErr.takeError());4211 4212  size_t SectionIndex = 0;4213  for (const Elf_Shdr &Sec : Sections) {4214    Fields[0].Str = to_string(SectionIndex);4215    if (SecStrTable.empty())4216      Fields[1].Str = "<no-strings>";4217    else4218      Fields[1].Str = std::string(unwrapOrError<StringRef>(4219          this->FileName, this->Obj.getSectionName(Sec, SecStrTable)));4220    Fields[2].Str =4221        getSectionTypeString(this->Obj.getHeader().e_machine, Sec.sh_type);4222    Fields[3].Str =4223        to_string(format_hex_no_prefix(Sec.sh_addr, ELFT::Is64Bits ? 16 : 8));4224    Fields[4].Str = to_string(format_hex_no_prefix(Sec.sh_offset, 6));4225    Fields[5].Str = to_string(format_hex_no_prefix(Sec.sh_size, 6));4226    Fields[6].Str = to_string(format_hex_no_prefix(Sec.sh_entsize, 2));4227    Fields[7].Str = getGNUFlags(this->Obj.getHeader().e_ident[ELF::EI_OSABI],4228                                this->Obj.getHeader().e_machine, Sec.sh_flags);4229    Fields[8].Str = to_string(Sec.sh_link);4230    Fields[9].Str = to_string(Sec.sh_info);4231    Fields[10].Str = to_string(Sec.sh_addralign);4232 4233    OS.PadToColumn(Fields[0].Column);4234    OS << "[" << right_justify(Fields[0].Str, 2) << "]";4235    for (int i = 1; i < 7; i++)4236      printField(Fields[i]);4237    OS.PadToColumn(Fields[7].Column);4238    OS << right_justify(Fields[7].Str, 3);4239    OS.PadToColumn(Fields[8].Column);4240    OS << right_justify(Fields[8].Str, 2);4241    OS.PadToColumn(Fields[9].Column);4242    OS << right_justify(Fields[9].Str, 3);4243    OS.PadToColumn(Fields[10].Column);4244    OS << right_justify(Fields[10].Str, 2);4245    OS << "\n";4246    ++SectionIndex;4247  }4248  printSectionDescription(OS, this->Obj.getHeader().e_machine);4249}4250 4251template <class ELFT>4252void GNUELFDumper<ELFT>::printSymtabMessage(const Elf_Shdr *Symtab,4253                                            size_t Entries,4254                                            bool NonVisibilityBitsUsed,4255                                            bool ExtraSymInfo) const {4256  StringRef Name;4257  if (Symtab)4258    Name = this->getPrintableSectionName(*Symtab);4259  if (!Name.empty())4260    OS << "\nSymbol table '" << Name << "'";4261  else4262    OS << "\nSymbol table for image";4263  OS << " contains " << Entries << " entries:\n";4264 4265  if (ELFT::Is64Bits) {4266    OS << "   Num:    Value          Size Type    Bind   Vis";4267    if (ExtraSymInfo)4268      OS << "+Other";4269  } else {4270    OS << "   Num:    Value  Size Type    Bind   Vis";4271    if (ExtraSymInfo)4272      OS << "+Other";4273  }4274 4275  OS.PadToColumn((ELFT::Is64Bits ? 56 : 48) + (NonVisibilityBitsUsed ? 13 : 0));4276  if (ExtraSymInfo)4277    OS << "Ndx(SecName) Name [+ Version Info]\n";4278  else4279    OS << "Ndx Name\n";4280}4281 4282template <class ELFT>4283std::string GNUELFDumper<ELFT>::getSymbolSectionNdx(4284    const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable,4285    bool ExtraSymInfo) const {4286  unsigned SectionIndex = Symbol.st_shndx;4287  switch (SectionIndex) {4288  case ELF::SHN_UNDEF:4289    return "UND";4290  case ELF::SHN_ABS:4291    return "ABS";4292  case ELF::SHN_COMMON:4293    return "COM";4294  case ELF::SHN_XINDEX: {4295    Expected<uint32_t> IndexOrErr =4296        object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex, ShndxTable);4297    if (!IndexOrErr) {4298      assert(Symbol.st_shndx == SHN_XINDEX &&4299             "getExtendedSymbolTableIndex should only fail due to an invalid "4300             "SHT_SYMTAB_SHNDX table/reference");4301      this->reportUniqueWarning(IndexOrErr.takeError());4302      return "RSV[0xffff]";4303    }4304    SectionIndex = *IndexOrErr;4305    break;4306  }4307  default:4308    // Find if:4309    // Processor specific4310    if (SectionIndex >= ELF::SHN_LOPROC && SectionIndex <= ELF::SHN_HIPROC)4311      return std::string("PRC[0x") +4312             to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";4313    // OS specific4314    if (SectionIndex >= ELF::SHN_LOOS && SectionIndex <= ELF::SHN_HIOS)4315      return std::string("OS[0x") +4316             to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";4317    // Architecture reserved:4318    if (SectionIndex >= ELF::SHN_LORESERVE &&4319        SectionIndex <= ELF::SHN_HIRESERVE)4320      return std::string("RSV[0x") +4321             to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";4322    break;4323  }4324 4325  std::string Extra;4326  if (ExtraSymInfo) {4327    auto Sec = this->Obj.getSection(SectionIndex);4328    if (!Sec) {4329      this->reportUniqueWarning(Sec.takeError());4330    } else {4331      auto SecName = this->Obj.getSectionName(**Sec);4332      if (!SecName)4333        this->reportUniqueWarning(SecName.takeError());4334      else4335        Extra = Twine(" (" + *SecName + ")").str();4336    }4337  }4338  return to_string(format_decimal(SectionIndex, 3)) + Extra;4339}4340 4341template <class ELFT>4342void GNUELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,4343                                     DataRegion<Elf_Word> ShndxTable,4344                                     std::optional<StringRef> StrTable,4345                                     bool IsDynamic, bool NonVisibilityBitsUsed,4346                                     bool ExtraSymInfo) const {4347  unsigned Bias = ELFT::Is64Bits ? 8 : 0;4348  Field Fields[8] = {0,         8,         17 + Bias, 23 + Bias,4349                     31 + Bias, 38 + Bias, 48 + Bias, 51 + Bias};4350  Fields[0].Str = to_string(format_decimal(SymIndex, 6)) + ":";4351  Fields[1].Str =4352      to_string(format_hex_no_prefix(Symbol.st_value, ELFT::Is64Bits ? 16 : 8));4353  Fields[2].Str = to_string(format_decimal(Symbol.st_size, 5));4354 4355  unsigned char SymbolType = Symbol.getType();4356  if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&4357      SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)4358    Fields[3].Str = enumToString(SymbolType, ArrayRef(AMDGPUSymbolTypes));4359  else4360    Fields[3].Str = enumToString(SymbolType, ArrayRef(ElfSymbolTypes));4361 4362  Fields[4].Str =4363      enumToString(Symbol.getBinding(), ArrayRef(ElfSymbolBindings));4364  Fields[5].Str =4365      enumToString(Symbol.getVisibility(), ArrayRef(ElfSymbolVisibilities));4366 4367  if (Symbol.st_other & ~0x3) {4368    if (this->Obj.getHeader().e_machine == ELF::EM_AARCH64) {4369      uint8_t Other = Symbol.st_other & ~0x3;4370      if (Other & STO_AARCH64_VARIANT_PCS) {4371        Other &= ~STO_AARCH64_VARIANT_PCS;4372        Fields[5].Str += " [VARIANT_PCS";4373        if (Other != 0)4374          Fields[5].Str.append(" | " + utohexstr(Other, /*LowerCase=*/true));4375        Fields[5].Str.append("]");4376      }4377    } else if (this->Obj.getHeader().e_machine == ELF::EM_RISCV) {4378      uint8_t Other = Symbol.st_other & ~0x3;4379      if (Other & STO_RISCV_VARIANT_CC) {4380        Other &= ~STO_RISCV_VARIANT_CC;4381        Fields[5].Str += " [VARIANT_CC";4382        if (Other != 0)4383          Fields[5].Str.append(" | " + utohexstr(Other, /*LowerCase=*/true));4384        Fields[5].Str.append("]");4385      }4386    } else {4387      Fields[5].Str +=4388          " [<other: " + to_string(format_hex(Symbol.st_other, 2)) + ">]";4389    }4390  }4391 4392  Fields[6].Column += NonVisibilityBitsUsed ? 13 : 0;4393  Fields[6].Str =4394      getSymbolSectionNdx(Symbol, SymIndex, ShndxTable, ExtraSymInfo);4395 4396  Fields[7].Column += ExtraSymInfo ? 10 : 0;4397  Fields[7].Str = this->getFullSymbolName(Symbol, SymIndex, ShndxTable,4398                                          StrTable, IsDynamic);4399  for (const Field &Entry : Fields)4400    printField(Entry);4401  OS << "\n";4402}4403 4404template <class ELFT>4405void GNUELFDumper<ELFT>::printHashedSymbol(const Elf_Sym *Symbol,4406                                           unsigned SymIndex,4407                                           DataRegion<Elf_Word> ShndxTable,4408                                           StringRef StrTable,4409                                           uint32_t Bucket) {4410  unsigned Bias = ELFT::Is64Bits ? 8 : 0;4411  Field Fields[9] = {0,         6,         11,        20 + Bias, 25 + Bias,4412                     34 + Bias, 41 + Bias, 49 + Bias, 53 + Bias};4413  Fields[0].Str = to_string(format_decimal(SymIndex, 5));4414  Fields[1].Str = to_string(format_decimal(Bucket, 3)) + ":";4415 4416  Fields[2].Str = to_string(4417      format_hex_no_prefix(Symbol->st_value, ELFT::Is64Bits ? 16 : 8));4418  Fields[3].Str = to_string(format_decimal(Symbol->st_size, 5));4419 4420  unsigned char SymbolType = Symbol->getType();4421  if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&4422      SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)4423    Fields[4].Str = enumToString(SymbolType, ArrayRef(AMDGPUSymbolTypes));4424  else4425    Fields[4].Str = enumToString(SymbolType, ArrayRef(ElfSymbolTypes));4426 4427  Fields[5].Str =4428      enumToString(Symbol->getBinding(), ArrayRef(ElfSymbolBindings));4429  Fields[6].Str =4430      enumToString(Symbol->getVisibility(), ArrayRef(ElfSymbolVisibilities));4431  Fields[7].Str = getSymbolSectionNdx(*Symbol, SymIndex, ShndxTable);4432  Fields[8].Str =4433      this->getFullSymbolName(*Symbol, SymIndex, ShndxTable, StrTable, true);4434 4435  for (const Field &Entry : Fields)4436    printField(Entry);4437  OS << "\n";4438}4439 4440template <class ELFT>4441void GNUELFDumper<ELFT>::printSymbols(bool PrintSymbols,4442                                      bool PrintDynamicSymbols,4443                                      bool ExtraSymInfo) {4444  if (!PrintSymbols && !PrintDynamicSymbols)4445    return;4446  // GNU readelf prints both the .dynsym and .symtab with --symbols.4447  this->printSymbolsHelper(true, ExtraSymInfo);4448  if (PrintSymbols)4449    this->printSymbolsHelper(false, ExtraSymInfo);4450}4451 4452template <class ELFT>4453void GNUELFDumper<ELFT>::printHashTableSymbols(const Elf_Hash &SysVHash) {4454  if (this->DynamicStringTable.empty())4455    return;4456 4457  if (ELFT::Is64Bits)4458    OS << "  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name";4459  else4460    OS << "  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name";4461  OS << "\n";4462 4463  Elf_Sym_Range DynSyms = this->dynamic_symbols();4464  const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];4465  if (!FirstSym) {4466    this->reportUniqueWarning(4467        Twine("unable to print symbols for the .hash table: the "4468              "dynamic symbol table ") +4469        (this->DynSymRegion ? "is empty" : "was not found"));4470    return;4471  }4472 4473  DataRegion<Elf_Word> ShndxTable(4474      (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());4475  auto Buckets = SysVHash.buckets();4476  auto Chains = SysVHash.chains();4477  for (uint32_t Buc = 0; Buc < SysVHash.nbucket; Buc++) {4478    if (Buckets[Buc] == ELF::STN_UNDEF)4479      continue;4480    BitVector Visited(SysVHash.nchain);4481    for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash.nchain; Ch = Chains[Ch]) {4482      if (Ch == ELF::STN_UNDEF)4483        break;4484 4485      if (Visited[Ch]) {4486        this->reportUniqueWarning(".hash section is invalid: bucket " +4487                                  Twine(Ch) +4488                                  ": a cycle was detected in the linked chain");4489        break;4490      }4491 4492      printHashedSymbol(FirstSym + Ch, Ch, ShndxTable, this->DynamicStringTable,4493                        Buc);4494      Visited[Ch] = true;4495    }4496  }4497}4498 4499template <class ELFT>4500void GNUELFDumper<ELFT>::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) {4501  if (this->DynamicStringTable.empty())4502    return;4503 4504  Elf_Sym_Range DynSyms = this->dynamic_symbols();4505  const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];4506  if (!FirstSym) {4507    this->reportUniqueWarning(4508        Twine("unable to print symbols for the .gnu.hash table: the "4509              "dynamic symbol table ") +4510        (this->DynSymRegion ? "is empty" : "was not found"));4511    return;4512  }4513 4514  auto GetSymbol = [&](uint64_t SymIndex,4515                       uint64_t SymsTotal) -> const Elf_Sym * {4516    if (SymIndex >= SymsTotal) {4517      this->reportUniqueWarning(4518          "unable to print hashed symbol with index " + Twine(SymIndex) +4519          ", which is greater than or equal to the number of dynamic symbols "4520          "(" +4521          Twine::utohexstr(SymsTotal) + ")");4522      return nullptr;4523    }4524    return FirstSym + SymIndex;4525  };4526 4527  Expected<ArrayRef<Elf_Word>> ValuesOrErr =4528      getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHash);4529  ArrayRef<Elf_Word> Values;4530  if (!ValuesOrErr)4531    this->reportUniqueWarning("unable to get hash values for the SHT_GNU_HASH "4532                              "section: " +4533                              toString(ValuesOrErr.takeError()));4534  else4535    Values = *ValuesOrErr;4536 4537  DataRegion<Elf_Word> ShndxTable(4538      (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());4539  ArrayRef<Elf_Word> Buckets = GnuHash.buckets();4540  for (uint32_t Buc = 0; Buc < GnuHash.nbuckets; Buc++) {4541    if (Buckets[Buc] == ELF::STN_UNDEF)4542      continue;4543    uint32_t Index = Buckets[Buc];4544    // Print whole chain.4545    while (true) {4546      uint32_t SymIndex = Index++;4547      if (const Elf_Sym *Sym = GetSymbol(SymIndex, DynSyms.size()))4548        printHashedSymbol(Sym, SymIndex, ShndxTable, this->DynamicStringTable,4549                          Buc);4550      else4551        break;4552 4553      if (SymIndex < GnuHash.symndx) {4554        this->reportUniqueWarning(4555            "unable to read the hash value for symbol with index " +4556            Twine(SymIndex) +4557            ", which is less than the index of the first hashed symbol (" +4558            Twine(GnuHash.symndx) + ")");4559        break;4560      }4561 4562       // Chain ends at symbol with stopper bit.4563      if ((Values[SymIndex - GnuHash.symndx] & 1) == 1)4564        break;4565    }4566  }4567}4568 4569template <class ELFT> void GNUELFDumper<ELFT>::printHashSymbols() {4570  if (this->HashTable) {4571    OS << "\n Symbol table of .hash for image:\n";4572    if (Error E = checkHashTable<ELFT>(*this, this->HashTable))4573      this->reportUniqueWarning(std::move(E));4574    else4575      printHashTableSymbols(*this->HashTable);4576  }4577 4578  // Try printing the .gnu.hash table.4579  if (this->GnuHashTable) {4580    OS << "\n Symbol table of .gnu.hash for image:\n";4581    if (ELFT::Is64Bits)4582      OS << "  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name";4583    else4584      OS << "  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name";4585    OS << "\n";4586 4587    if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable))4588      this->reportUniqueWarning(std::move(E));4589    else4590      printGnuHashTableSymbols(*this->GnuHashTable);4591  }4592}4593 4594template <class ELFT> void GNUELFDumper<ELFT>::printSectionDetails() {4595  ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections());4596  if (Sections.empty()) {4597    OS << "\nThere are no sections in this file.\n";4598    Expected<StringRef> SecStrTableOrErr =4599        this->Obj.getSectionStringTable(Sections, this->WarningHandler);4600    if (!SecStrTableOrErr)4601      this->reportUniqueWarning(SecStrTableOrErr.takeError());4602    return;4603  }4604  OS << "There are " << to_string(Sections.size())4605     << " section headers, starting at offset "4606     << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n";4607 4608  OS << "Section Headers:\n";4609 4610  auto PrintFields = [&](ArrayRef<Field> V) {4611    for (const Field &F : V)4612      printField(F);4613    OS << "\n";4614  };4615 4616  PrintFields({{"[Nr]", 2}, {"Name", 7}});4617 4618  constexpr bool Is64 = ELFT::Is64Bits;4619  PrintFields({{"Type", 7},4620               {Is64 ? "Address" : "Addr", 23},4621               {"Off", Is64 ? 40 : 32},4622               {"Size", Is64 ? 47 : 39},4623               {"ES", Is64 ? 54 : 46},4624               {"Lk", Is64 ? 59 : 51},4625               {"Inf", Is64 ? 62 : 54},4626               {"Al", Is64 ? 66 : 57}});4627  PrintFields({{"Flags", 7}});4628 4629  StringRef SecStrTable;4630  if (Expected<StringRef> SecStrTableOrErr =4631          this->Obj.getSectionStringTable(Sections, this->WarningHandler))4632    SecStrTable = *SecStrTableOrErr;4633  else4634    this->reportUniqueWarning(SecStrTableOrErr.takeError());4635 4636  size_t SectionIndex = 0;4637  const unsigned AddrSize = Is64 ? 16 : 8;4638  for (const Elf_Shdr &S : Sections) {4639    StringRef Name = "<?>";4640    if (Expected<StringRef> NameOrErr =4641            this->Obj.getSectionName(S, SecStrTable))4642      Name = *NameOrErr;4643    else4644      this->reportUniqueWarning(NameOrErr.takeError());4645 4646    OS.PadToColumn(2);4647    OS << "[" << right_justify(to_string(SectionIndex), 2) << "]";4648    PrintFields({{Name, 7}});4649    PrintFields(4650        {{getSectionTypeString(this->Obj.getHeader().e_machine, S.sh_type), 7},4651         {to_string(format_hex_no_prefix(S.sh_addr, AddrSize)), 23},4652         {to_string(format_hex_no_prefix(S.sh_offset, 6)), Is64 ? 39 : 32},4653         {to_string(format_hex_no_prefix(S.sh_size, 6)), Is64 ? 47 : 39},4654         {to_string(format_hex_no_prefix(S.sh_entsize, 2)), Is64 ? 54 : 46},4655         {to_string(S.sh_link), Is64 ? 59 : 51},4656         {to_string(S.sh_info), Is64 ? 63 : 55},4657         {to_string(S.sh_addralign), Is64 ? 66 : 58}});4658 4659    OS.PadToColumn(7);4660    OS << "[" << to_string(format_hex_no_prefix(S.sh_flags, AddrSize)) << "]: ";4661 4662    DenseMap<unsigned, StringRef> FlagToName = {4663        {SHF_WRITE, "WRITE"},           {SHF_ALLOC, "ALLOC"},4664        {SHF_EXECINSTR, "EXEC"},        {SHF_MERGE, "MERGE"},4665        {SHF_STRINGS, "STRINGS"},       {SHF_INFO_LINK, "INFO LINK"},4666        {SHF_LINK_ORDER, "LINK ORDER"}, {SHF_OS_NONCONFORMING, "OS NONCONF"},4667        {SHF_GROUP, "GROUP"},           {SHF_TLS, "TLS"},4668        {SHF_COMPRESSED, "COMPRESSED"}, {SHF_EXCLUDE, "EXCLUDE"}};4669 4670    uint64_t Flags = S.sh_flags;4671    uint64_t UnknownFlags = 0;4672    ListSeparator LS;4673    while (Flags) {4674      // Take the least significant bit as a flag.4675      uint64_t Flag = Flags & -Flags;4676      Flags -= Flag;4677 4678      auto It = FlagToName.find(Flag);4679      if (It != FlagToName.end())4680        OS << LS << It->second;4681      else4682        UnknownFlags |= Flag;4683    }4684 4685    auto PrintUnknownFlags = [&](uint64_t Mask, StringRef Name) {4686      uint64_t FlagsToPrint = UnknownFlags & Mask;4687      if (!FlagsToPrint)4688        return;4689 4690      OS << LS << Name << " ("4691         << to_string(format_hex_no_prefix(FlagsToPrint, AddrSize)) << ")";4692      UnknownFlags &= ~Mask;4693    };4694 4695    PrintUnknownFlags(SHF_MASKOS, "OS");4696    PrintUnknownFlags(SHF_MASKPROC, "PROC");4697    PrintUnknownFlags(uint64_t(-1), "UNKNOWN");4698 4699    OS << "\n";4700    ++SectionIndex;4701 4702    if (!(S.sh_flags & SHF_COMPRESSED))4703      continue;4704    Expected<ArrayRef<uint8_t>> Data = this->Obj.getSectionContents(S);4705    if (!Data || Data->size() < sizeof(Elf_Chdr)) {4706      consumeError(Data.takeError());4707      reportWarning(createError("SHF_COMPRESSED section '" + Name +4708                                "' does not have an Elf_Chdr header"),4709                    this->FileName);4710      OS.indent(7);4711      OS << "[<corrupt>]";4712    } else {4713      OS.indent(7);4714      auto *Chdr = reinterpret_cast<const Elf_Chdr *>(Data->data());4715      if (Chdr->ch_type == ELFCOMPRESS_ZLIB)4716        OS << "ZLIB";4717      else if (Chdr->ch_type == ELFCOMPRESS_ZSTD)4718        OS << "ZSTD";4719      else4720        OS << format("[<unknown>: 0x%x]", unsigned(Chdr->ch_type));4721      OS << ", " << format_hex_no_prefix(Chdr->ch_size, ELFT::Is64Bits ? 16 : 8)4722         << ", " << Chdr->ch_addralign;4723    }4724    OS << '\n';4725  }4726}4727 4728static inline std::string printPhdrFlags(unsigned Flag) {4729  std::string Str;4730  Str = (Flag & PF_R) ? "R" : " ";4731  Str += (Flag & PF_W) ? "W" : " ";4732  Str += (Flag & PF_X) ? "E" : " ";4733  return Str;4734}4735 4736template <class ELFT>4737static bool checkTLSSections(const typename ELFT::Phdr &Phdr,4738                             const typename ELFT::Shdr &Sec) {4739  if (Sec.sh_flags & ELF::SHF_TLS) {4740    // .tbss must only be shown in the PT_TLS segment.4741    if (Sec.sh_type == ELF::SHT_NOBITS)4742      return Phdr.p_type == ELF::PT_TLS;4743 4744    // SHF_TLS sections are only shown in PT_TLS, PT_LOAD or PT_GNU_RELRO4745    // segments.4746    return (Phdr.p_type == ELF::PT_TLS) || (Phdr.p_type == ELF::PT_LOAD) ||4747           (Phdr.p_type == ELF::PT_GNU_RELRO);4748  }4749 4750  // PT_TLS must only have SHF_TLS sections.4751  return Phdr.p_type != ELF::PT_TLS;4752}4753 4754template <class ELFT>4755static bool checkPTDynamic(const typename ELFT::Phdr &Phdr,4756                           const typename ELFT::Shdr &Sec) {4757  if (Phdr.p_type != ELF::PT_DYNAMIC || Phdr.p_memsz == 0 || Sec.sh_size != 0)4758    return true;4759 4760  // We get here when we have an empty section. Only non-empty sections can be4761  // at the start or at the end of PT_DYNAMIC.4762  // Is section within the phdr both based on offset and VMA?4763  bool CheckOffset = (Sec.sh_type == ELF::SHT_NOBITS) ||4764                     (Sec.sh_offset > Phdr.p_offset &&4765                      Sec.sh_offset < Phdr.p_offset + Phdr.p_filesz);4766  bool CheckVA = !(Sec.sh_flags & ELF::SHF_ALLOC) ||4767                 (Sec.sh_addr > Phdr.p_vaddr && Sec.sh_addr < Phdr.p_memsz);4768  return CheckOffset && CheckVA;4769}4770 4771template <class ELFT>4772void GNUELFDumper<ELFT>::printProgramHeaders(4773    bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {4774  const bool ShouldPrintSectionMapping = (PrintSectionMapping != cl::BOU_FALSE);4775  // Exit early if no program header or section mapping details were requested.4776  if (!PrintProgramHeaders && !ShouldPrintSectionMapping)4777    return;4778 4779  if (PrintProgramHeaders) {4780    const Elf_Ehdr &Header = this->Obj.getHeader();4781    if (Header.e_phnum == 0) {4782      OS << "\nThere are no program headers in this file.\n";4783    } else {4784      printProgramHeaders();4785    }4786  }4787 4788  if (ShouldPrintSectionMapping)4789    printSectionMapping();4790}4791 4792template <class ELFT> void GNUELFDumper<ELFT>::printProgramHeaders() {4793  unsigned Bias = ELFT::Is64Bits ? 8 : 0;4794  const Elf_Ehdr &Header = this->Obj.getHeader();4795  Field Fields[8] = {2,         17,        26,        37 + Bias,4796                     48 + Bias, 56 + Bias, 64 + Bias, 68 + Bias};4797  OS << "\nElf file type is "4798     << enumToString(Header.e_type, ArrayRef(ElfObjectFileType)) << "\n"4799     << "Entry point " << format_hex(Header.e_entry, 3) << "\n"4800     << "There are " << Header.e_phnum << " program headers,"4801     << " starting at offset " << Header.e_phoff << "\n\n"4802     << "Program Headers:\n";4803  if (ELFT::Is64Bits)4804    OS << "  Type           Offset   VirtAddr           PhysAddr         "4805       << "  FileSiz  MemSiz   Flg Align\n";4806  else4807    OS << "  Type           Offset   VirtAddr   PhysAddr   FileSiz "4808       << "MemSiz  Flg Align\n";4809 4810  unsigned Width = ELFT::Is64Bits ? 18 : 10;4811  unsigned SizeWidth = ELFT::Is64Bits ? 8 : 7;4812 4813  Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();4814  if (!PhdrsOrErr) {4815    this->reportUniqueWarning("unable to dump program headers: " +4816                              toString(PhdrsOrErr.takeError()));4817    return;4818  }4819 4820  for (const Elf_Phdr &Phdr : *PhdrsOrErr) {4821    Fields[0].Str = getGNUPtType(Header.e_machine, Phdr.p_type);4822    Fields[1].Str = to_string(format_hex(Phdr.p_offset, 8));4823    Fields[2].Str = to_string(format_hex(Phdr.p_vaddr, Width));4824    Fields[3].Str = to_string(format_hex(Phdr.p_paddr, Width));4825    Fields[4].Str = to_string(format_hex(Phdr.p_filesz, SizeWidth));4826    Fields[5].Str = to_string(format_hex(Phdr.p_memsz, SizeWidth));4827    Fields[6].Str = printPhdrFlags(Phdr.p_flags);4828    Fields[7].Str = to_string(format_hex(Phdr.p_align, 1));4829    for (const Field &F : Fields)4830      printField(F);4831    if (Phdr.p_type == ELF::PT_INTERP) {4832      OS << "\n";4833      auto ReportBadInterp = [&](const Twine &Msg) {4834        this->reportUniqueWarning(4835            "unable to read program interpreter name at offset 0x" +4836            Twine::utohexstr(Phdr.p_offset) + ": " + Msg);4837      };4838 4839      if (Phdr.p_offset >= this->Obj.getBufSize()) {4840        ReportBadInterp("it goes past the end of the file (0x" +4841                        Twine::utohexstr(this->Obj.getBufSize()) + ")");4842        continue;4843      }4844 4845      const char *Data =4846          reinterpret_cast<const char *>(this->Obj.base()) + Phdr.p_offset;4847      size_t MaxSize = this->Obj.getBufSize() - Phdr.p_offset;4848      size_t Len = strnlen(Data, MaxSize);4849      if (Len == MaxSize) {4850        ReportBadInterp("it is not null-terminated");4851        continue;4852      }4853 4854      OS << "      [Requesting program interpreter: ";4855      OS << StringRef(Data, Len) << "]";4856    }4857    OS << "\n";4858  }4859}4860 4861template <class ELFT> void GNUELFDumper<ELFT>::printSectionMapping() {4862  OS << "\n Section to Segment mapping:\n  Segment Sections...\n";4863  DenseSet<const Elf_Shdr *> BelongsToSegment;4864  int Phnum = 0;4865 4866  Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();4867  if (!PhdrsOrErr) {4868    this->reportUniqueWarning(4869        "can't read program headers to build section to segment mapping: " +4870        toString(PhdrsOrErr.takeError()));4871    return;4872  }4873 4874  for (const Elf_Phdr &Phdr : *PhdrsOrErr) {4875    std::string Sections;4876    OS << format("   %2.2d     ", Phnum++);4877    // Check if each section is in a segment and then print mapping.4878    for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {4879      if (Sec.sh_type == ELF::SHT_NULL)4880        continue;4881 4882      // readelf additionally makes sure it does not print zero sized sections4883      // at end of segments and for PT_DYNAMIC both start and end of section4884      // .tbss must only be shown in PT_TLS section.4885      if (isSectionInSegment<ELFT>(Phdr, Sec) &&4886          checkTLSSections<ELFT>(Phdr, Sec) &&4887          checkPTDynamic<ELFT>(Phdr, Sec)) {4888        Sections +=4889            unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() +4890            " ";4891        BelongsToSegment.insert(&Sec);4892      }4893    }4894    OS << Sections << "\n";4895    OS.flush();4896  }4897 4898  // Display sections that do not belong to a segment.4899  std::string Sections;4900  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {4901    if (BelongsToSegment.find(&Sec) == BelongsToSegment.end())4902      Sections +=4903          unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() +4904          ' ';4905  }4906  if (!Sections.empty()) {4907    OS << "   None  " << Sections << '\n';4908    OS.flush();4909  }4910}4911 4912namespace {4913 4914template <class ELFT>4915RelSymbol<ELFT> getSymbolForReloc(const ELFDumper<ELFT> &Dumper,4916                                  const Relocation<ELFT> &Reloc) {4917  using Elf_Sym = typename ELFT::Sym;4918  auto WarnAndReturn = [&](const Elf_Sym *Sym,4919                           const Twine &Reason) -> RelSymbol<ELFT> {4920    Dumper.reportUniqueWarning(4921        "unable to get name of the dynamic symbol with index " +4922        Twine(Reloc.Symbol) + ": " + Reason);4923    return {Sym, "<corrupt>"};4924  };4925 4926  ArrayRef<Elf_Sym> Symbols = Dumper.dynamic_symbols();4927  const Elf_Sym *FirstSym = Symbols.begin();4928  if (!FirstSym)4929    return WarnAndReturn(nullptr, "no dynamic symbol table found");4930 4931  // We might have an object without a section header. In this case the size of4932  // Symbols is zero, because there is no way to know the size of the dynamic4933  // table. We should allow this case and not print a warning.4934  if (!Symbols.empty() && Reloc.Symbol >= Symbols.size())4935    return WarnAndReturn(4936        nullptr,4937        "index is greater than or equal to the number of dynamic symbols (" +4938            Twine(Symbols.size()) + ")");4939 4940  const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();4941  const uint64_t FileSize = Obj.getBufSize();4942  const uint64_t SymOffset = ((const uint8_t *)FirstSym - Obj.base()) +4943                             (uint64_t)Reloc.Symbol * sizeof(Elf_Sym);4944  if (SymOffset + sizeof(Elf_Sym) > FileSize)4945    return WarnAndReturn(nullptr, "symbol at 0x" + Twine::utohexstr(SymOffset) +4946                                      " goes past the end of the file (0x" +4947                                      Twine::utohexstr(FileSize) + ")");4948 4949  const Elf_Sym *Sym = FirstSym + Reloc.Symbol;4950  Expected<StringRef> ErrOrName = Sym->getName(Dumper.getDynamicStringTable());4951  if (!ErrOrName)4952    return WarnAndReturn(Sym, toString(ErrOrName.takeError()));4953 4954  return {Sym == FirstSym ? nullptr : Sym, maybeDemangle(*ErrOrName)};4955}4956} // namespace4957 4958template <class ELFT>4959static size_t getMaxDynamicTagSize(const ELFFile<ELFT> &Obj,4960                                   typename ELFT::DynRange Tags) {4961  size_t Max = 0;4962  for (const typename ELFT::Dyn &Dyn : Tags)4963    Max = std::max(Max, Obj.getDynamicTagAsString(Dyn.d_tag).size());4964  return Max;4965}4966 4967template <class ELFT> void GNUELFDumper<ELFT>::printDynamicTable() {4968  Elf_Dyn_Range Table = this->dynamic_table();4969  if (Table.empty())4970    return;4971 4972  OS << "Dynamic section at offset "4973     << format_hex(reinterpret_cast<const uint8_t *>(this->DynamicTable.Addr) -4974                       this->Obj.base(),4975                   1)4976     << " contains " << Table.size() << " entries:\n";4977 4978  // The type name is surrounded with round brackets, hence add 2.4979  size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table) + 2;4980  // The "Name/Value" column should be indented from the "Type" column by N4981  // spaces, where N = MaxTagSize - length of "Type" (4) + trailing4982  // space (1) = 3.4983  OS << "  Tag" + std::string(ELFT::Is64Bits ? 16 : 8, ' ') + "Type"4984     << std::string(MaxTagSize - 3, ' ') << "Name/Value\n";4985 4986  std::string ValueFmt = " %-" + std::to_string(MaxTagSize) + "s ";4987  for (auto Entry : Table) {4988    uintX_t Tag = Entry.getTag();4989    std::string Type =4990        std::string("(") + this->Obj.getDynamicTagAsString(Tag) + ")";4991    std::string Value = this->getDynamicEntry(Tag, Entry.getVal());4992    OS << "  " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10)4993       << format(ValueFmt.c_str(), Type.c_str()) << Value << "\n";4994  }4995}4996 4997template <class ELFT> void GNUELFDumper<ELFT>::printDynamicRelocations() {4998  this->printDynamicRelocationsHelper();4999}5000 5001template <class ELFT>5002void ELFDumper<ELFT>::printDynamicReloc(const Relocation<ELFT> &R) {5003  printRelRelaReloc(R, getSymbolForReloc(*this, R));5004}5005 5006template <class ELFT>5007void ELFDumper<ELFT>::printRelocationsHelper(const Elf_Shdr &Sec) {5008  this->forEachRelocationDo(5009      Sec, [&](const Relocation<ELFT> &R, unsigned Ndx, const Elf_Shdr &Sec,5010               const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); });5011}5012 5013template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocationsHelper() {5014  const bool IsMips64EL = this->Obj.isMips64EL();5015  auto DumpCrelRegion = [&](DynRegionInfo &Region) {5016    // While the size is unknown, a valid CREL has at least one byte. We can5017    // check whether Addr is in bounds, and then decode CREL until the file5018    // end.5019    Region.Size = Region.EntSize = 1;5020    if (!Region.template getAsArrayRef<uint8_t>().empty()) {5021      const uint64_t Offset =5022          Region.Addr - reinterpret_cast<const uint8_t *>(5023                            ObjF.getMemoryBufferRef().getBufferStart());5024      const uint64_t ObjSize = ObjF.getMemoryBufferRef().getBufferSize();5025      auto RelsOrRelas =5026          Obj.decodeCrel(ArrayRef<uint8_t>(Region.Addr, ObjSize - Offset));5027      if (!RelsOrRelas) {5028        reportUniqueWarning(toString(RelsOrRelas.takeError()));5029      } else {5030        for (const Elf_Rel &R : RelsOrRelas->first)5031          printDynamicReloc(Relocation<ELFT>(R, false));5032        for (const Elf_Rela &R : RelsOrRelas->second)5033          printDynamicReloc(Relocation<ELFT>(R, false));5034      }5035    }5036  };5037 5038  if (this->DynCrelRegion.Addr) {5039    printDynamicRelocHeader(ELF::SHT_CREL, "CREL", this->DynCrelRegion);5040    DumpCrelRegion(this->DynCrelRegion);5041  }5042 5043  if (this->DynRelaRegion.Size > 0) {5044    printDynamicRelocHeader(ELF::SHT_RELA, "RELA", this->DynRelaRegion);5045    for (const Elf_Rela &Rela :5046         this->DynRelaRegion.template getAsArrayRef<Elf_Rela>())5047      printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL));5048  }5049 5050  if (this->DynRelRegion.Size > 0) {5051    printDynamicRelocHeader(ELF::SHT_REL, "REL", this->DynRelRegion);5052    for (const Elf_Rel &Rel :5053         this->DynRelRegion.template getAsArrayRef<Elf_Rel>())5054      printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));5055  }5056 5057  if (this->DynRelrRegion.Size > 0) {5058    printDynamicRelocHeader(ELF::SHT_REL, "RELR", this->DynRelrRegion);5059    Elf_Relr_Range Relrs =5060        this->DynRelrRegion.template getAsArrayRef<Elf_Relr>();5061    for (const Elf_Rel &Rel : Obj.decode_relrs(Relrs))5062      printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));5063  }5064 5065  if (this->DynPLTRelRegion.Size) {5066    if (this->DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) {5067      printDynamicRelocHeader(ELF::SHT_RELA, "PLT", this->DynPLTRelRegion);5068      for (const Elf_Rela &Rela :5069           this->DynPLTRelRegion.template getAsArrayRef<Elf_Rela>())5070        printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL));5071    } else if (this->DynPLTRelRegion.EntSize == 1) {5072      DumpCrelRegion(this->DynPLTRelRegion);5073    } else {5074      printDynamicRelocHeader(ELF::SHT_REL, "PLT", this->DynPLTRelRegion);5075      for (const Elf_Rel &Rel :5076           this->DynPLTRelRegion.template getAsArrayRef<Elf_Rel>())5077        printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));5078    }5079  }5080}5081 5082template <class ELFT>5083void GNUELFDumper<ELFT>::printGNUVersionSectionProlog(5084    const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum) {5085  // Don't inline the SecName, because it might report a warning to stderr and5086  // corrupt the output.5087  StringRef SecName = this->getPrintableSectionName(Sec);5088  OS << Label << " section '" << SecName << "' "5089     << "contains " << EntriesNum << " entries:\n";5090 5091  StringRef LinkedSecName = "<corrupt>";5092  if (Expected<const typename ELFT::Shdr *> LinkedSecOrErr =5093          this->Obj.getSection(Sec.sh_link))5094    LinkedSecName = this->getPrintableSectionName(**LinkedSecOrErr);5095  else5096    this->reportUniqueWarning("invalid section linked to " +5097                              this->describe(Sec) + ": " +5098                              toString(LinkedSecOrErr.takeError()));5099 5100  OS << " Addr: " << format_hex_no_prefix(Sec.sh_addr, 16)5101     << "  Offset: " << format_hex(Sec.sh_offset, 8)5102     << "  Link: " << Sec.sh_link << " (" << LinkedSecName << ")\n";5103}5104 5105template <class ELFT>5106void GNUELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) {5107  if (!Sec)5108    return;5109 5110  printGNUVersionSectionProlog(*Sec, "Version symbols",5111                               Sec->sh_size / sizeof(Elf_Versym));5112  Expected<ArrayRef<Elf_Versym>> VerTableOrErr =5113      this->getVersionTable(*Sec, /*SymTab=*/nullptr,5114                            /*StrTab=*/nullptr, /*SymTabSec=*/nullptr);5115  if (!VerTableOrErr) {5116    this->reportUniqueWarning(VerTableOrErr.takeError());5117    return;5118  }5119 5120  SmallVector<std::optional<VersionEntry>, 0> *VersionMap = nullptr;5121  if (Expected<SmallVector<std::optional<VersionEntry>, 0> *> MapOrErr =5122          this->getVersionMap())5123    VersionMap = *MapOrErr;5124  else5125    this->reportUniqueWarning(MapOrErr.takeError());5126 5127  ArrayRef<Elf_Versym> VerTable = *VerTableOrErr;5128  std::vector<StringRef> Versions;5129  for (size_t I = 0, E = VerTable.size(); I < E; ++I) {5130    unsigned Ndx = VerTable[I].vs_index;5131    if (Ndx == VER_NDX_LOCAL || Ndx == VER_NDX_GLOBAL) {5132      Versions.emplace_back(Ndx == VER_NDX_LOCAL ? "*local*" : "*global*");5133      continue;5134    }5135 5136    if (!VersionMap) {5137      Versions.emplace_back("<corrupt>");5138      continue;5139    }5140 5141    bool IsDefault;5142    Expected<StringRef> NameOrErr = this->Obj.getSymbolVersionByIndex(5143        Ndx, IsDefault, *VersionMap, /*IsSymHidden=*/std::nullopt);5144    if (!NameOrErr) {5145      this->reportUniqueWarning("unable to get a version for entry " +5146                                Twine(I) + " of " + this->describe(*Sec) +5147                                ": " + toString(NameOrErr.takeError()));5148      Versions.emplace_back("<corrupt>");5149      continue;5150    }5151    Versions.emplace_back(*NameOrErr);5152  }5153 5154  // readelf prints 4 entries per line.5155  uint64_t Entries = VerTable.size();5156  for (uint64_t VersymRow = 0; VersymRow < Entries; VersymRow += 4) {5157    OS << "  " << format_hex_no_prefix(VersymRow, 3) << ":";5158    for (uint64_t I = 0; (I < 4) && (I + VersymRow) < Entries; ++I) {5159      unsigned Ndx = VerTable[VersymRow + I].vs_index;5160      OS << format("%4x%c", Ndx & VERSYM_VERSION,5161                   Ndx & VERSYM_HIDDEN ? 'h' : ' ');5162      OS << left_justify("(" + std::string(Versions[VersymRow + I]) + ")", 13);5163    }5164    OS << '\n';5165  }5166  OS << '\n';5167}5168 5169static std::string versionFlagToString(unsigned Flags) {5170  if (Flags == 0)5171    return "none";5172 5173  std::string Ret;5174  auto AddFlag = [&Ret, &Flags](unsigned Flag, StringRef Name) {5175    if (!(Flags & Flag))5176      return;5177    if (!Ret.empty())5178      Ret += " | ";5179    Ret += Name;5180    Flags &= ~Flag;5181  };5182 5183  AddFlag(VER_FLG_BASE, "BASE");5184  AddFlag(VER_FLG_WEAK, "WEAK");5185  AddFlag(VER_FLG_INFO, "INFO");5186  AddFlag(~0, "<unknown>");5187  return Ret;5188}5189 5190template <class ELFT>5191void GNUELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) {5192  if (!Sec)5193    return;5194 5195  printGNUVersionSectionProlog(*Sec, "Version definition", Sec->sh_info);5196 5197  Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec);5198  if (!V) {5199    this->reportUniqueWarning(V.takeError());5200    return;5201  }5202 5203  for (const VerDef &Def : *V) {5204    OS << format("  0x%04x: Rev: %u  Flags: %s  Index: %u  Cnt: %u  Name: %s\n",5205                 Def.Offset, Def.Version,5206                 versionFlagToString(Def.Flags).c_str(), Def.Ndx, Def.Cnt,5207                 Def.Name.data());5208    unsigned I = 0;5209    for (const VerdAux &Aux : Def.AuxV)5210      OS << format("  0x%04x: Parent %u: %s\n", Aux.Offset, ++I,5211                   Aux.Name.data());5212  }5213 5214  OS << '\n';5215}5216 5217template <class ELFT>5218void GNUELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) {5219  if (!Sec)5220    return;5221 5222  unsigned VerneedNum = Sec->sh_info;5223  printGNUVersionSectionProlog(*Sec, "Version needs", VerneedNum);5224 5225  Expected<std::vector<VerNeed>> V =5226      this->Obj.getVersionDependencies(*Sec, this->WarningHandler);5227  if (!V) {5228    this->reportUniqueWarning(V.takeError());5229    return;5230  }5231 5232  for (const VerNeed &VN : *V) {5233    OS << format("  0x%04x: Version: %u  File: %s  Cnt: %u\n", VN.Offset,5234                 VN.Version, VN.File.data(), VN.Cnt);5235    for (const VernAux &Aux : VN.AuxV)5236      OS << format("  0x%04x:   Name: %s  Flags: %s  Version: %u\n", Aux.Offset,5237                   Aux.Name.data(), versionFlagToString(Aux.Flags).c_str(),5238                   Aux.Other);5239  }5240  OS << '\n';5241}5242 5243template <class ELFT>5244void GNUELFDumper<ELFT>::printHashHistogramStats(size_t NBucket,5245                                                 size_t MaxChain,5246                                                 size_t TotalSyms,5247                                                 ArrayRef<size_t> Count,5248                                                 bool IsGnu) const {5249  size_t CumulativeNonZero = 0;5250  OS << "Histogram for" << (IsGnu ? " `.gnu.hash'" : "")5251     << " bucket list length (total of " << NBucket << " buckets)\n"5252     << " Length  Number     % of total  Coverage\n";5253  for (size_t I = 0; I < MaxChain; ++I) {5254    CumulativeNonZero += Count[I] * I;5255    OS << format("%7lu  %-10lu (%5.1f%%)     %5.1f%%\n", I, Count[I],5256                 (Count[I] * 100.0) / NBucket,5257                 (CumulativeNonZero * 100.0) / TotalSyms);5258  }5259}5260 5261template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() {5262  OS << "GNUStyle::printCGProfile not implemented\n";5263}5264 5265template <class ELFT>5266void GNUELFDumper<ELFT>::printBBAddrMaps(bool /*PrettyPGOAnalysis*/) {5267  OS << "GNUStyle::printBBAddrMaps not implemented\n";5268}5269 5270static Expected<std::vector<uint64_t>> toULEB128Array(ArrayRef<uint8_t> Data) {5271  std::vector<uint64_t> Ret;5272  const uint8_t *Cur = Data.begin();5273  const uint8_t *End = Data.end();5274  while (Cur != End) {5275    unsigned Size;5276    const char *Err = nullptr;5277    Ret.push_back(decodeULEB128(Cur, &Size, End, &Err));5278    if (Err)5279      return createError(Err);5280    Cur += Size;5281  }5282  return Ret;5283}5284 5285template <class ELFT>5286static Expected<std::vector<uint64_t>>5287decodeAddrsigSection(const ELFFile<ELFT> &Obj, const typename ELFT::Shdr &Sec) {5288  Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Sec);5289  if (!ContentsOrErr)5290    return ContentsOrErr.takeError();5291 5292  if (Expected<std::vector<uint64_t>> SymsOrErr =5293          toULEB128Array(*ContentsOrErr))5294    return *SymsOrErr;5295  else5296    return createError("unable to decode " + describe(Obj, Sec) + ": " +5297                       toString(SymsOrErr.takeError()));5298}5299 5300template <class ELFT> void GNUELFDumper<ELFT>::printAddrsig() {5301  if (!this->DotAddrsigSec)5302    return;5303 5304  Expected<std::vector<uint64_t>> SymsOrErr =5305      decodeAddrsigSection(this->Obj, *this->DotAddrsigSec);5306  if (!SymsOrErr) {5307    this->reportUniqueWarning(SymsOrErr.takeError());5308    return;5309  }5310 5311  StringRef Name = this->getPrintableSectionName(*this->DotAddrsigSec);5312  OS << "\nAddress-significant symbols section '" << Name << "'"5313     << " contains " << SymsOrErr->size() << " entries:\n";5314  OS << "   Num: Name\n";5315 5316  Field Fields[2] = {0, 8};5317  size_t SymIndex = 0;5318  for (uint64_t Sym : *SymsOrErr) {5319    Fields[0].Str = to_string(format_decimal(++SymIndex, 6)) + ":";5320    Fields[1].Str = this->getStaticSymbolName(Sym);5321    for (const Field &Entry : Fields)5322      printField(Entry);5323    OS << "\n";5324  }5325}5326 5327template <class ELFT>5328static bool printAArch64PAuthABICoreInfo(raw_ostream &OS, uint32_t DataSize,5329                                         ArrayRef<uint8_t> Desc) {5330  OS << "    AArch64 PAuth ABI core info: ";5331  // DataSize - size without padding, Desc.size() - size with padding5332  if (DataSize != 16) {5333    OS << format("<corrupted size: expected 16, got %d>", DataSize);5334    return false;5335  }5336 5337  uint64_t Platform =5338      support::endian::read64<ELFT::Endianness>(Desc.data() + 0);5339  uint64_t Version = support::endian::read64<ELFT::Endianness>(Desc.data() + 8);5340 5341  const char *PlatformDesc = [Platform]() {5342    switch (Platform) {5343    case AARCH64_PAUTH_PLATFORM_INVALID:5344      return "invalid";5345    case AARCH64_PAUTH_PLATFORM_BAREMETAL:5346      return "baremetal";5347    case AARCH64_PAUTH_PLATFORM_LLVM_LINUX:5348      return "llvm_linux";5349    default:5350      return "unknown";5351    }5352  }();5353 5354  std::string VersionDesc = [Platform, Version]() -> std::string {5355    if (Platform != AARCH64_PAUTH_PLATFORM_LLVM_LINUX)5356      return "";5357    if (Version >= (1 << (AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST + 1)))5358      return "unknown";5359 5360    std::array<StringRef, AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST + 1>5361        Flags;5362    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS] = "Intrinsics";5363    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS] = "Calls";5364    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS] = "Returns";5365    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS] = "AuthTraps";5366    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR] =5367        "VTPtrAddressDiscrimination";5368    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR] =5369        "VTPtrTypeDiscrimination";5370    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI] = "InitFini";5371    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINIADDRDISC] =5372        "InitFiniAddressDiscrimination";5373    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT] = "ELFGOT";5374    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOTOS] = "IndirectGotos";5375    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_TYPEINFOVPTRDISCR] =5376        "TypeInfoVTPtrDiscrimination";5377    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_FPTRTYPEDISCR] =5378        "FPtrTypeDiscrimination";5379 5380    static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_FPTRTYPEDISCR ==5381                      AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST,5382                  "Update when new enum items are defined");5383 5384    std::string Desc;5385    for (uint32_t I = 0, End = Flags.size(); I < End; ++I) {5386      if (!(Version & (1ULL << I)))5387        Desc += '!';5388      Desc +=5389          Twine("PointerAuth" + Flags[I] + (I == End - 1 ? "" : ", ")).str();5390    }5391    return Desc;5392  }();5393 5394  OS << format("platform 0x%" PRIx64 " (%s), version 0x%" PRIx64, Platform,5395               PlatformDesc, Version);5396  if (!VersionDesc.empty())5397    OS << format(" (%s)", VersionDesc.c_str());5398 5399  return true;5400}5401 5402template <typename ELFT>5403static std::string getGNUProperty(uint32_t Type, uint32_t DataSize,5404                                  ArrayRef<uint8_t> Data,5405                                  typename ELFT::Half EMachine) {5406  std::string str;5407  raw_string_ostream OS(str);5408  uint32_t PrData;5409  auto DumpBit = [&](uint32_t Flag, StringRef Name) {5410    if (PrData & Flag) {5411      PrData &= ~Flag;5412      OS << Name;5413      if (PrData)5414        OS << ", ";5415    }5416  };5417 5418  switch (Type) {5419  default:5420    OS << format("<application-specific type 0x%x>", Type);5421    return str;5422  case GNU_PROPERTY_STACK_SIZE: {5423    OS << "stack size: ";5424    if (DataSize == sizeof(typename ELFT::uint))5425      OS << formatv("{0:x}",5426                    (uint64_t)(*(const typename ELFT::Addr *)Data.data()));5427    else5428      OS << format("<corrupt length: 0x%x>", DataSize);5429    return str;5430  }5431  case GNU_PROPERTY_NO_COPY_ON_PROTECTED:5432    OS << "no copy on protected";5433    if (DataSize)5434      OS << format(" <corrupt length: 0x%x>", DataSize);5435    return str;5436  case GNU_PROPERTY_AARCH64_FEATURE_1_AND:5437  case GNU_PROPERTY_X86_FEATURE_1_AND:5438    static_assert(GNU_PROPERTY_AARCH64_FEATURE_1_AND ==5439                      GNU_PROPERTY_RISCV_FEATURE_1_AND,5440                  "GNU_PROPERTY_RISCV_FEATURE_1_AND should equal "5441                  "GNU_PROPERTY_AARCH64_FEATURE_1_AND, otherwise "5442                  "GNU_PROPERTY_RISCV_FEATURE_1_AND would be skipped!");5443 5444    if (EMachine == EM_AARCH64 && Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {5445      OS << "aarch64 feature: ";5446    } else if (EMachine == EM_RISCV &&5447               Type == GNU_PROPERTY_RISCV_FEATURE_1_AND) {5448      OS << "RISC-V feature: ";5449    } else if ((EMachine == EM_386 || EMachine == EM_X86_64) &&5450               Type == GNU_PROPERTY_X86_FEATURE_1_AND) {5451      OS << "x86 feature: ";5452    } else {5453      OS << format("<application-specific type 0x%x>", Type);5454      return str;5455    }5456 5457    if (DataSize != 4) {5458      OS << format("<corrupt length: 0x%x>", DataSize);5459      return str;5460    }5461    PrData = endian::read32<ELFT::Endianness>(Data.data());5462    if (PrData == 0) {5463      OS << "<None>";5464      return str;5465    }5466 5467    if (EMachine == EM_AARCH64) {5468      DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI");5469      DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC");5470      DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_GCS, "GCS");5471    } else if (EMachine == EM_RISCV) {5472      DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED,5473              "ZICFILP-unlabeled");5474      DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS, "ZICFISS");5475      DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG, "ZICFILP-func-sig");5476    } else {5477      DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT");5478      DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK");5479    }5480    if (PrData)5481      OS << format("<unknown flags: 0x%x>", PrData);5482    return str;5483  case GNU_PROPERTY_AARCH64_FEATURE_PAUTH:5484    printAArch64PAuthABICoreInfo<ELFT>(OS, DataSize, Data);5485    return str;5486  case GNU_PROPERTY_X86_FEATURE_2_NEEDED:5487  case GNU_PROPERTY_X86_FEATURE_2_USED:5488    OS << "x86 feature "5489       << (Type == GNU_PROPERTY_X86_FEATURE_2_NEEDED ? "needed: " : "used: ");5490    if (DataSize != 4) {5491      OS << format("<corrupt length: 0x%x>", DataSize);5492      return str;5493    }5494    PrData = endian::read32<ELFT::Endianness>(Data.data());5495    if (PrData == 0) {5496      OS << "<None>";5497      return str;5498    }5499    DumpBit(GNU_PROPERTY_X86_FEATURE_2_X86, "x86");5500    DumpBit(GNU_PROPERTY_X86_FEATURE_2_X87, "x87");5501    DumpBit(GNU_PROPERTY_X86_FEATURE_2_MMX, "MMX");5502    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XMM, "XMM");5503    DumpBit(GNU_PROPERTY_X86_FEATURE_2_YMM, "YMM");5504    DumpBit(GNU_PROPERTY_X86_FEATURE_2_ZMM, "ZMM");5505    DumpBit(GNU_PROPERTY_X86_FEATURE_2_FXSR, "FXSR");5506    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVE, "XSAVE");5507    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT, "XSAVEOPT");5508    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEC, "XSAVEC");5509    if (PrData)5510      OS << format("<unknown flags: 0x%x>", PrData);5511    return str;5512  case GNU_PROPERTY_X86_ISA_1_NEEDED:5513  case GNU_PROPERTY_X86_ISA_1_USED:5514    OS << "x86 ISA "5515       << (Type == GNU_PROPERTY_X86_ISA_1_NEEDED ? "needed: " : "used: ");5516    if (DataSize != 4) {5517      OS << format("<corrupt length: 0x%x>", DataSize);5518      return str;5519    }5520    PrData = endian::read32<ELFT::Endianness>(Data.data());5521    if (PrData == 0) {5522      OS << "<None>";5523      return str;5524    }5525    DumpBit(GNU_PROPERTY_X86_ISA_1_BASELINE, "x86-64-baseline");5526    DumpBit(GNU_PROPERTY_X86_ISA_1_V2, "x86-64-v2");5527    DumpBit(GNU_PROPERTY_X86_ISA_1_V3, "x86-64-v3");5528    DumpBit(GNU_PROPERTY_X86_ISA_1_V4, "x86-64-v4");5529    if (PrData)5530      OS << format("<unknown flags: 0x%x>", PrData);5531    return str;5532  }5533}5534 5535template <typename ELFT>5536static SmallVector<std::string, 4>5537getGNUPropertyList(ArrayRef<uint8_t> Arr, typename ELFT::Half EMachine) {5538  using Elf_Word = typename ELFT::Word;5539 5540  SmallVector<std::string, 4> Properties;5541  while (Arr.size() >= 8) {5542    uint32_t Type = *reinterpret_cast<const Elf_Word *>(Arr.data());5543    uint32_t DataSize = *reinterpret_cast<const Elf_Word *>(Arr.data() + 4);5544    Arr = Arr.drop_front(8);5545 5546    // Take padding size into account if present.5547    uint64_t PaddedSize = alignTo(DataSize, sizeof(typename ELFT::uint));5548    std::string str;5549    raw_string_ostream OS(str);5550    if (Arr.size() < PaddedSize) {5551      OS << format("<corrupt type (0x%x) datasz: 0x%x>", Type, DataSize);5552      Properties.push_back(str);5553      break;5554    }5555    Properties.push_back(getGNUProperty<ELFT>(5556        Type, DataSize, Arr.take_front(PaddedSize), EMachine));5557    Arr = Arr.drop_front(PaddedSize);5558  }5559 5560  if (!Arr.empty())5561    Properties.push_back("<corrupted GNU_PROPERTY_TYPE_0>");5562 5563  return Properties;5564}5565 5566struct GNUAbiTag {5567  std::string OSName;5568  std::string ABI;5569  bool IsValid;5570};5571 5572template <typename ELFT> static GNUAbiTag getGNUAbiTag(ArrayRef<uint8_t> Desc) {5573  typedef typename ELFT::Word Elf_Word;5574 5575  ArrayRef<Elf_Word> Words(reinterpret_cast<const Elf_Word *>(Desc.begin()),5576                           reinterpret_cast<const Elf_Word *>(Desc.end()));5577 5578  if (Words.size() < 4)5579    return {"", "", /*IsValid=*/false};5580 5581  static const char *OSNames[] = {5582      "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable",5583  };5584  StringRef OSName = "Unknown";5585  if (Words[0] < std::size(OSNames))5586    OSName = OSNames[Words[0]];5587  uint32_t Major = Words[1], Minor = Words[2], Patch = Words[3];5588  std::string str;5589  raw_string_ostream ABI(str);5590  ABI << Major << "." << Minor << "." << Patch;5591  return {std::string(OSName), str, /*IsValid=*/true};5592}5593 5594static std::string getGNUBuildId(ArrayRef<uint8_t> Desc) {5595  std::string str;5596  raw_string_ostream OS(str);5597  for (uint8_t B : Desc)5598    OS << format_hex_no_prefix(B, 2);5599  return str;5600}5601 5602static StringRef getDescAsStringRef(ArrayRef<uint8_t> Desc) {5603  return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());5604}5605 5606template <typename ELFT>5607static bool printGNUNote(raw_ostream &OS, uint32_t NoteType,5608                         ArrayRef<uint8_t> Desc, typename ELFT::Half EMachine) {5609  // Return true if we were able to pretty-print the note, false otherwise.5610  switch (NoteType) {5611  default:5612    return false;5613  case ELF::NT_GNU_ABI_TAG: {5614    const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);5615    if (!AbiTag.IsValid)5616      OS << "    <corrupt GNU_ABI_TAG>";5617    else5618      OS << "    OS: " << AbiTag.OSName << ", ABI: " << AbiTag.ABI;5619    break;5620  }5621  case ELF::NT_GNU_BUILD_ID: {5622    OS << "    Build ID: " << getGNUBuildId(Desc);5623    break;5624  }5625  case ELF::NT_GNU_GOLD_VERSION:5626    OS << "    Version: " << getDescAsStringRef(Desc);5627    break;5628  case ELF::NT_GNU_PROPERTY_TYPE_0:5629    OS << "    Properties:";5630    for (const std::string &Property : getGNUPropertyList<ELFT>(Desc, EMachine))5631      OS << "    " << Property << "\n";5632    break;5633  }5634  OS << '\n';5635  return true;5636}5637 5638using AndroidNoteProperties = std::vector<std::pair<StringRef, std::string>>;5639static AndroidNoteProperties getAndroidNoteProperties(uint32_t NoteType,5640                                                      ArrayRef<uint8_t> Desc) {5641  AndroidNoteProperties Props;5642  switch (NoteType) {5643  case ELF::NT_ANDROID_TYPE_MEMTAG:5644    if (Desc.empty()) {5645      Props.emplace_back("Invalid .note.android.memtag", "");5646      return Props;5647    }5648 5649    switch (Desc[0] & NT_MEMTAG_LEVEL_MASK) {5650    case NT_MEMTAG_LEVEL_NONE:5651      Props.emplace_back("Tagging Mode", "NONE");5652      break;5653    case NT_MEMTAG_LEVEL_ASYNC:5654      Props.emplace_back("Tagging Mode", "ASYNC");5655      break;5656    case NT_MEMTAG_LEVEL_SYNC:5657      Props.emplace_back("Tagging Mode", "SYNC");5658      break;5659    default:5660      Props.emplace_back(5661          "Tagging Mode",5662          ("Unknown (" + Twine::utohexstr(Desc[0] & NT_MEMTAG_LEVEL_MASK) + ")")5663              .str());5664      break;5665    }5666    Props.emplace_back("Heap",5667                       (Desc[0] & NT_MEMTAG_HEAP) ? "Enabled" : "Disabled");5668    Props.emplace_back("Stack",5669                       (Desc[0] & NT_MEMTAG_STACK) ? "Enabled" : "Disabled");5670    break;5671  default:5672    return Props;5673  }5674  return Props;5675}5676 5677static bool printAndroidNote(raw_ostream &OS, uint32_t NoteType,5678                             ArrayRef<uint8_t> Desc) {5679  // Return true if we were able to pretty-print the note, false otherwise.5680  AndroidNoteProperties Props = getAndroidNoteProperties(NoteType, Desc);5681  if (Props.empty())5682    return false;5683  for (const auto &KV : Props)5684    OS << "    " << KV.first << ": " << KV.second << '\n';5685  return true;5686}5687 5688template <class ELFT>5689void GNUELFDumper<ELFT>::printMemtag(5690    const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,5691    const ArrayRef<uint8_t> AndroidNoteDesc,5692    const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) {5693  OS << "Memtag Dynamic Entries:\n";5694  if (DynamicEntries.empty())5695    OS << "    < none found >\n";5696  for (const auto &DynamicEntryKV : DynamicEntries)5697    OS << "    " << DynamicEntryKV.first << ": " << DynamicEntryKV.second5698       << "\n";5699 5700  if (!AndroidNoteDesc.empty()) {5701    OS << "Memtag Android Note:\n";5702    printAndroidNote(OS, ELF::NT_ANDROID_TYPE_MEMTAG, AndroidNoteDesc);5703  }5704 5705  if (Descriptors.empty())5706    return;5707 5708  OS << "Memtag Global Descriptors:\n";5709  for (const auto &[Addr, BytesToTag] : Descriptors) {5710    OS << "    0x" << utohexstr(Addr, /*LowerCase=*/true) << ": 0x"5711       << utohexstr(BytesToTag, /*LowerCase=*/true) << "\n";5712  }5713}5714 5715template <typename ELFT>5716static bool printLLVMOMPOFFLOADNote(raw_ostream &OS, uint32_t NoteType,5717                                    ArrayRef<uint8_t> Desc) {5718  switch (NoteType) {5719  default:5720    return false;5721  case ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION:5722    OS << "    Version: " << getDescAsStringRef(Desc);5723    break;5724  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER:5725    OS << "    Producer: " << getDescAsStringRef(Desc);5726    break;5727  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION:5728    OS << "    Producer version: " << getDescAsStringRef(Desc);5729    break;5730  }5731  OS << '\n';5732  return true;5733}5734 5735const EnumEntry<unsigned> FreeBSDFeatureCtlFlags[] = {5736    {"ASLR_DISABLE", NT_FREEBSD_FCTL_ASLR_DISABLE},5737    {"PROTMAX_DISABLE", NT_FREEBSD_FCTL_PROTMAX_DISABLE},5738    {"STKGAP_DISABLE", NT_FREEBSD_FCTL_STKGAP_DISABLE},5739    {"WXNEEDED", NT_FREEBSD_FCTL_WXNEEDED},5740    {"LA48", NT_FREEBSD_FCTL_LA48},5741    {"ASG_DISABLE", NT_FREEBSD_FCTL_ASG_DISABLE},5742};5743 5744struct FreeBSDNote {5745  std::string Type;5746  std::string Value;5747};5748 5749template <typename ELFT>5750static std::optional<FreeBSDNote>5751getFreeBSDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc, bool IsCore) {5752  if (IsCore)5753    return std::nullopt; // No pretty-printing yet.5754  switch (NoteType) {5755  case ELF::NT_FREEBSD_ABI_TAG:5756    if (Desc.size() != 4)5757      return std::nullopt;5758    return FreeBSDNote{"ABI tag",5759                       utostr(endian::read32<ELFT::Endianness>(Desc.data()))};5760  case ELF::NT_FREEBSD_ARCH_TAG:5761    return FreeBSDNote{"Arch tag", toStringRef(Desc).str()};5762  case ELF::NT_FREEBSD_FEATURE_CTL: {5763    if (Desc.size() != 4)5764      return std::nullopt;5765    unsigned Value = endian::read32<ELFT::Endianness>(Desc.data());5766    std::string FlagsStr;5767    raw_string_ostream OS(FlagsStr);5768    printFlags(Value, ArrayRef(FreeBSDFeatureCtlFlags), OS);5769    if (FlagsStr.empty())5770      OS << "0x" << utohexstr(Value, /*LowerCase=*/true);5771    else5772      OS << "(0x" << utohexstr(Value, /*LowerCase=*/true) << ")";5773    return FreeBSDNote{"Feature flags", FlagsStr};5774  }5775  default:5776    return std::nullopt;5777  }5778}5779 5780struct AMDNote {5781  std::string Type;5782  std::string Value;5783};5784 5785template <typename ELFT>5786static AMDNote getAMDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {5787  switch (NoteType) {5788  default:5789    return {"", ""};5790  case ELF::NT_AMD_HSA_CODE_OBJECT_VERSION: {5791    struct CodeObjectVersion {5792      support::aligned_ulittle32_t MajorVersion;5793      support::aligned_ulittle32_t MinorVersion;5794    };5795    if (Desc.size() != sizeof(CodeObjectVersion))5796      return {"AMD HSA Code Object Version",5797              "Invalid AMD HSA Code Object Version"};5798    std::string VersionString;5799    raw_string_ostream StrOS(VersionString);5800    auto Version = reinterpret_cast<const CodeObjectVersion *>(Desc.data());5801    StrOS << "[Major: " << Version->MajorVersion5802          << ", Minor: " << Version->MinorVersion << "]";5803    return {"AMD HSA Code Object Version", VersionString};5804  }5805  case ELF::NT_AMD_HSA_HSAIL: {5806    struct HSAILProperties {5807      support::aligned_ulittle32_t HSAILMajorVersion;5808      support::aligned_ulittle32_t HSAILMinorVersion;5809      uint8_t Profile;5810      uint8_t MachineModel;5811      uint8_t DefaultFloatRound;5812    };5813    if (Desc.size() != sizeof(HSAILProperties))5814      return {"AMD HSA HSAIL Properties", "Invalid AMD HSA HSAIL Properties"};5815    auto Properties = reinterpret_cast<const HSAILProperties *>(Desc.data());5816    std::string HSAILPropetiesString;5817    raw_string_ostream StrOS(HSAILPropetiesString);5818    StrOS << "[HSAIL Major: " << Properties->HSAILMajorVersion5819          << ", HSAIL Minor: " << Properties->HSAILMinorVersion5820          << ", Profile: " << uint32_t(Properties->Profile)5821          << ", Machine Model: " << uint32_t(Properties->MachineModel)5822          << ", Default Float Round: "5823          << uint32_t(Properties->DefaultFloatRound) << "]";5824    return {"AMD HSA HSAIL Properties", HSAILPropetiesString};5825  }5826  case ELF::NT_AMD_HSA_ISA_VERSION: {5827    struct IsaVersion {5828      support::aligned_ulittle16_t VendorNameSize;5829      support::aligned_ulittle16_t ArchitectureNameSize;5830      support::aligned_ulittle32_t Major;5831      support::aligned_ulittle32_t Minor;5832      support::aligned_ulittle32_t Stepping;5833    };5834    if (Desc.size() < sizeof(IsaVersion))5835      return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"};5836    auto Isa = reinterpret_cast<const IsaVersion *>(Desc.data());5837    if (Desc.size() < sizeof(IsaVersion) +5838                          Isa->VendorNameSize + Isa->ArchitectureNameSize ||5839        Isa->VendorNameSize == 0 || Isa->ArchitectureNameSize == 0)5840      return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"};5841    std::string IsaString;5842    raw_string_ostream StrOS(IsaString);5843    StrOS << "[Vendor: "5844          << StringRef((const char*)Desc.data() + sizeof(IsaVersion), Isa->VendorNameSize - 1)5845          << ", Architecture: "5846          << StringRef((const char*)Desc.data() + sizeof(IsaVersion) + Isa->VendorNameSize,5847                       Isa->ArchitectureNameSize - 1)5848          << ", Major: " << Isa->Major << ", Minor: " << Isa->Minor5849          << ", Stepping: " << Isa->Stepping << "]";5850    return {"AMD HSA ISA Version", IsaString};5851  }5852  case ELF::NT_AMD_HSA_METADATA: {5853    if (Desc.size() == 0)5854      return {"AMD HSA Metadata", ""};5855    return {5856        "AMD HSA Metadata",5857        std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size() - 1)};5858  }5859  case ELF::NT_AMD_HSA_ISA_NAME: {5860    if (Desc.size() == 0)5861      return {"AMD HSA ISA Name", ""};5862    return {5863        "AMD HSA ISA Name",5864        std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size())};5865  }5866  case ELF::NT_AMD_PAL_METADATA: {5867    struct PALMetadata {5868      support::aligned_ulittle32_t Key;5869      support::aligned_ulittle32_t Value;5870    };5871    if (Desc.size() % sizeof(PALMetadata) != 0)5872      return {"AMD PAL Metadata", "Invalid AMD PAL Metadata"};5873    auto Isa = reinterpret_cast<const PALMetadata *>(Desc.data());5874    std::string MetadataString;5875    raw_string_ostream StrOS(MetadataString);5876    for (size_t I = 0, E = Desc.size() / sizeof(PALMetadata); I < E; ++I) {5877      StrOS << "[" << Isa[I].Key << ": " << Isa[I].Value << "]";5878    }5879    return {"AMD PAL Metadata", MetadataString};5880  }5881  }5882}5883 5884struct AMDGPUNote {5885  std::string Type;5886  std::string Value;5887};5888 5889template <typename ELFT>5890static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {5891  switch (NoteType) {5892  default:5893    return {"", ""};5894  case ELF::NT_AMDGPU_METADATA: {5895    StringRef MsgPackString =5896        StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());5897    msgpack::Document MsgPackDoc;5898    if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false))5899      return {"", ""};5900 5901    std::string MetadataString;5902 5903    // FIXME: Metadata Verifier only works with AMDHSA.5904    //  This is an ugly workaround to avoid the verifier for other MD5905    //  formats (e.g. amdpal)5906    if (MsgPackString.contains("amdhsa.")) {5907      AMDGPU::HSAMD::V3::MetadataVerifier Verifier(true);5908      if (!Verifier.verify(MsgPackDoc.getRoot()))5909        MetadataString = "Invalid AMDGPU Metadata\n";5910    }5911 5912    raw_string_ostream StrOS(MetadataString);5913    if (MsgPackDoc.getRoot().isScalar()) {5914      // TODO: passing a scalar root to toYAML() asserts:5915      // (PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar &&5916      //    "plain scalar documents are not supported")5917      // To avoid this crash we print the raw data instead.5918      return {"", ""};5919    }5920    MsgPackDoc.toYAML(StrOS);5921    return {"AMDGPU Metadata", MetadataString};5922  }5923  }5924}5925 5926struct CoreFileMapping {5927  uint64_t Start, End, Offset;5928  StringRef Filename;5929};5930 5931struct CoreNote {5932  uint64_t PageSize;5933  std::vector<CoreFileMapping> Mappings;5934};5935 5936static Expected<CoreNote> readCoreNote(DataExtractor Desc) {5937  // Expected format of the NT_FILE note description:5938  // 1. # of file mappings (call it N)5939  // 2. Page size5940  // 3. N (start, end, offset) triples5941  // 4. N packed filenames (null delimited)5942  // Each field is an Elf_Addr, except for filenames which are char* strings.5943 5944  CoreNote Ret;5945  const int Bytes = Desc.getAddressSize();5946 5947  if (!Desc.isValidOffsetForAddress(2))5948    return createError("the note of size 0x" + Twine::utohexstr(Desc.size()) +5949                       " is too short, expected at least 0x" +5950                       Twine::utohexstr(Bytes * 2));5951  if (Desc.getData().back() != 0)5952    return createError("the note is not NUL terminated");5953 5954  uint64_t DescOffset = 0;5955  uint64_t FileCount = Desc.getAddress(&DescOffset);5956  Ret.PageSize = Desc.getAddress(&DescOffset);5957 5958  if (!Desc.isValidOffsetForAddress(3 * FileCount * Bytes))5959    return createError("unable to read file mappings (found " +5960                       Twine(FileCount) + "): the note of size 0x" +5961                       Twine::utohexstr(Desc.size()) + " is too short");5962 5963  uint64_t FilenamesOffset = 0;5964  DataExtractor Filenames(5965      Desc.getData().drop_front(DescOffset + 3 * FileCount * Bytes),5966      Desc.isLittleEndian(), Desc.getAddressSize());5967 5968  Ret.Mappings.resize(FileCount);5969  size_t I = 0;5970  for (CoreFileMapping &Mapping : Ret.Mappings) {5971    ++I;5972    if (!Filenames.isValidOffsetForDataOfSize(FilenamesOffset, 1))5973      return createError(5974          "unable to read the file name for the mapping with index " +5975          Twine(I) + ": the note of size 0x" + Twine::utohexstr(Desc.size()) +5976          " is truncated");5977    Mapping.Start = Desc.getAddress(&DescOffset);5978    Mapping.End = Desc.getAddress(&DescOffset);5979    Mapping.Offset = Desc.getAddress(&DescOffset);5980    Mapping.Filename = Filenames.getCStrRef(&FilenamesOffset);5981  }5982 5983  return Ret;5984}5985 5986template <typename ELFT>5987static void printCoreNote(raw_ostream &OS, const CoreNote &Note) {5988  // Length of "0x<address>" string.5989  const int FieldWidth = ELFT::Is64Bits ? 18 : 10;5990 5991  OS << "    Page size: " << format_decimal(Note.PageSize, 0) << '\n';5992  OS << "    " << right_justify("Start", FieldWidth) << "  "5993     << right_justify("End", FieldWidth) << "  "5994     << right_justify("Page Offset", FieldWidth) << '\n';5995  for (const CoreFileMapping &Mapping : Note.Mappings) {5996    OS << "    " << format_hex(Mapping.Start, FieldWidth) << "  "5997       << format_hex(Mapping.End, FieldWidth) << "  "5998       << format_hex(Mapping.Offset, FieldWidth) << "\n        "5999       << Mapping.Filename << '\n';6000  }6001}6002 6003const NoteType GenericNoteTypes[] = {6004    {ELF::NT_VERSION, "NT_VERSION (version)"},6005    {ELF::NT_ARCH, "NT_ARCH (architecture)"},6006    {ELF::NT_GNU_BUILD_ATTRIBUTE_OPEN, "OPEN"},6007    {ELF::NT_GNU_BUILD_ATTRIBUTE_FUNC, "func"},6008};6009 6010const NoteType GNUNoteTypes[] = {6011    {ELF::NT_GNU_ABI_TAG, "NT_GNU_ABI_TAG (ABI version tag)"},6012    {ELF::NT_GNU_HWCAP, "NT_GNU_HWCAP (DSO-supplied software HWCAP info)"},6013    {ELF::NT_GNU_BUILD_ID, "NT_GNU_BUILD_ID (unique build ID bitstring)"},6014    {ELF::NT_GNU_GOLD_VERSION, "NT_GNU_GOLD_VERSION (gold version)"},6015    {ELF::NT_GNU_PROPERTY_TYPE_0, "NT_GNU_PROPERTY_TYPE_0 (property note)"},6016};6017 6018const NoteType FreeBSDCoreNoteTypes[] = {6019    {ELF::NT_FREEBSD_THRMISC, "NT_THRMISC (thrmisc structure)"},6020    {ELF::NT_FREEBSD_PROCSTAT_PROC, "NT_PROCSTAT_PROC (proc data)"},6021    {ELF::NT_FREEBSD_PROCSTAT_FILES, "NT_PROCSTAT_FILES (files data)"},6022    {ELF::NT_FREEBSD_PROCSTAT_VMMAP, "NT_PROCSTAT_VMMAP (vmmap data)"},6023    {ELF::NT_FREEBSD_PROCSTAT_GROUPS, "NT_PROCSTAT_GROUPS (groups data)"},6024    {ELF::NT_FREEBSD_PROCSTAT_UMASK, "NT_PROCSTAT_UMASK (umask data)"},6025    {ELF::NT_FREEBSD_PROCSTAT_RLIMIT, "NT_PROCSTAT_RLIMIT (rlimit data)"},6026    {ELF::NT_FREEBSD_PROCSTAT_OSREL, "NT_PROCSTAT_OSREL (osreldate data)"},6027    {ELF::NT_FREEBSD_PROCSTAT_PSSTRINGS,6028     "NT_PROCSTAT_PSSTRINGS (ps_strings data)"},6029    {ELF::NT_FREEBSD_PROCSTAT_AUXV, "NT_PROCSTAT_AUXV (auxv data)"},6030};6031 6032const NoteType FreeBSDNoteTypes[] = {6033    {ELF::NT_FREEBSD_ABI_TAG, "NT_FREEBSD_ABI_TAG (ABI version tag)"},6034    {ELF::NT_FREEBSD_NOINIT_TAG, "NT_FREEBSD_NOINIT_TAG (no .init tag)"},6035    {ELF::NT_FREEBSD_ARCH_TAG, "NT_FREEBSD_ARCH_TAG (architecture tag)"},6036    {ELF::NT_FREEBSD_FEATURE_CTL,6037     "NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)"},6038};6039 6040const NoteType NetBSDCoreNoteTypes[] = {6041    {ELF::NT_NETBSDCORE_PROCINFO,6042     "NT_NETBSDCORE_PROCINFO (procinfo structure)"},6043    {ELF::NT_NETBSDCORE_AUXV, "NT_NETBSDCORE_AUXV (ELF auxiliary vector data)"},6044    {ELF::NT_NETBSDCORE_LWPSTATUS, "PT_LWPSTATUS (ptrace_lwpstatus structure)"},6045};6046 6047const NoteType OpenBSDCoreNoteTypes[] = {6048    {ELF::NT_OPENBSD_PROCINFO, "NT_OPENBSD_PROCINFO (procinfo structure)"},6049    {ELF::NT_OPENBSD_AUXV, "NT_OPENBSD_AUXV (ELF auxiliary vector data)"},6050    {ELF::NT_OPENBSD_REGS, "NT_OPENBSD_REGS (regular registers)"},6051    {ELF::NT_OPENBSD_FPREGS, "NT_OPENBSD_FPREGS (floating point registers)"},6052    {ELF::NT_OPENBSD_WCOOKIE, "NT_OPENBSD_WCOOKIE (window cookie)"},6053};6054 6055const NoteType AMDNoteTypes[] = {6056    {ELF::NT_AMD_HSA_CODE_OBJECT_VERSION,6057     "NT_AMD_HSA_CODE_OBJECT_VERSION (AMD HSA Code Object Version)"},6058    {ELF::NT_AMD_HSA_HSAIL, "NT_AMD_HSA_HSAIL (AMD HSA HSAIL Properties)"},6059    {ELF::NT_AMD_HSA_ISA_VERSION, "NT_AMD_HSA_ISA_VERSION (AMD HSA ISA Version)"},6060    {ELF::NT_AMD_HSA_METADATA, "NT_AMD_HSA_METADATA (AMD HSA Metadata)"},6061    {ELF::NT_AMD_HSA_ISA_NAME, "NT_AMD_HSA_ISA_NAME (AMD HSA ISA Name)"},6062    {ELF::NT_AMD_PAL_METADATA, "NT_AMD_PAL_METADATA (AMD PAL Metadata)"},6063};6064 6065const NoteType AMDGPUNoteTypes[] = {6066    {ELF::NT_AMDGPU_METADATA, "NT_AMDGPU_METADATA (AMDGPU Metadata)"},6067};6068 6069const NoteType LLVMOMPOFFLOADNoteTypes[] = {6070    {ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION,6071     "NT_LLVM_OPENMP_OFFLOAD_VERSION (image format version)"},6072    {ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER,6073     "NT_LLVM_OPENMP_OFFLOAD_PRODUCER (producing toolchain)"},6074    {ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION,6075     "NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION (producing toolchain version)"},6076};6077 6078const NoteType AndroidNoteTypes[] = {6079    {ELF::NT_ANDROID_TYPE_IDENT, "NT_ANDROID_TYPE_IDENT"},6080    {ELF::NT_ANDROID_TYPE_KUSER, "NT_ANDROID_TYPE_KUSER"},6081    {ELF::NT_ANDROID_TYPE_MEMTAG,6082     "NT_ANDROID_TYPE_MEMTAG (Android memory tagging information)"},6083};6084 6085const NoteType CoreNoteTypes[] = {6086    {ELF::NT_PRSTATUS, "NT_PRSTATUS (prstatus structure)"},6087    {ELF::NT_FPREGSET, "NT_FPREGSET (floating point registers)"},6088    {ELF::NT_PRPSINFO, "NT_PRPSINFO (prpsinfo structure)"},6089    {ELF::NT_TASKSTRUCT, "NT_TASKSTRUCT (task structure)"},6090    {ELF::NT_AUXV, "NT_AUXV (auxiliary vector)"},6091    {ELF::NT_PSTATUS, "NT_PSTATUS (pstatus structure)"},6092    {ELF::NT_FPREGS, "NT_FPREGS (floating point registers)"},6093    {ELF::NT_PSINFO, "NT_PSINFO (psinfo structure)"},6094    {ELF::NT_LWPSTATUS, "NT_LWPSTATUS (lwpstatus_t structure)"},6095    {ELF::NT_LWPSINFO, "NT_LWPSINFO (lwpsinfo_t structure)"},6096    {ELF::NT_WIN32PSTATUS, "NT_WIN32PSTATUS (win32_pstatus structure)"},6097 6098    {ELF::NT_PPC_VMX, "NT_PPC_VMX (ppc Altivec registers)"},6099    {ELF::NT_PPC_VSX, "NT_PPC_VSX (ppc VSX registers)"},6100    {ELF::NT_PPC_TAR, "NT_PPC_TAR (ppc TAR register)"},6101    {ELF::NT_PPC_PPR, "NT_PPC_PPR (ppc PPR register)"},6102    {ELF::NT_PPC_DSCR, "NT_PPC_DSCR (ppc DSCR register)"},6103    {ELF::NT_PPC_EBB, "NT_PPC_EBB (ppc EBB registers)"},6104    {ELF::NT_PPC_PMU, "NT_PPC_PMU (ppc PMU registers)"},6105    {ELF::NT_PPC_TM_CGPR, "NT_PPC_TM_CGPR (ppc checkpointed GPR registers)"},6106    {ELF::NT_PPC_TM_CFPR,6107     "NT_PPC_TM_CFPR (ppc checkpointed floating point registers)"},6108    {ELF::NT_PPC_TM_CVMX,6109     "NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)"},6110    {ELF::NT_PPC_TM_CVSX, "NT_PPC_TM_CVSX (ppc checkpointed VSX registers)"},6111    {ELF::NT_PPC_TM_SPR, "NT_PPC_TM_SPR (ppc TM special purpose registers)"},6112    {ELF::NT_PPC_TM_CTAR, "NT_PPC_TM_CTAR (ppc checkpointed TAR register)"},6113    {ELF::NT_PPC_TM_CPPR, "NT_PPC_TM_CPPR (ppc checkpointed PPR register)"},6114    {ELF::NT_PPC_TM_CDSCR, "NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)"},6115 6116    {ELF::NT_386_TLS, "NT_386_TLS (x86 TLS information)"},6117    {ELF::NT_386_IOPERM, "NT_386_IOPERM (x86 I/O permissions)"},6118    {ELF::NT_X86_XSTATE, "NT_X86_XSTATE (x86 XSAVE extended state)"},6119 6120    {ELF::NT_S390_HIGH_GPRS, "NT_S390_HIGH_GPRS (s390 upper register halves)"},6121    {ELF::NT_S390_TIMER, "NT_S390_TIMER (s390 timer register)"},6122    {ELF::NT_S390_TODCMP, "NT_S390_TODCMP (s390 TOD comparator register)"},6123    {ELF::NT_S390_TODPREG, "NT_S390_TODPREG (s390 TOD programmable register)"},6124    {ELF::NT_S390_CTRS, "NT_S390_CTRS (s390 control registers)"},6125    {ELF::NT_S390_PREFIX, "NT_S390_PREFIX (s390 prefix register)"},6126    {ELF::NT_S390_LAST_BREAK,6127     "NT_S390_LAST_BREAK (s390 last breaking event address)"},6128    {ELF::NT_S390_SYSTEM_CALL,6129     "NT_S390_SYSTEM_CALL (s390 system call restart data)"},6130    {ELF::NT_S390_TDB, "NT_S390_TDB (s390 transaction diagnostic block)"},6131    {ELF::NT_S390_VXRS_LOW,6132     "NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)"},6133    {ELF::NT_S390_VXRS_HIGH, "NT_S390_VXRS_HIGH (s390 vector registers 16-31)"},6134    {ELF::NT_S390_GS_CB, "NT_S390_GS_CB (s390 guarded-storage registers)"},6135    {ELF::NT_S390_GS_BC,6136     "NT_S390_GS_BC (s390 guarded-storage broadcast control)"},6137 6138    {ELF::NT_ARM_VFP, "NT_ARM_VFP (arm VFP registers)"},6139    {ELF::NT_ARM_TLS, "NT_ARM_TLS (AArch TLS registers)"},6140    {ELF::NT_ARM_HW_BREAK,6141     "NT_ARM_HW_BREAK (AArch hardware breakpoint registers)"},6142    {ELF::NT_ARM_HW_WATCH,6143     "NT_ARM_HW_WATCH (AArch hardware watchpoint registers)"},6144    {ELF::NT_ARM_SVE, "NT_ARM_SVE (AArch64 SVE registers)"},6145    {ELF::NT_ARM_PAC_MASK,6146     "NT_ARM_PAC_MASK (AArch64 Pointer Authentication code masks)"},6147    {ELF::NT_ARM_TAGGED_ADDR_CTRL,6148     "NT_ARM_TAGGED_ADDR_CTRL (AArch64 Tagged Address Control)"},6149    {ELF::NT_ARM_SSVE, "NT_ARM_SSVE (AArch64 Streaming SVE registers)"},6150    {ELF::NT_ARM_ZA, "NT_ARM_ZA (AArch64 SME ZA registers)"},6151    {ELF::NT_ARM_ZT, "NT_ARM_ZT (AArch64 SME ZT registers)"},6152    {ELF::NT_ARM_FPMR, "NT_ARM_FPMR (AArch64 Floating Point Mode Register)"},6153    {ELF::NT_ARM_GCS, "NT_ARM_GCS (AArch64 Guarded Control Stack state)"},6154 6155    {ELF::NT_FILE, "NT_FILE (mapped files)"},6156    {ELF::NT_PRXFPREG, "NT_PRXFPREG (user_xfpregs structure)"},6157    {ELF::NT_SIGINFO, "NT_SIGINFO (siginfo_t data)"},6158};6159 6160template <class ELFT>6161StringRef getNoteTypeName(const typename ELFT::Note &Note, unsigned ELFType) {6162  uint32_t Type = Note.getType();6163  auto FindNote = [&](ArrayRef<NoteType> V) -> StringRef {6164    for (const NoteType &N : V)6165      if (N.ID == Type)6166        return N.Name;6167    return "";6168  };6169 6170  StringRef Name = Note.getName();6171  if (Name == "GNU")6172    return FindNote(GNUNoteTypes);6173  if (Name == "FreeBSD") {6174    if (ELFType == ELF::ET_CORE) {6175      // FreeBSD also places the generic core notes in the FreeBSD namespace.6176      StringRef Result = FindNote(FreeBSDCoreNoteTypes);6177      if (!Result.empty())6178        return Result;6179      return FindNote(CoreNoteTypes);6180    } else {6181      return FindNote(FreeBSDNoteTypes);6182    }6183  }6184  if (ELFType == ELF::ET_CORE && Name.starts_with("NetBSD-CORE")) {6185    StringRef Result = FindNote(NetBSDCoreNoteTypes);6186    if (!Result.empty())6187      return Result;6188    return FindNote(CoreNoteTypes);6189  }6190  if (ELFType == ELF::ET_CORE && Name.starts_with("OpenBSD")) {6191    // OpenBSD also places the generic core notes in the OpenBSD namespace.6192    StringRef Result = FindNote(OpenBSDCoreNoteTypes);6193    if (!Result.empty())6194      return Result;6195    return FindNote(CoreNoteTypes);6196  }6197  if (Name == "AMD")6198    return FindNote(AMDNoteTypes);6199  if (Name == "AMDGPU")6200    return FindNote(AMDGPUNoteTypes);6201  if (Name == "LLVMOMPOFFLOAD")6202    return FindNote(LLVMOMPOFFLOADNoteTypes);6203  if (Name == "Android")6204    return FindNote(AndroidNoteTypes);6205 6206  if (ELFType == ELF::ET_CORE)6207    return FindNote(CoreNoteTypes);6208  return FindNote(GenericNoteTypes);6209}6210 6211template <class ELFT>6212static void processNotesHelper(6213    const ELFDumper<ELFT> &Dumper,6214    llvm::function_ref<void(std::optional<StringRef>, typename ELFT::Off,6215                            typename ELFT::Addr, size_t)>6216        StartNotesFn,6217    llvm::function_ref<Error(const typename ELFT::Note &, bool)> ProcessNoteFn,6218    llvm::function_ref<void()> FinishNotesFn) {6219  const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();6220  bool IsCoreFile = Obj.getHeader().e_type == ELF::ET_CORE;6221 6222  ArrayRef<typename ELFT::Shdr> Sections = cantFail(Obj.sections());6223  if (!IsCoreFile && !Sections.empty()) {6224    for (const typename ELFT::Shdr &S : Sections) {6225      if (S.sh_type != SHT_NOTE)6226        continue;6227      StartNotesFn(expectedToStdOptional(Obj.getSectionName(S)), S.sh_offset,6228                   S.sh_size, S.sh_addralign);6229      Error Err = Error::success();6230      size_t I = 0;6231      for (const typename ELFT::Note Note : Obj.notes(S, Err)) {6232        if (Error E = ProcessNoteFn(Note, IsCoreFile))6233          Dumper.reportUniqueWarning(6234              "unable to read note with index " + Twine(I) + " from the " +6235              describe(Obj, S) + ": " + toString(std::move(E)));6236        ++I;6237      }6238      if (Err)6239        Dumper.reportUniqueWarning("unable to read notes from the " +6240                                   describe(Obj, S) + ": " +6241                                   toString(std::move(Err)));6242      FinishNotesFn();6243    }6244    return;6245  }6246 6247  Expected<ArrayRef<typename ELFT::Phdr>> PhdrsOrErr = Obj.program_headers();6248  if (!PhdrsOrErr) {6249    Dumper.reportUniqueWarning(6250        "unable to read program headers to locate the PT_NOTE segment: " +6251        toString(PhdrsOrErr.takeError()));6252    return;6253  }6254 6255  for (size_t I = 0, E = (*PhdrsOrErr).size(); I != E; ++I) {6256    const typename ELFT::Phdr &P = (*PhdrsOrErr)[I];6257    if (P.p_type != PT_NOTE)6258      continue;6259    StartNotesFn(/*SecName=*/std::nullopt, P.p_offset, P.p_filesz, P.p_align);6260    Error Err = Error::success();6261    size_t Index = 0;6262    for (const typename ELFT::Note Note : Obj.notes(P, Err)) {6263      if (Error E = ProcessNoteFn(Note, IsCoreFile))6264        Dumper.reportUniqueWarning("unable to read note with index " +6265                                   Twine(Index) +6266                                   " from the PT_NOTE segment with index " +6267                                   Twine(I) + ": " + toString(std::move(E)));6268      ++Index;6269    }6270    if (Err)6271      Dumper.reportUniqueWarning(6272          "unable to read notes from the PT_NOTE segment with index " +6273          Twine(I) + ": " + toString(std::move(Err)));6274    FinishNotesFn();6275  }6276}6277 6278template <class ELFT> void GNUELFDumper<ELFT>::printNotes() {6279  size_t Align = 0;6280  bool IsFirstHeader = true;6281  auto PrintHeader = [&](std::optional<StringRef> SecName,6282                         const typename ELFT::Off Offset,6283                         const typename ELFT::Addr Size, size_t Al) {6284    Align = std::max<size_t>(Al, 4);6285    // Print a newline between notes sections to match GNU readelf.6286    if (!IsFirstHeader) {6287      OS << '\n';6288    } else {6289      IsFirstHeader = false;6290    }6291 6292    OS << "Displaying notes found ";6293 6294    if (SecName)6295      OS << "in: " << *SecName << "\n";6296    else6297      OS << "at file offset " << format_hex(Offset, 10) << " with length "6298         << format_hex(Size, 10) << ":\n";6299 6300    OS << "  Owner                Data size \tDescription\n";6301  };6302 6303  auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {6304    StringRef Name = Note.getName();6305    ArrayRef<uint8_t> Descriptor = Note.getDesc(Align);6306    Elf_Word Type = Note.getType();6307 6308    // Print the note owner/type.6309    OS << "  " << left_justify(Name, 20) << ' '6310       << format_hex(Descriptor.size(), 10) << '\t';6311 6312    StringRef NoteType =6313        getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type);6314    if (!NoteType.empty())6315      OS << NoteType << '\n';6316    else6317      OS << "Unknown note type: (" << format_hex(Type, 10) << ")\n";6318 6319    const typename ELFT::Half EMachine = this->Obj.getHeader().e_machine;6320 6321    // Print the description, or fallback to printing raw bytes for unknown6322    // owners/if we fail to pretty-print the contents.6323    if (Name == "GNU") {6324      if (printGNUNote<ELFT>(OS, Type, Descriptor, EMachine))6325        return Error::success();6326    } else if (Name == "FreeBSD") {6327      if (std::optional<FreeBSDNote> N =6328              getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {6329        OS << "    " << N->Type << ": " << N->Value << '\n';6330        return Error::success();6331      }6332    } else if (Name == "AMD") {6333      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);6334      if (!N.Type.empty()) {6335        OS << "    " << N.Type << ":\n        " << N.Value << '\n';6336        return Error::success();6337      }6338    } else if (Name == "AMDGPU") {6339      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);6340      if (!N.Type.empty()) {6341        OS << "    " << N.Type << ":\n        " << N.Value << '\n';6342        return Error::success();6343      }6344    } else if (Name == "LLVMOMPOFFLOAD") {6345      if (printLLVMOMPOFFLOADNote<ELFT>(OS, Type, Descriptor))6346        return Error::success();6347    } else if (Name == "CORE") {6348      if (Type == ELF::NT_FILE) {6349        DataExtractor DescExtractor(6350            Descriptor, ELFT::Endianness == llvm::endianness::little,6351            sizeof(Elf_Addr));6352        if (Expected<CoreNote> NoteOrErr = readCoreNote(DescExtractor)) {6353          printCoreNote<ELFT>(OS, *NoteOrErr);6354          return Error::success();6355        } else {6356          return NoteOrErr.takeError();6357        }6358      }6359    } else if (Name == "Android") {6360      if (printAndroidNote(OS, Type, Descriptor))6361        return Error::success();6362    }6363    if (!Descriptor.empty()) {6364      OS << "   description data:";6365      for (uint8_t B : Descriptor)6366        OS << " " << format("%02x", B);6367      OS << '\n';6368    }6369    return Error::success();6370  };6371 6372  processNotesHelper(*this, /*StartNotesFn=*/PrintHeader,6373                     /*ProcessNoteFn=*/ProcessNote, /*FinishNotesFn=*/[]() {});6374}6375 6376template <class ELFT>6377ArrayRef<uint8_t>6378ELFDumper<ELFT>::getMemtagGlobalsSectionContents(uint64_t ExpectedAddr) {6379  for (const typename ELFT::Shdr &Sec : cantFail(Obj.sections())) {6380    if (Sec.sh_type != SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC)6381      continue;6382    if (Sec.sh_addr != ExpectedAddr) {6383      reportUniqueWarning(6384          "SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section was unexpectedly at 0x" +6385          Twine::utohexstr(Sec.sh_addr) +6386          ", when DT_AARCH64_MEMTAG_GLOBALS says it should be at 0x" +6387          Twine::utohexstr(ExpectedAddr));6388      return ArrayRef<uint8_t>();6389    }6390    Expected<ArrayRef<uint8_t>> Contents = Obj.getSectionContents(Sec);6391    if (auto E = Contents.takeError()) {6392      reportUniqueWarning(6393          "couldn't get SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section contents: " +6394          toString(std::move(E)));6395      return ArrayRef<uint8_t>();6396    }6397    return Contents.get();6398  }6399  return ArrayRef<uint8_t>();6400}6401 6402// Reserve the lower three bits of the first byte of the step distance when6403// encoding the memtag descriptors. Found to be the best overall size tradeoff6404// when compiling Android T with full MTE globals enabled.6405constexpr uint64_t MemtagStepVarintReservedBits = 3;6406constexpr uint64_t MemtagGranuleSize = 16;6407 6408template <typename ELFT> void ELFDumper<ELFT>::printMemtag() {6409  if (Obj.getHeader().e_machine != EM_AARCH64) return;6410  std::vector<std::pair<std::string, std::string>> DynamicEntries;6411  uint64_t MemtagGlobalsSz = 0;6412  uint64_t MemtagGlobals = 0;6413  for (const typename ELFT::Dyn &Entry : dynamic_table()) {6414    uintX_t Tag = Entry.getTag();6415    switch (Tag) {6416    case DT_AARCH64_MEMTAG_GLOBALSSZ:6417      MemtagGlobalsSz = Entry.getVal();6418      DynamicEntries.emplace_back(Obj.getDynamicTagAsString(Tag),6419                                  getDynamicEntry(Tag, Entry.getVal()));6420      break;6421    case DT_AARCH64_MEMTAG_GLOBALS:6422      MemtagGlobals = Entry.getVal();6423      DynamicEntries.emplace_back(Obj.getDynamicTagAsString(Tag),6424                                  getDynamicEntry(Tag, Entry.getVal()));6425      break;6426    case DT_AARCH64_MEMTAG_MODE:6427    case DT_AARCH64_MEMTAG_HEAP:6428    case DT_AARCH64_MEMTAG_STACK:6429      DynamicEntries.emplace_back(Obj.getDynamicTagAsString(Tag),6430                                  getDynamicEntry(Tag, Entry.getVal()));6431      break;6432    }6433  }6434 6435  ArrayRef<uint8_t> AndroidNoteDesc;6436  auto FindAndroidNote = [&](const Elf_Note &Note, bool IsCore) -> Error {6437    if (Note.getName() == "Android" &&6438        Note.getType() == ELF::NT_ANDROID_TYPE_MEMTAG)6439      AndroidNoteDesc = Note.getDesc(4);6440    return Error::success();6441  };6442 6443  processNotesHelper(6444      *this,6445      /*StartNotesFn=*/6446      [](std::optional<StringRef>, const typename ELFT::Off,6447         const typename ELFT::Addr, size_t) {},6448      /*ProcessNoteFn=*/FindAndroidNote, /*FinishNotesFn=*/[]() {});6449 6450  ArrayRef<uint8_t> Contents = getMemtagGlobalsSectionContents(MemtagGlobals);6451  if (Contents.size() != MemtagGlobalsSz) {6452    reportUniqueWarning(6453        "mismatch between DT_AARCH64_MEMTAG_GLOBALSSZ (0x" +6454        Twine::utohexstr(MemtagGlobalsSz) +6455        ") and SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section size (0x" +6456        Twine::utohexstr(Contents.size()) + ")");6457    Contents = ArrayRef<uint8_t>();6458  }6459 6460  std::vector<std::pair<uint64_t, uint64_t>> GlobalDescriptors;6461  uint64_t Address = 0;6462  // See the AArch64 MemtagABI document for a description of encoding scheme:6463  // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#83encoding-of-sht_aarch64_memtag_globals_dynamic6464  for (size_t I = 0; I < Contents.size();) {6465    const char *Error = nullptr;6466    unsigned DecodedBytes = 0;6467    uint64_t Value = decodeULEB128(Contents.data() + I, &DecodedBytes,6468                                   Contents.end(), &Error);6469    I += DecodedBytes;6470    if (Error) {6471      reportUniqueWarning(6472          "error decoding distance uleb, " + Twine(DecodedBytes) +6473          " byte(s) into SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC: " + Twine(Error));6474      GlobalDescriptors.clear();6475      break;6476    }6477    uint64_t Distance = Value >> MemtagStepVarintReservedBits;6478    uint64_t GranulesToTag = Value & ((1 << MemtagStepVarintReservedBits) - 1);6479    if (GranulesToTag == 0) {6480      GranulesToTag = decodeULEB128(Contents.data() + I, &DecodedBytes,6481                                    Contents.end(), &Error) +6482                      1;6483      I += DecodedBytes;6484      if (Error) {6485        reportUniqueWarning(6486            "error decoding size-only uleb, " + Twine(DecodedBytes) +6487            " byte(s) into SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC: " + Twine(Error));6488        GlobalDescriptors.clear();6489        break;6490      }6491    }6492    Address += Distance * MemtagGranuleSize;6493    GlobalDescriptors.emplace_back(Address, GranulesToTag * MemtagGranuleSize);6494    Address += GranulesToTag * MemtagGranuleSize;6495  }6496 6497  printMemtag(DynamicEntries, AndroidNoteDesc, GlobalDescriptors);6498}6499 6500template <typename ELFT>6501void ELFDumper<ELFT>::printSFrameHeader(6502    const SFrameParser<ELFT::Endianness> &Parser) {6503  DictScope HeaderScope(W, "Header");6504 6505  const sframe::Preamble<ELFT::Endianness> &Preamble = Parser.getPreamble();6506  W.printHex("Magic", Preamble.Magic.value());6507  W.printEnum("Version", Preamble.Version.value(), sframe::getVersions());6508  W.printFlags("Flags", Preamble.Flags.value(), sframe::getFlags());6509 6510  const sframe::Header<ELFT::Endianness> &Header = Parser.getHeader();6511  W.printEnum("ABI", Header.ABIArch.value(), sframe::getABIs());6512 6513  W.printNumber(("CFA fixed FP offset" +6514                 Twine(Parser.usesFixedFPOffset() ? "" : " (unused)"))6515                    .str(),6516                Header.CFAFixedFPOffset.value());6517 6518  W.printNumber(("CFA fixed RA offset" +6519                 Twine(Parser.usesFixedRAOffset() ? "" : " (unused)"))6520                    .str(),6521                Header.CFAFixedRAOffset.value());6522 6523  W.printNumber("Auxiliary header length", Header.AuxHdrLen.value());6524  W.printNumber("Num FDEs", Header.NumFDEs.value());6525  W.printNumber("Num FREs", Header.NumFREs.value());6526  W.printNumber("FRE subsection length", Header.FRELen.value());6527  W.printNumber("FDE subsection offset", Header.FDEOff.value());6528  W.printNumber("FRE subsection offset", Header.FREOff.value());6529 6530  if (Expected<ArrayRef<uint8_t>> Aux = Parser.getAuxHeader())6531    W.printHexList("Auxiliary header", *Aux);6532  else6533    reportUniqueWarning(Aux.takeError());6534}6535 6536template <typename ELFT>6537void ELFDumper<ELFT>::printSFrameFDEs(6538    const SFrameParser<ELFT::Endianness> &Parser,6539    ArrayRef<Relocation<ELFT>> Relocations, const Elf_Shdr *RelocSymTab) {6540  typename SFrameParser<ELFT::Endianness>::FDERange FDEs;6541  if (Error Err = Parser.fdes().moveInto(FDEs)) {6542    reportUniqueWarning(std::move(Err));6543    return;6544  }6545 6546  ListScope IndexScope(W, "Function Index");6547  for (auto It = FDEs.begin(); It != FDEs.end(); ++It) {6548    DictScope FDEScope(6549        W,6550        formatv("FuncDescEntry [{0}]", std::distance(FDEs.begin(), It)).str());6551 6552    uint64_t FDEStartAddress =6553        getAndPrintSFrameFDEStartAddress(Parser, It, Relocations, RelocSymTab);6554    W.printHex("Size", It->Size);6555    W.printHex("Start FRE Offset", It->StartFREOff);6556    W.printNumber("Num FREs", It->NumFREs);6557 6558    {6559      DictScope InfoScope(W, "Info");6560      W.printEnum("FRE Type", It->Info.getFREType(), sframe::getFRETypes());6561      W.printEnum("FDE Type", It->Info.getFDEType(), sframe::getFDETypes());6562      switch (Parser.getHeader().ABIArch) {6563      case sframe::ABI::AArch64EndianBig:6564      case sframe::ABI::AArch64EndianLittle:6565        W.printEnum("PAuth Key",6566                    sframe::AArch64PAuthKey(It->Info.getPAuthKey()),6567                    sframe::getAArch64PAuthKeys());6568        break;6569      case sframe::ABI::AMD64EndianLittle:6570        // unused6571        break;6572      }6573 6574      W.printHex("Raw", It->Info.Info);6575    }6576 6577    W.printHex(6578        ("Repetitive block size" +6579         Twine(It->Info.getFDEType() == sframe::FDEType::PCMask ? ""6580                                                                : " (unused)"))6581            .str(),6582        It->RepSize);6583 6584    W.printHex("Padding2", It->Padding2);6585 6586    ListScope FREListScope(W, "FREs");6587    Error Err = Error::success();6588    for (const typename SFrameParser<ELFT::Endianness>::FrameRowEntry &FRE :6589         Parser.fres(*It, Err)) {6590      DictScope FREScope(W, "Frame Row Entry");6591      W.printHex("Start Address",6592                 (It->Info.getFDEType() == sframe::FDEType::PCInc6593                      ? FDEStartAddress6594                      : 0) +6595                     FRE.StartAddress);6596      W.printBoolean("Return Address Signed", FRE.Info.isReturnAddressSigned());6597      W.printEnum("Offset Size", FRE.Info.getOffsetSize(),6598                  sframe::getFREOffsets());6599      W.printEnum("Base Register", FRE.Info.getBaseRegister(),6600                  sframe::getBaseRegisters());6601      if (std::optional<int32_t> Off = Parser.getCFAOffset(FRE))6602        W.printNumber("CFA Offset", *Off);6603      if (std::optional<int32_t> Off = Parser.getRAOffset(FRE))6604        W.printNumber("RA Offset", *Off);6605      if (std::optional<int32_t> Off = Parser.getFPOffset(FRE))6606        W.printNumber("FP Offset", *Off);6607      if (ArrayRef<int32_t> Offs = Parser.getExtraOffsets(FRE); !Offs.empty())6608        W.printList("Extra Offsets", Offs);6609    }6610    if (Err)6611      reportUniqueWarning(std::move(Err));6612  }6613}6614 6615template <typename ELFT>6616uint64_t ELFDumper<ELFT>::getAndPrintSFrameFDEStartAddress(6617    const SFrameParser<ELFT::Endianness> &Parser,6618    const typename SFrameParser<ELFT::Endianness>::FDERange::iterator FDE,6619    ArrayRef<Relocation<ELFT>> Relocations, const Elf_Shdr *RelocSymTab) {6620  uint64_t Address = Parser.getAbsoluteStartAddress(FDE);6621  uint64_t Offset = Parser.offsetOf(FDE);6622 6623  auto Reloc = llvm::lower_bound(6624      Relocations, Offset, [](auto R, uint64_t O) { return R.Offset < O; });6625  if (Reloc == Relocations.end() || Reloc->Offset != Offset) {6626    W.printHex("PC", Address);6627  } else if (std::next(Reloc) != Relocations.end() &&6628             std::next(Reloc)->Offset == Offset) {6629    reportUniqueWarning(6630        formatv("more than one relocation at offset {0:x+}", Offset));6631    W.printHex("PC", Address);6632  } else if (Expected<RelSymbol<ELFT>> RelSym =6633                 getRelocationTarget(*Reloc, RelocSymTab);6634             !RelSym) {6635    reportUniqueWarning(RelSym.takeError());6636    W.printHex("PC", Address);6637  } else {6638    // Exactly one relocation at the given offset. Print it.6639    DictScope PCScope(W, "PC");6640    SmallString<32> RelocName;6641    Obj.getRelocationTypeName(Reloc->Type, RelocName);6642    W.printString("Relocation", RelocName);6643    W.printString("Symbol Name", RelSym->Name);6644    Address = FDE->StartAddress + Reloc->Addend.value_or(0);6645    W.printHex("Start Address", Address);6646  }6647  return Address;6648}6649 6650template <typename ELFT>6651void ELFDumper<ELFT>::printSectionsAsSFrame(ArrayRef<std::string> Sections) {6652  constexpr endianness E = ELFT::Endianness;6653 6654  for (object::SectionRef Section :6655       getSectionRefsByNameOrIndex(ObjF, Sections)) {6656    // Validity of sections names checked in getSectionRefsByNameOrIndex.6657    StringRef SectionName = cantFail(Section.getName());6658 6659    DictScope SectionScope(W,6660                           formatv("SFrame section '{0}'", SectionName).str());6661 6662    StringRef SectionContent;6663    if (Error Err = Section.getContents().moveInto(SectionContent)) {6664      reportUniqueWarning(std::move(Err));6665      continue;6666    }6667 6668    Expected<object::SFrameParser<E>> Parser = object::SFrameParser<E>::create(6669        arrayRefFromStringRef(SectionContent), Section.getAddress());6670    if (!Parser) {6671      reportUniqueWarning("invalid sframe section: " +6672                          toString(Parser.takeError()));6673      continue;6674    }6675 6676    const Elf_Shdr *ELFSection = ObjF.getSection(Section.getRawDataRefImpl());6677    MapVector<const Elf_Shdr *, const Elf_Shdr *> RelocationMap;6678    if (Error Err = Obj.getSectionAndRelocations(6679                           [&](const Elf_Shdr &S) { return &S == ELFSection; })6680                        .moveInto(RelocationMap)) {6681      reportUniqueWarning(std::move(Err));6682    }6683 6684    std::vector<Relocation<ELFT>> Relocations;6685    const Elf_Shdr *RelocSymTab = nullptr;6686    if (const Elf_Shdr *RelocSection = RelocationMap.lookup(ELFSection)) {6687      forEachRelocationDo(*RelocSection,6688                          [&](const Relocation<ELFT> &R, unsigned Ndx,6689                              const Elf_Shdr &Sec, const Elf_Shdr *SymTab) {6690                            RelocSymTab = SymTab;6691                            Relocations.push_back(R);6692                          });6693      llvm::stable_sort(Relocations, [](const auto &LHS, const auto &RHS) {6694        return LHS.Offset < RHS.Offset;6695      });6696    }6697 6698    printSFrameHeader(*Parser);6699    printSFrameFDEs(*Parser, Relocations, RelocSymTab);6700  }6701}6702 6703template <class ELFT> void GNUELFDumper<ELFT>::printELFLinkerOptions() {6704  OS << "printELFLinkerOptions not implemented!\n";6705}6706 6707template <class ELFT>6708void ELFDumper<ELFT>::printDependentLibsHelper(6709    function_ref<void(const Elf_Shdr &)> OnSectionStart,6710    function_ref<void(StringRef, uint64_t)> OnLibEntry) {6711  auto Warn = [this](unsigned SecNdx, StringRef Msg) {6712    this->reportUniqueWarning("SHT_LLVM_DEPENDENT_LIBRARIES section at index " +6713                              Twine(SecNdx) + " is broken: " + Msg);6714  };6715 6716  unsigned I = -1;6717  for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) {6718    ++I;6719    if (Shdr.sh_type != ELF::SHT_LLVM_DEPENDENT_LIBRARIES)6720      continue;6721 6722    OnSectionStart(Shdr);6723 6724    Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Shdr);6725    if (!ContentsOrErr) {6726      Warn(I, toString(ContentsOrErr.takeError()));6727      continue;6728    }6729 6730    ArrayRef<uint8_t> Contents = *ContentsOrErr;6731    if (!Contents.empty() && Contents.back() != 0) {6732      Warn(I, "the content is not null-terminated");6733      continue;6734    }6735 6736    for (const uint8_t *I = Contents.begin(), *E = Contents.end(); I < E;) {6737      StringRef Lib((const char *)I);6738      OnLibEntry(Lib, I - Contents.begin());6739      I += Lib.size() + 1;6740    }6741  }6742}6743 6744template <class ELFT>6745void ELFDumper<ELFT>::forEachRelocationDo(6746    const Elf_Shdr &Sec,6747    llvm::function_ref<void(const Relocation<ELFT> &, unsigned,6748                            const Elf_Shdr &, const Elf_Shdr *)>6749        RelRelaFn) {6750  auto Warn = [&](Error &&E,6751                  const Twine &Prefix = "unable to read relocations from") {6752    this->reportUniqueWarning(Prefix + " " + describe(Sec) + ": " +6753                              toString(std::move(E)));6754  };6755 6756  // SHT_RELR/SHT_ANDROID_RELR/SHT_AARCH64_AUTH_RELR sections do not have an6757  // associated symbol table. For them we should not treat the value of the6758  // sh_link field as an index of a symbol table.6759  const Elf_Shdr *SymTab;6760  if (Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_RELR &&6761      !(Obj.getHeader().e_machine == EM_AARCH64 &&6762        Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR)) {6763    Expected<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Sec.sh_link);6764    if (!SymTabOrErr) {6765      Warn(SymTabOrErr.takeError(), "unable to locate a symbol table for");6766      return;6767    }6768    SymTab = *SymTabOrErr;6769  }6770 6771  unsigned RelNdx = 0;6772  const bool IsMips64EL = this->Obj.isMips64EL();6773  switch (Sec.sh_type) {6774  case ELF::SHT_REL:6775    if (Expected<Elf_Rel_Range> RangeOrErr = Obj.rels(Sec)) {6776      for (const Elf_Rel &R : *RangeOrErr)6777        RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);6778    } else {6779      Warn(RangeOrErr.takeError());6780    }6781    break;6782  case ELF::SHT_RELA:6783    if (Expected<Elf_Rela_Range> RangeOrErr = Obj.relas(Sec)) {6784      for (const Elf_Rela &R : *RangeOrErr)6785        RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);6786    } else {6787      Warn(RangeOrErr.takeError());6788    }6789    break;6790  case ELF::SHT_AARCH64_AUTH_RELR:6791    if (Obj.getHeader().e_machine != EM_AARCH64)6792      break;6793    [[fallthrough]];6794  case ELF::SHT_RELR:6795  case ELF::SHT_ANDROID_RELR: {6796    Expected<Elf_Relr_Range> RangeOrErr = Obj.relrs(Sec);6797    if (!RangeOrErr) {6798      Warn(RangeOrErr.takeError());6799      break;6800    }6801 6802    for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr))6803      RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec,6804                /*SymTab=*/nullptr);6805    break;6806  }6807  case ELF::SHT_CREL: {6808    if (auto RelsOrRelas = Obj.crels(Sec)) {6809      for (const Elf_Rel &R : RelsOrRelas->first)6810        RelRelaFn(Relocation<ELFT>(R, false), RelNdx++, Sec, SymTab);6811      for (const Elf_Rela &R : RelsOrRelas->second)6812        RelRelaFn(Relocation<ELFT>(R, false), RelNdx++, Sec, SymTab);6813    } else {6814      Warn(RelsOrRelas.takeError());6815    }6816    break;6817  }6818  case ELF::SHT_ANDROID_REL:6819  case ELF::SHT_ANDROID_RELA:6820    if (Expected<std::vector<Elf_Rela>> RelasOrErr = Obj.android_relas(Sec)) {6821      for (const Elf_Rela &R : *RelasOrErr)6822        RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);6823    } else {6824      Warn(RelasOrErr.takeError());6825    }6826    break;6827  }6828}6829 6830template <class ELFT>6831StringRef ELFDumper<ELFT>::getPrintableSectionName(const Elf_Shdr &Sec) const {6832  StringRef Name = "<?>";6833  if (Expected<StringRef> SecNameOrErr =6834          Obj.getSectionName(Sec, this->WarningHandler))6835    Name = *SecNameOrErr;6836  else6837    this->reportUniqueWarning("unable to get the name of " + describe(Sec) +6838                              ": " + toString(SecNameOrErr.takeError()));6839  return Name;6840}6841 6842template <class ELFT> void GNUELFDumper<ELFT>::printDependentLibs() {6843  bool SectionStarted = false;6844  struct NameOffset {6845    StringRef Name;6846    uint64_t Offset;6847  };6848  std::vector<NameOffset> SecEntries;6849  NameOffset Current;6850  auto PrintSection = [&]() {6851    OS << "Dependent libraries section " << Current.Name << " at offset "6852       << format_hex(Current.Offset, 1) << " contains " << SecEntries.size()6853       << " entries:\n";6854    for (NameOffset Entry : SecEntries)6855      OS << "  [" << format("%6" PRIx64, Entry.Offset) << "]  " << Entry.Name6856         << "\n";6857    OS << "\n";6858    SecEntries.clear();6859  };6860 6861  auto OnSectionStart = [&](const Elf_Shdr &Shdr) {6862    if (SectionStarted)6863      PrintSection();6864    SectionStarted = true;6865    Current.Offset = Shdr.sh_offset;6866    Current.Name = this->getPrintableSectionName(Shdr);6867  };6868  auto OnLibEntry = [&](StringRef Lib, uint64_t Offset) {6869    SecEntries.push_back(NameOffset{Lib, Offset});6870  };6871 6872  this->printDependentLibsHelper(OnSectionStart, OnLibEntry);6873  if (SectionStarted)6874    PrintSection();6875}6876 6877template <class ELFT>6878SmallVector<uint32_t> ELFDumper<ELFT>::getSymbolIndexesForFunctionAddress(6879    uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec) {6880  SmallVector<uint32_t> SymbolIndexes;6881  if (!this->AddressToIndexMap) {6882    // Populate the address to index map upon the first invocation of this6883    // function.6884    this->AddressToIndexMap.emplace();6885    if (this->DotSymtabSec) {6886      if (Expected<Elf_Sym_Range> SymsOrError =6887              Obj.symbols(this->DotSymtabSec)) {6888        uint32_t Index = (uint32_t)-1;6889        for (const Elf_Sym &Sym : *SymsOrError) {6890          ++Index;6891 6892          if (Sym.st_shndx == ELF::SHN_UNDEF || Sym.getType() != ELF::STT_FUNC)6893            continue;6894 6895          Expected<uint64_t> SymAddrOrErr =6896              ObjF.toSymbolRef(this->DotSymtabSec, Index).getAddress();6897          if (!SymAddrOrErr) {6898            std::string Name = this->getStaticSymbolName(Index);6899            reportUniqueWarning("unable to get address of symbol '" + Name +6900                                "': " + toString(SymAddrOrErr.takeError()));6901            return SymbolIndexes;6902          }6903 6904          (*this->AddressToIndexMap)[*SymAddrOrErr].push_back(Index);6905        }6906      } else {6907        reportUniqueWarning("unable to read the symbol table: " +6908                            toString(SymsOrError.takeError()));6909      }6910    }6911  }6912 6913  auto Symbols = this->AddressToIndexMap->find(SymValue);6914  if (Symbols == this->AddressToIndexMap->end())6915    return SymbolIndexes;6916 6917  for (uint32_t Index : Symbols->second) {6918    // Check if the symbol is in the right section. FunctionSec == None6919    // means "any section".6920    if (FunctionSec) {6921      const Elf_Sym &Sym = *cantFail(Obj.getSymbol(this->DotSymtabSec, Index));6922      if (Expected<const Elf_Shdr *> SecOrErr =6923              Obj.getSection(Sym, this->DotSymtabSec,6924                             this->getShndxTable(this->DotSymtabSec))) {6925        if (*FunctionSec != *SecOrErr)6926          continue;6927      } else {6928        std::string Name = this->getStaticSymbolName(Index);6929        // Note: it is impossible to trigger this error currently, it is6930        // untested.6931        reportUniqueWarning("unable to get section of symbol '" + Name +6932                            "': " + toString(SecOrErr.takeError()));6933        return SymbolIndexes;6934      }6935    }6936 6937    SymbolIndexes.push_back(Index);6938  }6939 6940  return SymbolIndexes;6941}6942 6943template <class ELFT>6944bool ELFDumper<ELFT>::printFunctionStackSize(6945    uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec,6946    const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) {6947  SmallVector<uint32_t> FuncSymIndexes =6948      this->getSymbolIndexesForFunctionAddress(SymValue, FunctionSec);6949  if (FuncSymIndexes.empty())6950    reportUniqueWarning(6951        "could not identify function symbol for stack size entry in " +6952        describe(StackSizeSec));6953 6954  // Extract the size. The expectation is that Offset is pointing to the right6955  // place, i.e. past the function address.6956  Error Err = Error::success();6957  uint64_t StackSize = Data.getULEB128(Offset, &Err);6958  if (Err) {6959    reportUniqueWarning("could not extract a valid stack size from " +6960                        describe(StackSizeSec) + ": " +6961                        toString(std::move(Err)));6962    return false;6963  }6964 6965  if (FuncSymIndexes.empty()) {6966    printStackSizeEntry(StackSize, {"?"});6967  } else {6968    SmallVector<std::string> FuncSymNames;6969    for (uint32_t Index : FuncSymIndexes)6970      FuncSymNames.push_back(this->getStaticSymbolName(Index));6971    printStackSizeEntry(StackSize, FuncSymNames);6972  }6973 6974  return true;6975}6976 6977template <class ELFT>6978void GNUELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,6979                                             ArrayRef<std::string> FuncNames) {6980  OS.PadToColumn(2);6981  OS << format_decimal(Size, 11);6982  OS.PadToColumn(18);6983 6984  OS << join(FuncNames.begin(), FuncNames.end(), ", ") << "\n";6985}6986 6987template <class ELFT>6988void ELFDumper<ELFT>::printStackSize(const Relocation<ELFT> &R,6989                                     const Elf_Shdr &RelocSec, unsigned Ndx,6990                                     const Elf_Shdr *SymTab,6991                                     const Elf_Shdr *FunctionSec,6992                                     const Elf_Shdr &StackSizeSec,6993                                     const RelocationResolver &Resolver,6994                                     DataExtractor Data) {6995  // This function ignores potentially erroneous input, unless it is directly6996  // related to stack size reporting.6997  const Elf_Sym *Sym = nullptr;6998  Expected<RelSymbol<ELFT>> TargetOrErr = this->getRelocationTarget(R, SymTab);6999  if (!TargetOrErr)7000    reportUniqueWarning("unable to get the target of relocation with index " +7001                        Twine(Ndx) + " in " + describe(RelocSec) + ": " +7002                        toString(TargetOrErr.takeError()));7003  else7004    Sym = TargetOrErr->Sym;7005 7006  uint64_t RelocSymValue = 0;7007  if (Sym) {7008    Expected<const Elf_Shdr *> SectionOrErr =7009        this->Obj.getSection(*Sym, SymTab, this->getShndxTable(SymTab));7010    if (!SectionOrErr) {7011      reportUniqueWarning(7012          "cannot identify the section for relocation symbol '" +7013          (*TargetOrErr).Name + "': " + toString(SectionOrErr.takeError()));7014    } else if (*SectionOrErr != FunctionSec) {7015      reportUniqueWarning("relocation symbol '" + (*TargetOrErr).Name +7016                          "' is not in the expected section");7017      // Pretend that the symbol is in the correct section and report its7018      // stack size anyway.7019      FunctionSec = *SectionOrErr;7020    }7021 7022    RelocSymValue = Sym->st_value;7023  }7024 7025  uint64_t Offset = R.Offset;7026  if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {7027    reportUniqueWarning("found invalid relocation offset (0x" +7028                        Twine::utohexstr(Offset) + ") into " +7029                        describe(StackSizeSec) +7030                        " while trying to extract a stack size entry");7031    return;7032  }7033 7034  uint64_t SymValue = Resolver(R.Type, Offset, RelocSymValue,7035                               Data.getAddress(&Offset), R.Addend.value_or(0));7036  this->printFunctionStackSize(SymValue, FunctionSec, StackSizeSec, Data,7037                               &Offset);7038}7039 7040template <class ELFT>7041void ELFDumper<ELFT>::printNonRelocatableStackSizes(7042    std::function<void()> PrintHeader) {7043  // This function ignores potentially erroneous input, unless it is directly7044  // related to stack size reporting.7045  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {7046    if (this->getPrintableSectionName(Sec) != ".stack_sizes")7047      continue;7048    PrintHeader();7049    ArrayRef<uint8_t> Contents =7050        unwrapOrError(this->FileName, Obj.getSectionContents(Sec));7051    DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr));7052    uint64_t Offset = 0;7053    while (Offset < Contents.size()) {7054      // The function address is followed by a ULEB representing the stack7055      // size. Check for an extra byte before we try to process the entry.7056      if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {7057        reportUniqueWarning(7058            describe(Sec) +7059            " ended while trying to extract a stack size entry");7060        break;7061      }7062      uint64_t SymValue = Data.getAddress(&Offset);7063      if (!printFunctionStackSize(SymValue, /*FunctionSec=*/std::nullopt, Sec,7064                                  Data, &Offset))7065        break;7066    }7067  }7068}7069 7070template <class ELFT>7071void ELFDumper<ELFT>::printRelocatableStackSizes(7072    std::function<void()> PrintHeader) {7073  // Build a map between stack size sections and their corresponding relocation7074  // sections.7075  auto IsMatch = [&](const Elf_Shdr &Sec) -> bool {7076    StringRef SectionName;7077    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Sec))7078      SectionName = *NameOrErr;7079    else7080      consumeError(NameOrErr.takeError());7081 7082    return SectionName == ".stack_sizes";7083  };7084 7085  Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>>7086      StackSizeRelocMapOrErr = Obj.getSectionAndRelocations(IsMatch);7087  if (!StackSizeRelocMapOrErr) {7088    reportUniqueWarning("unable to get stack size map section(s): " +7089                        toString(StackSizeRelocMapOrErr.takeError()));7090    return;7091  }7092 7093  for (const auto &StackSizeMapEntry : *StackSizeRelocMapOrErr) {7094    PrintHeader();7095    const Elf_Shdr *StackSizesELFSec = StackSizeMapEntry.first;7096    const Elf_Shdr *RelocSec = StackSizeMapEntry.second;7097 7098    // Warn about stack size sections without a relocation section.7099    if (!RelocSec) {7100      reportWarning(createError(".stack_sizes (" + describe(*StackSizesELFSec) +7101                                ") does not have a corresponding "7102                                "relocation section"),7103                    FileName);7104      continue;7105    }7106 7107    // We might end up with relocations in CREL here. If we do, report a7108    // warning since we do not currently support them.7109    if (RelocSec->sh_type == ELF::SHT_CREL) {7110      reportWarning(createError(".stack_sizes (" + describe(*StackSizesELFSec) +7111                                ") has a corresponding CREL relocation "7112                                "section, which is not currently supported"),7113                    FileName);7114      continue;7115    }7116 7117    // A .stack_sizes section header's sh_link field is supposed to point7118    // to the section that contains the functions whose stack sizes are7119    // described in it.7120    const Elf_Shdr *FunctionSec = unwrapOrError(7121        this->FileName, Obj.getSection(StackSizesELFSec->sh_link));7122 7123    SupportsRelocation IsSupportedFn;7124    RelocationResolver Resolver;7125    std::tie(IsSupportedFn, Resolver) = getRelocationResolver(this->ObjF);7126    ArrayRef<uint8_t> Contents =7127        unwrapOrError(this->FileName, Obj.getSectionContents(*StackSizesELFSec));7128    DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr));7129 7130    forEachRelocationDo(7131        *RelocSec, [&](const Relocation<ELFT> &R, unsigned Ndx,7132                       const Elf_Shdr &Sec, const Elf_Shdr *SymTab) {7133          if (!IsSupportedFn || !IsSupportedFn(R.Type)) {7134            reportUniqueWarning(7135                describe(*RelocSec) +7136                " contains an unsupported relocation with index " + Twine(Ndx) +7137                ": " + Obj.getRelocationTypeName(R.Type));7138            return;7139          }7140 7141          this->printStackSize(R, *RelocSec, Ndx, SymTab, FunctionSec,7142                               *StackSizesELFSec, Resolver, Data);7143        });7144  }7145}7146 7147template <class ELFT>7148void GNUELFDumper<ELFT>::printStackSizes() {7149  bool HeaderHasBeenPrinted = false;7150  auto PrintHeader = [&]() {7151    if (HeaderHasBeenPrinted)7152      return;7153    OS << "\nStack Sizes:\n";7154    OS.PadToColumn(9);7155    OS << "Size";7156    OS.PadToColumn(18);7157    OS << "Functions\n";7158    HeaderHasBeenPrinted = true;7159  };7160 7161  // For non-relocatable objects, look directly for sections whose name starts7162  // with .stack_sizes and process the contents.7163  if (this->Obj.getHeader().e_type == ELF::ET_REL)7164    this->printRelocatableStackSizes(PrintHeader);7165  else7166    this->printNonRelocatableStackSizes(PrintHeader);7167}7168 7169template <class ELFT>7170void GNUELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {7171  size_t Bias = ELFT::Is64Bits ? 8 : 0;7172  auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {7173    OS.PadToColumn(2);7174    OS << format_hex_no_prefix(Parser.getGotAddress(E), 8 + Bias);7175    OS.PadToColumn(11 + Bias);7176    OS << format_decimal(Parser.getGotOffset(E), 6) << "(gp)";7177    OS.PadToColumn(22 + Bias);7178    OS << format_hex_no_prefix(*E, 8 + Bias);7179    OS.PadToColumn(31 + 2 * Bias);7180    OS << Purpose << "\n";7181  };7182 7183  OS << (Parser.IsStatic ? "Static GOT:\n" : "Primary GOT:\n");7184  OS << " Canonical gp value: "7185     << format_hex_no_prefix(Parser.getGp(), 8 + Bias) << "\n\n";7186 7187  OS << " Reserved entries:\n";7188  if (ELFT::Is64Bits)7189    OS << "           Address     Access          Initial Purpose\n";7190  else7191    OS << "   Address     Access  Initial Purpose\n";7192  PrintEntry(Parser.getGotLazyResolver(), "Lazy resolver");7193  if (Parser.getGotModulePointer())7194    PrintEntry(Parser.getGotModulePointer(), "Module pointer (GNU extension)");7195 7196  if (!Parser.getLocalEntries().empty()) {7197    OS << "\n";7198    OS << " Local entries:\n";7199    if (ELFT::Is64Bits)7200      OS << "           Address     Access          Initial\n";7201    else7202      OS << "   Address     Access  Initial\n";7203    for (auto &E : Parser.getLocalEntries())7204      PrintEntry(&E, "");7205  }7206 7207  if (Parser.IsStatic)7208    return;7209 7210  if (!Parser.getGlobalEntries().empty()) {7211    OS << "\n";7212    OS << " Global entries:\n";7213    if (ELFT::Is64Bits)7214      OS << "           Address     Access          Initial         Sym.Val."7215         << " Type    Ndx Name\n";7216    else7217      OS << "   Address     Access  Initial Sym.Val. Type    Ndx Name\n";7218 7219    DataRegion<Elf_Word> ShndxTable(7220        (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());7221    for (auto &E : Parser.getGlobalEntries()) {7222      const Elf_Sym &Sym = *Parser.getGotSym(&E);7223      const Elf_Sym &FirstSym = this->dynamic_symbols()[0];7224      std::string SymName = this->getFullSymbolName(7225          Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false);7226 7227      OS.PadToColumn(2);7228      OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias));7229      OS.PadToColumn(11 + Bias);7230      OS << to_string(format_decimal(Parser.getGotOffset(&E), 6)) + "(gp)";7231      OS.PadToColumn(22 + Bias);7232      OS << to_string(format_hex_no_prefix(E, 8 + Bias));7233      OS.PadToColumn(31 + 2 * Bias);7234      OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias));7235      OS.PadToColumn(40 + 3 * Bias);7236      OS << enumToString(Sym.getType(), ArrayRef(ElfSymbolTypes));7237      OS.PadToColumn(48 + 3 * Bias);7238      OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(),7239                                ShndxTable);7240      OS.PadToColumn(52 + 3 * Bias);7241      OS << SymName << "\n";7242    }7243  }7244 7245  if (!Parser.getOtherEntries().empty())7246    OS << "\n Number of TLS and multi-GOT entries "7247       << Parser.getOtherEntries().size() << "\n";7248}7249 7250template <class ELFT>7251void GNUELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {7252  size_t Bias = ELFT::Is64Bits ? 8 : 0;7253  auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {7254    OS.PadToColumn(2);7255    OS << format_hex_no_prefix(Parser.getPltAddress(E), 8 + Bias);7256    OS.PadToColumn(11 + Bias);7257    OS << format_hex_no_prefix(*E, 8 + Bias);7258    OS.PadToColumn(20 + 2 * Bias);7259    OS << Purpose << "\n";7260  };7261 7262  OS << "PLT GOT:\n\n";7263 7264  OS << " Reserved entries:\n";7265  OS << "   Address  Initial Purpose\n";7266  PrintEntry(Parser.getPltLazyResolver(), "PLT lazy resolver");7267  if (Parser.getPltModulePointer())7268    PrintEntry(Parser.getPltModulePointer(), "Module pointer");7269 7270  if (!Parser.getPltEntries().empty()) {7271    OS << "\n";7272    OS << " Entries:\n";7273    OS << "   Address  Initial Sym.Val. Type    Ndx Name\n";7274    DataRegion<Elf_Word> ShndxTable(7275        (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());7276    for (auto &E : Parser.getPltEntries()) {7277      const Elf_Sym &Sym = *Parser.getPltSym(&E);7278      const Elf_Sym &FirstSym = *cantFail(7279          this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));7280      std::string SymName = this->getFullSymbolName(7281          Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false);7282 7283      OS.PadToColumn(2);7284      OS << to_string(format_hex_no_prefix(Parser.getPltAddress(&E), 8 + Bias));7285      OS.PadToColumn(11 + Bias);7286      OS << to_string(format_hex_no_prefix(E, 8 + Bias));7287      OS.PadToColumn(20 + 2 * Bias);7288      OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias));7289      OS.PadToColumn(29 + 3 * Bias);7290      OS << enumToString(Sym.getType(), ArrayRef(ElfSymbolTypes));7291      OS.PadToColumn(37 + 3 * Bias);7292      OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(),7293                                ShndxTable);7294      OS.PadToColumn(41 + 3 * Bias);7295      OS << SymName << "\n";7296    }7297  }7298}7299 7300template <class ELFT>7301Expected<const Elf_Mips_ABIFlags<ELFT> *>7302getMipsAbiFlagsSection(const ELFDumper<ELFT> &Dumper) {7303  const typename ELFT::Shdr *Sec = Dumper.findSectionByName(".MIPS.abiflags");7304  if (Sec == nullptr)7305    return nullptr;7306 7307  constexpr StringRef ErrPrefix = "unable to read the .MIPS.abiflags section: ";7308  Expected<ArrayRef<uint8_t>> DataOrErr =7309      Dumper.getElfObject().getELFFile().getSectionContents(*Sec);7310  if (!DataOrErr)7311    return createError(ErrPrefix + toString(DataOrErr.takeError()));7312 7313  if (DataOrErr->size() != sizeof(Elf_Mips_ABIFlags<ELFT>))7314    return createError(ErrPrefix + "it has a wrong size (" +7315        Twine(DataOrErr->size()) + ")");7316  return reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(DataOrErr->data());7317}7318 7319template <class ELFT> void GNUELFDumper<ELFT>::printMipsABIFlags() {7320  const Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;7321  if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =7322          getMipsAbiFlagsSection(*this))7323    Flags = *SecOrErr;7324  else7325    this->reportUniqueWarning(SecOrErr.takeError());7326  if (!Flags)7327    return;7328 7329  OS << "MIPS ABI Flags Version: " << Flags->version << "\n\n";7330  OS << "ISA: MIPS" << int(Flags->isa_level);7331  if (Flags->isa_rev > 1)7332    OS << "r" << int(Flags->isa_rev);7333  OS << "\n";7334  OS << "GPR size: " << getMipsRegisterSize(Flags->gpr_size) << "\n";7335  OS << "CPR1 size: " << getMipsRegisterSize(Flags->cpr1_size) << "\n";7336  OS << "CPR2 size: " << getMipsRegisterSize(Flags->cpr2_size) << "\n";7337  OS << "FP ABI: " << enumToString(Flags->fp_abi, ArrayRef(ElfMipsFpABIType))7338     << "\n";7339  OS << "ISA Extension: "7340     << enumToString(Flags->isa_ext, ArrayRef(ElfMipsISAExtType)) << "\n";7341  if (Flags->ases == 0)7342    OS << "ASEs: None\n";7343  else7344    // FIXME: Print each flag on a separate line.7345    OS << "ASEs: " << printFlags(Flags->ases, ArrayRef(ElfMipsASEFlags))7346       << "\n";7347  OS << "FLAGS 1: " << format_hex_no_prefix(Flags->flags1, 8, false) << "\n";7348  OS << "FLAGS 2: " << format_hex_no_prefix(Flags->flags2, 8, false) << "\n";7349  OS << "\n";7350}7351 7352template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() {7353  const Elf_Ehdr &E = this->Obj.getHeader();7354  {7355    DictScope D(W, "ElfHeader");7356    {7357      DictScope D(W, "Ident");7358      W.printBinary("Magic",7359                    ArrayRef<unsigned char>(E.e_ident).slice(ELF::EI_MAG0, 4));7360      W.printEnum("Class", E.e_ident[ELF::EI_CLASS], ArrayRef(ElfClass));7361      W.printEnum("DataEncoding", E.e_ident[ELF::EI_DATA],7362                  ArrayRef(ElfDataEncoding));7363      W.printNumber("FileVersion", E.e_ident[ELF::EI_VERSION]);7364 7365      auto OSABI = ArrayRef(ElfOSABI);7366      if (E.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH &&7367          E.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) {7368        switch (E.e_machine) {7369        case ELF::EM_AMDGPU:7370          OSABI = ArrayRef(AMDGPUElfOSABI);7371          break;7372        case ELF::EM_ARM:7373          OSABI = ArrayRef(ARMElfOSABI);7374          break;7375        case ELF::EM_TI_C6000:7376          OSABI = ArrayRef(C6000ElfOSABI);7377          break;7378        }7379      }7380      W.printEnum("OS/ABI", E.e_ident[ELF::EI_OSABI], OSABI);7381      W.printNumber("ABIVersion", E.e_ident[ELF::EI_ABIVERSION]);7382      W.printBinary("Unused",7383                    ArrayRef<unsigned char>(E.e_ident).slice(ELF::EI_PAD));7384    }7385 7386    std::string TypeStr;7387    if (const EnumEntry<unsigned> *Ent = getObjectFileEnumEntry(E.e_type)) {7388      TypeStr = Ent->Name.str();7389    } else {7390      if (E.e_type >= ET_LOPROC)7391        TypeStr = "Processor Specific";7392      else if (E.e_type >= ET_LOOS)7393        TypeStr = "OS Specific";7394      else7395        TypeStr = "Unknown";7396    }7397    W.printString("Type", TypeStr + " (0x" +7398                              utohexstr(E.e_type, /*LowerCase=*/true) + ")");7399 7400    W.printEnum("Machine", E.e_machine, ArrayRef(ElfMachineType));7401    W.printNumber("Version", E.e_version);7402    W.printHex("Entry", E.e_entry);7403    W.printHex("ProgramHeaderOffset", E.e_phoff);7404    W.printHex("SectionHeaderOffset", E.e_shoff);7405    if (E.e_machine == EM_MIPS)7406      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderMipsFlags),7407                   unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),7408                   unsigned(ELF::EF_MIPS_MACH));7409    else if (E.e_machine == EM_AMDGPU) {7410      switch (E.e_ident[ELF::EI_ABIVERSION]) {7411      default:7412        W.printHex("Flags", E.e_flags);7413        break;7414      case 0:7415        // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags.7416        [[fallthrough]];7417      case ELF::ELFABIVERSION_AMDGPU_HSA_V3:7418        W.printFlags("Flags", E.e_flags,7419                     ArrayRef(ElfHeaderAMDGPUFlagsABIVersion3),7420                     unsigned(ELF::EF_AMDGPU_MACH));7421        break;7422      case ELF::ELFABIVERSION_AMDGPU_HSA_V4:7423      case ELF::ELFABIVERSION_AMDGPU_HSA_V5:7424        W.printFlags("Flags", E.e_flags,7425                     ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),7426                     unsigned(ELF::EF_AMDGPU_MACH),7427                     unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),7428                     unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4));7429        break;7430      case ELF::ELFABIVERSION_AMDGPU_HSA_V6: {7431        std::optional<FlagEntry> VerFlagEntry;7432        // The string needs to remain alive from the moment we create a7433        // FlagEntry until printFlags is done.7434        std::string FlagStr;7435        if (auto VersionFlag = E.e_flags & ELF::EF_AMDGPU_GENERIC_VERSION) {7436          unsigned Version =7437              VersionFlag >> ELF::EF_AMDGPU_GENERIC_VERSION_OFFSET;7438          FlagStr = "EF_AMDGPU_GENERIC_VERSION_V" + std::to_string(Version);7439          VerFlagEntry = FlagEntry(FlagStr, VersionFlag);7440        }7441        W.printFlags(7442            "Flags", E.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),7443            unsigned(ELF::EF_AMDGPU_MACH),7444            unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),7445            unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4),7446            VerFlagEntry ? ArrayRef(*VerFlagEntry) : ArrayRef<FlagEntry>());7447        break;7448      }7449      }7450    } else if (E.e_machine == EM_RISCV)7451      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderRISCVFlags));7452    else if (E.e_machine == EM_SPARC32PLUS || E.e_machine == EM_SPARCV9)7453      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderSPARCFlags),7454                   unsigned(ELF::EF_SPARCV9_MM));7455    else if (E.e_machine == EM_AVR)7456      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderAVRFlags),7457                   unsigned(ELF::EF_AVR_ARCH_MASK));7458    else if (E.e_machine == EM_LOONGARCH)7459      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderLoongArchFlags),7460                   unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK),7461                   unsigned(ELF::EF_LOONGARCH_OBJABI_MASK));7462    else if (E.e_machine == EM_XTENSA)7463      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderXtensaFlags),7464                   unsigned(ELF::EF_XTENSA_MACH));7465    else if (E.e_machine == EM_CUDA)7466      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderNVPTXFlags),7467                   unsigned(ELF::EF_CUDA_SM));7468    else7469      W.printFlags("Flags", E.e_flags);7470    W.printNumber("HeaderSize", E.e_ehsize);7471    W.printNumber("ProgramHeaderEntrySize", E.e_phentsize);7472    W.printNumber("ProgramHeaderCount", E.e_phnum);7473    W.printNumber("SectionHeaderEntrySize", E.e_shentsize);7474    W.printString("SectionHeaderCount",7475                  getSectionHeadersNumString(this->Obj, this->FileName));7476    W.printString("StringTableSectionIndex",7477                  getSectionHeaderTableIndexString(this->Obj, this->FileName));7478  }7479}7480 7481template <class ELFT> void LLVMELFDumper<ELFT>::printGroupSections() {7482  DictScope Lists(W, "Groups");7483  std::vector<GroupSection> V = this->getGroups();7484  DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);7485  for (const GroupSection &G : V) {7486    DictScope D(W, "Group");7487    W.printNumber("Name", G.Name, G.ShName);7488    W.printNumber("Index", G.Index);7489    W.printNumber("Link", G.Link);7490    W.printNumber("Info", G.Info);7491    W.printHex("Type", getGroupType(G.Type), G.Type);7492    W.printString("Signature", G.Signature);7493 7494    ListScope L(W, getGroupSectionHeaderName());7495    for (const GroupMember &GM : G.Members) {7496      const GroupSection *MainGroup = Map[GM.Index];7497      if (MainGroup != &G)7498        this->reportUniqueWarning(7499            "section with index " + Twine(GM.Index) +7500            ", included in the group section with index " +7501            Twine(MainGroup->Index) +7502            ", was also found in the group section with index " +7503            Twine(G.Index));7504      printSectionGroupMembers(GM.Name, GM.Index);7505    }7506  }7507 7508  if (V.empty())7509    printEmptyGroupMessage();7510}7511 7512template <class ELFT>7513std::string LLVMELFDumper<ELFT>::getGroupSectionHeaderName() const {7514  return "Section(s) in group";7515}7516 7517template <class ELFT>7518void LLVMELFDumper<ELFT>::printSectionGroupMembers(StringRef Name,7519                                                   uint64_t Idx) const {7520  W.startLine() << Name << " (" << Idx << ")\n";7521}7522 7523template <class ELFT> void LLVMELFDumper<ELFT>::printRelocations() {7524  ListScope D(W, "Relocations");7525 7526  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {7527    if (!isRelocationSec<ELFT>(Sec, this->Obj.getHeader()))7528      continue;7529 7530    StringRef Name = this->getPrintableSectionName(Sec);7531    unsigned SecNdx = &Sec - &cantFail(this->Obj.sections()).front();7532    printRelocationSectionInfo(Sec, Name, SecNdx);7533  }7534}7535 7536template <class ELFT>7537void LLVMELFDumper<ELFT>::printExpandedRelRelaReloc(const Relocation<ELFT> &R,7538                                                    StringRef SymbolName,7539                                                    StringRef RelocName) {7540  DictScope Group(W, "Relocation");7541  W.printHex("Offset", R.Offset);7542  W.printNumber("Type", RelocName, R.Type);7543  W.printNumber("Symbol", !SymbolName.empty() ? SymbolName : "-", R.Symbol);7544  if (R.Addend)7545    W.printHex("Addend", (uintX_t)*R.Addend);7546}7547 7548template <class ELFT>7549void LLVMELFDumper<ELFT>::printDefaultRelRelaReloc(const Relocation<ELFT> &R,7550                                                   StringRef SymbolName,7551                                                   StringRef RelocName) {7552  raw_ostream &OS = W.startLine();7553  OS << W.hex(R.Offset) << " " << RelocName << " "7554     << (!SymbolName.empty() ? SymbolName : "-");7555  if (R.Addend)7556    OS << " " << W.hex((uintX_t)*R.Addend);7557  OS << "\n";7558}7559 7560template <class ELFT>7561void LLVMELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec,7562                                                     StringRef Name,7563                                                     const unsigned SecNdx) {7564  DictScope D(W, (Twine("Section (") + Twine(SecNdx) + ") " + Name).str());7565  this->printRelocationsHelper(Sec);7566}7567 7568template <class ELFT> void LLVMELFDumper<ELFT>::printEmptyGroupMessage() const {7569  W.startLine() << "There are no group sections in the file.\n";7570}7571 7572template <class ELFT>7573void LLVMELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,7574                                            const RelSymbol<ELFT> &RelSym) {7575  StringRef SymbolName = RelSym.Name;7576  if (RelSym.Sym && RelSym.Name.empty())7577    SymbolName = "<null>";7578  SmallString<32> RelocName;7579  this->Obj.getRelocationTypeName(R.Type, RelocName);7580 7581  if (opts::ExpandRelocs) {7582    printExpandedRelRelaReloc(R, SymbolName, RelocName);7583  } else {7584    printDefaultRelRelaReloc(R, SymbolName, RelocName);7585  }7586}7587 7588template <class ELFT> void LLVMELFDumper<ELFT>::printSectionHeaders() {7589  ListScope SectionsD(W, "Sections");7590 7591  int SectionIndex = -1;7592  std::vector<EnumEntry<unsigned>> FlagsList =7593      getSectionFlagsForTarget(this->Obj.getHeader().e_ident[ELF::EI_OSABI],7594                               this->Obj.getHeader().e_machine);7595  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {7596    DictScope SectionD(W, "Section");7597    W.printNumber("Index", ++SectionIndex);7598    W.printNumber("Name", this->getPrintableSectionName(Sec), Sec.sh_name);7599    W.printHex("Type",7600               object::getELFSectionTypeName(this->Obj.getHeader().e_machine,7601                                             Sec.sh_type),7602               Sec.sh_type);7603    W.printFlags("Flags", Sec.sh_flags, ArrayRef(FlagsList));7604    W.printHex("Address", Sec.sh_addr);7605    W.printHex("Offset", Sec.sh_offset);7606    W.printNumber("Size", Sec.sh_size);7607    W.printNumber("Link", Sec.sh_link);7608    W.printNumber("Info", Sec.sh_info);7609    W.printNumber("AddressAlignment", Sec.sh_addralign);7610    W.printNumber("EntrySize", Sec.sh_entsize);7611 7612    if (opts::SectionRelocations) {7613      ListScope D(W, "Relocations");7614      this->printRelocationsHelper(Sec);7615    }7616 7617    if (opts::SectionSymbols) {7618      ListScope D(W, "Symbols");7619      if (this->DotSymtabSec) {7620        StringRef StrTable = unwrapOrError(7621            this->FileName,7622            this->Obj.getStringTableForSymtab(*this->DotSymtabSec));7623        ArrayRef<Elf_Word> ShndxTable = this->getShndxTable(this->DotSymtabSec);7624 7625        typename ELFT::SymRange Symbols = unwrapOrError(7626            this->FileName, this->Obj.symbols(this->DotSymtabSec));7627        for (const Elf_Sym &Sym : Symbols) {7628          const Elf_Shdr *SymSec = unwrapOrError(7629              this->FileName,7630              this->Obj.getSection(Sym, this->DotSymtabSec, ShndxTable));7631          if (SymSec == &Sec)7632            printSymbol(Sym, &Sym - &Symbols[0], ShndxTable, StrTable, false,7633                        /*NonVisibilityBitsUsed=*/false,7634                        /*ExtraSymInfo=*/false);7635        }7636      }7637    }7638 7639    if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {7640      ArrayRef<uint8_t> Data =7641          unwrapOrError(this->FileName, this->Obj.getSectionContents(Sec));7642      W.printBinaryBlock(7643          "SectionData",7644          StringRef(reinterpret_cast<const char *>(Data.data()), Data.size()));7645    }7646  }7647}7648 7649template <class ELFT>7650void LLVMELFDumper<ELFT>::printSymbolSection(7651    const Elf_Sym &Symbol, unsigned SymIndex,7652    DataRegion<Elf_Word> ShndxTable) const {7653  auto GetSectionSpecialType = [&]() -> std::optional<StringRef> {7654    if (Symbol.isUndefined())7655      return StringRef("Undefined");7656    if (Symbol.isProcessorSpecific())7657      return StringRef("Processor Specific");7658    if (Symbol.isOSSpecific())7659      return StringRef("Operating System Specific");7660    if (Symbol.isAbsolute())7661      return StringRef("Absolute");7662    if (Symbol.isCommon())7663      return StringRef("Common");7664    if (Symbol.isReserved() && Symbol.st_shndx != SHN_XINDEX)7665      return StringRef("Reserved");7666    return std::nullopt;7667  };7668 7669  if (std::optional<StringRef> Type = GetSectionSpecialType()) {7670    W.printHex("Section", *Type, Symbol.st_shndx);7671    return;7672  }7673 7674  Expected<unsigned> SectionIndex =7675      this->getSymbolSectionIndex(Symbol, SymIndex, ShndxTable);7676  if (!SectionIndex) {7677    assert(Symbol.st_shndx == SHN_XINDEX &&7678           "getSymbolSectionIndex should only fail due to an invalid "7679           "SHT_SYMTAB_SHNDX table/reference");7680    this->reportUniqueWarning(SectionIndex.takeError());7681    W.printHex("Section", "Reserved", SHN_XINDEX);7682    return;7683  }7684 7685  Expected<StringRef> SectionName =7686      this->getSymbolSectionName(Symbol, *SectionIndex);7687  if (!SectionName) {7688    // Don't report an invalid section name if the section headers are missing.7689    // In such situations, all sections will be "invalid".7690    if (!this->ObjF.sections().empty())7691      this->reportUniqueWarning(SectionName.takeError());7692    else7693      consumeError(SectionName.takeError());7694    W.printHex("Section", "<?>", *SectionIndex);7695  } else {7696    W.printHex("Section", *SectionName, *SectionIndex);7697  }7698}7699 7700template <class ELFT>7701void LLVMELFDumper<ELFT>::printSymbolOtherField(const Elf_Sym &Symbol) const {7702  std::vector<EnumEntry<unsigned>> SymOtherFlags =7703      this->getOtherFlagsFromSymbol(this->Obj.getHeader(), Symbol);7704  W.printFlags("Other", Symbol.st_other, ArrayRef(SymOtherFlags), 0x3u);7705}7706 7707template <class ELFT>7708void LLVMELFDumper<ELFT>::printZeroSymbolOtherField(7709    const Elf_Sym &Symbol) const {7710  assert(Symbol.st_other == 0 && "non-zero Other Field");7711  // Usually st_other flag is zero. Do not pollute the output7712  // by flags enumeration in that case.7713  W.printNumber("Other", 0);7714}7715 7716template <class ELFT>7717void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,7718                                      DataRegion<Elf_Word> ShndxTable,7719                                      std::optional<StringRef> StrTable,7720                                      bool IsDynamic,7721                                      bool /*NonVisibilityBitsUsed*/,7722                                      bool /*ExtraSymInfo*/) const {7723  std::string FullSymbolName = this->getFullSymbolName(7724      Symbol, SymIndex, ShndxTable, StrTable, IsDynamic);7725  unsigned char SymbolType = Symbol.getType();7726 7727  DictScope D(W, "Symbol");7728  W.printNumber("Name", FullSymbolName, Symbol.st_name);7729  W.printHex("Value", Symbol.st_value);7730  W.printNumber("Size", Symbol.st_size);7731  W.printEnum("Binding", Symbol.getBinding(), ArrayRef(ElfSymbolBindings));7732  if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&7733      SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)7734    W.printEnum("Type", SymbolType, ArrayRef(AMDGPUSymbolTypes));7735  else7736    W.printEnum("Type", SymbolType, ArrayRef(ElfSymbolTypes));7737  if (Symbol.st_other == 0)7738    printZeroSymbolOtherField(Symbol);7739  else7740    printSymbolOtherField(Symbol);7741  printSymbolSection(Symbol, SymIndex, ShndxTable);7742}7743 7744template <class ELFT>7745void LLVMELFDumper<ELFT>::printSymbols(bool PrintSymbols,7746                                       bool PrintDynamicSymbols,7747                                       bool ExtraSymInfo) {7748  if (PrintSymbols) {7749    ListScope Group(W, "Symbols");7750    this->printSymbolsHelper(false, ExtraSymInfo);7751  }7752  if (PrintDynamicSymbols) {7753    ListScope Group(W, "DynamicSymbols");7754    this->printSymbolsHelper(true, ExtraSymInfo);7755  }7756}7757 7758template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicTable() {7759  Elf_Dyn_Range Table = this->dynamic_table();7760  if (Table.empty())7761    return;7762 7763  W.startLine() << "DynamicSection [ (" << Table.size() << " entries)\n";7764 7765  size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table);7766  // The "Name/Value" column should be indented from the "Type" column by N7767  // spaces, where N = MaxTagSize - length of "Type" (4) + trailing7768  // space (1) = -3.7769  W.startLine() << "  Tag" << std::string(ELFT::Is64Bits ? 16 : 8, ' ')7770                << "Type" << std::string(MaxTagSize - 3, ' ') << "Name/Value\n";7771 7772  std::string ValueFmt = "%-" + std::to_string(MaxTagSize) + "s ";7773  for (auto Entry : Table) {7774    uintX_t Tag = Entry.getTag();7775    std::string Value = this->getDynamicEntry(Tag, Entry.getVal());7776    W.startLine() << "  " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10, true)7777                  << " "7778                  << format(ValueFmt.c_str(),7779                            this->Obj.getDynamicTagAsString(Tag).c_str())7780                  << Value << "\n";7781  }7782  W.startLine() << "]\n";7783}7784 7785template <class ELFT>7786void JSONELFDumper<ELFT>::printAuxillaryDynamicTableEntryInfo(7787    const Elf_Dyn &Entry) {7788  auto FormatFlags = [this, Value = Entry.getVal()](auto Flags) {7789    ListScope L(this->W, "Flags");7790    for (const auto &Flag : Flags) {7791      if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value)7792        this->W.printString(Flag.Name);7793    }7794  };7795  switch (Entry.getTag()) {7796  case DT_SONAME:7797    this->W.printString("Name", this->getDynamicString(Entry.getVal()));7798    break;7799  case DT_AUXILIARY:7800  case DT_FILTER:7801  case DT_NEEDED:7802    this->W.printString("Library", this->getDynamicString(Entry.getVal()));7803    break;7804  case DT_USED:7805    this->W.printString("Object", this->getDynamicString(Entry.getVal()));7806    break;7807  case DT_RPATH:7808  case DT_RUNPATH: {7809    StringRef Value = this->getDynamicString(Entry.getVal());7810    ListScope L(this->W, "Path");7811    while (!Value.empty()) {7812      auto [Front, Back] = Value.split(':');7813      this->W.printString(Front);7814      Value = Back;7815    }7816    break;7817  }7818  case DT_FLAGS:7819    FormatFlags(ArrayRef(ElfDynamicDTFlags));7820    break;7821  case DT_FLAGS_1:7822    FormatFlags(ArrayRef(ElfDynamicDTFlags1));7823    break;7824  default:7825    return;7826  }7827}7828 7829template <class ELFT> void JSONELFDumper<ELFT>::printDynamicTable() {7830  Elf_Dyn_Range Table = this->dynamic_table();7831  ListScope L(this->W, "DynamicSection");7832  for (const auto &Entry : Table) {7833    DictScope D(this->W);7834    uintX_t Tag = Entry.getTag();7835    this->W.printHex("Tag", Tag);7836    this->W.printString("Type", this->Obj.getDynamicTagAsString(Tag));7837    this->W.printHex("Value", Entry.getVal());7838    this->printAuxillaryDynamicTableEntryInfo(Entry);7839  }7840}7841 7842template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicRelocations() {7843  W.startLine() << "Dynamic Relocations {\n";7844  W.indent();7845  this->printDynamicRelocationsHelper();7846  W.unindent();7847  W.startLine() << "}\n";7848}7849 7850template <class ELFT>7851void LLVMELFDumper<ELFT>::printProgramHeaders(7852    bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {7853  if (PrintProgramHeaders)7854    printProgramHeaders();7855  if (PrintSectionMapping == cl::BOU_TRUE)7856    printSectionMapping();7857}7858 7859template <class ELFT> void LLVMELFDumper<ELFT>::printProgramHeaders() {7860  ListScope L(W, "ProgramHeaders");7861 7862  Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();7863  if (!PhdrsOrErr) {7864    this->reportUniqueWarning("unable to dump program headers: " +7865                              toString(PhdrsOrErr.takeError()));7866    return;7867  }7868 7869  for (const Elf_Phdr &Phdr : *PhdrsOrErr) {7870    DictScope P(W, "ProgramHeader");7871    StringRef Type =7872        segmentTypeToString(this->Obj.getHeader().e_machine, Phdr.p_type);7873 7874    W.printHex("Type", Type.empty() ? "Unknown" : Type, Phdr.p_type);7875    W.printHex("Offset", Phdr.p_offset);7876    W.printHex("VirtualAddress", Phdr.p_vaddr);7877    W.printHex("PhysicalAddress", Phdr.p_paddr);7878    W.printNumber("FileSize", Phdr.p_filesz);7879    W.printNumber("MemSize", Phdr.p_memsz);7880    W.printFlags("Flags", Phdr.p_flags, ArrayRef(ElfSegmentFlags));7881    W.printNumber("Alignment", Phdr.p_align);7882  }7883}7884 7885template <class ELFT>7886void LLVMELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) {7887  ListScope SS(W, "VersionSymbols");7888  if (!Sec)7889    return;7890 7891  StringRef StrTable;7892  ArrayRef<Elf_Sym> Syms;7893  const Elf_Shdr *SymTabSec;7894  Expected<ArrayRef<Elf_Versym>> VerTableOrErr =7895      this->getVersionTable(*Sec, &Syms, &StrTable, &SymTabSec);7896  if (!VerTableOrErr) {7897    this->reportUniqueWarning(VerTableOrErr.takeError());7898    return;7899  }7900 7901  if (StrTable.empty() || Syms.empty() || Syms.size() != VerTableOrErr->size())7902    return;7903 7904  ArrayRef<Elf_Word> ShNdxTable = this->getShndxTable(SymTabSec);7905  for (size_t I = 0, E = Syms.size(); I < E; ++I) {7906    DictScope S(W, "Symbol");7907    W.printNumber("Version", (*VerTableOrErr)[I].vs_index & VERSYM_VERSION);7908    W.printString("Name",7909                  this->getFullSymbolName(Syms[I], I, ShNdxTable, StrTable,7910                                          /*IsDynamic=*/true));7911  }7912}7913 7914const EnumEntry<unsigned> SymVersionFlags[] = {7915    {"Base", "BASE", VER_FLG_BASE},7916    {"Weak", "WEAK", VER_FLG_WEAK},7917    {"Info", "INFO", VER_FLG_INFO}};7918 7919template <class ELFT>7920void LLVMELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) {7921  ListScope SD(W, "VersionDefinitions");7922  if (!Sec)7923    return;7924 7925  Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec);7926  if (!V) {7927    this->reportUniqueWarning(V.takeError());7928    return;7929  }7930 7931  for (const VerDef &D : *V) {7932    DictScope Def(W, "Definition");7933    W.printNumber("Version", D.Version);7934    W.printFlags("Flags", D.Flags, ArrayRef(SymVersionFlags));7935    W.printNumber("Index", D.Ndx);7936    W.printNumber("Hash", D.Hash);7937    W.printString("Name", D.Name);7938    W.printList(7939        "Predecessors", D.AuxV,7940        [](raw_ostream &OS, const VerdAux &Aux) { OS << Aux.Name.c_str(); });7941  }7942}7943 7944template <class ELFT>7945void LLVMELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) {7946  ListScope SD(W, "VersionRequirements");7947  if (!Sec)7948    return;7949 7950  Expected<std::vector<VerNeed>> V =7951      this->Obj.getVersionDependencies(*Sec, this->WarningHandler);7952  if (!V) {7953    this->reportUniqueWarning(V.takeError());7954    return;7955  }7956 7957  for (const VerNeed &VN : *V) {7958    DictScope Entry(W, "Dependency");7959    W.printNumber("Version", VN.Version);7960    W.printNumber("Count", VN.Cnt);7961    W.printString("FileName", VN.File.c_str());7962 7963    ListScope L(W, "Entries");7964    for (const VernAux &Aux : VN.AuxV) {7965      DictScope Entry(W, "Entry");7966      W.printNumber("Hash", Aux.Hash);7967      W.printFlags("Flags", Aux.Flags, ArrayRef(SymVersionFlags));7968      W.printNumber("Index", Aux.Other);7969      W.printString("Name", Aux.Name.c_str());7970    }7971  }7972}7973 7974template <class ELFT>7975void LLVMELFDumper<ELFT>::printHashHistogramStats(size_t NBucket,7976                                                  size_t MaxChain,7977                                                  size_t TotalSyms,7978                                                  ArrayRef<size_t> Count,7979                                                  bool IsGnu) const {7980  StringRef HistName = IsGnu ? "GnuHashHistogram" : "HashHistogram";7981  StringRef BucketName = IsGnu ? "Bucket" : "Chain";7982  StringRef ListName = IsGnu ? "Buckets" : "Chains";7983  DictScope Outer(W, HistName);7984  W.printNumber("TotalBuckets", NBucket);7985  ListScope Buckets(W, ListName);7986  size_t CumulativeNonZero = 0;7987  for (size_t I = 0; I < MaxChain; ++I) {7988    CumulativeNonZero += Count[I] * I;7989    DictScope Bucket(W, BucketName);7990    W.printNumber("Length", I);7991    W.printNumber("Count", Count[I]);7992    W.printNumber("Percentage", (float)(Count[I] * 100.0) / NBucket);7993    W.printNumber("Coverage", (float)(CumulativeNonZero * 100.0) / TotalSyms);7994  }7995}7996 7997// Returns true if rel/rela section exists, and populates SymbolIndices.7998// Otherwise returns false.7999template <class ELFT>8000static bool getSymbolIndices(const typename ELFT::Shdr *CGRelSection,8001                             const ELFFile<ELFT> &Obj,8002                             const LLVMELFDumper<ELFT> *Dumper,8003                             SmallVector<uint32_t, 128> &SymbolIndices) {8004  if (!CGRelSection) {8005    Dumper->reportUniqueWarning(8006        "relocation section for a call graph section doesn't exist");8007    return false;8008  }8009 8010  if (CGRelSection->sh_type == SHT_REL) {8011    typename ELFT::RelRange CGProfileRel;8012    Expected<typename ELFT::RelRange> CGProfileRelOrError =8013        Obj.rels(*CGRelSection);8014    if (!CGProfileRelOrError) {8015      Dumper->reportUniqueWarning("unable to load relocations for "8016                                  "SHT_LLVM_CALL_GRAPH_PROFILE section: " +8017                                  toString(CGProfileRelOrError.takeError()));8018      return false;8019    }8020 8021    CGProfileRel = *CGProfileRelOrError;8022    for (const typename ELFT::Rel &Rel : CGProfileRel)8023      SymbolIndices.push_back(Rel.getSymbol(Obj.isMips64EL()));8024  } else {8025    // MC unconditionally produces SHT_REL, but GNU strip/objcopy may convert8026    // the format to SHT_RELA8027    // (https://sourceware.org/bugzilla/show_bug.cgi?id=28035)8028    typename ELFT::RelaRange CGProfileRela;8029    Expected<typename ELFT::RelaRange> CGProfileRelaOrError =8030        Obj.relas(*CGRelSection);8031    if (!CGProfileRelaOrError) {8032      Dumper->reportUniqueWarning("unable to load relocations for "8033                                  "SHT_LLVM_CALL_GRAPH_PROFILE section: " +8034                                  toString(CGProfileRelaOrError.takeError()));8035      return false;8036    }8037 8038    CGProfileRela = *CGProfileRelaOrError;8039    for (const typename ELFT::Rela &Rela : CGProfileRela)8040      SymbolIndices.push_back(Rela.getSymbol(Obj.isMips64EL()));8041  }8042 8043  return true;8044}8045 8046template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {8047  auto IsMatch = [](const Elf_Shdr &Sec) -> bool {8048    return Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE;8049  };8050 8051  Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecToRelocMapOrErr =8052      this->Obj.getSectionAndRelocations(IsMatch);8053  if (!SecToRelocMapOrErr) {8054    this->reportUniqueWarning("unable to get CG Profile section(s): " +8055                              toString(SecToRelocMapOrErr.takeError()));8056    return;8057  }8058 8059  for (const auto &CGMapEntry : *SecToRelocMapOrErr) {8060    const Elf_Shdr *CGSection = CGMapEntry.first;8061    const Elf_Shdr *CGRelSection = CGMapEntry.second;8062 8063    Expected<ArrayRef<Elf_CGProfile>> CGProfileOrErr =8064        this->Obj.template getSectionContentsAsArray<Elf_CGProfile>(*CGSection);8065    if (!CGProfileOrErr) {8066      this->reportUniqueWarning(8067          "unable to load the SHT_LLVM_CALL_GRAPH_PROFILE section: " +8068          toString(CGProfileOrErr.takeError()));8069      return;8070    }8071 8072    SmallVector<uint32_t, 128> SymbolIndices;8073    bool UseReloc =8074        getSymbolIndices<ELFT>(CGRelSection, this->Obj, this, SymbolIndices);8075    if (UseReloc && SymbolIndices.size() != CGProfileOrErr->size() * 2) {8076      this->reportUniqueWarning(8077          "number of from/to pairs does not match number of frequencies");8078      UseReloc = false;8079    }8080 8081    ListScope L(W, "CGProfile");8082    for (uint32_t I = 0, Size = CGProfileOrErr->size(); I != Size; ++I) {8083      const Elf_CGProfile &CGPE = (*CGProfileOrErr)[I];8084      DictScope D(W, "CGProfileEntry");8085      if (UseReloc) {8086        uint32_t From = SymbolIndices[I * 2];8087        uint32_t To = SymbolIndices[I * 2 + 1];8088        W.printNumber("From", this->getStaticSymbolName(From), From);8089        W.printNumber("To", this->getStaticSymbolName(To), To);8090      }8091      W.printNumber("Weight", CGPE.cgp_weight);8092    }8093  }8094}8095 8096template <class ELFT>8097void LLVMELFDumper<ELFT>::printBBAddrMaps(bool PrettyPGOAnalysis) {8098  bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL;8099  using Elf_Shdr = typename ELFT::Shdr;8100  auto IsMatch = [](const Elf_Shdr &Sec) -> bool {8101    return Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP;8102  };8103  Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecRelocMapOrErr =8104      this->Obj.getSectionAndRelocations(IsMatch);8105  if (!SecRelocMapOrErr) {8106    this->reportUniqueWarning(8107        "failed to get SHT_LLVM_BB_ADDR_MAP section(s): " +8108        toString(SecRelocMapOrErr.takeError()));8109    return;8110  }8111  for (auto const &[Sec, RelocSec] : *SecRelocMapOrErr) {8112    std::optional<const Elf_Shdr *> FunctionSec;8113    if (IsRelocatable)8114      FunctionSec =8115          unwrapOrError(this->FileName, this->Obj.getSection(Sec->sh_link));8116    ListScope L(W, "BBAddrMap");8117    if (IsRelocatable && !RelocSec) {8118      this->reportUniqueWarning("unable to get relocation section for " +8119                                this->describe(*Sec));8120      continue;8121    }8122    std::vector<PGOAnalysisMap> PGOAnalyses;8123    Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =8124        this->Obj.decodeBBAddrMap(*Sec, RelocSec, &PGOAnalyses);8125    if (!BBAddrMapOrErr) {8126      this->reportUniqueWarning("unable to dump " + this->describe(*Sec) +8127                                ": " + toString(BBAddrMapOrErr.takeError()));8128      continue;8129    }8130    for (const auto &[AM, PAM] : zip_equal(*BBAddrMapOrErr, PGOAnalyses)) {8131      DictScope D(W, "Function");8132      W.printHex("At", AM.getFunctionAddress());8133      SmallVector<uint32_t> FuncSymIndex =8134          this->getSymbolIndexesForFunctionAddress(AM.getFunctionAddress(),8135                                                   FunctionSec);8136      std::string FuncName = "<?>";8137      if (FuncSymIndex.empty())8138        this->reportUniqueWarning(8139            "could not identify function symbol for address (0x" +8140            Twine::utohexstr(AM.getFunctionAddress()) + ") in " +8141            this->describe(*Sec));8142      else8143        FuncName = this->getStaticSymbolName(FuncSymIndex.front());8144      W.printString("Name", FuncName);8145      {8146        ListScope BBRL(W, "BB Ranges");8147        for (const BBAddrMap::BBRangeEntry &BBR : AM.BBRanges) {8148          DictScope BBRD(W);8149          W.printHex("Base Address", BBR.BaseAddress);8150          ListScope BBEL(W, "BB Entries");8151          for (const BBAddrMap::BBEntry &BBE : BBR.BBEntries) {8152            DictScope BBED(W);8153            W.printNumber("ID", BBE.ID);8154            W.printHex("Offset", BBE.Offset);8155            if (!BBE.CallsiteEndOffsets.empty())8156              W.printList("Callsite End Offsets", BBE.CallsiteEndOffsets);8157            if (PAM.FeatEnable.BBHash)8158              W.printHex("Hash", BBE.Hash);8159            W.printHex("Size", BBE.Size);8160            W.printBoolean("HasReturn", BBE.hasReturn());8161            W.printBoolean("HasTailCall", BBE.hasTailCall());8162            W.printBoolean("IsEHPad", BBE.isEHPad());8163            W.printBoolean("CanFallThrough", BBE.canFallThrough());8164            W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());8165          }8166        }8167      }8168 8169      if (PAM.FeatEnable.hasPGOAnalysis()) {8170        DictScope PD(W, "PGO analyses");8171 8172        if (PAM.FeatEnable.FuncEntryCount)8173          W.printNumber("FuncEntryCount", PAM.FuncEntryCount);8174 8175        if (PAM.FeatEnable.hasPGOAnalysisBBData()) {8176          ListScope L(W, "PGO BB entries");8177          for (const PGOAnalysisMap::PGOBBEntry &PBBE : PAM.BBEntries) {8178            DictScope L(W);8179 8180            if (PAM.FeatEnable.BBFreq) {8181              if (PrettyPGOAnalysis) {8182                std::string BlockFreqStr;8183                raw_string_ostream SS(BlockFreqStr);8184                printRelativeBlockFreq(SS, PAM.BBEntries.front().BlockFreq,8185                                       PBBE.BlockFreq);8186                W.printString("Frequency", BlockFreqStr);8187              } else {8188                W.printNumber("Frequency", PBBE.BlockFreq.getFrequency());8189              }8190              if (PAM.FeatEnable.PostLinkCfg)8191                W.printNumber("PostLink Frequency", PBBE.PostLinkBlockFreq);8192            }8193 8194            if (PAM.FeatEnable.BrProb) {8195              ListScope L(W, "Successors");8196              for (const auto &Succ : PBBE.Successors) {8197                DictScope L(W);8198                W.printNumber("ID", Succ.ID);8199                if (PrettyPGOAnalysis) {8200                  W.printObject("Probability", Succ.Prob);8201                } else {8202                  W.printHex("Probability", Succ.Prob.getNumerator());8203                }8204                if (PAM.FeatEnable.PostLinkCfg)8205                  W.printNumber("PostLink Probability", Succ.PostLinkFreq);8206              }8207            }8208          }8209        }8210      }8211    }8212  }8213}8214 8215template <class ELFT> void LLVMELFDumper<ELFT>::printAddrsig() {8216  ListScope L(W, "Addrsig");8217  if (!this->DotAddrsigSec)8218    return;8219 8220  Expected<std::vector<uint64_t>> SymsOrErr =8221      decodeAddrsigSection(this->Obj, *this->DotAddrsigSec);8222  if (!SymsOrErr) {8223    this->reportUniqueWarning(SymsOrErr.takeError());8224    return;8225  }8226 8227  for (uint64_t Sym : *SymsOrErr)8228    W.printNumber("Sym", this->getStaticSymbolName(Sym), Sym);8229}8230 8231template <typename ELFT>8232static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,8233                                  ScopedPrinter &W,8234                                  typename ELFT::Half EMachine) {8235  // Return true if we were able to pretty-print the note, false otherwise.8236  switch (NoteType) {8237  default:8238    return false;8239  case ELF::NT_GNU_ABI_TAG: {8240    const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);8241    if (!AbiTag.IsValid) {8242      W.printString("ABI", "<corrupt GNU_ABI_TAG>");8243      return false;8244    } else {8245      W.printString("OS", AbiTag.OSName);8246      W.printString("ABI", AbiTag.ABI);8247    }8248    break;8249  }8250  case ELF::NT_GNU_BUILD_ID: {8251    W.printString("Build ID", getGNUBuildId(Desc));8252    break;8253  }8254  case ELF::NT_GNU_GOLD_VERSION:8255    W.printString("Version", getDescAsStringRef(Desc));8256    break;8257  case ELF::NT_GNU_PROPERTY_TYPE_0:8258    ListScope D(W, "Property");8259    for (const std::string &Property : getGNUPropertyList<ELFT>(Desc, EMachine))8260      W.printString(Property);8261    break;8262  }8263  return true;8264}8265 8266static bool printAndroidNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,8267                                      ScopedPrinter &W) {8268  // Return true if we were able to pretty-print the note, false otherwise.8269  AndroidNoteProperties Props = getAndroidNoteProperties(NoteType, Desc);8270  if (Props.empty())8271    return false;8272  for (const auto &KV : Props)8273    W.printString(KV.first, KV.second);8274  return true;8275}8276 8277template <class ELFT>8278void LLVMELFDumper<ELFT>::printMemtag(8279    const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,8280    const ArrayRef<uint8_t> AndroidNoteDesc,8281    const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) {8282  {8283    ListScope L(W, "Memtag Dynamic Entries:");8284    if (DynamicEntries.empty())8285      W.printString("< none found >");8286    for (const auto &DynamicEntryKV : DynamicEntries)8287      W.printString(DynamicEntryKV.first, DynamicEntryKV.second);8288  }8289 8290  if (!AndroidNoteDesc.empty()) {8291    ListScope L(W, "Memtag Android Note:");8292    printAndroidNoteLLVMStyle(ELF::NT_ANDROID_TYPE_MEMTAG, AndroidNoteDesc, W);8293  }8294 8295  if (Descriptors.empty())8296    return;8297 8298  {8299    ListScope L(W, "Memtag Global Descriptors:");8300    for (const auto &[Addr, BytesToTag] : Descriptors) {8301      W.printHex("0x" + utohexstr(Addr, /*LowerCase=*/true), BytesToTag);8302    }8303  }8304}8305 8306template <typename ELFT>8307static bool printLLVMOMPOFFLOADNoteLLVMStyle(uint32_t NoteType,8308                                             ArrayRef<uint8_t> Desc,8309                                             ScopedPrinter &W) {8310  switch (NoteType) {8311  default:8312    return false;8313  case ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION:8314    W.printString("Version", getDescAsStringRef(Desc));8315    break;8316  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER:8317    W.printString("Producer", getDescAsStringRef(Desc));8318    break;8319  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION:8320    W.printString("Producer version", getDescAsStringRef(Desc));8321    break;8322  }8323  return true;8324}8325 8326static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {8327  W.printNumber("Page Size", Note.PageSize);8328  ListScope D(W, "Mappings");8329  for (const CoreFileMapping &Mapping : Note.Mappings) {8330    DictScope D(W);8331    W.printHex("Start", Mapping.Start);8332    W.printHex("End", Mapping.End);8333    W.printHex("Offset", Mapping.Offset);8334    W.printString("Filename", Mapping.Filename);8335  }8336}8337 8338template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {8339  ListScope L(W, "NoteSections");8340 8341  std::unique_ptr<DictScope> NoteSectionScope;8342  std::unique_ptr<ListScope> NotesScope;8343  size_t Align = 0;8344  auto StartNotes = [&](std::optional<StringRef> SecName,8345                        const typename ELFT::Off Offset,8346                        const typename ELFT::Addr Size, size_t Al) {8347    Align = std::max<size_t>(Al, 4);8348    NoteSectionScope = std::make_unique<DictScope>(W, "NoteSection");8349    W.printString("Name", SecName ? *SecName : "<?>");8350    W.printHex("Offset", Offset);8351    W.printHex("Size", Size);8352    NotesScope = std::make_unique<ListScope>(W, "Notes");8353  };8354 8355  auto EndNotes = [&] {8356    NotesScope.reset();8357    NoteSectionScope.reset();8358  };8359 8360  auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {8361    DictScope D2(W);8362    StringRef Name = Note.getName();8363    ArrayRef<uint8_t> Descriptor = Note.getDesc(Align);8364    Elf_Word Type = Note.getType();8365 8366    // Print the note owner/type.8367    W.printString("Owner", Name);8368    W.printHex("Data size", Descriptor.size());8369 8370    StringRef NoteType =8371        getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type);8372    if (!NoteType.empty())8373      W.printString("Type", NoteType);8374    else8375      W.printString("Type",8376                    "Unknown (" + to_string(format_hex(Type, 10)) + ")");8377 8378    const typename ELFT::Half EMachine = this->Obj.getHeader().e_machine;8379    // Print the description, or fallback to printing raw bytes for unknown8380    // owners/if we fail to pretty-print the contents.8381    if (Name == "GNU") {8382      if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W, EMachine))8383        return Error::success();8384    } else if (Name == "FreeBSD") {8385      if (std::optional<FreeBSDNote> N =8386              getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {8387        W.printString(N->Type, N->Value);8388        return Error::success();8389      }8390    } else if (Name == "AMD") {8391      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);8392      if (!N.Type.empty()) {8393        W.printString(N.Type, N.Value);8394        return Error::success();8395      }8396    } else if (Name == "AMDGPU") {8397      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);8398      if (!N.Type.empty()) {8399        W.printString(N.Type, N.Value);8400        return Error::success();8401      }8402    } else if (Name == "LLVMOMPOFFLOAD") {8403      if (printLLVMOMPOFFLOADNoteLLVMStyle<ELFT>(Type, Descriptor, W))8404        return Error::success();8405    } else if (Name == "CORE") {8406      if (Type == ELF::NT_FILE) {8407        DataExtractor DescExtractor(8408            Descriptor, ELFT::Endianness == llvm::endianness::little,8409            sizeof(Elf_Addr));8410        if (Expected<CoreNote> N = readCoreNote(DescExtractor)) {8411          printCoreNoteLLVMStyle(*N, W);8412          return Error::success();8413        } else {8414          return N.takeError();8415        }8416      }8417    } else if (Name == "Android") {8418      if (printAndroidNoteLLVMStyle(Type, Descriptor, W))8419        return Error::success();8420    }8421    if (!Descriptor.empty()) {8422      W.printBinaryBlock("Description data", Descriptor);8423    }8424    return Error::success();8425  };8426 8427  processNotesHelper(*this, /*StartNotesFn=*/StartNotes,8428                     /*ProcessNoteFn=*/ProcessNote, /*FinishNotesFn=*/EndNotes);8429}8430 8431template <class ELFT> void LLVMELFDumper<ELFT>::printELFLinkerOptions() {8432  ListScope L(W, "LinkerOptions");8433 8434  unsigned I = -1;8435  for (const Elf_Shdr &Shdr : cantFail(this->Obj.sections())) {8436    ++I;8437    if (Shdr.sh_type != ELF::SHT_LLVM_LINKER_OPTIONS)8438      continue;8439 8440    Expected<ArrayRef<uint8_t>> ContentsOrErr =8441        this->Obj.getSectionContents(Shdr);8442    if (!ContentsOrErr) {8443      this->reportUniqueWarning("unable to read the content of the "8444                                "SHT_LLVM_LINKER_OPTIONS section: " +8445                                toString(ContentsOrErr.takeError()));8446      continue;8447    }8448    if (ContentsOrErr->empty())8449      continue;8450 8451    if (ContentsOrErr->back() != 0) {8452      this->reportUniqueWarning("SHT_LLVM_LINKER_OPTIONS section at index " +8453                                Twine(I) +8454                                " is broken: the "8455                                "content is not null-terminated");8456      continue;8457    }8458 8459    SmallVector<StringRef, 16> Strings;8460    toStringRef(ContentsOrErr->drop_back()).split(Strings, '\0');8461    if (Strings.size() % 2 != 0) {8462      this->reportUniqueWarning(8463          "SHT_LLVM_LINKER_OPTIONS section at index " + Twine(I) +8464          " is broken: an incomplete "8465          "key-value pair was found. The last possible key was: \"" +8466          Strings.back() + "\"");8467      continue;8468    }8469 8470    for (size_t I = 0; I < Strings.size(); I += 2)8471      W.printString(Strings[I], Strings[I + 1]);8472  }8473}8474 8475template <class ELFT> void LLVMELFDumper<ELFT>::printDependentLibs() {8476  ListScope L(W, "DependentLibs");8477  this->printDependentLibsHelper(8478      [](const Elf_Shdr &) {},8479      [this](StringRef Lib, uint64_t) { W.printString(Lib); });8480}8481 8482template <class ELFT> void LLVMELFDumper<ELFT>::printStackSizes() {8483  ListScope L(W, "StackSizes");8484  if (this->Obj.getHeader().e_type == ELF::ET_REL)8485    this->printRelocatableStackSizes([]() {});8486  else8487    this->printNonRelocatableStackSizes([]() {});8488}8489 8490template <class ELFT>8491void LLVMELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,8492                                              ArrayRef<std::string> FuncNames) {8493  DictScope D(W, "Entry");8494  W.printList("Functions", FuncNames);8495  W.printHex("Size", Size);8496}8497 8498template <class ELFT>8499void LLVMELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {8500  auto PrintEntry = [&](const Elf_Addr *E) {8501    W.printHex("Address", Parser.getGotAddress(E));8502    W.printNumber("Access", Parser.getGotOffset(E));8503    W.printHex("Initial", *E);8504  };8505 8506  DictScope GS(W, Parser.IsStatic ? "Static GOT" : "Primary GOT");8507 8508  W.printHex("Canonical gp value", Parser.getGp());8509  {8510    ListScope RS(W, "Reserved entries");8511    {8512      DictScope D(W, "Entry");8513      PrintEntry(Parser.getGotLazyResolver());8514      W.printString("Purpose", StringRef("Lazy resolver"));8515    }8516 8517    if (Parser.getGotModulePointer()) {8518      DictScope D(W, "Entry");8519      PrintEntry(Parser.getGotModulePointer());8520      W.printString("Purpose", StringRef("Module pointer (GNU extension)"));8521    }8522  }8523  {8524    ListScope LS(W, "Local entries");8525    for (auto &E : Parser.getLocalEntries()) {8526      DictScope D(W, "Entry");8527      PrintEntry(&E);8528    }8529  }8530 8531  if (Parser.IsStatic)8532    return;8533 8534  {8535    ListScope GS(W, "Global entries");8536    for (auto &E : Parser.getGlobalEntries()) {8537      DictScope D(W, "Entry");8538 8539      PrintEntry(&E);8540 8541      const Elf_Sym &Sym = *Parser.getGotSym(&E);8542      W.printHex("Value", Sym.st_value);8543      W.printEnum("Type", Sym.getType(), ArrayRef(ElfSymbolTypes));8544 8545      const unsigned SymIndex = &Sym - this->dynamic_symbols().begin();8546      DataRegion<Elf_Word> ShndxTable(8547          (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());8548      printSymbolSection(Sym, SymIndex, ShndxTable);8549 8550      std::string SymName = this->getFullSymbolName(8551          Sym, SymIndex, ShndxTable, this->DynamicStringTable, true);8552      W.printNumber("Name", SymName, Sym.st_name);8553    }8554  }8555 8556  W.printNumber("Number of TLS and multi-GOT entries",8557                uint64_t(Parser.getOtherEntries().size()));8558}8559 8560template <class ELFT>8561void LLVMELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {8562  auto PrintEntry = [&](const Elf_Addr *E) {8563    W.printHex("Address", Parser.getPltAddress(E));8564    W.printHex("Initial", *E);8565  };8566 8567  DictScope GS(W, "PLT GOT");8568 8569  {8570    ListScope RS(W, "Reserved entries");8571    {8572      DictScope D(W, "Entry");8573      PrintEntry(Parser.getPltLazyResolver());8574      W.printString("Purpose", StringRef("PLT lazy resolver"));8575    }8576 8577    if (auto E = Parser.getPltModulePointer()) {8578      DictScope D(W, "Entry");8579      PrintEntry(E);8580      W.printString("Purpose", StringRef("Module pointer"));8581    }8582  }8583  {8584    ListScope LS(W, "Entries");8585    DataRegion<Elf_Word> ShndxTable(8586        (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());8587    for (auto &E : Parser.getPltEntries()) {8588      DictScope D(W, "Entry");8589      PrintEntry(&E);8590 8591      const Elf_Sym &Sym = *Parser.getPltSym(&E);8592      W.printHex("Value", Sym.st_value);8593      W.printEnum("Type", Sym.getType(), ArrayRef(ElfSymbolTypes));8594      printSymbolSection(Sym, &Sym - this->dynamic_symbols().begin(),8595                         ShndxTable);8596 8597      const Elf_Sym *FirstSym = cantFail(8598          this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));8599      std::string SymName = this->getFullSymbolName(8600          Sym, &Sym - FirstSym, ShndxTable, Parser.getPltStrTable(), true);8601      W.printNumber("Name", SymName, Sym.st_name);8602    }8603  }8604}8605 8606template <class ELFT> void LLVMELFDumper<ELFT>::printMipsABIFlags() {8607  const Elf_Mips_ABIFlags<ELFT> *Flags;8608  if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =8609          getMipsAbiFlagsSection(*this)) {8610    Flags = *SecOrErr;8611    if (!Flags) {8612      W.startLine() << "There is no .MIPS.abiflags section in the file.\n";8613      return;8614    }8615  } else {8616    this->reportUniqueWarning(SecOrErr.takeError());8617    return;8618  }8619 8620  raw_ostream &OS = W.getOStream();8621  DictScope GS(W, "MIPS ABI Flags");8622 8623  W.printNumber("Version", Flags->version);8624  W.startLine() << "ISA: ";8625  if (Flags->isa_rev <= 1)8626    OS << format("MIPS%u", Flags->isa_level);8627  else8628    OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev);8629  OS << "\n";8630  W.printEnum("ISA Extension", Flags->isa_ext, ArrayRef(ElfMipsISAExtType));8631  W.printFlags("ASEs", Flags->ases, ArrayRef(ElfMipsASEFlags));8632  W.printEnum("FP ABI", Flags->fp_abi, ArrayRef(ElfMipsFpABIType));8633  W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size));8634  W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size));8635  W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size));8636  W.printFlags("Flags 1", Flags->flags1, ArrayRef(ElfMipsFlags1));8637  W.printHex("Flags 2", Flags->flags2);8638}8639 8640template <class ELFT>8641void JSONELFDumper<ELFT>::printFileSummary(StringRef FileStr, ObjectFile &Obj,8642                                           ArrayRef<std::string> InputFilenames,8643                                           const Archive *A) {8644  FileScope = std::make_unique<DictScope>(this->W);8645  DictScope D(this->W, "FileSummary");8646  this->W.printString("File", FileStr);8647  this->W.printString("Format", Obj.getFileFormatName());8648  this->W.printString("Arch", Triple::getArchTypeName(Obj.getArch()));8649  this->W.printString(8650      "AddressSize",8651      std::string(formatv("{0}bit", 8 * Obj.getBytesInAddress())));8652  this->printLoadName();8653}8654 8655template <class ELFT>8656void JSONELFDumper<ELFT>::printZeroSymbolOtherField(8657    const Elf_Sym &Symbol) const {8658  // We want the JSON format to be uniform, since it is machine readable, so8659  // always print the `Other` field the same way.8660  this->printSymbolOtherField(Symbol);8661}8662 8663template <class ELFT>8664void JSONELFDumper<ELFT>::printDefaultRelRelaReloc(const Relocation<ELFT> &R,8665                                                   StringRef SymbolName,8666                                                   StringRef RelocName) {8667  this->printExpandedRelRelaReloc(R, SymbolName, RelocName);8668}8669 8670template <class ELFT>8671void JSONELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec,8672                                                     StringRef Name,8673                                                     const unsigned SecNdx) {8674  DictScope Group(this->W);8675  this->W.printNumber("SectionIndex", SecNdx);8676  ListScope D(this->W, "Relocs");8677  this->printRelocationsHelper(Sec);8678}8679 8680template <class ELFT>8681std::string JSONELFDumper<ELFT>::getGroupSectionHeaderName() const {8682  return "GroupSections";8683}8684 8685template <class ELFT>8686void JSONELFDumper<ELFT>::printSectionGroupMembers(StringRef Name,8687                                                   uint64_t Idx) const {8688  DictScope Grp(this->W);8689  this->W.printString("Name", Name);8690  this->W.printNumber("Index", Idx);8691}8692 8693template <class ELFT> void JSONELFDumper<ELFT>::printEmptyGroupMessage() const {8694  // JSON output does not need to print anything for empty groups8695}8696