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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// 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/DenseMap.h"
21 #include "llvm/ADT/DenseSet.h"
22 #include "llvm/ADT/MapVector.h"
23 #include "llvm/ADT/Optional.h"
24 #include "llvm/ADT/PointerIntPair.h"
25 #include "llvm/ADT/STLExtras.h"
26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/ADT/SmallVector.h"
28 #include "llvm/ADT/StringExtras.h"
29 #include "llvm/ADT/StringRef.h"
30 #include "llvm/ADT/Twine.h"
31 #include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h"
32 #include "llvm/BinaryFormat/ELF.h"
33 #include "llvm/Demangle/Demangle.h"
34 #include "llvm/Object/ELF.h"
35 #include "llvm/Object/ELFObjectFile.h"
36 #include "llvm/Object/ELFTypes.h"
37 #include "llvm/Object/Error.h"
38 #include "llvm/Object/ObjectFile.h"
39 #include "llvm/Object/RelocationResolver.h"
40 #include "llvm/Object/StackMapParser.h"
41 #include "llvm/Support/AMDGPUMetadata.h"
42 #include "llvm/Support/ARMAttributeParser.h"
43 #include "llvm/Support/ARMBuildAttributes.h"
44 #include "llvm/Support/Casting.h"
45 #include "llvm/Support/Compiler.h"
46 #include "llvm/Support/Endian.h"
47 #include "llvm/Support/ErrorHandling.h"
48 #include "llvm/Support/Format.h"
49 #include "llvm/Support/FormatVariadic.h"
50 #include "llvm/Support/FormattedStream.h"
51 #include "llvm/Support/LEB128.h"
52 #include "llvm/Support/MathExtras.h"
53 #include "llvm/Support/MipsABIFlags.h"
54 #include "llvm/Support/RISCVAttributeParser.h"
55 #include "llvm/Support/RISCVAttributes.h"
56 #include "llvm/Support/ScopedPrinter.h"
57 #include "llvm/Support/raw_ostream.h"
58 #include <algorithm>
59 #include <cinttypes>
60 #include <cstddef>
61 #include <cstdint>
62 #include <cstdlib>
63 #include <iterator>
64 #include <memory>
65 #include <string>
66 #include <system_error>
67 #include <vector>
68 
69 using namespace llvm;
70 using namespace llvm::object;
71 using namespace ELF;
72 
73 #define LLVM_READOBJ_ENUM_CASE(ns, enum)                                       \
74   case ns::enum:                                                               \
75     return #enum;
76 
77 #define ENUM_ENT(enum, altName)                                                \
78   { #enum, altName, ELF::enum }
79 
80 #define ENUM_ENT_1(enum)                                                       \
81   { #enum, #enum, ELF::enum }
82 
83 namespace {
84 
85 template <class ELFT> struct RelSymbol {
86   RelSymbol(const typename ELFT::Sym *S, StringRef N)
87       : Sym(S), Name(N.str()) {}
88   const typename ELFT::Sym *Sym;
89   std::string Name;
90 };
91 
92 /// Represents a contiguous uniform range in the file. We cannot just create a
93 /// range directly because when creating one of these from the .dynamic table
94 /// the size, entity size and virtual address are different entries in arbitrary
95 /// order (DT_REL, DT_RELSZ, DT_RELENT for example).
96 struct DynRegionInfo {
97   DynRegionInfo(const Binary &Owner, const ObjDumper &D)
98       : Obj(&Owner), Dumper(&D) {}
99   DynRegionInfo(const Binary &Owner, const ObjDumper &D, const uint8_t *A,
100                 uint64_t S, uint64_t ES)
101       : Addr(A), Size(S), EntSize(ES), Obj(&Owner), Dumper(&D) {}
102 
103   /// Address in current address space.
104   const uint8_t *Addr = nullptr;
105   /// Size in bytes of the region.
106   uint64_t Size = 0;
107   /// Size of each entity in the region.
108   uint64_t EntSize = 0;
109 
110   /// Owner object. Used for error reporting.
111   const Binary *Obj;
112   /// Dumper used for error reporting.
113   const ObjDumper *Dumper;
114   /// Error prefix. Used for error reporting to provide more information.
115   std::string Context;
116   /// Region size name. Used for error reporting.
117   StringRef SizePrintName = "size";
118   /// Entry size name. Used for error reporting. If this field is empty, errors
119   /// will not mention the entry size.
120   StringRef EntSizePrintName = "entry size";
121 
122   template <typename Type> ArrayRef<Type> getAsArrayRef() const {
123     const Type *Start = reinterpret_cast<const Type *>(Addr);
124     if (!Start)
125       return {Start, Start};
126 
127     const uint64_t Offset =
128         Addr - (const uint8_t *)Obj->getMemoryBufferRef().getBufferStart();
129     const uint64_t ObjSize = Obj->getMemoryBufferRef().getBufferSize();
130 
131     if (Size > ObjSize - Offset) {
132       Dumper->reportUniqueWarning(
133           "unable to read data at 0x" + Twine::utohexstr(Offset) +
134           " of size 0x" + Twine::utohexstr(Size) + " (" + SizePrintName +
135           "): it goes past the end of the file of size 0x" +
136           Twine::utohexstr(ObjSize));
137       return {Start, Start};
138     }
139 
140     if (EntSize == sizeof(Type) && (Size % EntSize == 0))
141       return {Start, Start + (Size / EntSize)};
142 
143     std::string Msg;
144     if (!Context.empty())
145       Msg += Context + " has ";
146 
147     Msg += ("invalid " + SizePrintName + " (0x" + Twine::utohexstr(Size) + ")")
148                .str();
149     if (!EntSizePrintName.empty())
150       Msg +=
151           (" or " + EntSizePrintName + " (0x" + Twine::utohexstr(EntSize) + ")")
152               .str();
153 
154     Dumper->reportUniqueWarning(Msg);
155     return {Start, Start};
156   }
157 };
158 
159 struct GroupMember {
160   StringRef Name;
161   uint64_t Index;
162 };
163 
164 struct GroupSection {
165   StringRef Name;
166   std::string Signature;
167   uint64_t ShName;
168   uint64_t Index;
169   uint32_t Link;
170   uint32_t Info;
171   uint32_t Type;
172   std::vector<GroupMember> Members;
173 };
174 
175 namespace {
176 
177 struct NoteType {
178   uint32_t ID;
179   StringRef Name;
180 };
181 
182 } // namespace
183 
184 template <class ELFT> class Relocation {
185 public:
186   Relocation(const typename ELFT::Rel &R, bool IsMips64EL)
187       : Type(R.getType(IsMips64EL)), Symbol(R.getSymbol(IsMips64EL)),
188         Offset(R.r_offset), Info(R.r_info) {}
189 
190   Relocation(const typename ELFT::Rela &R, bool IsMips64EL)
191       : Relocation((const typename ELFT::Rel &)R, IsMips64EL) {
192     Addend = R.r_addend;
193   }
194 
195   uint32_t Type;
196   uint32_t Symbol;
197   typename ELFT::uint Offset;
198   typename ELFT::uint Info;
199   Optional<int64_t> Addend;
200 };
201 
202 template <class ELFT> class MipsGOTParser;
203 
204 template <typename ELFT> class ELFDumper : public ObjDumper {
205   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
206 
207 public:
208   ELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer);
209 
210   void printUnwindInfo() override;
211   void printNeededLibraries() override;
212   void printHashTable() override;
213   void printGnuHashTable() override;
214   void printLoadName() override;
215   void printVersionInfo() override;
216   void printArchSpecificInfo() override;
217   void printStackMap() const override;
218 
219   const object::ELFObjectFile<ELFT> &getElfObject() const { return ObjF; };
220 
221   std::string describe(const Elf_Shdr &Sec) const;
222 
223   unsigned getHashTableEntSize() const {
224     // EM_S390 and ELF::EM_ALPHA platforms use 8-bytes entries in SHT_HASH
225     // sections. This violates the ELF specification.
226     if (Obj.getHeader().e_machine == ELF::EM_S390 ||
227         Obj.getHeader().e_machine == ELF::EM_ALPHA)
228       return 8;
229     return 4;
230   }
231 
232   Elf_Dyn_Range dynamic_table() const {
233     // A valid .dynamic section contains an array of entries terminated
234     // with a DT_NULL entry. However, sometimes the section content may
235     // continue past the DT_NULL entry, so to dump the section correctly,
236     // we first find the end of the entries by iterating over them.
237     Elf_Dyn_Range Table = DynamicTable.template getAsArrayRef<Elf_Dyn>();
238 
239     size_t Size = 0;
240     while (Size < Table.size())
241       if (Table[Size++].getTag() == DT_NULL)
242         break;
243 
244     return Table.slice(0, Size);
245   }
246 
247   Elf_Sym_Range dynamic_symbols() const {
248     if (!DynSymRegion)
249       return Elf_Sym_Range();
250     return DynSymRegion->template getAsArrayRef<Elf_Sym>();
251   }
252 
253   const Elf_Shdr *findSectionByName(StringRef Name) const;
254 
255   StringRef getDynamicStringTable() const { return DynamicStringTable; }
256 
257 protected:
258   virtual void printVersionSymbolSection(const Elf_Shdr *Sec) = 0;
259   virtual void printVersionDefinitionSection(const Elf_Shdr *Sec) = 0;
260   virtual void printVersionDependencySection(const Elf_Shdr *Sec) = 0;
261 
262   void
263   printDependentLibsHelper(function_ref<void(const Elf_Shdr &)> OnSectionStart,
264                            function_ref<void(StringRef, uint64_t)> OnLibEntry);
265 
266   virtual void printRelRelaReloc(const Relocation<ELFT> &R,
267                                  const RelSymbol<ELFT> &RelSym) = 0;
268   virtual void printRelrReloc(const Elf_Relr &R) = 0;
269   virtual void printDynamicRelocHeader(unsigned Type, StringRef Name,
270                                        const DynRegionInfo &Reg) {}
271   void printReloc(const Relocation<ELFT> &R, unsigned RelIndex,
272                   const Elf_Shdr &Sec, const Elf_Shdr *SymTab);
273   void printDynamicReloc(const Relocation<ELFT> &R);
274   void printDynamicRelocationsHelper();
275   void printRelocationsHelper(const Elf_Shdr &Sec);
276   void forEachRelocationDo(
277       const Elf_Shdr &Sec, bool RawRelr,
278       llvm::function_ref<void(const Relocation<ELFT> &, unsigned,
279                               const Elf_Shdr &, const Elf_Shdr *)>
280           RelRelaFn,
281       llvm::function_ref<void(const Elf_Relr &)> RelrFn);
282 
283   virtual void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset,
284                                   bool NonVisibilityBitsUsed) const {};
285   virtual void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
286                            DataRegion<Elf_Word> ShndxTable,
287                            Optional<StringRef> StrTable, bool IsDynamic,
288                            bool NonVisibilityBitsUsed) const = 0;
289 
290   virtual void printMipsABIFlags() = 0;
291   virtual void printMipsGOT(const MipsGOTParser<ELFT> &Parser) = 0;
292   virtual void printMipsPLT(const MipsGOTParser<ELFT> &Parser) = 0;
293 
294   Expected<ArrayRef<Elf_Versym>>
295   getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,
296                   StringRef *StrTab, const Elf_Shdr **SymTabSec) const;
297   StringRef getPrintableSectionName(const Elf_Shdr &Sec) const;
298 
299   std::vector<GroupSection> getGroups();
300 
301   bool printFunctionStackSize(uint64_t SymValue,
302                               Optional<const Elf_Shdr *> FunctionSec,
303                               const Elf_Shdr &StackSizeSec, DataExtractor Data,
304                               uint64_t *Offset);
305   void printStackSize(const Relocation<ELFT> &R, const Elf_Shdr &RelocSec,
306                       unsigned Ndx, const Elf_Shdr *SymTab,
307                       const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec,
308                       const RelocationResolver &Resolver, DataExtractor Data);
309   virtual void printStackSizeEntry(uint64_t Size, StringRef FuncName) = 0;
310 
311   void printRelocatableStackSizes(std::function<void()> PrintHeader);
312   void printNonRelocatableStackSizes(std::function<void()> PrintHeader);
313 
314   const object::ELFObjectFile<ELFT> &ObjF;
315   const ELFFile<ELFT> &Obj;
316   StringRef FileName;
317 
318   Expected<DynRegionInfo> createDRI(uint64_t Offset, uint64_t Size,
319                                     uint64_t EntSize) {
320     if (Offset + Size < Offset || Offset + Size > Obj.getBufSize())
321       return createError("offset (0x" + Twine::utohexstr(Offset) +
322                          ") + size (0x" + Twine::utohexstr(Size) +
323                          ") is greater than the file size (0x" +
324                          Twine::utohexstr(Obj.getBufSize()) + ")");
325     return DynRegionInfo(ObjF, *this, Obj.base() + Offset, Size, EntSize);
326   }
327 
328   void printAttributes();
329   void printMipsReginfo();
330   void printMipsOptions();
331 
332   std::pair<const Elf_Phdr *, const Elf_Shdr *> findDynamic();
333   void loadDynamicTable();
334   void parseDynamicTable();
335 
336   Expected<StringRef> getSymbolVersion(const Elf_Sym &Sym,
337                                        bool &IsDefault) const;
338   Expected<SmallVector<Optional<VersionEntry>, 0> *> getVersionMap() const;
339 
340   DynRegionInfo DynRelRegion;
341   DynRegionInfo DynRelaRegion;
342   DynRegionInfo DynRelrRegion;
343   DynRegionInfo DynPLTRelRegion;
344   Optional<DynRegionInfo> DynSymRegion;
345   DynRegionInfo DynSymTabShndxRegion;
346   DynRegionInfo DynamicTable;
347   StringRef DynamicStringTable;
348   const Elf_Hash *HashTable = nullptr;
349   const Elf_GnuHash *GnuHashTable = nullptr;
350   const Elf_Shdr *DotSymtabSec = nullptr;
351   const Elf_Shdr *DotDynsymSec = nullptr;
352   const Elf_Shdr *DotCGProfileSec = nullptr;
353   const Elf_Shdr *DotAddrsigSec = nullptr;
354   DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
355   Optional<uint64_t> SONameOffset;
356 
357   const Elf_Shdr *SymbolVersionSection = nullptr;   // .gnu.version
358   const Elf_Shdr *SymbolVersionNeedSection = nullptr; // .gnu.version_r
359   const Elf_Shdr *SymbolVersionDefSection = nullptr; // .gnu.version_d
360 
361   std::string getFullSymbolName(const Elf_Sym &Symbol, unsigned SymIndex,
362                                 DataRegion<Elf_Word> ShndxTable,
363                                 Optional<StringRef> StrTable,
364                                 bool IsDynamic) const;
365   Expected<unsigned>
366   getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex,
367                         DataRegion<Elf_Word> ShndxTable) const;
368   Expected<StringRef> getSymbolSectionName(const Elf_Sym &Symbol,
369                                            unsigned SectionIndex) const;
370   std::string getStaticSymbolName(uint32_t Index) const;
371   StringRef getDynamicString(uint64_t Value) const;
372 
373   void printSymbolsHelper(bool IsDynamic) const;
374   std::string getDynamicEntry(uint64_t Type, uint64_t Value) const;
375 
376   Expected<RelSymbol<ELFT>> getRelocationTarget(const Relocation<ELFT> &R,
377                                                 const Elf_Shdr *SymTab) const;
378 
379   ArrayRef<Elf_Word> getShndxTable(const Elf_Shdr *Symtab) const;
380 
381 private:
382   mutable SmallVector<Optional<VersionEntry>, 0> VersionMap;
383 };
384 
385 template <class ELFT>
386 std::string ELFDumper<ELFT>::describe(const Elf_Shdr &Sec) const {
387   return ::describe(Obj, Sec);
388 }
389 
390 namespace {
391 
392 template <class ELFT> struct SymtabLink {
393   typename ELFT::SymRange Symbols;
394   StringRef StringTable;
395   const typename ELFT::Shdr *SymTab;
396 };
397 
398 // Returns the linked symbol table, symbols and associated string table for a
399 // given section.
400 template <class ELFT>
401 Expected<SymtabLink<ELFT>> getLinkAsSymtab(const ELFFile<ELFT> &Obj,
402                                            const typename ELFT::Shdr &Sec,
403                                            unsigned ExpectedType) {
404   Expected<const typename ELFT::Shdr *> SymtabOrErr =
405       Obj.getSection(Sec.sh_link);
406   if (!SymtabOrErr)
407     return createError("invalid section linked to " + describe(Obj, Sec) +
408                        ": " + toString(SymtabOrErr.takeError()));
409 
410   if ((*SymtabOrErr)->sh_type != ExpectedType)
411     return createError(
412         "invalid section linked to " + describe(Obj, Sec) + ": expected " +
413         object::getELFSectionTypeName(Obj.getHeader().e_machine, ExpectedType) +
414         ", but got " +
415         object::getELFSectionTypeName(Obj.getHeader().e_machine,
416                                       (*SymtabOrErr)->sh_type));
417 
418   Expected<StringRef> StrTabOrErr = Obj.getLinkAsStrtab(**SymtabOrErr);
419   if (!StrTabOrErr)
420     return createError(
421         "can't get a string table for the symbol table linked to " +
422         describe(Obj, Sec) + ": " + toString(StrTabOrErr.takeError()));
423 
424   Expected<typename ELFT::SymRange> SymsOrErr = Obj.symbols(*SymtabOrErr);
425   if (!SymsOrErr)
426     return createError("unable to read symbols from the " + describe(Obj, Sec) +
427                        ": " + toString(SymsOrErr.takeError()));
428 
429   return SymtabLink<ELFT>{*SymsOrErr, *StrTabOrErr, *SymtabOrErr};
430 }
431 
432 } // namespace
433 
434 template <class ELFT>
435 Expected<ArrayRef<typename ELFT::Versym>>
436 ELFDumper<ELFT>::getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,
437                                  StringRef *StrTab,
438                                  const Elf_Shdr **SymTabSec) const {
439   assert((!SymTab && !StrTab && !SymTabSec) || (SymTab && StrTab && SymTabSec));
440   if (reinterpret_cast<uintptr_t>(Obj.base() + Sec.sh_offset) %
441           sizeof(uint16_t) !=
442       0)
443     return createError("the " + describe(Sec) + " is misaligned");
444 
445   Expected<ArrayRef<Elf_Versym>> VersionsOrErr =
446       Obj.template getSectionContentsAsArray<Elf_Versym>(Sec);
447   if (!VersionsOrErr)
448     return createError("cannot read content of " + describe(Sec) + ": " +
449                        toString(VersionsOrErr.takeError()));
450 
451   Expected<SymtabLink<ELFT>> SymTabOrErr =
452       getLinkAsSymtab(Obj, Sec, SHT_DYNSYM);
453   if (!SymTabOrErr) {
454     reportUniqueWarning(SymTabOrErr.takeError());
455     return *VersionsOrErr;
456   }
457 
458   if (SymTabOrErr->Symbols.size() != VersionsOrErr->size())
459     reportUniqueWarning(describe(Sec) + ": the number of entries (" +
460                         Twine(VersionsOrErr->size()) +
461                         ") does not match the number of symbols (" +
462                         Twine(SymTabOrErr->Symbols.size()) +
463                         ") in the symbol table with index " +
464                         Twine(Sec.sh_link));
465 
466   if (SymTab) {
467     *SymTab = SymTabOrErr->Symbols;
468     *StrTab = SymTabOrErr->StringTable;
469     *SymTabSec = SymTabOrErr->SymTab;
470   }
471   return *VersionsOrErr;
472 }
473 
474 template <class ELFT>
475 void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {
476   Optional<StringRef> StrTable;
477   size_t Entries = 0;
478   Elf_Sym_Range Syms(nullptr, nullptr);
479   const Elf_Shdr *SymtabSec = IsDynamic ? DotDynsymSec : DotSymtabSec;
480 
481   if (IsDynamic) {
482     StrTable = DynamicStringTable;
483     Syms = dynamic_symbols();
484     Entries = Syms.size();
485   } else if (DotSymtabSec) {
486     if (Expected<StringRef> StrTableOrErr =
487             Obj.getStringTableForSymtab(*DotSymtabSec))
488       StrTable = *StrTableOrErr;
489     else
490       reportUniqueWarning(
491           "unable to get the string table for the SHT_SYMTAB section: " +
492           toString(StrTableOrErr.takeError()));
493 
494     if (Expected<Elf_Sym_Range> SymsOrErr = Obj.symbols(DotSymtabSec))
495       Syms = *SymsOrErr;
496     else
497       reportUniqueWarning(
498           "unable to read symbols from the SHT_SYMTAB section: " +
499           toString(SymsOrErr.takeError()));
500     Entries = DotSymtabSec->getEntityCount();
501   }
502   if (Syms.empty())
503     return;
504 
505   // The st_other field has 2 logical parts. The first two bits hold the symbol
506   // visibility (STV_*) and the remainder hold other platform-specific values.
507   bool NonVisibilityBitsUsed =
508       llvm::any_of(Syms, [](const Elf_Sym &S) { return S.st_other & ~0x3; });
509 
510   DataRegion<Elf_Word> ShndxTable =
511       IsDynamic ? DataRegion<Elf_Word>(
512                       (const Elf_Word *)this->DynSymTabShndxRegion.Addr,
513                       this->getElfObject().getELFFile().end())
514                 : DataRegion<Elf_Word>(this->getShndxTable(SymtabSec));
515 
516   printSymtabMessage(SymtabSec, Entries, NonVisibilityBitsUsed);
517   for (const Elf_Sym &Sym : Syms)
518     printSymbol(Sym, &Sym - Syms.begin(), ShndxTable, StrTable, IsDynamic,
519                 NonVisibilityBitsUsed);
520 }
521 
522 template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {
523   formatted_raw_ostream &OS;
524 
525 public:
526   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
527 
528   GNUELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)
529       : ELFDumper<ELFT>(ObjF, Writer),
530         OS(static_cast<formatted_raw_ostream &>(Writer.getOStream())) {
531     assert(&this->W.getOStream() == &llvm::fouts());
532   }
533 
534   void printFileHeaders() override;
535   void printGroupSections() override;
536   void printRelocations() override;
537   void printSectionHeaders() override;
538   void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override;
539   void printHashSymbols() override;
540   void printSectionDetails() override;
541   void printDependentLibs() override;
542   void printDynamicTable() override;
543   void printDynamicRelocations() override;
544   void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset,
545                           bool NonVisibilityBitsUsed) const override;
546   void printProgramHeaders(bool PrintProgramHeaders,
547                            cl::boolOrDefault PrintSectionMapping) override;
548   void printVersionSymbolSection(const Elf_Shdr *Sec) override;
549   void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
550   void printVersionDependencySection(const Elf_Shdr *Sec) override;
551   void printHashHistograms() override;
552   void printCGProfile() override;
553   void printBBAddrMaps() override;
554   void printAddrsig() override;
555   void printNotes() override;
556   void printELFLinkerOptions() override;
557   void printStackSizes() override;
558 
559 private:
560   void printHashHistogram(const Elf_Hash &HashTable);
561   void printGnuHashHistogram(const Elf_GnuHash &GnuHashTable);
562   void printHashTableSymbols(const Elf_Hash &HashTable);
563   void printGnuHashTableSymbols(const Elf_GnuHash &GnuHashTable);
564 
565   struct Field {
566     std::string Str;
567     unsigned Column;
568 
569     Field(StringRef S, unsigned Col) : Str(std::string(S)), Column(Col) {}
570     Field(unsigned Col) : Column(Col) {}
571   };
572 
573   template <typename T, typename TEnum>
574   std::string printEnum(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) const {
575     for (const EnumEntry<TEnum> &EnumItem : EnumValues)
576       if (EnumItem.Value == Value)
577         return std::string(EnumItem.AltName);
578     return to_hexString(Value, false);
579   }
580 
581   template <typename T, typename TEnum>
582   std::string printFlags(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues,
583                          TEnum EnumMask1 = {}, TEnum EnumMask2 = {},
584                          TEnum EnumMask3 = {}) const {
585     std::string Str;
586     for (const EnumEntry<TEnum> &Flag : EnumValues) {
587       if (Flag.Value == 0)
588         continue;
589 
590       TEnum EnumMask{};
591       if (Flag.Value & EnumMask1)
592         EnumMask = EnumMask1;
593       else if (Flag.Value & EnumMask2)
594         EnumMask = EnumMask2;
595       else if (Flag.Value & EnumMask3)
596         EnumMask = EnumMask3;
597       bool IsEnum = (Flag.Value & EnumMask) != 0;
598       if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
599           (IsEnum && (Value & EnumMask) == Flag.Value)) {
600         if (!Str.empty())
601           Str += ", ";
602         Str += Flag.AltName;
603       }
604     }
605     return Str;
606   }
607 
608   formatted_raw_ostream &printField(struct Field F) const {
609     if (F.Column != 0)
610       OS.PadToColumn(F.Column);
611     OS << F.Str;
612     OS.flush();
613     return OS;
614   }
615   void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex,
616                          DataRegion<Elf_Word> ShndxTable, StringRef StrTable,
617                          uint32_t Bucket);
618   void printRelrReloc(const Elf_Relr &R) override;
619   void printRelRelaReloc(const Relocation<ELFT> &R,
620                          const RelSymbol<ELFT> &RelSym) override;
621   void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
622                    DataRegion<Elf_Word> ShndxTable,
623                    Optional<StringRef> StrTable, bool IsDynamic,
624                    bool NonVisibilityBitsUsed) const override;
625   void printDynamicRelocHeader(unsigned Type, StringRef Name,
626                                const DynRegionInfo &Reg) override;
627 
628   std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex,
629                                   DataRegion<Elf_Word> ShndxTable) const;
630   void printProgramHeaders() override;
631   void printSectionMapping() override;
632   void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec,
633                                     const Twine &Label, unsigned EntriesNum);
634 
635   void printStackSizeEntry(uint64_t Size, StringRef FuncName) override;
636 
637   void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
638   void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
639   void printMipsABIFlags() override;
640 };
641 
642 template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
643 public:
644   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
645 
646   LLVMELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)
647       : ELFDumper<ELFT>(ObjF, Writer), W(Writer) {}
648 
649   void printFileHeaders() override;
650   void printGroupSections() override;
651   void printRelocations() override;
652   void printSectionHeaders() override;
653   void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override;
654   void printDependentLibs() override;
655   void printDynamicTable() override;
656   void printDynamicRelocations() override;
657   void printProgramHeaders(bool PrintProgramHeaders,
658                            cl::boolOrDefault PrintSectionMapping) override;
659   void printVersionSymbolSection(const Elf_Shdr *Sec) override;
660   void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
661   void printVersionDependencySection(const Elf_Shdr *Sec) override;
662   void printHashHistograms() override;
663   void printCGProfile() override;
664   void printBBAddrMaps() override;
665   void printAddrsig() override;
666   void printNotes() override;
667   void printELFLinkerOptions() override;
668   void printStackSizes() override;
669 
670 private:
671   void printRelrReloc(const Elf_Relr &R) override;
672   void printRelRelaReloc(const Relocation<ELFT> &R,
673                          const RelSymbol<ELFT> &RelSym) override;
674 
675   void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex,
676                           DataRegion<Elf_Word> ShndxTable) const;
677   void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
678                    DataRegion<Elf_Word> ShndxTable,
679                    Optional<StringRef> StrTable, bool IsDynamic,
680                    bool /*NonVisibilityBitsUsed*/) const override;
681   void printProgramHeaders() override;
682   void printSectionMapping() override {}
683   void printStackSizeEntry(uint64_t Size, StringRef FuncName) override;
684 
685   void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
686   void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
687   void printMipsABIFlags() override;
688 
689   ScopedPrinter &W;
690 };
691 
692 } // end anonymous namespace
693 
694 namespace llvm {
695 
696 template <class ELFT>
697 static std::unique_ptr<ObjDumper>
698 createELFDumper(const ELFObjectFile<ELFT> &Obj, ScopedPrinter &Writer) {
699   if (opts::Output == opts::GNU)
700     return std::make_unique<GNUELFDumper<ELFT>>(Obj, Writer);
701   return std::make_unique<LLVMELFDumper<ELFT>>(Obj, Writer);
702 }
703 
704 std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj,
705                                            ScopedPrinter &Writer) {
706   // Little-endian 32-bit
707   if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(&Obj))
708     return createELFDumper(*ELFObj, Writer);
709 
710   // Big-endian 32-bit
711   if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(&Obj))
712     return createELFDumper(*ELFObj, Writer);
713 
714   // Little-endian 64-bit
715   if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(&Obj))
716     return createELFDumper(*ELFObj, Writer);
717 
718   // Big-endian 64-bit
719   return createELFDumper(*cast<ELF64BEObjectFile>(&Obj), Writer);
720 }
721 
722 } // end namespace llvm
723 
724 template <class ELFT>
725 Expected<SmallVector<Optional<VersionEntry>, 0> *>
726 ELFDumper<ELFT>::getVersionMap() const {
727   // If the VersionMap has already been loaded or if there is no dynamic symtab
728   // or version table, there is nothing to do.
729   if (!VersionMap.empty() || !DynSymRegion || !SymbolVersionSection)
730     return &VersionMap;
731 
732   Expected<SmallVector<Optional<VersionEntry>, 0>> MapOrErr =
733       Obj.loadVersionMap(SymbolVersionNeedSection, SymbolVersionDefSection);
734   if (MapOrErr)
735     VersionMap = *MapOrErr;
736   else
737     return MapOrErr.takeError();
738 
739   return &VersionMap;
740 }
741 
742 template <typename ELFT>
743 Expected<StringRef> ELFDumper<ELFT>::getSymbolVersion(const Elf_Sym &Sym,
744                                                       bool &IsDefault) const {
745   // This is a dynamic symbol. Look in the GNU symbol version table.
746   if (!SymbolVersionSection) {
747     // No version table.
748     IsDefault = false;
749     return "";
750   }
751 
752   assert(DynSymRegion && "DynSymRegion has not been initialised");
753   // Determine the position in the symbol table of this entry.
754   size_t EntryIndex = (reinterpret_cast<uintptr_t>(&Sym) -
755                        reinterpret_cast<uintptr_t>(DynSymRegion->Addr)) /
756                       sizeof(Elf_Sym);
757 
758   // Get the corresponding version index entry.
759   Expected<const Elf_Versym *> EntryOrErr =
760       Obj.template getEntry<Elf_Versym>(*SymbolVersionSection, EntryIndex);
761   if (!EntryOrErr)
762     return EntryOrErr.takeError();
763 
764   unsigned Version = (*EntryOrErr)->vs_index;
765   if (Version == VER_NDX_LOCAL || Version == VER_NDX_GLOBAL) {
766     IsDefault = false;
767     return "";
768   }
769 
770   Expected<SmallVector<Optional<VersionEntry>, 0> *> MapOrErr =
771       getVersionMap();
772   if (!MapOrErr)
773     return MapOrErr.takeError();
774 
775   return Obj.getSymbolVersionByIndex(Version, IsDefault, **MapOrErr,
776                                      Sym.st_shndx == ELF::SHN_UNDEF);
777 }
778 
779 template <typename ELFT>
780 Expected<RelSymbol<ELFT>>
781 ELFDumper<ELFT>::getRelocationTarget(const Relocation<ELFT> &R,
782                                      const Elf_Shdr *SymTab) const {
783   if (R.Symbol == 0)
784     return RelSymbol<ELFT>(nullptr, "");
785 
786   Expected<const Elf_Sym *> SymOrErr =
787       Obj.template getEntry<Elf_Sym>(*SymTab, R.Symbol);
788   if (!SymOrErr)
789     return createError("unable to read an entry with index " + Twine(R.Symbol) +
790                        " from " + describe(*SymTab) + ": " +
791                        toString(SymOrErr.takeError()));
792   const Elf_Sym *Sym = *SymOrErr;
793   if (!Sym)
794     return RelSymbol<ELFT>(nullptr, "");
795 
796   Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(*SymTab);
797   if (!StrTableOrErr)
798     return StrTableOrErr.takeError();
799 
800   const Elf_Sym *FirstSym =
801       cantFail(Obj.template getEntry<Elf_Sym>(*SymTab, 0));
802   std::string SymbolName =
803       getFullSymbolName(*Sym, Sym - FirstSym, getShndxTable(SymTab),
804                         *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM);
805   return RelSymbol<ELFT>(Sym, SymbolName);
806 }
807 
808 template <typename ELFT>
809 ArrayRef<typename ELFT::Word>
810 ELFDumper<ELFT>::getShndxTable(const Elf_Shdr *Symtab) const {
811   if (Symtab) {
812     auto It = ShndxTables.find(Symtab);
813     if (It != ShndxTables.end())
814       return It->second;
815   }
816   return {};
817 }
818 
819 static std::string maybeDemangle(StringRef Name) {
820   return opts::Demangle ? demangle(std::string(Name)) : Name.str();
821 }
822 
823 template <typename ELFT>
824 std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
825   auto Warn = [&](Error E) -> std::string {
826     reportUniqueWarning("unable to read the name of symbol with index " +
827                         Twine(Index) + ": " + toString(std::move(E)));
828     return "<?>";
829   };
830 
831   Expected<const typename ELFT::Sym *> SymOrErr =
832       Obj.getSymbol(DotSymtabSec, Index);
833   if (!SymOrErr)
834     return Warn(SymOrErr.takeError());
835 
836   Expected<StringRef> StrTabOrErr = Obj.getStringTableForSymtab(*DotSymtabSec);
837   if (!StrTabOrErr)
838     return Warn(StrTabOrErr.takeError());
839 
840   Expected<StringRef> NameOrErr = (*SymOrErr)->getName(*StrTabOrErr);
841   if (!NameOrErr)
842     return Warn(NameOrErr.takeError());
843   return maybeDemangle(*NameOrErr);
844 }
845 
846 template <typename ELFT>
847 std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym &Symbol,
848                                                unsigned SymIndex,
849                                                DataRegion<Elf_Word> ShndxTable,
850                                                Optional<StringRef> StrTable,
851                                                bool IsDynamic) const {
852   if (!StrTable)
853     return "<?>";
854 
855   std::string SymbolName;
856   if (Expected<StringRef> NameOrErr = Symbol.getName(*StrTable)) {
857     SymbolName = maybeDemangle(*NameOrErr);
858   } else {
859     reportUniqueWarning(NameOrErr.takeError());
860     return "<?>";
861   }
862 
863   if (SymbolName.empty() && Symbol.getType() == ELF::STT_SECTION) {
864     Expected<unsigned> SectionIndex =
865         getSymbolSectionIndex(Symbol, SymIndex, ShndxTable);
866     if (!SectionIndex) {
867       reportUniqueWarning(SectionIndex.takeError());
868       return "<?>";
869     }
870     Expected<StringRef> NameOrErr = getSymbolSectionName(Symbol, *SectionIndex);
871     if (!NameOrErr) {
872       reportUniqueWarning(NameOrErr.takeError());
873       return ("<section " + Twine(*SectionIndex) + ">").str();
874     }
875     return std::string(*NameOrErr);
876   }
877 
878   if (!IsDynamic)
879     return SymbolName;
880 
881   bool IsDefault;
882   Expected<StringRef> VersionOrErr = getSymbolVersion(Symbol, IsDefault);
883   if (!VersionOrErr) {
884     reportUniqueWarning(VersionOrErr.takeError());
885     return SymbolName + "@<corrupt>";
886   }
887 
888   if (!VersionOrErr->empty()) {
889     SymbolName += (IsDefault ? "@@" : "@");
890     SymbolName += *VersionOrErr;
891   }
892   return SymbolName;
893 }
894 
895 template <typename ELFT>
896 Expected<unsigned>
897 ELFDumper<ELFT>::getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex,
898                                        DataRegion<Elf_Word> ShndxTable) const {
899   unsigned Ndx = Symbol.st_shndx;
900   if (Ndx == SHN_XINDEX)
901     return object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex,
902                                                      ShndxTable);
903   if (Ndx != SHN_UNDEF && Ndx < SHN_LORESERVE)
904     return Ndx;
905 
906   auto CreateErr = [&](const Twine &Name, Optional<unsigned> Offset = None) {
907     std::string Desc;
908     if (Offset)
909       Desc = (Name + "+0x" + Twine::utohexstr(*Offset)).str();
910     else
911       Desc = Name.str();
912     return createError(
913         "unable to get section index for symbol with st_shndx = 0x" +
914         Twine::utohexstr(Ndx) + " (" + Desc + ")");
915   };
916 
917   if (Ndx >= ELF::SHN_LOPROC && Ndx <= ELF::SHN_HIPROC)
918     return CreateErr("SHN_LOPROC", Ndx - ELF::SHN_LOPROC);
919   if (Ndx >= ELF::SHN_LOOS && Ndx <= ELF::SHN_HIOS)
920     return CreateErr("SHN_LOOS", Ndx - ELF::SHN_LOOS);
921   if (Ndx == ELF::SHN_UNDEF)
922     return CreateErr("SHN_UNDEF");
923   if (Ndx == ELF::SHN_ABS)
924     return CreateErr("SHN_ABS");
925   if (Ndx == ELF::SHN_COMMON)
926     return CreateErr("SHN_COMMON");
927   return CreateErr("SHN_LORESERVE", Ndx - SHN_LORESERVE);
928 }
929 
930 template <typename ELFT>
931 Expected<StringRef>
932 ELFDumper<ELFT>::getSymbolSectionName(const Elf_Sym &Symbol,
933                                       unsigned SectionIndex) const {
934   Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(SectionIndex);
935   if (!SecOrErr)
936     return SecOrErr.takeError();
937   return Obj.getSectionName(**SecOrErr);
938 }
939 
940 template <class ELFO>
941 static const typename ELFO::Elf_Shdr *
942 findNotEmptySectionByAddress(const ELFO &Obj, StringRef FileName,
943                              uint64_t Addr) {
944   for (const typename ELFO::Elf_Shdr &Shdr : cantFail(Obj.sections()))
945     if (Shdr.sh_addr == Addr && Shdr.sh_size > 0)
946       return &Shdr;
947   return nullptr;
948 }
949 
950 static const EnumEntry<unsigned> ElfClass[] = {
951   {"None",   "none",   ELF::ELFCLASSNONE},
952   {"32-bit", "ELF32",  ELF::ELFCLASS32},
953   {"64-bit", "ELF64",  ELF::ELFCLASS64},
954 };
955 
956 static const EnumEntry<unsigned> ElfDataEncoding[] = {
957   {"None",         "none",                          ELF::ELFDATANONE},
958   {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB},
959   {"BigEndian",    "2's complement, big endian",    ELF::ELFDATA2MSB},
960 };
961 
962 static const EnumEntry<unsigned> ElfObjectFileType[] = {
963   {"None",         "NONE (none)",              ELF::ET_NONE},
964   {"Relocatable",  "REL (Relocatable file)",   ELF::ET_REL},
965   {"Executable",   "EXEC (Executable file)",   ELF::ET_EXEC},
966   {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN},
967   {"Core",         "CORE (Core file)",         ELF::ET_CORE},
968 };
969 
970 static const EnumEntry<unsigned> ElfOSABI[] = {
971   {"SystemV",      "UNIX - System V",      ELF::ELFOSABI_NONE},
972   {"HPUX",         "UNIX - HP-UX",         ELF::ELFOSABI_HPUX},
973   {"NetBSD",       "UNIX - NetBSD",        ELF::ELFOSABI_NETBSD},
974   {"GNU/Linux",    "UNIX - GNU",           ELF::ELFOSABI_LINUX},
975   {"GNU/Hurd",     "GNU/Hurd",             ELF::ELFOSABI_HURD},
976   {"Solaris",      "UNIX - Solaris",       ELF::ELFOSABI_SOLARIS},
977   {"AIX",          "UNIX - AIX",           ELF::ELFOSABI_AIX},
978   {"IRIX",         "UNIX - IRIX",          ELF::ELFOSABI_IRIX},
979   {"FreeBSD",      "UNIX - FreeBSD",       ELF::ELFOSABI_FREEBSD},
980   {"TRU64",        "UNIX - TRU64",         ELF::ELFOSABI_TRU64},
981   {"Modesto",      "Novell - Modesto",     ELF::ELFOSABI_MODESTO},
982   {"OpenBSD",      "UNIX - OpenBSD",       ELF::ELFOSABI_OPENBSD},
983   {"OpenVMS",      "VMS - OpenVMS",        ELF::ELFOSABI_OPENVMS},
984   {"NSK",          "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK},
985   {"AROS",         "AROS",                 ELF::ELFOSABI_AROS},
986   {"FenixOS",      "FenixOS",              ELF::ELFOSABI_FENIXOS},
987   {"CloudABI",     "CloudABI",             ELF::ELFOSABI_CLOUDABI},
988   {"Standalone",   "Standalone App",       ELF::ELFOSABI_STANDALONE}
989 };
990 
991 static const EnumEntry<unsigned> AMDGPUElfOSABI[] = {
992   {"AMDGPU_HSA",    "AMDGPU - HSA",    ELF::ELFOSABI_AMDGPU_HSA},
993   {"AMDGPU_PAL",    "AMDGPU - PAL",    ELF::ELFOSABI_AMDGPU_PAL},
994   {"AMDGPU_MESA3D", "AMDGPU - MESA3D", ELF::ELFOSABI_AMDGPU_MESA3D}
995 };
996 
997 static const EnumEntry<unsigned> ARMElfOSABI[] = {
998   {"ARM", "ARM", ELF::ELFOSABI_ARM}
999 };
1000 
1001 static const EnumEntry<unsigned> C6000ElfOSABI[] = {
1002   {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI},
1003   {"C6000_LINUX",  "Linux C6000",      ELF::ELFOSABI_C6000_LINUX}
1004 };
1005 
1006 static const EnumEntry<unsigned> ElfMachineType[] = {
1007   ENUM_ENT(EM_NONE,          "None"),
1008   ENUM_ENT(EM_M32,           "WE32100"),
1009   ENUM_ENT(EM_SPARC,         "Sparc"),
1010   ENUM_ENT(EM_386,           "Intel 80386"),
1011   ENUM_ENT(EM_68K,           "MC68000"),
1012   ENUM_ENT(EM_88K,           "MC88000"),
1013   ENUM_ENT(EM_IAMCU,         "EM_IAMCU"),
1014   ENUM_ENT(EM_860,           "Intel 80860"),
1015   ENUM_ENT(EM_MIPS,          "MIPS R3000"),
1016   ENUM_ENT(EM_S370,          "IBM System/370"),
1017   ENUM_ENT(EM_MIPS_RS3_LE,   "MIPS R3000 little-endian"),
1018   ENUM_ENT(EM_PARISC,        "HPPA"),
1019   ENUM_ENT(EM_VPP500,        "Fujitsu VPP500"),
1020   ENUM_ENT(EM_SPARC32PLUS,   "Sparc v8+"),
1021   ENUM_ENT(EM_960,           "Intel 80960"),
1022   ENUM_ENT(EM_PPC,           "PowerPC"),
1023   ENUM_ENT(EM_PPC64,         "PowerPC64"),
1024   ENUM_ENT(EM_S390,          "IBM S/390"),
1025   ENUM_ENT(EM_SPU,           "SPU"),
1026   ENUM_ENT(EM_V800,          "NEC V800 series"),
1027   ENUM_ENT(EM_FR20,          "Fujistsu FR20"),
1028   ENUM_ENT(EM_RH32,          "TRW RH-32"),
1029   ENUM_ENT(EM_RCE,           "Motorola RCE"),
1030   ENUM_ENT(EM_ARM,           "ARM"),
1031   ENUM_ENT(EM_ALPHA,         "EM_ALPHA"),
1032   ENUM_ENT(EM_SH,            "Hitachi SH"),
1033   ENUM_ENT(EM_SPARCV9,       "Sparc v9"),
1034   ENUM_ENT(EM_TRICORE,       "Siemens Tricore"),
1035   ENUM_ENT(EM_ARC,           "ARC"),
1036   ENUM_ENT(EM_H8_300,        "Hitachi H8/300"),
1037   ENUM_ENT(EM_H8_300H,       "Hitachi H8/300H"),
1038   ENUM_ENT(EM_H8S,           "Hitachi H8S"),
1039   ENUM_ENT(EM_H8_500,        "Hitachi H8/500"),
1040   ENUM_ENT(EM_IA_64,         "Intel IA-64"),
1041   ENUM_ENT(EM_MIPS_X,        "Stanford MIPS-X"),
1042   ENUM_ENT(EM_COLDFIRE,      "Motorola Coldfire"),
1043   ENUM_ENT(EM_68HC12,        "Motorola MC68HC12 Microcontroller"),
1044   ENUM_ENT(EM_MMA,           "Fujitsu Multimedia Accelerator"),
1045   ENUM_ENT(EM_PCP,           "Siemens PCP"),
1046   ENUM_ENT(EM_NCPU,          "Sony nCPU embedded RISC processor"),
1047   ENUM_ENT(EM_NDR1,          "Denso NDR1 microprocesspr"),
1048   ENUM_ENT(EM_STARCORE,      "Motorola Star*Core processor"),
1049   ENUM_ENT(EM_ME16,          "Toyota ME16 processor"),
1050   ENUM_ENT(EM_ST100,         "STMicroelectronics ST100 processor"),
1051   ENUM_ENT(EM_TINYJ,         "Advanced Logic Corp. TinyJ embedded processor"),
1052   ENUM_ENT(EM_X86_64,        "Advanced Micro Devices X86-64"),
1053   ENUM_ENT(EM_PDSP,          "Sony DSP processor"),
1054   ENUM_ENT(EM_PDP10,         "Digital Equipment Corp. PDP-10"),
1055   ENUM_ENT(EM_PDP11,         "Digital Equipment Corp. PDP-11"),
1056   ENUM_ENT(EM_FX66,          "Siemens FX66 microcontroller"),
1057   ENUM_ENT(EM_ST9PLUS,       "STMicroelectronics ST9+ 8/16 bit microcontroller"),
1058   ENUM_ENT(EM_ST7,           "STMicroelectronics ST7 8-bit microcontroller"),
1059   ENUM_ENT(EM_68HC16,        "Motorola MC68HC16 Microcontroller"),
1060   ENUM_ENT(EM_68HC11,        "Motorola MC68HC11 Microcontroller"),
1061   ENUM_ENT(EM_68HC08,        "Motorola MC68HC08 Microcontroller"),
1062   ENUM_ENT(EM_68HC05,        "Motorola MC68HC05 Microcontroller"),
1063   ENUM_ENT(EM_SVX,           "Silicon Graphics SVx"),
1064   ENUM_ENT(EM_ST19,          "STMicroelectronics ST19 8-bit microcontroller"),
1065   ENUM_ENT(EM_VAX,           "Digital VAX"),
1066   ENUM_ENT(EM_CRIS,          "Axis Communications 32-bit embedded processor"),
1067   ENUM_ENT(EM_JAVELIN,       "Infineon Technologies 32-bit embedded cpu"),
1068   ENUM_ENT(EM_FIREPATH,      "Element 14 64-bit DSP processor"),
1069   ENUM_ENT(EM_ZSP,           "LSI Logic's 16-bit DSP processor"),
1070   ENUM_ENT(EM_MMIX,          "Donald Knuth's educational 64-bit processor"),
1071   ENUM_ENT(EM_HUANY,         "Harvard Universitys's machine-independent object format"),
1072   ENUM_ENT(EM_PRISM,         "Vitesse Prism"),
1073   ENUM_ENT(EM_AVR,           "Atmel AVR 8-bit microcontroller"),
1074   ENUM_ENT(EM_FR30,          "Fujitsu FR30"),
1075   ENUM_ENT(EM_D10V,          "Mitsubishi D10V"),
1076   ENUM_ENT(EM_D30V,          "Mitsubishi D30V"),
1077   ENUM_ENT(EM_V850,          "NEC v850"),
1078   ENUM_ENT(EM_M32R,          "Renesas M32R (formerly Mitsubishi M32r)"),
1079   ENUM_ENT(EM_MN10300,       "Matsushita MN10300"),
1080   ENUM_ENT(EM_MN10200,       "Matsushita MN10200"),
1081   ENUM_ENT(EM_PJ,            "picoJava"),
1082   ENUM_ENT(EM_OPENRISC,      "OpenRISC 32-bit embedded processor"),
1083   ENUM_ENT(EM_ARC_COMPACT,   "EM_ARC_COMPACT"),
1084   ENUM_ENT(EM_XTENSA,        "Tensilica Xtensa Processor"),
1085   ENUM_ENT(EM_VIDEOCORE,     "Alphamosaic VideoCore processor"),
1086   ENUM_ENT(EM_TMM_GPP,       "Thompson Multimedia General Purpose Processor"),
1087   ENUM_ENT(EM_NS32K,         "National Semiconductor 32000 series"),
1088   ENUM_ENT(EM_TPC,           "Tenor Network TPC processor"),
1089   ENUM_ENT(EM_SNP1K,         "EM_SNP1K"),
1090   ENUM_ENT(EM_ST200,         "STMicroelectronics ST200 microcontroller"),
1091   ENUM_ENT(EM_IP2K,          "Ubicom IP2xxx 8-bit microcontrollers"),
1092   ENUM_ENT(EM_MAX,           "MAX Processor"),
1093   ENUM_ENT(EM_CR,            "National Semiconductor CompactRISC"),
1094   ENUM_ENT(EM_F2MC16,        "Fujitsu F2MC16"),
1095   ENUM_ENT(EM_MSP430,        "Texas Instruments msp430 microcontroller"),
1096   ENUM_ENT(EM_BLACKFIN,      "Analog Devices Blackfin"),
1097   ENUM_ENT(EM_SE_C33,        "S1C33 Family of Seiko Epson processors"),
1098   ENUM_ENT(EM_SEP,           "Sharp embedded microprocessor"),
1099   ENUM_ENT(EM_ARCA,          "Arca RISC microprocessor"),
1100   ENUM_ENT(EM_UNICORE,       "Unicore"),
1101   ENUM_ENT(EM_EXCESS,        "eXcess 16/32/64-bit configurable embedded CPU"),
1102   ENUM_ENT(EM_DXP,           "Icera Semiconductor Inc. Deep Execution Processor"),
1103   ENUM_ENT(EM_ALTERA_NIOS2,  "Altera Nios"),
1104   ENUM_ENT(EM_CRX,           "National Semiconductor CRX microprocessor"),
1105   ENUM_ENT(EM_XGATE,         "Motorola XGATE embedded processor"),
1106   ENUM_ENT(EM_C166,          "Infineon Technologies xc16x"),
1107   ENUM_ENT(EM_M16C,          "Renesas M16C"),
1108   ENUM_ENT(EM_DSPIC30F,      "Microchip Technology dsPIC30F Digital Signal Controller"),
1109   ENUM_ENT(EM_CE,            "Freescale Communication Engine RISC core"),
1110   ENUM_ENT(EM_M32C,          "Renesas M32C"),
1111   ENUM_ENT(EM_TSK3000,       "Altium TSK3000 core"),
1112   ENUM_ENT(EM_RS08,          "Freescale RS08 embedded processor"),
1113   ENUM_ENT(EM_SHARC,         "EM_SHARC"),
1114   ENUM_ENT(EM_ECOG2,         "Cyan Technology eCOG2 microprocessor"),
1115   ENUM_ENT(EM_SCORE7,        "SUNPLUS S+Core"),
1116   ENUM_ENT(EM_DSP24,         "New Japan Radio (NJR) 24-bit DSP Processor"),
1117   ENUM_ENT(EM_VIDEOCORE3,    "Broadcom VideoCore III processor"),
1118   ENUM_ENT(EM_LATTICEMICO32, "Lattice Mico32"),
1119   ENUM_ENT(EM_SE_C17,        "Seiko Epson C17 family"),
1120   ENUM_ENT(EM_TI_C6000,      "Texas Instruments TMS320C6000 DSP family"),
1121   ENUM_ENT(EM_TI_C2000,      "Texas Instruments TMS320C2000 DSP family"),
1122   ENUM_ENT(EM_TI_C5500,      "Texas Instruments TMS320C55x DSP family"),
1123   ENUM_ENT(EM_MMDSP_PLUS,    "STMicroelectronics 64bit VLIW Data Signal Processor"),
1124   ENUM_ENT(EM_CYPRESS_M8C,   "Cypress M8C microprocessor"),
1125   ENUM_ENT(EM_R32C,          "Renesas R32C series microprocessors"),
1126   ENUM_ENT(EM_TRIMEDIA,      "NXP Semiconductors TriMedia architecture family"),
1127   ENUM_ENT(EM_HEXAGON,       "Qualcomm Hexagon"),
1128   ENUM_ENT(EM_8051,          "Intel 8051 and variants"),
1129   ENUM_ENT(EM_STXP7X,        "STMicroelectronics STxP7x family"),
1130   ENUM_ENT(EM_NDS32,         "Andes Technology compact code size embedded RISC processor family"),
1131   ENUM_ENT(EM_ECOG1,         "Cyan Technology eCOG1 microprocessor"),
1132   // FIXME: Following EM_ECOG1X definitions is dead code since EM_ECOG1X has
1133   //        an identical number to EM_ECOG1.
1134   ENUM_ENT(EM_ECOG1X,        "Cyan Technology eCOG1X family"),
1135   ENUM_ENT(EM_MAXQ30,        "Dallas Semiconductor MAXQ30 Core microcontrollers"),
1136   ENUM_ENT(EM_XIMO16,        "New Japan Radio (NJR) 16-bit DSP Processor"),
1137   ENUM_ENT(EM_MANIK,         "M2000 Reconfigurable RISC Microprocessor"),
1138   ENUM_ENT(EM_CRAYNV2,       "Cray Inc. NV2 vector architecture"),
1139   ENUM_ENT(EM_RX,            "Renesas RX"),
1140   ENUM_ENT(EM_METAG,         "Imagination Technologies Meta processor architecture"),
1141   ENUM_ENT(EM_MCST_ELBRUS,   "MCST Elbrus general purpose hardware architecture"),
1142   ENUM_ENT(EM_ECOG16,        "Cyan Technology eCOG16 family"),
1143   ENUM_ENT(EM_CR16,          "Xilinx MicroBlaze"),
1144   ENUM_ENT(EM_ETPU,          "Freescale Extended Time Processing Unit"),
1145   ENUM_ENT(EM_SLE9X,         "Infineon Technologies SLE9X core"),
1146   ENUM_ENT(EM_L10M,          "EM_L10M"),
1147   ENUM_ENT(EM_K10M,          "EM_K10M"),
1148   ENUM_ENT(EM_AARCH64,       "AArch64"),
1149   ENUM_ENT(EM_AVR32,         "Atmel Corporation 32-bit microprocessor family"),
1150   ENUM_ENT(EM_STM8,          "STMicroeletronics STM8 8-bit microcontroller"),
1151   ENUM_ENT(EM_TILE64,        "Tilera TILE64 multicore architecture family"),
1152   ENUM_ENT(EM_TILEPRO,       "Tilera TILEPro multicore architecture family"),
1153   ENUM_ENT(EM_CUDA,          "NVIDIA CUDA architecture"),
1154   ENUM_ENT(EM_TILEGX,        "Tilera TILE-Gx multicore architecture family"),
1155   ENUM_ENT(EM_CLOUDSHIELD,   "EM_CLOUDSHIELD"),
1156   ENUM_ENT(EM_COREA_1ST,     "EM_COREA_1ST"),
1157   ENUM_ENT(EM_COREA_2ND,     "EM_COREA_2ND"),
1158   ENUM_ENT(EM_ARC_COMPACT2,  "EM_ARC_COMPACT2"),
1159   ENUM_ENT(EM_OPEN8,         "EM_OPEN8"),
1160   ENUM_ENT(EM_RL78,          "Renesas RL78"),
1161   ENUM_ENT(EM_VIDEOCORE5,    "Broadcom VideoCore V processor"),
1162   ENUM_ENT(EM_78KOR,         "EM_78KOR"),
1163   ENUM_ENT(EM_56800EX,       "EM_56800EX"),
1164   ENUM_ENT(EM_AMDGPU,        "EM_AMDGPU"),
1165   ENUM_ENT(EM_RISCV,         "RISC-V"),
1166   ENUM_ENT(EM_LANAI,         "EM_LANAI"),
1167   ENUM_ENT(EM_BPF,           "EM_BPF"),
1168   ENUM_ENT(EM_VE,            "NEC SX-Aurora Vector Engine"),
1169 };
1170 
1171 static const EnumEntry<unsigned> ElfSymbolBindings[] = {
1172     {"Local",  "LOCAL",  ELF::STB_LOCAL},
1173     {"Global", "GLOBAL", ELF::STB_GLOBAL},
1174     {"Weak",   "WEAK",   ELF::STB_WEAK},
1175     {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE}};
1176 
1177 static const EnumEntry<unsigned> ElfSymbolVisibilities[] = {
1178     {"DEFAULT",   "DEFAULT",   ELF::STV_DEFAULT},
1179     {"INTERNAL",  "INTERNAL",  ELF::STV_INTERNAL},
1180     {"HIDDEN",    "HIDDEN",    ELF::STV_HIDDEN},
1181     {"PROTECTED", "PROTECTED", ELF::STV_PROTECTED}};
1182 
1183 static const EnumEntry<unsigned> AMDGPUSymbolTypes[] = {
1184   { "AMDGPU_HSA_KERNEL",            ELF::STT_AMDGPU_HSA_KERNEL }
1185 };
1186 
1187 static const char *getGroupType(uint32_t Flag) {
1188   if (Flag & ELF::GRP_COMDAT)
1189     return "COMDAT";
1190   else
1191     return "(unknown)";
1192 }
1193 
1194 static const EnumEntry<unsigned> ElfSectionFlags[] = {
1195   ENUM_ENT(SHF_WRITE,            "W"),
1196   ENUM_ENT(SHF_ALLOC,            "A"),
1197   ENUM_ENT(SHF_EXECINSTR,        "X"),
1198   ENUM_ENT(SHF_MERGE,            "M"),
1199   ENUM_ENT(SHF_STRINGS,          "S"),
1200   ENUM_ENT(SHF_INFO_LINK,        "I"),
1201   ENUM_ENT(SHF_LINK_ORDER,       "L"),
1202   ENUM_ENT(SHF_OS_NONCONFORMING, "O"),
1203   ENUM_ENT(SHF_GROUP,            "G"),
1204   ENUM_ENT(SHF_TLS,              "T"),
1205   ENUM_ENT(SHF_COMPRESSED,       "C"),
1206   ENUM_ENT(SHF_GNU_RETAIN,       "R"),
1207   ENUM_ENT(SHF_EXCLUDE,          "E"),
1208 };
1209 
1210 static const EnumEntry<unsigned> ElfXCoreSectionFlags[] = {
1211   ENUM_ENT(XCORE_SHF_CP_SECTION, ""),
1212   ENUM_ENT(XCORE_SHF_DP_SECTION, "")
1213 };
1214 
1215 static const EnumEntry<unsigned> ElfARMSectionFlags[] = {
1216   ENUM_ENT(SHF_ARM_PURECODE, "y")
1217 };
1218 
1219 static const EnumEntry<unsigned> ElfHexagonSectionFlags[] = {
1220   ENUM_ENT(SHF_HEX_GPREL, "")
1221 };
1222 
1223 static const EnumEntry<unsigned> ElfMipsSectionFlags[] = {
1224   ENUM_ENT(SHF_MIPS_NODUPES, ""),
1225   ENUM_ENT(SHF_MIPS_NAMES,   ""),
1226   ENUM_ENT(SHF_MIPS_LOCAL,   ""),
1227   ENUM_ENT(SHF_MIPS_NOSTRIP, ""),
1228   ENUM_ENT(SHF_MIPS_GPREL,   ""),
1229   ENUM_ENT(SHF_MIPS_MERGE,   ""),
1230   ENUM_ENT(SHF_MIPS_ADDR,    ""),
1231   ENUM_ENT(SHF_MIPS_STRING,  "")
1232 };
1233 
1234 static const EnumEntry<unsigned> ElfX86_64SectionFlags[] = {
1235   ENUM_ENT(SHF_X86_64_LARGE, "l")
1236 };
1237 
1238 static std::vector<EnumEntry<unsigned>>
1239 getSectionFlagsForTarget(unsigned EMachine) {
1240   std::vector<EnumEntry<unsigned>> Ret(std::begin(ElfSectionFlags),
1241                                        std::end(ElfSectionFlags));
1242   switch (EMachine) {
1243   case EM_ARM:
1244     Ret.insert(Ret.end(), std::begin(ElfARMSectionFlags),
1245                std::end(ElfARMSectionFlags));
1246     break;
1247   case EM_HEXAGON:
1248     Ret.insert(Ret.end(), std::begin(ElfHexagonSectionFlags),
1249                std::end(ElfHexagonSectionFlags));
1250     break;
1251   case EM_MIPS:
1252     Ret.insert(Ret.end(), std::begin(ElfMipsSectionFlags),
1253                std::end(ElfMipsSectionFlags));
1254     break;
1255   case EM_X86_64:
1256     Ret.insert(Ret.end(), std::begin(ElfX86_64SectionFlags),
1257                std::end(ElfX86_64SectionFlags));
1258     break;
1259   case EM_XCORE:
1260     Ret.insert(Ret.end(), std::begin(ElfXCoreSectionFlags),
1261                std::end(ElfXCoreSectionFlags));
1262     break;
1263   default:
1264     break;
1265   }
1266   return Ret;
1267 }
1268 
1269 static std::string getGNUFlags(unsigned EMachine, uint64_t Flags) {
1270   // Here we are trying to build the flags string in the same way as GNU does.
1271   // It is not that straightforward. Imagine we have sh_flags == 0x90000000.
1272   // SHF_EXCLUDE ("E") has a value of 0x80000000 and SHF_MASKPROC is 0xf0000000.
1273   // GNU readelf will not print "E" or "Ep" in this case, but will print just
1274   // "p". It only will print "E" when no other processor flag is set.
1275   std::string Str;
1276   bool HasUnknownFlag = false;
1277   bool HasOSFlag = false;
1278   bool HasProcFlag = false;
1279   std::vector<EnumEntry<unsigned>> FlagsList =
1280       getSectionFlagsForTarget(EMachine);
1281   while (Flags) {
1282     // Take the least significant bit as a flag.
1283     uint64_t Flag = Flags & -Flags;
1284     Flags -= Flag;
1285 
1286     // Find the flag in the known flags list.
1287     auto I = llvm::find_if(FlagsList, [=](const EnumEntry<unsigned> &E) {
1288       // Flags with empty names are not printed in GNU style output.
1289       return E.Value == Flag && !E.AltName.empty();
1290     });
1291     if (I != FlagsList.end()) {
1292       Str += I->AltName;
1293       continue;
1294     }
1295 
1296     // If we did not find a matching regular flag, then we deal with an OS
1297     // specific flag, processor specific flag or an unknown flag.
1298     if (Flag & ELF::SHF_MASKOS) {
1299       HasOSFlag = true;
1300       Flags &= ~ELF::SHF_MASKOS;
1301     } else if (Flag & ELF::SHF_MASKPROC) {
1302       HasProcFlag = true;
1303       // Mask off all the processor-specific bits. This removes the SHF_EXCLUDE
1304       // bit if set so that it doesn't also get printed.
1305       Flags &= ~ELF::SHF_MASKPROC;
1306     } else {
1307       HasUnknownFlag = true;
1308     }
1309   }
1310 
1311   // "o", "p" and "x" are printed last.
1312   if (HasOSFlag)
1313     Str += "o";
1314   if (HasProcFlag)
1315     Str += "p";
1316   if (HasUnknownFlag)
1317     Str += "x";
1318   return Str;
1319 }
1320 
1321 static StringRef segmentTypeToString(unsigned Arch, unsigned Type) {
1322   // Check potentially overlapped processor-specific program header type.
1323   switch (Arch) {
1324   case ELF::EM_ARM:
1325     switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); }
1326     break;
1327   case ELF::EM_MIPS:
1328   case ELF::EM_MIPS_RS3_LE:
1329     switch (Type) {
1330       LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
1331       LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
1332       LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
1333       LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);
1334     }
1335     break;
1336   }
1337 
1338   switch (Type) {
1339     LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL);
1340     LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD);
1341     LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
1342     LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP);
1343     LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE);
1344     LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB);
1345     LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR);
1346     LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS);
1347 
1348     LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
1349     LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
1350 
1351     LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
1352     LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
1353     LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_PROPERTY);
1354 
1355     LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE);
1356     LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED);
1357     LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA);
1358   default:
1359     return "";
1360   }
1361 }
1362 
1363 static std::string getGNUPtType(unsigned Arch, unsigned Type) {
1364   StringRef Seg = segmentTypeToString(Arch, Type);
1365   if (Seg.empty())
1366     return std::string("<unknown>: ") + to_string(format_hex(Type, 1));
1367 
1368   // E.g. "PT_ARM_EXIDX" -> "EXIDX".
1369   if (Seg.startswith("PT_ARM_"))
1370     return Seg.drop_front(7).str();
1371 
1372   // E.g. "PT_MIPS_REGINFO" -> "REGINFO".
1373   if (Seg.startswith("PT_MIPS_"))
1374     return Seg.drop_front(8).str();
1375 
1376   // E.g. "PT_LOAD" -> "LOAD".
1377   assert(Seg.startswith("PT_"));
1378   return Seg.drop_front(3).str();
1379 }
1380 
1381 static const EnumEntry<unsigned> ElfSegmentFlags[] = {
1382   LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
1383   LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
1384   LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
1385 };
1386 
1387 static const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
1388   ENUM_ENT(EF_MIPS_NOREORDER, "noreorder"),
1389   ENUM_ENT(EF_MIPS_PIC, "pic"),
1390   ENUM_ENT(EF_MIPS_CPIC, "cpic"),
1391   ENUM_ENT(EF_MIPS_ABI2, "abi2"),
1392   ENUM_ENT(EF_MIPS_32BITMODE, "32bitmode"),
1393   ENUM_ENT(EF_MIPS_FP64, "fp64"),
1394   ENUM_ENT(EF_MIPS_NAN2008, "nan2008"),
1395   ENUM_ENT(EF_MIPS_ABI_O32, "o32"),
1396   ENUM_ENT(EF_MIPS_ABI_O64, "o64"),
1397   ENUM_ENT(EF_MIPS_ABI_EABI32, "eabi32"),
1398   ENUM_ENT(EF_MIPS_ABI_EABI64, "eabi64"),
1399   ENUM_ENT(EF_MIPS_MACH_3900, "3900"),
1400   ENUM_ENT(EF_MIPS_MACH_4010, "4010"),
1401   ENUM_ENT(EF_MIPS_MACH_4100, "4100"),
1402   ENUM_ENT(EF_MIPS_MACH_4650, "4650"),
1403   ENUM_ENT(EF_MIPS_MACH_4120, "4120"),
1404   ENUM_ENT(EF_MIPS_MACH_4111, "4111"),
1405   ENUM_ENT(EF_MIPS_MACH_SB1, "sb1"),
1406   ENUM_ENT(EF_MIPS_MACH_OCTEON, "octeon"),
1407   ENUM_ENT(EF_MIPS_MACH_XLR, "xlr"),
1408   ENUM_ENT(EF_MIPS_MACH_OCTEON2, "octeon2"),
1409   ENUM_ENT(EF_MIPS_MACH_OCTEON3, "octeon3"),
1410   ENUM_ENT(EF_MIPS_MACH_5400, "5400"),
1411   ENUM_ENT(EF_MIPS_MACH_5900, "5900"),
1412   ENUM_ENT(EF_MIPS_MACH_5500, "5500"),
1413   ENUM_ENT(EF_MIPS_MACH_9000, "9000"),
1414   ENUM_ENT(EF_MIPS_MACH_LS2E, "loongson-2e"),
1415   ENUM_ENT(EF_MIPS_MACH_LS2F, "loongson-2f"),
1416   ENUM_ENT(EF_MIPS_MACH_LS3A, "loongson-3a"),
1417   ENUM_ENT(EF_MIPS_MICROMIPS, "micromips"),
1418   ENUM_ENT(EF_MIPS_ARCH_ASE_M16, "mips16"),
1419   ENUM_ENT(EF_MIPS_ARCH_ASE_MDMX, "mdmx"),
1420   ENUM_ENT(EF_MIPS_ARCH_1, "mips1"),
1421   ENUM_ENT(EF_MIPS_ARCH_2, "mips2"),
1422   ENUM_ENT(EF_MIPS_ARCH_3, "mips3"),
1423   ENUM_ENT(EF_MIPS_ARCH_4, "mips4"),
1424   ENUM_ENT(EF_MIPS_ARCH_5, "mips5"),
1425   ENUM_ENT(EF_MIPS_ARCH_32, "mips32"),
1426   ENUM_ENT(EF_MIPS_ARCH_64, "mips64"),
1427   ENUM_ENT(EF_MIPS_ARCH_32R2, "mips32r2"),
1428   ENUM_ENT(EF_MIPS_ARCH_64R2, "mips64r2"),
1429   ENUM_ENT(EF_MIPS_ARCH_32R6, "mips32r6"),
1430   ENUM_ENT(EF_MIPS_ARCH_64R6, "mips64r6")
1431 };
1432 
1433 static const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion3[] = {
1434   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_NONE),
1435   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R600),
1436   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R630),
1437   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RS880),
1438   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV670),
1439   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV710),
1440   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV730),
1441   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV770),
1442   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CEDAR),
1443   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CYPRESS),
1444   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_JUNIPER),
1445   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_REDWOOD),
1446   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_SUMO),
1447   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_BARTS),
1448   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAICOS),
1449   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAYMAN),
1450   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_TURKS),
1451   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX600),
1452   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX601),
1453   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX602),
1454   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX700),
1455   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX701),
1456   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX702),
1457   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX703),
1458   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX704),
1459   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX705),
1460   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX801),
1461   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX802),
1462   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX803),
1463   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX805),
1464   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX810),
1465   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX900),
1466   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX902),
1467   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX904),
1468   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX906),
1469   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX908),
1470   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX909),
1471   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX90A),
1472   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX90C),
1473   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1010),
1474   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1011),
1475   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1012),
1476   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1030),
1477   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1031),
1478   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1032),
1479   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1033),
1480   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_XNACK_V3),
1481   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_SRAMECC_V3)
1482 };
1483 
1484 static const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion4[] = {
1485   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_NONE),
1486   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R600),
1487   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_R630),
1488   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RS880),
1489   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV670),
1490   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV710),
1491   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV730),
1492   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_RV770),
1493   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CEDAR),
1494   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CYPRESS),
1495   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_JUNIPER),
1496   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_REDWOOD),
1497   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_SUMO),
1498   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_BARTS),
1499   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAICOS),
1500   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_CAYMAN),
1501   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_R600_TURKS),
1502   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX600),
1503   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX601),
1504   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX602),
1505   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX700),
1506   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX701),
1507   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX702),
1508   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX703),
1509   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX704),
1510   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX705),
1511   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX801),
1512   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX802),
1513   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX803),
1514   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX805),
1515   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX810),
1516   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX900),
1517   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX902),
1518   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX904),
1519   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX906),
1520   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX908),
1521   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX909),
1522   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX90A),
1523   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX90C),
1524   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1010),
1525   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1011),
1526   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1012),
1527   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1030),
1528   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1031),
1529   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1032),
1530   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1033),
1531   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_XNACK_ANY_V4),
1532   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_XNACK_OFF_V4),
1533   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_XNACK_ON_V4),
1534   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_SRAMECC_ANY_V4),
1535   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_SRAMECC_OFF_V4),
1536   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_FEATURE_SRAMECC_ON_V4)
1537 };
1538 
1539 static const EnumEntry<unsigned> ElfHeaderRISCVFlags[] = {
1540   ENUM_ENT(EF_RISCV_RVC, "RVC"),
1541   ENUM_ENT(EF_RISCV_FLOAT_ABI_SINGLE, "single-float ABI"),
1542   ENUM_ENT(EF_RISCV_FLOAT_ABI_DOUBLE, "double-float ABI"),
1543   ENUM_ENT(EF_RISCV_FLOAT_ABI_QUAD, "quad-float ABI"),
1544   ENUM_ENT(EF_RISCV_RVE, "RVE")
1545 };
1546 
1547 static const EnumEntry<unsigned> ElfHeaderAVRFlags[] = {
1548   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR1),
1549   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR2),
1550   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR25),
1551   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR3),
1552   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR31),
1553   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR35),
1554   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR4),
1555   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR5),
1556   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR51),
1557   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR6),
1558   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVRTINY),
1559   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA1),
1560   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA2),
1561   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA3),
1562   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA4),
1563   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA5),
1564   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA6),
1565   LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA7),
1566   ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"),
1567 };
1568 
1569 
1570 static const EnumEntry<unsigned> ElfSymOtherFlags[] = {
1571   LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL),
1572   LLVM_READOBJ_ENUM_ENT(ELF, STV_HIDDEN),
1573   LLVM_READOBJ_ENUM_ENT(ELF, STV_PROTECTED)
1574 };
1575 
1576 static const EnumEntry<unsigned> ElfMipsSymOtherFlags[] = {
1577   LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
1578   LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
1579   LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PIC),
1580   LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MICROMIPS)
1581 };
1582 
1583 static const EnumEntry<unsigned> ElfAArch64SymOtherFlags[] = {
1584   LLVM_READOBJ_ENUM_ENT(ELF, STO_AARCH64_VARIANT_PCS)
1585 };
1586 
1587 static const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = {
1588   LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
1589   LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
1590   LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16)
1591 };
1592 
1593 static const char *getElfMipsOptionsOdkType(unsigned Odk) {
1594   switch (Odk) {
1595   LLVM_READOBJ_ENUM_CASE(ELF, ODK_NULL);
1596   LLVM_READOBJ_ENUM_CASE(ELF, ODK_REGINFO);
1597   LLVM_READOBJ_ENUM_CASE(ELF, ODK_EXCEPTIONS);
1598   LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAD);
1599   LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWPATCH);
1600   LLVM_READOBJ_ENUM_CASE(ELF, ODK_FILL);
1601   LLVM_READOBJ_ENUM_CASE(ELF, ODK_TAGS);
1602   LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWAND);
1603   LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWOR);
1604   LLVM_READOBJ_ENUM_CASE(ELF, ODK_GP_GROUP);
1605   LLVM_READOBJ_ENUM_CASE(ELF, ODK_IDENT);
1606   LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAGESIZE);
1607   default:
1608     return "Unknown";
1609   }
1610 }
1611 
1612 template <typename ELFT>
1613 std::pair<const typename ELFT::Phdr *, const typename ELFT::Shdr *>
1614 ELFDumper<ELFT>::findDynamic() {
1615   // Try to locate the PT_DYNAMIC header.
1616   const Elf_Phdr *DynamicPhdr = nullptr;
1617   if (Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = Obj.program_headers()) {
1618     for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
1619       if (Phdr.p_type != ELF::PT_DYNAMIC)
1620         continue;
1621       DynamicPhdr = &Phdr;
1622       break;
1623     }
1624   } else {
1625     reportUniqueWarning(
1626         "unable to read program headers to locate the PT_DYNAMIC segment: " +
1627         toString(PhdrsOrErr.takeError()));
1628   }
1629 
1630   // Try to locate the .dynamic section in the sections header table.
1631   const Elf_Shdr *DynamicSec = nullptr;
1632   for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
1633     if (Sec.sh_type != ELF::SHT_DYNAMIC)
1634       continue;
1635     DynamicSec = &Sec;
1636     break;
1637   }
1638 
1639   if (DynamicPhdr && ((DynamicPhdr->p_offset + DynamicPhdr->p_filesz >
1640                        ObjF.getMemoryBufferRef().getBufferSize()) ||
1641                       (DynamicPhdr->p_offset + DynamicPhdr->p_filesz <
1642                        DynamicPhdr->p_offset))) {
1643     reportUniqueWarning(
1644         "PT_DYNAMIC segment offset (0x" +
1645         Twine::utohexstr(DynamicPhdr->p_offset) + ") + file size (0x" +
1646         Twine::utohexstr(DynamicPhdr->p_filesz) +
1647         ") exceeds the size of the file (0x" +
1648         Twine::utohexstr(ObjF.getMemoryBufferRef().getBufferSize()) + ")");
1649     // Don't use the broken dynamic header.
1650     DynamicPhdr = nullptr;
1651   }
1652 
1653   if (DynamicPhdr && DynamicSec) {
1654     if (DynamicSec->sh_addr + DynamicSec->sh_size >
1655             DynamicPhdr->p_vaddr + DynamicPhdr->p_memsz ||
1656         DynamicSec->sh_addr < DynamicPhdr->p_vaddr)
1657       reportUniqueWarning(describe(*DynamicSec) +
1658                           " is not contained within the "
1659                           "PT_DYNAMIC segment");
1660 
1661     if (DynamicSec->sh_addr != DynamicPhdr->p_vaddr)
1662       reportUniqueWarning(describe(*DynamicSec) + " is not at the start of "
1663                                                   "PT_DYNAMIC segment");
1664   }
1665 
1666   return std::make_pair(DynamicPhdr, DynamicSec);
1667 }
1668 
1669 template <typename ELFT>
1670 void ELFDumper<ELFT>::loadDynamicTable() {
1671   const Elf_Phdr *DynamicPhdr;
1672   const Elf_Shdr *DynamicSec;
1673   std::tie(DynamicPhdr, DynamicSec) = findDynamic();
1674   if (!DynamicPhdr && !DynamicSec)
1675     return;
1676 
1677   DynRegionInfo FromPhdr(ObjF, *this);
1678   bool IsPhdrTableValid = false;
1679   if (DynamicPhdr) {
1680     // Use cantFail(), because p_offset/p_filesz fields of a PT_DYNAMIC are
1681     // validated in findDynamic() and so createDRI() is not expected to fail.
1682     FromPhdr = cantFail(createDRI(DynamicPhdr->p_offset, DynamicPhdr->p_filesz,
1683                                   sizeof(Elf_Dyn)));
1684     FromPhdr.SizePrintName = "PT_DYNAMIC size";
1685     FromPhdr.EntSizePrintName = "";
1686     IsPhdrTableValid = !FromPhdr.template getAsArrayRef<Elf_Dyn>().empty();
1687   }
1688 
1689   // Locate the dynamic table described in a section header.
1690   // Ignore sh_entsize and use the expected value for entry size explicitly.
1691   // This allows us to dump dynamic sections with a broken sh_entsize
1692   // field.
1693   DynRegionInfo FromSec(ObjF, *this);
1694   bool IsSecTableValid = false;
1695   if (DynamicSec) {
1696     Expected<DynRegionInfo> RegOrErr =
1697         createDRI(DynamicSec->sh_offset, DynamicSec->sh_size, sizeof(Elf_Dyn));
1698     if (RegOrErr) {
1699       FromSec = *RegOrErr;
1700       FromSec.Context = describe(*DynamicSec);
1701       FromSec.EntSizePrintName = "";
1702       IsSecTableValid = !FromSec.template getAsArrayRef<Elf_Dyn>().empty();
1703     } else {
1704       reportUniqueWarning("unable to read the dynamic table from " +
1705                           describe(*DynamicSec) + ": " +
1706                           toString(RegOrErr.takeError()));
1707     }
1708   }
1709 
1710   // When we only have information from one of the SHT_DYNAMIC section header or
1711   // PT_DYNAMIC program header, just use that.
1712   if (!DynamicPhdr || !DynamicSec) {
1713     if ((DynamicPhdr && IsPhdrTableValid) || (DynamicSec && IsSecTableValid)) {
1714       DynamicTable = DynamicPhdr ? FromPhdr : FromSec;
1715       parseDynamicTable();
1716     } else {
1717       reportUniqueWarning("no valid dynamic table was found");
1718     }
1719     return;
1720   }
1721 
1722   // At this point we have tables found from the section header and from the
1723   // dynamic segment. Usually they match, but we have to do sanity checks to
1724   // verify that.
1725 
1726   if (FromPhdr.Addr != FromSec.Addr)
1727     reportUniqueWarning("SHT_DYNAMIC section header and PT_DYNAMIC "
1728                         "program header disagree about "
1729                         "the location of the dynamic table");
1730 
1731   if (!IsPhdrTableValid && !IsSecTableValid) {
1732     reportUniqueWarning("no valid dynamic table was found");
1733     return;
1734   }
1735 
1736   // Information in the PT_DYNAMIC program header has priority over the
1737   // information in a section header.
1738   if (IsPhdrTableValid) {
1739     if (!IsSecTableValid)
1740       reportUniqueWarning(
1741           "SHT_DYNAMIC dynamic table is invalid: PT_DYNAMIC will be used");
1742     DynamicTable = FromPhdr;
1743   } else {
1744     reportUniqueWarning(
1745         "PT_DYNAMIC dynamic table is invalid: SHT_DYNAMIC will be used");
1746     DynamicTable = FromSec;
1747   }
1748 
1749   parseDynamicTable();
1750 }
1751 
1752 template <typename ELFT>
1753 ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> &O,
1754                            ScopedPrinter &Writer)
1755     : ObjDumper(Writer, O.getFileName()), ObjF(O), Obj(O.getELFFile()),
1756       FileName(O.getFileName()), DynRelRegion(O, *this),
1757       DynRelaRegion(O, *this), DynRelrRegion(O, *this),
1758       DynPLTRelRegion(O, *this), DynSymTabShndxRegion(O, *this),
1759       DynamicTable(O, *this) {
1760   if (!O.IsContentValid())
1761     return;
1762 
1763   typename ELFT::ShdrRange Sections = cantFail(Obj.sections());
1764   for (const Elf_Shdr &Sec : Sections) {
1765     switch (Sec.sh_type) {
1766     case ELF::SHT_SYMTAB:
1767       if (!DotSymtabSec)
1768         DotSymtabSec = &Sec;
1769       break;
1770     case ELF::SHT_DYNSYM:
1771       if (!DotDynsymSec)
1772         DotDynsymSec = &Sec;
1773 
1774       if (!DynSymRegion) {
1775         Expected<DynRegionInfo> RegOrErr =
1776             createDRI(Sec.sh_offset, Sec.sh_size, Sec.sh_entsize);
1777         if (RegOrErr) {
1778           DynSymRegion = *RegOrErr;
1779           DynSymRegion->Context = describe(Sec);
1780 
1781           if (Expected<StringRef> E = Obj.getStringTableForSymtab(Sec))
1782             DynamicStringTable = *E;
1783           else
1784             reportUniqueWarning("unable to get the string table for the " +
1785                                 describe(Sec) + ": " + toString(E.takeError()));
1786         } else {
1787           reportUniqueWarning("unable to read dynamic symbols from " +
1788                               describe(Sec) + ": " +
1789                               toString(RegOrErr.takeError()));
1790         }
1791       }
1792       break;
1793     case ELF::SHT_SYMTAB_SHNDX: {
1794       uint32_t SymtabNdx = Sec.sh_link;
1795       if (SymtabNdx >= Sections.size()) {
1796         reportUniqueWarning(
1797             "unable to get the associated symbol table for " + describe(Sec) +
1798             ": sh_link (" + Twine(SymtabNdx) +
1799             ") is greater than or equal to the total number of sections (" +
1800             Twine(Sections.size()) + ")");
1801         continue;
1802       }
1803 
1804       if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
1805               Obj.getSHNDXTable(Sec)) {
1806         if (!ShndxTables.insert({&Sections[SymtabNdx], *ShndxTableOrErr})
1807                  .second)
1808           reportUniqueWarning(
1809               "multiple SHT_SYMTAB_SHNDX sections are linked to " +
1810               describe(Sec));
1811       } else {
1812         reportUniqueWarning(ShndxTableOrErr.takeError());
1813       }
1814       break;
1815     }
1816     case ELF::SHT_GNU_versym:
1817       if (!SymbolVersionSection)
1818         SymbolVersionSection = &Sec;
1819       break;
1820     case ELF::SHT_GNU_verdef:
1821       if (!SymbolVersionDefSection)
1822         SymbolVersionDefSection = &Sec;
1823       break;
1824     case ELF::SHT_GNU_verneed:
1825       if (!SymbolVersionNeedSection)
1826         SymbolVersionNeedSection = &Sec;
1827       break;
1828     case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
1829       if (!DotCGProfileSec)
1830         DotCGProfileSec = &Sec;
1831       break;
1832     case ELF::SHT_LLVM_ADDRSIG:
1833       if (!DotAddrsigSec)
1834         DotAddrsigSec = &Sec;
1835       break;
1836     }
1837   }
1838 
1839   loadDynamicTable();
1840 }
1841 
1842 template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() {
1843   auto toMappedAddr = [&](uint64_t Tag, uint64_t VAddr) -> const uint8_t * {
1844     auto MappedAddrOrError = Obj.toMappedAddr(VAddr, [&](const Twine &Msg) {
1845       this->reportUniqueWarning(Msg);
1846       return Error::success();
1847     });
1848     if (!MappedAddrOrError) {
1849       this->reportUniqueWarning("unable to parse DT_" +
1850                                 Obj.getDynamicTagAsString(Tag) + ": " +
1851                                 llvm::toString(MappedAddrOrError.takeError()));
1852       return nullptr;
1853     }
1854     return MappedAddrOrError.get();
1855   };
1856 
1857   const char *StringTableBegin = nullptr;
1858   uint64_t StringTableSize = 0;
1859   Optional<DynRegionInfo> DynSymFromTable;
1860   for (const Elf_Dyn &Dyn : dynamic_table()) {
1861     switch (Dyn.d_tag) {
1862     case ELF::DT_HASH:
1863       HashTable = reinterpret_cast<const Elf_Hash *>(
1864           toMappedAddr(Dyn.getTag(), Dyn.getPtr()));
1865       break;
1866     case ELF::DT_GNU_HASH:
1867       GnuHashTable = reinterpret_cast<const Elf_GnuHash *>(
1868           toMappedAddr(Dyn.getTag(), Dyn.getPtr()));
1869       break;
1870     case ELF::DT_STRTAB:
1871       StringTableBegin = reinterpret_cast<const char *>(
1872           toMappedAddr(Dyn.getTag(), Dyn.getPtr()));
1873       break;
1874     case ELF::DT_STRSZ:
1875       StringTableSize = Dyn.getVal();
1876       break;
1877     case ELF::DT_SYMTAB: {
1878       // If we can't map the DT_SYMTAB value to an address (e.g. when there are
1879       // no program headers), we ignore its value.
1880       if (const uint8_t *VA = toMappedAddr(Dyn.getTag(), Dyn.getPtr())) {
1881         DynSymFromTable.emplace(ObjF, *this);
1882         DynSymFromTable->Addr = VA;
1883         DynSymFromTable->EntSize = sizeof(Elf_Sym);
1884         DynSymFromTable->EntSizePrintName = "";
1885       }
1886       break;
1887     }
1888     case ELF::DT_SYMENT: {
1889       uint64_t Val = Dyn.getVal();
1890       if (Val != sizeof(Elf_Sym))
1891         this->reportUniqueWarning("DT_SYMENT value of 0x" +
1892                                   Twine::utohexstr(Val) +
1893                                   " is not the size of a symbol (0x" +
1894                                   Twine::utohexstr(sizeof(Elf_Sym)) + ")");
1895       break;
1896     }
1897     case ELF::DT_RELA:
1898       DynRelaRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
1899       break;
1900     case ELF::DT_RELASZ:
1901       DynRelaRegion.Size = Dyn.getVal();
1902       DynRelaRegion.SizePrintName = "DT_RELASZ value";
1903       break;
1904     case ELF::DT_RELAENT:
1905       DynRelaRegion.EntSize = Dyn.getVal();
1906       DynRelaRegion.EntSizePrintName = "DT_RELAENT value";
1907       break;
1908     case ELF::DT_SONAME:
1909       SONameOffset = Dyn.getVal();
1910       break;
1911     case ELF::DT_REL:
1912       DynRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
1913       break;
1914     case ELF::DT_RELSZ:
1915       DynRelRegion.Size = Dyn.getVal();
1916       DynRelRegion.SizePrintName = "DT_RELSZ value";
1917       break;
1918     case ELF::DT_RELENT:
1919       DynRelRegion.EntSize = Dyn.getVal();
1920       DynRelRegion.EntSizePrintName = "DT_RELENT value";
1921       break;
1922     case ELF::DT_RELR:
1923     case ELF::DT_ANDROID_RELR:
1924       DynRelrRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
1925       break;
1926     case ELF::DT_RELRSZ:
1927     case ELF::DT_ANDROID_RELRSZ:
1928       DynRelrRegion.Size = Dyn.getVal();
1929       DynRelrRegion.SizePrintName = Dyn.d_tag == ELF::DT_RELRSZ
1930                                         ? "DT_RELRSZ value"
1931                                         : "DT_ANDROID_RELRSZ value";
1932       break;
1933     case ELF::DT_RELRENT:
1934     case ELF::DT_ANDROID_RELRENT:
1935       DynRelrRegion.EntSize = Dyn.getVal();
1936       DynRelrRegion.EntSizePrintName = Dyn.d_tag == ELF::DT_RELRENT
1937                                            ? "DT_RELRENT value"
1938                                            : "DT_ANDROID_RELRENT value";
1939       break;
1940     case ELF::DT_PLTREL:
1941       if (Dyn.getVal() == DT_REL)
1942         DynPLTRelRegion.EntSize = sizeof(Elf_Rel);
1943       else if (Dyn.getVal() == DT_RELA)
1944         DynPLTRelRegion.EntSize = sizeof(Elf_Rela);
1945       else
1946         reportUniqueWarning(Twine("unknown DT_PLTREL value of ") +
1947                             Twine((uint64_t)Dyn.getVal()));
1948       DynPLTRelRegion.EntSizePrintName = "PLTREL entry size";
1949       break;
1950     case ELF::DT_JMPREL:
1951       DynPLTRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
1952       break;
1953     case ELF::DT_PLTRELSZ:
1954       DynPLTRelRegion.Size = Dyn.getVal();
1955       DynPLTRelRegion.SizePrintName = "DT_PLTRELSZ value";
1956       break;
1957     case ELF::DT_SYMTAB_SHNDX:
1958       DynSymTabShndxRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
1959       DynSymTabShndxRegion.EntSize = sizeof(Elf_Word);
1960       break;
1961     }
1962   }
1963 
1964   if (StringTableBegin) {
1965     const uint64_t FileSize = Obj.getBufSize();
1966     const uint64_t Offset = (const uint8_t *)StringTableBegin - Obj.base();
1967     if (StringTableSize > FileSize - Offset)
1968       reportUniqueWarning(
1969           "the dynamic string table at 0x" + Twine::utohexstr(Offset) +
1970           " goes past the end of the file (0x" + Twine::utohexstr(FileSize) +
1971           ") with DT_STRSZ = 0x" + Twine::utohexstr(StringTableSize));
1972     else
1973       DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
1974   }
1975 
1976   const bool IsHashTableSupported = getHashTableEntSize() == 4;
1977   if (DynSymRegion) {
1978     // Often we find the information about the dynamic symbol table
1979     // location in the SHT_DYNSYM section header. However, the value in
1980     // DT_SYMTAB has priority, because it is used by dynamic loaders to
1981     // locate .dynsym at runtime. The location we find in the section header
1982     // and the location we find here should match.
1983     if (DynSymFromTable && DynSymFromTable->Addr != DynSymRegion->Addr)
1984       reportUniqueWarning(
1985           createError("SHT_DYNSYM section header and DT_SYMTAB disagree about "
1986                       "the location of the dynamic symbol table"));
1987 
1988     // According to the ELF gABI: "The number of symbol table entries should
1989     // equal nchain". Check to see if the DT_HASH hash table nchain value
1990     // conflicts with the number of symbols in the dynamic symbol table
1991     // according to the section header.
1992     if (HashTable && IsHashTableSupported) {
1993       if (DynSymRegion->EntSize == 0)
1994         reportUniqueWarning("SHT_DYNSYM section has sh_entsize == 0");
1995       else if (HashTable->nchain != DynSymRegion->Size / DynSymRegion->EntSize)
1996         reportUniqueWarning(
1997             "hash table nchain (" + Twine(HashTable->nchain) +
1998             ") differs from symbol count derived from SHT_DYNSYM section "
1999             "header (" +
2000             Twine(DynSymRegion->Size / DynSymRegion->EntSize) + ")");
2001     }
2002   }
2003 
2004   // Delay the creation of the actual dynamic symbol table until now, so that
2005   // checks can always be made against the section header-based properties,
2006   // without worrying about tag order.
2007   if (DynSymFromTable) {
2008     if (!DynSymRegion) {
2009       DynSymRegion = DynSymFromTable;
2010     } else {
2011       DynSymRegion->Addr = DynSymFromTable->Addr;
2012       DynSymRegion->EntSize = DynSymFromTable->EntSize;
2013       DynSymRegion->EntSizePrintName = DynSymFromTable->EntSizePrintName;
2014     }
2015   }
2016 
2017   // Derive the dynamic symbol table size from the DT_HASH hash table, if
2018   // present.
2019   if (HashTable && IsHashTableSupported && DynSymRegion) {
2020     const uint64_t FileSize = Obj.getBufSize();
2021     const uint64_t DerivedSize =
2022         (uint64_t)HashTable->nchain * DynSymRegion->EntSize;
2023     const uint64_t Offset = (const uint8_t *)DynSymRegion->Addr - Obj.base();
2024     if (DerivedSize > FileSize - Offset)
2025       reportUniqueWarning(
2026           "the size (0x" + Twine::utohexstr(DerivedSize) +
2027           ") of the dynamic symbol table at 0x" + Twine::utohexstr(Offset) +
2028           ", derived from the hash table, goes past the end of the file (0x" +
2029           Twine::utohexstr(FileSize) + ") and will be ignored");
2030     else
2031       DynSymRegion->Size = HashTable->nchain * DynSymRegion->EntSize;
2032   }
2033 }
2034 
2035 template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
2036   // Dump version symbol section.
2037   printVersionSymbolSection(SymbolVersionSection);
2038 
2039   // Dump version definition section.
2040   printVersionDefinitionSection(SymbolVersionDefSection);
2041 
2042   // Dump version dependency section.
2043   printVersionDependencySection(SymbolVersionNeedSection);
2044 }
2045 
2046 #define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum)                                 \
2047   { #enum, prefix##_##enum }
2048 
2049 static const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
2050   LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
2051   LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
2052   LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
2053   LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
2054   LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
2055 };
2056 
2057 static const EnumEntry<unsigned> ElfDynamicDTFlags1[] = {
2058   LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW),
2059   LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL),
2060   LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP),
2061   LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE),
2062   LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR),
2063   LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST),
2064   LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN),
2065   LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN),
2066   LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT),
2067   LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS),
2068   LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE),
2069   LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB),
2070   LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP),
2071   LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT),
2072   LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE),
2073   LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE),
2074   LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELPND),
2075   LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT),
2076   LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF),
2077   LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS),
2078   LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR),
2079   LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED),
2080   LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC),
2081   LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE),
2082   LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT),
2083   LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON),
2084   LLVM_READOBJ_DT_FLAG_ENT(DF_1, PIE),
2085 };
2086 
2087 static const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
2088   LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
2089   LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
2090   LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
2091   LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
2092   LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
2093   LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
2094   LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
2095   LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
2096   LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
2097   LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
2098   LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
2099   LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
2100   LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
2101   LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
2102   LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
2103   LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
2104 };
2105 
2106 #undef LLVM_READOBJ_DT_FLAG_ENT
2107 
2108 template <typename T, typename TFlag>
2109 void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
2110   SmallVector<EnumEntry<TFlag>, 10> SetFlags;
2111   for (const EnumEntry<TFlag> &Flag : Flags)
2112     if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value)
2113       SetFlags.push_back(Flag);
2114 
2115   for (const EnumEntry<TFlag> &Flag : SetFlags)
2116     OS << Flag.Name << " ";
2117 }
2118 
2119 template <class ELFT>
2120 const typename ELFT::Shdr *
2121 ELFDumper<ELFT>::findSectionByName(StringRef Name) const {
2122   for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) {
2123     if (Expected<StringRef> NameOrErr = Obj.getSectionName(Shdr)) {
2124       if (*NameOrErr == Name)
2125         return &Shdr;
2126     } else {
2127       reportUniqueWarning("unable to read the name of " + describe(Shdr) +
2128                           ": " + toString(NameOrErr.takeError()));
2129     }
2130   }
2131   return nullptr;
2132 }
2133 
2134 template <class ELFT>
2135 std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type,
2136                                              uint64_t Value) const {
2137   auto FormatHexValue = [](uint64_t V) {
2138     std::string Str;
2139     raw_string_ostream OS(Str);
2140     const char *ConvChar =
2141         (opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64;
2142     OS << format(ConvChar, V);
2143     return OS.str();
2144   };
2145 
2146   auto FormatFlags = [](uint64_t V,
2147                         llvm::ArrayRef<llvm::EnumEntry<unsigned int>> Array) {
2148     std::string Str;
2149     raw_string_ostream OS(Str);
2150     printFlags(V, Array, OS);
2151     return OS.str();
2152   };
2153 
2154   // Handle custom printing of architecture specific tags
2155   switch (Obj.getHeader().e_machine) {
2156   case EM_AARCH64:
2157     switch (Type) {
2158     case DT_AARCH64_BTI_PLT:
2159     case DT_AARCH64_PAC_PLT:
2160     case DT_AARCH64_VARIANT_PCS:
2161       return std::to_string(Value);
2162     default:
2163       break;
2164     }
2165     break;
2166   case EM_HEXAGON:
2167     switch (Type) {
2168     case DT_HEXAGON_VER:
2169       return std::to_string(Value);
2170     case DT_HEXAGON_SYMSZ:
2171     case DT_HEXAGON_PLT:
2172       return FormatHexValue(Value);
2173     default:
2174       break;
2175     }
2176     break;
2177   case EM_MIPS:
2178     switch (Type) {
2179     case DT_MIPS_RLD_VERSION:
2180     case DT_MIPS_LOCAL_GOTNO:
2181     case DT_MIPS_SYMTABNO:
2182     case DT_MIPS_UNREFEXTNO:
2183       return std::to_string(Value);
2184     case DT_MIPS_TIME_STAMP:
2185     case DT_MIPS_ICHECKSUM:
2186     case DT_MIPS_IVERSION:
2187     case DT_MIPS_BASE_ADDRESS:
2188     case DT_MIPS_MSYM:
2189     case DT_MIPS_CONFLICT:
2190     case DT_MIPS_LIBLIST:
2191     case DT_MIPS_CONFLICTNO:
2192     case DT_MIPS_LIBLISTNO:
2193     case DT_MIPS_GOTSYM:
2194     case DT_MIPS_HIPAGENO:
2195     case DT_MIPS_RLD_MAP:
2196     case DT_MIPS_DELTA_CLASS:
2197     case DT_MIPS_DELTA_CLASS_NO:
2198     case DT_MIPS_DELTA_INSTANCE:
2199     case DT_MIPS_DELTA_RELOC:
2200     case DT_MIPS_DELTA_RELOC_NO:
2201     case DT_MIPS_DELTA_SYM:
2202     case DT_MIPS_DELTA_SYM_NO:
2203     case DT_MIPS_DELTA_CLASSSYM:
2204     case DT_MIPS_DELTA_CLASSSYM_NO:
2205     case DT_MIPS_CXX_FLAGS:
2206     case DT_MIPS_PIXIE_INIT:
2207     case DT_MIPS_SYMBOL_LIB:
2208     case DT_MIPS_LOCALPAGE_GOTIDX:
2209     case DT_MIPS_LOCAL_GOTIDX:
2210     case DT_MIPS_HIDDEN_GOTIDX:
2211     case DT_MIPS_PROTECTED_GOTIDX:
2212     case DT_MIPS_OPTIONS:
2213     case DT_MIPS_INTERFACE:
2214     case DT_MIPS_DYNSTR_ALIGN:
2215     case DT_MIPS_INTERFACE_SIZE:
2216     case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:
2217     case DT_MIPS_PERF_SUFFIX:
2218     case DT_MIPS_COMPACT_SIZE:
2219     case DT_MIPS_GP_VALUE:
2220     case DT_MIPS_AUX_DYNAMIC:
2221     case DT_MIPS_PLTGOT:
2222     case DT_MIPS_RWPLT:
2223     case DT_MIPS_RLD_MAP_REL:
2224       return FormatHexValue(Value);
2225     case DT_MIPS_FLAGS:
2226       return FormatFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags));
2227     default:
2228       break;
2229     }
2230     break;
2231   default:
2232     break;
2233   }
2234 
2235   switch (Type) {
2236   case DT_PLTREL:
2237     if (Value == DT_REL)
2238       return "REL";
2239     if (Value == DT_RELA)
2240       return "RELA";
2241     LLVM_FALLTHROUGH;
2242   case DT_PLTGOT:
2243   case DT_HASH:
2244   case DT_STRTAB:
2245   case DT_SYMTAB:
2246   case DT_RELA:
2247   case DT_INIT:
2248   case DT_FINI:
2249   case DT_REL:
2250   case DT_JMPREL:
2251   case DT_INIT_ARRAY:
2252   case DT_FINI_ARRAY:
2253   case DT_PREINIT_ARRAY:
2254   case DT_DEBUG:
2255   case DT_VERDEF:
2256   case DT_VERNEED:
2257   case DT_VERSYM:
2258   case DT_GNU_HASH:
2259   case DT_NULL:
2260     return FormatHexValue(Value);
2261   case DT_RELACOUNT:
2262   case DT_RELCOUNT:
2263   case DT_VERDEFNUM:
2264   case DT_VERNEEDNUM:
2265     return std::to_string(Value);
2266   case DT_PLTRELSZ:
2267   case DT_RELASZ:
2268   case DT_RELAENT:
2269   case DT_STRSZ:
2270   case DT_SYMENT:
2271   case DT_RELSZ:
2272   case DT_RELENT:
2273   case DT_INIT_ARRAYSZ:
2274   case DT_FINI_ARRAYSZ:
2275   case DT_PREINIT_ARRAYSZ:
2276   case DT_ANDROID_RELSZ:
2277   case DT_ANDROID_RELASZ:
2278     return std::to_string(Value) + " (bytes)";
2279   case DT_NEEDED:
2280   case DT_SONAME:
2281   case DT_AUXILIARY:
2282   case DT_USED:
2283   case DT_FILTER:
2284   case DT_RPATH:
2285   case DT_RUNPATH: {
2286     const std::map<uint64_t, const char *> TagNames = {
2287         {DT_NEEDED, "Shared library"},       {DT_SONAME, "Library soname"},
2288         {DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"},
2289         {DT_FILTER, "Filter library"},       {DT_RPATH, "Library rpath"},
2290         {DT_RUNPATH, "Library runpath"},
2291     };
2292 
2293     return (Twine(TagNames.at(Type)) + ": [" + getDynamicString(Value) + "]")
2294         .str();
2295   }
2296   case DT_FLAGS:
2297     return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags));
2298   case DT_FLAGS_1:
2299     return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags1));
2300   default:
2301     return FormatHexValue(Value);
2302   }
2303 }
2304 
2305 template <class ELFT>
2306 StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
2307   if (DynamicStringTable.empty() && !DynamicStringTable.data()) {
2308     reportUniqueWarning("string table was not found");
2309     return "<?>";
2310   }
2311 
2312   auto WarnAndReturn = [this](const Twine &Msg, uint64_t Offset) {
2313     reportUniqueWarning("string table at offset 0x" + Twine::utohexstr(Offset) +
2314                         Msg);
2315     return "<?>";
2316   };
2317 
2318   const uint64_t FileSize = Obj.getBufSize();
2319   const uint64_t Offset =
2320       (const uint8_t *)DynamicStringTable.data() - Obj.base();
2321   if (DynamicStringTable.size() > FileSize - Offset)
2322     return WarnAndReturn(" with size 0x" +
2323                              Twine::utohexstr(DynamicStringTable.size()) +
2324                              " goes past the end of the file (0x" +
2325                              Twine::utohexstr(FileSize) + ")",
2326                          Offset);
2327 
2328   if (Value >= DynamicStringTable.size())
2329     return WarnAndReturn(
2330         ": unable to read the string at 0x" + Twine::utohexstr(Offset + Value) +
2331             ": it goes past the end of the table (0x" +
2332             Twine::utohexstr(Offset + DynamicStringTable.size()) + ")",
2333         Offset);
2334 
2335   if (DynamicStringTable.back() != '\0')
2336     return WarnAndReturn(": unable to read the string at 0x" +
2337                              Twine::utohexstr(Offset + Value) +
2338                              ": the string table is not null-terminated",
2339                          Offset);
2340 
2341   return DynamicStringTable.data() + Value;
2342 }
2343 
2344 template <class ELFT> void ELFDumper<ELFT>::printUnwindInfo() {
2345   DwarfCFIEH::PrinterContext<ELFT> Ctx(W, ObjF);
2346   Ctx.printUnwindInformation();
2347 }
2348 
2349 // The namespace is needed to fix the compilation with GCC older than 7.0+.
2350 namespace {
2351 template <> void ELFDumper<ELF32LE>::printUnwindInfo() {
2352   if (Obj.getHeader().e_machine == EM_ARM) {
2353     ARM::EHABI::PrinterContext<ELF32LE> Ctx(W, Obj, ObjF.getFileName(),
2354                                             DotSymtabSec);
2355     Ctx.PrintUnwindInformation();
2356   }
2357   DwarfCFIEH::PrinterContext<ELF32LE> Ctx(W, ObjF);
2358   Ctx.printUnwindInformation();
2359 }
2360 } // namespace
2361 
2362 template <class ELFT> void ELFDumper<ELFT>::printNeededLibraries() {
2363   ListScope D(W, "NeededLibraries");
2364 
2365   std::vector<StringRef> Libs;
2366   for (const auto &Entry : dynamic_table())
2367     if (Entry.d_tag == ELF::DT_NEEDED)
2368       Libs.push_back(getDynamicString(Entry.d_un.d_val));
2369 
2370   llvm::sort(Libs);
2371 
2372   for (StringRef L : Libs)
2373     W.startLine() << L << "\n";
2374 }
2375 
2376 template <class ELFT>
2377 static Error checkHashTable(const ELFDumper<ELFT> &Dumper,
2378                             const typename ELFT::Hash *H,
2379                             bool *IsHeaderValid = nullptr) {
2380   const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
2381   const uint64_t SecOffset = (const uint8_t *)H - Obj.base();
2382   if (Dumper.getHashTableEntSize() == 8) {
2383     auto It = llvm::find_if(ElfMachineType, [&](const EnumEntry<unsigned> &E) {
2384       return E.Value == Obj.getHeader().e_machine;
2385     });
2386     if (IsHeaderValid)
2387       *IsHeaderValid = false;
2388     return createError("the hash table at 0x" + Twine::utohexstr(SecOffset) +
2389                        " is not supported: it contains non-standard 8 "
2390                        "byte entries on " +
2391                        It->AltName + " platform");
2392   }
2393 
2394   auto MakeError = [&](const Twine &Msg = "") {
2395     return createError("the hash table at offset 0x" +
2396                        Twine::utohexstr(SecOffset) +
2397                        " goes past the end of the file (0x" +
2398                        Twine::utohexstr(Obj.getBufSize()) + ")" + Msg);
2399   };
2400 
2401   // Each SHT_HASH section starts from two 32-bit fields: nbucket and nchain.
2402   const unsigned HeaderSize = 2 * sizeof(typename ELFT::Word);
2403 
2404   if (IsHeaderValid)
2405     *IsHeaderValid = Obj.getBufSize() - SecOffset >= HeaderSize;
2406 
2407   if (Obj.getBufSize() - SecOffset < HeaderSize)
2408     return MakeError();
2409 
2410   if (Obj.getBufSize() - SecOffset - HeaderSize <
2411       ((uint64_t)H->nbucket + H->nchain) * sizeof(typename ELFT::Word))
2412     return MakeError(", nbucket = " + Twine(H->nbucket) +
2413                      ", nchain = " + Twine(H->nchain));
2414   return Error::success();
2415 }
2416 
2417 template <class ELFT>
2418 static Error checkGNUHashTable(const ELFFile<ELFT> &Obj,
2419                                const typename ELFT::GnuHash *GnuHashTable,
2420                                bool *IsHeaderValid = nullptr) {
2421   const uint8_t *TableData = reinterpret_cast<const uint8_t *>(GnuHashTable);
2422   assert(TableData >= Obj.base() && TableData < Obj.base() + Obj.getBufSize() &&
2423          "GnuHashTable must always point to a location inside the file");
2424 
2425   uint64_t TableOffset = TableData - Obj.base();
2426   if (IsHeaderValid)
2427     *IsHeaderValid = TableOffset + /*Header size:*/ 16 < Obj.getBufSize();
2428   if (TableOffset + 16 + (uint64_t)GnuHashTable->nbuckets * 4 +
2429           (uint64_t)GnuHashTable->maskwords * sizeof(typename ELFT::Off) >=
2430       Obj.getBufSize())
2431     return createError("unable to dump the SHT_GNU_HASH "
2432                        "section at 0x" +
2433                        Twine::utohexstr(TableOffset) +
2434                        ": it goes past the end of the file");
2435   return Error::success();
2436 }
2437 
2438 template <typename ELFT> void ELFDumper<ELFT>::printHashTable() {
2439   DictScope D(W, "HashTable");
2440   if (!HashTable)
2441     return;
2442 
2443   bool IsHeaderValid;
2444   Error Err = checkHashTable(*this, HashTable, &IsHeaderValid);
2445   if (IsHeaderValid) {
2446     W.printNumber("Num Buckets", HashTable->nbucket);
2447     W.printNumber("Num Chains", HashTable->nchain);
2448   }
2449 
2450   if (Err) {
2451     reportUniqueWarning(std::move(Err));
2452     return;
2453   }
2454 
2455   W.printList("Buckets", HashTable->buckets());
2456   W.printList("Chains", HashTable->chains());
2457 }
2458 
2459 template <class ELFT>
2460 static Expected<ArrayRef<typename ELFT::Word>>
2461 getGnuHashTableChains(Optional<DynRegionInfo> DynSymRegion,
2462                       const typename ELFT::GnuHash *GnuHashTable) {
2463   if (!DynSymRegion)
2464     return createError("no dynamic symbol table found");
2465 
2466   ArrayRef<typename ELFT::Sym> DynSymTable =
2467       DynSymRegion->template getAsArrayRef<typename ELFT::Sym>();
2468   size_t NumSyms = DynSymTable.size();
2469   if (!NumSyms)
2470     return createError("the dynamic symbol table is empty");
2471 
2472   if (GnuHashTable->symndx < NumSyms)
2473     return GnuHashTable->values(NumSyms);
2474 
2475   // A normal empty GNU hash table section produced by linker might have
2476   // symndx set to the number of dynamic symbols + 1 (for the zero symbol)
2477   // and have dummy null values in the Bloom filter and in the buckets
2478   // vector (or no values at all). It happens because the value of symndx is not
2479   // important for dynamic loaders when the GNU hash table is empty. They just
2480   // skip the whole object during symbol lookup. In such cases, the symndx value
2481   // is irrelevant and we should not report a warning.
2482   ArrayRef<typename ELFT::Word> Buckets = GnuHashTable->buckets();
2483   if (!llvm::all_of(Buckets, [](typename ELFT::Word V) { return V == 0; }))
2484     return createError(
2485         "the first hashed symbol index (" + Twine(GnuHashTable->symndx) +
2486         ") is greater than or equal to the number of dynamic symbols (" +
2487         Twine(NumSyms) + ")");
2488   // There is no way to represent an array of (dynamic symbols count - symndx)
2489   // length.
2490   return ArrayRef<typename ELFT::Word>();
2491 }
2492 
2493 template <typename ELFT>
2494 void ELFDumper<ELFT>::printGnuHashTable() {
2495   DictScope D(W, "GnuHashTable");
2496   if (!GnuHashTable)
2497     return;
2498 
2499   bool IsHeaderValid;
2500   Error Err = checkGNUHashTable<ELFT>(Obj, GnuHashTable, &IsHeaderValid);
2501   if (IsHeaderValid) {
2502     W.printNumber("Num Buckets", GnuHashTable->nbuckets);
2503     W.printNumber("First Hashed Symbol Index", GnuHashTable->symndx);
2504     W.printNumber("Num Mask Words", GnuHashTable->maskwords);
2505     W.printNumber("Shift Count", GnuHashTable->shift2);
2506   }
2507 
2508   if (Err) {
2509     reportUniqueWarning(std::move(Err));
2510     return;
2511   }
2512 
2513   ArrayRef<typename ELFT::Off> BloomFilter = GnuHashTable->filter();
2514   W.printHexList("Bloom Filter", BloomFilter);
2515 
2516   ArrayRef<Elf_Word> Buckets = GnuHashTable->buckets();
2517   W.printList("Buckets", Buckets);
2518 
2519   Expected<ArrayRef<Elf_Word>> Chains =
2520       getGnuHashTableChains<ELFT>(DynSymRegion, GnuHashTable);
2521   if (!Chains) {
2522     reportUniqueWarning("unable to dump 'Values' for the SHT_GNU_HASH "
2523                         "section: " +
2524                         toString(Chains.takeError()));
2525     return;
2526   }
2527 
2528   W.printHexList("Values", *Chains);
2529 }
2530 
2531 template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {
2532   StringRef SOName = "<Not found>";
2533   if (SONameOffset)
2534     SOName = getDynamicString(*SONameOffset);
2535   W.printString("LoadName", SOName);
2536 }
2537 
2538 template <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() {
2539   switch (Obj.getHeader().e_machine) {
2540   case EM_ARM:
2541   case EM_RISCV:
2542     printAttributes();
2543     break;
2544   case EM_MIPS: {
2545     printMipsABIFlags();
2546     printMipsOptions();
2547     printMipsReginfo();
2548     MipsGOTParser<ELFT> Parser(*this);
2549     if (Error E = Parser.findGOT(dynamic_table(), dynamic_symbols()))
2550       reportUniqueWarning(std::move(E));
2551     else if (!Parser.isGotEmpty())
2552       printMipsGOT(Parser);
2553 
2554     if (Error E = Parser.findPLT(dynamic_table()))
2555       reportUniqueWarning(std::move(E));
2556     else if (!Parser.isPltEmpty())
2557       printMipsPLT(Parser);
2558     break;
2559   }
2560   default:
2561     break;
2562   }
2563 }
2564 
2565 template <class ELFT> void ELFDumper<ELFT>::printAttributes() {
2566   if (!Obj.isLE()) {
2567     W.startLine() << "Attributes not implemented.\n";
2568     return;
2569   }
2570 
2571   const unsigned Machine = Obj.getHeader().e_machine;
2572   assert((Machine == EM_ARM || Machine == EM_RISCV) &&
2573          "Attributes not implemented.");
2574 
2575   DictScope BA(W, "BuildAttributes");
2576   for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
2577     if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES &&
2578         Sec.sh_type != ELF::SHT_RISCV_ATTRIBUTES)
2579       continue;
2580 
2581     ArrayRef<uint8_t> Contents;
2582     if (Expected<ArrayRef<uint8_t>> ContentOrErr =
2583             Obj.getSectionContents(Sec)) {
2584       Contents = *ContentOrErr;
2585       if (Contents.empty()) {
2586         reportUniqueWarning("the " + describe(Sec) + " is empty");
2587         continue;
2588       }
2589     } else {
2590       reportUniqueWarning("unable to read the content of the " + describe(Sec) +
2591                           ": " + toString(ContentOrErr.takeError()));
2592       continue;
2593     }
2594 
2595     W.printHex("FormatVersion", Contents[0]);
2596 
2597     auto ParseAttrubutes = [&]() {
2598       if (Machine == EM_ARM)
2599         return ARMAttributeParser(&W).parse(Contents, support::little);
2600       return RISCVAttributeParser(&W).parse(Contents, support::little);
2601     };
2602 
2603     if (Error E = ParseAttrubutes())
2604       reportUniqueWarning("unable to dump attributes from the " +
2605                           describe(Sec) + ": " + toString(std::move(E)));
2606   }
2607 }
2608 
2609 namespace {
2610 
2611 template <class ELFT> class MipsGOTParser {
2612 public:
2613   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
2614   using Entry = typename ELFT::Addr;
2615   using Entries = ArrayRef<Entry>;
2616 
2617   const bool IsStatic;
2618   const ELFFile<ELFT> &Obj;
2619   const ELFDumper<ELFT> &Dumper;
2620 
2621   MipsGOTParser(const ELFDumper<ELFT> &D);
2622   Error findGOT(Elf_Dyn_Range DynTable, Elf_Sym_Range DynSyms);
2623   Error findPLT(Elf_Dyn_Range DynTable);
2624 
2625   bool isGotEmpty() const { return GotEntries.empty(); }
2626   bool isPltEmpty() const { return PltEntries.empty(); }
2627 
2628   uint64_t getGp() const;
2629 
2630   const Entry *getGotLazyResolver() const;
2631   const Entry *getGotModulePointer() const;
2632   const Entry *getPltLazyResolver() const;
2633   const Entry *getPltModulePointer() const;
2634 
2635   Entries getLocalEntries() const;
2636   Entries getGlobalEntries() const;
2637   Entries getOtherEntries() const;
2638   Entries getPltEntries() const;
2639 
2640   uint64_t getGotAddress(const Entry * E) const;
2641   int64_t getGotOffset(const Entry * E) const;
2642   const Elf_Sym *getGotSym(const Entry *E) const;
2643 
2644   uint64_t getPltAddress(const Entry * E) const;
2645   const Elf_Sym *getPltSym(const Entry *E) const;
2646 
2647   StringRef getPltStrTable() const { return PltStrTable; }
2648   const Elf_Shdr *getPltSymTable() const { return PltSymTable; }
2649 
2650 private:
2651   const Elf_Shdr *GotSec;
2652   size_t LocalNum;
2653   size_t GlobalNum;
2654 
2655   const Elf_Shdr *PltSec;
2656   const Elf_Shdr *PltRelSec;
2657   const Elf_Shdr *PltSymTable;
2658   StringRef FileName;
2659 
2660   Elf_Sym_Range GotDynSyms;
2661   StringRef PltStrTable;
2662 
2663   Entries GotEntries;
2664   Entries PltEntries;
2665 };
2666 
2667 } // end anonymous namespace
2668 
2669 template <class ELFT>
2670 MipsGOTParser<ELFT>::MipsGOTParser(const ELFDumper<ELFT> &D)
2671     : IsStatic(D.dynamic_table().empty()), Obj(D.getElfObject().getELFFile()),
2672       Dumper(D), GotSec(nullptr), LocalNum(0), GlobalNum(0), PltSec(nullptr),
2673       PltRelSec(nullptr), PltSymTable(nullptr),
2674       FileName(D.getElfObject().getFileName()) {}
2675 
2676 template <class ELFT>
2677 Error MipsGOTParser<ELFT>::findGOT(Elf_Dyn_Range DynTable,
2678                                    Elf_Sym_Range DynSyms) {
2679   // See "Global Offset Table" in Chapter 5 in the following document
2680   // for detailed GOT description.
2681   // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
2682 
2683   // Find static GOT secton.
2684   if (IsStatic) {
2685     GotSec = Dumper.findSectionByName(".got");
2686     if (!GotSec)
2687       return Error::success();
2688 
2689     ArrayRef<uint8_t> Content =
2690         unwrapOrError(FileName, Obj.getSectionContents(*GotSec));
2691     GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),
2692                          Content.size() / sizeof(Entry));
2693     LocalNum = GotEntries.size();
2694     return Error::success();
2695   }
2696 
2697   // Lookup dynamic table tags which define the GOT layout.
2698   Optional<uint64_t> DtPltGot;
2699   Optional<uint64_t> DtLocalGotNum;
2700   Optional<uint64_t> DtGotSym;
2701   for (const auto &Entry : DynTable) {
2702     switch (Entry.getTag()) {
2703     case ELF::DT_PLTGOT:
2704       DtPltGot = Entry.getVal();
2705       break;
2706     case ELF::DT_MIPS_LOCAL_GOTNO:
2707       DtLocalGotNum = Entry.getVal();
2708       break;
2709     case ELF::DT_MIPS_GOTSYM:
2710       DtGotSym = Entry.getVal();
2711       break;
2712     }
2713   }
2714 
2715   if (!DtPltGot && !DtLocalGotNum && !DtGotSym)
2716     return Error::success();
2717 
2718   if (!DtPltGot)
2719     return createError("cannot find PLTGOT dynamic tag");
2720   if (!DtLocalGotNum)
2721     return createError("cannot find MIPS_LOCAL_GOTNO dynamic tag");
2722   if (!DtGotSym)
2723     return createError("cannot find MIPS_GOTSYM dynamic tag");
2724 
2725   size_t DynSymTotal = DynSyms.size();
2726   if (*DtGotSym > DynSymTotal)
2727     return createError("DT_MIPS_GOTSYM value (" + Twine(*DtGotSym) +
2728                        ") exceeds the number of dynamic symbols (" +
2729                        Twine(DynSymTotal) + ")");
2730 
2731   GotSec = findNotEmptySectionByAddress(Obj, FileName, *DtPltGot);
2732   if (!GotSec)
2733     return createError("there is no non-empty GOT section at 0x" +
2734                        Twine::utohexstr(*DtPltGot));
2735 
2736   LocalNum = *DtLocalGotNum;
2737   GlobalNum = DynSymTotal - *DtGotSym;
2738 
2739   ArrayRef<uint8_t> Content =
2740       unwrapOrError(FileName, Obj.getSectionContents(*GotSec));
2741   GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),
2742                        Content.size() / sizeof(Entry));
2743   GotDynSyms = DynSyms.drop_front(*DtGotSym);
2744 
2745   return Error::success();
2746 }
2747 
2748 template <class ELFT>
2749 Error MipsGOTParser<ELFT>::findPLT(Elf_Dyn_Range DynTable) {
2750   // Lookup dynamic table tags which define the PLT layout.
2751   Optional<uint64_t> DtMipsPltGot;
2752   Optional<uint64_t> DtJmpRel;
2753   for (const auto &Entry : DynTable) {
2754     switch (Entry.getTag()) {
2755     case ELF::DT_MIPS_PLTGOT:
2756       DtMipsPltGot = Entry.getVal();
2757       break;
2758     case ELF::DT_JMPREL:
2759       DtJmpRel = Entry.getVal();
2760       break;
2761     }
2762   }
2763 
2764   if (!DtMipsPltGot && !DtJmpRel)
2765     return Error::success();
2766 
2767   // Find PLT section.
2768   if (!DtMipsPltGot)
2769     return createError("cannot find MIPS_PLTGOT dynamic tag");
2770   if (!DtJmpRel)
2771     return createError("cannot find JMPREL dynamic tag");
2772 
2773   PltSec = findNotEmptySectionByAddress(Obj, FileName, *DtMipsPltGot);
2774   if (!PltSec)
2775     return createError("there is no non-empty PLTGOT section at 0x" +
2776                        Twine::utohexstr(*DtMipsPltGot));
2777 
2778   PltRelSec = findNotEmptySectionByAddress(Obj, FileName, *DtJmpRel);
2779   if (!PltRelSec)
2780     return createError("there is no non-empty RELPLT section at 0x" +
2781                        Twine::utohexstr(*DtJmpRel));
2782 
2783   if (Expected<ArrayRef<uint8_t>> PltContentOrErr =
2784           Obj.getSectionContents(*PltSec))
2785     PltEntries =
2786         Entries(reinterpret_cast<const Entry *>(PltContentOrErr->data()),
2787                 PltContentOrErr->size() / sizeof(Entry));
2788   else
2789     return createError("unable to read PLTGOT section content: " +
2790                        toString(PltContentOrErr.takeError()));
2791 
2792   if (Expected<const Elf_Shdr *> PltSymTableOrErr =
2793           Obj.getSection(PltRelSec->sh_link))
2794     PltSymTable = *PltSymTableOrErr;
2795   else
2796     return createError("unable to get a symbol table linked to the " +
2797                        describe(Obj, *PltRelSec) + ": " +
2798                        toString(PltSymTableOrErr.takeError()));
2799 
2800   if (Expected<StringRef> StrTabOrErr =
2801           Obj.getStringTableForSymtab(*PltSymTable))
2802     PltStrTable = *StrTabOrErr;
2803   else
2804     return createError("unable to get a string table for the " +
2805                        describe(Obj, *PltSymTable) + ": " +
2806                        toString(StrTabOrErr.takeError()));
2807 
2808   return Error::success();
2809 }
2810 
2811 template <class ELFT> uint64_t MipsGOTParser<ELFT>::getGp() const {
2812   return GotSec->sh_addr + 0x7ff0;
2813 }
2814 
2815 template <class ELFT>
2816 const typename MipsGOTParser<ELFT>::Entry *
2817 MipsGOTParser<ELFT>::getGotLazyResolver() const {
2818   return LocalNum > 0 ? &GotEntries[0] : nullptr;
2819 }
2820 
2821 template <class ELFT>
2822 const typename MipsGOTParser<ELFT>::Entry *
2823 MipsGOTParser<ELFT>::getGotModulePointer() const {
2824   if (LocalNum < 2)
2825     return nullptr;
2826   const Entry &E = GotEntries[1];
2827   if ((E >> (sizeof(Entry) * 8 - 1)) == 0)
2828     return nullptr;
2829   return &E;
2830 }
2831 
2832 template <class ELFT>
2833 typename MipsGOTParser<ELFT>::Entries
2834 MipsGOTParser<ELFT>::getLocalEntries() const {
2835   size_t Skip = getGotModulePointer() ? 2 : 1;
2836   if (LocalNum - Skip <= 0)
2837     return Entries();
2838   return GotEntries.slice(Skip, LocalNum - Skip);
2839 }
2840 
2841 template <class ELFT>
2842 typename MipsGOTParser<ELFT>::Entries
2843 MipsGOTParser<ELFT>::getGlobalEntries() const {
2844   if (GlobalNum == 0)
2845     return Entries();
2846   return GotEntries.slice(LocalNum, GlobalNum);
2847 }
2848 
2849 template <class ELFT>
2850 typename MipsGOTParser<ELFT>::Entries
2851 MipsGOTParser<ELFT>::getOtherEntries() const {
2852   size_t OtherNum = GotEntries.size() - LocalNum - GlobalNum;
2853   if (OtherNum == 0)
2854     return Entries();
2855   return GotEntries.slice(LocalNum + GlobalNum, OtherNum);
2856 }
2857 
2858 template <class ELFT>
2859 uint64_t MipsGOTParser<ELFT>::getGotAddress(const Entry *E) const {
2860   int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);
2861   return GotSec->sh_addr + Offset;
2862 }
2863 
2864 template <class ELFT>
2865 int64_t MipsGOTParser<ELFT>::getGotOffset(const Entry *E) const {
2866   int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);
2867   return Offset - 0x7ff0;
2868 }
2869 
2870 template <class ELFT>
2871 const typename MipsGOTParser<ELFT>::Elf_Sym *
2872 MipsGOTParser<ELFT>::getGotSym(const Entry *E) const {
2873   int64_t Offset = std::distance(GotEntries.data(), E);
2874   return &GotDynSyms[Offset - LocalNum];
2875 }
2876 
2877 template <class ELFT>
2878 const typename MipsGOTParser<ELFT>::Entry *
2879 MipsGOTParser<ELFT>::getPltLazyResolver() const {
2880   return PltEntries.empty() ? nullptr : &PltEntries[0];
2881 }
2882 
2883 template <class ELFT>
2884 const typename MipsGOTParser<ELFT>::Entry *
2885 MipsGOTParser<ELFT>::getPltModulePointer() const {
2886   return PltEntries.size() < 2 ? nullptr : &PltEntries[1];
2887 }
2888 
2889 template <class ELFT>
2890 typename MipsGOTParser<ELFT>::Entries
2891 MipsGOTParser<ELFT>::getPltEntries() const {
2892   if (PltEntries.size() <= 2)
2893     return Entries();
2894   return PltEntries.slice(2, PltEntries.size() - 2);
2895 }
2896 
2897 template <class ELFT>
2898 uint64_t MipsGOTParser<ELFT>::getPltAddress(const Entry *E) const {
2899   int64_t Offset = std::distance(PltEntries.data(), E) * sizeof(Entry);
2900   return PltSec->sh_addr + Offset;
2901 }
2902 
2903 template <class ELFT>
2904 const typename MipsGOTParser<ELFT>::Elf_Sym *
2905 MipsGOTParser<ELFT>::getPltSym(const Entry *E) const {
2906   int64_t Offset = std::distance(getPltEntries().data(), E);
2907   if (PltRelSec->sh_type == ELF::SHT_REL) {
2908     Elf_Rel_Range Rels = unwrapOrError(FileName, Obj.rels(*PltRelSec));
2909     return unwrapOrError(FileName,
2910                          Obj.getRelocationSymbol(Rels[Offset], PltSymTable));
2911   } else {
2912     Elf_Rela_Range Rels = unwrapOrError(FileName, Obj.relas(*PltRelSec));
2913     return unwrapOrError(FileName,
2914                          Obj.getRelocationSymbol(Rels[Offset], PltSymTable));
2915   }
2916 }
2917 
2918 static const EnumEntry<unsigned> ElfMipsISAExtType[] = {
2919   {"None",                    Mips::AFL_EXT_NONE},
2920   {"Broadcom SB-1",           Mips::AFL_EXT_SB1},
2921   {"Cavium Networks Octeon",  Mips::AFL_EXT_OCTEON},
2922   {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2},
2923   {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP},
2924   {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3},
2925   {"LSI R4010",               Mips::AFL_EXT_4010},
2926   {"Loongson 2E",             Mips::AFL_EXT_LOONGSON_2E},
2927   {"Loongson 2F",             Mips::AFL_EXT_LOONGSON_2F},
2928   {"Loongson 3A",             Mips::AFL_EXT_LOONGSON_3A},
2929   {"MIPS R4650",              Mips::AFL_EXT_4650},
2930   {"MIPS R5900",              Mips::AFL_EXT_5900},
2931   {"MIPS R10000",             Mips::AFL_EXT_10000},
2932   {"NEC VR4100",              Mips::AFL_EXT_4100},
2933   {"NEC VR4111/VR4181",       Mips::AFL_EXT_4111},
2934   {"NEC VR4120",              Mips::AFL_EXT_4120},
2935   {"NEC VR5400",              Mips::AFL_EXT_5400},
2936   {"NEC VR5500",              Mips::AFL_EXT_5500},
2937   {"RMI Xlr",                 Mips::AFL_EXT_XLR},
2938   {"Toshiba R3900",           Mips::AFL_EXT_3900}
2939 };
2940 
2941 static const EnumEntry<unsigned> ElfMipsASEFlags[] = {
2942   {"DSP",                Mips::AFL_ASE_DSP},
2943   {"DSPR2",              Mips::AFL_ASE_DSPR2},
2944   {"Enhanced VA Scheme", Mips::AFL_ASE_EVA},
2945   {"MCU",                Mips::AFL_ASE_MCU},
2946   {"MDMX",               Mips::AFL_ASE_MDMX},
2947   {"MIPS-3D",            Mips::AFL_ASE_MIPS3D},
2948   {"MT",                 Mips::AFL_ASE_MT},
2949   {"SmartMIPS",          Mips::AFL_ASE_SMARTMIPS},
2950   {"VZ",                 Mips::AFL_ASE_VIRT},
2951   {"MSA",                Mips::AFL_ASE_MSA},
2952   {"MIPS16",             Mips::AFL_ASE_MIPS16},
2953   {"microMIPS",          Mips::AFL_ASE_MICROMIPS},
2954   {"XPA",                Mips::AFL_ASE_XPA},
2955   {"CRC",                Mips::AFL_ASE_CRC},
2956   {"GINV",               Mips::AFL_ASE_GINV},
2957 };
2958 
2959 static const EnumEntry<unsigned> ElfMipsFpABIType[] = {
2960   {"Hard or soft float",                  Mips::Val_GNU_MIPS_ABI_FP_ANY},
2961   {"Hard float (double precision)",       Mips::Val_GNU_MIPS_ABI_FP_DOUBLE},
2962   {"Hard float (single precision)",       Mips::Val_GNU_MIPS_ABI_FP_SINGLE},
2963   {"Soft float",                          Mips::Val_GNU_MIPS_ABI_FP_SOFT},
2964   {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)",
2965    Mips::Val_GNU_MIPS_ABI_FP_OLD_64},
2966   {"Hard float (32-bit CPU, Any FPU)",    Mips::Val_GNU_MIPS_ABI_FP_XX},
2967   {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64},
2968   {"Hard float compat (32-bit CPU, 64-bit FPU)",
2969    Mips::Val_GNU_MIPS_ABI_FP_64A}
2970 };
2971 
2972 static const EnumEntry<unsigned> ElfMipsFlags1[] {
2973   {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG},
2974 };
2975 
2976 static int getMipsRegisterSize(uint8_t Flag) {
2977   switch (Flag) {
2978   case Mips::AFL_REG_NONE:
2979     return 0;
2980   case Mips::AFL_REG_32:
2981     return 32;
2982   case Mips::AFL_REG_64:
2983     return 64;
2984   case Mips::AFL_REG_128:
2985     return 128;
2986   default:
2987     return -1;
2988   }
2989 }
2990 
2991 template <class ELFT>
2992 static void printMipsReginfoData(ScopedPrinter &W,
2993                                  const Elf_Mips_RegInfo<ELFT> &Reginfo) {
2994   W.printHex("GP", Reginfo.ri_gp_value);
2995   W.printHex("General Mask", Reginfo.ri_gprmask);
2996   W.printHex("Co-Proc Mask0", Reginfo.ri_cprmask[0]);
2997   W.printHex("Co-Proc Mask1", Reginfo.ri_cprmask[1]);
2998   W.printHex("Co-Proc Mask2", Reginfo.ri_cprmask[2]);
2999   W.printHex("Co-Proc Mask3", Reginfo.ri_cprmask[3]);
3000 }
3001 
3002 template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
3003   const Elf_Shdr *RegInfoSec = findSectionByName(".reginfo");
3004   if (!RegInfoSec) {
3005     W.startLine() << "There is no .reginfo section in the file.\n";
3006     return;
3007   }
3008 
3009   Expected<ArrayRef<uint8_t>> ContentsOrErr =
3010       Obj.getSectionContents(*RegInfoSec);
3011   if (!ContentsOrErr) {
3012     this->reportUniqueWarning(
3013         "unable to read the content of the .reginfo section (" +
3014         describe(*RegInfoSec) + "): " + toString(ContentsOrErr.takeError()));
3015     return;
3016   }
3017 
3018   if (ContentsOrErr->size() < sizeof(Elf_Mips_RegInfo<ELFT>)) {
3019     this->reportUniqueWarning("the .reginfo section has an invalid size (0x" +
3020                               Twine::utohexstr(ContentsOrErr->size()) + ")");
3021     return;
3022   }
3023 
3024   DictScope GS(W, "MIPS RegInfo");
3025   printMipsReginfoData(W, *reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(
3026                               ContentsOrErr->data()));
3027 }
3028 
3029 template <class ELFT>
3030 static Expected<const Elf_Mips_Options<ELFT> *>
3031 readMipsOptions(const uint8_t *SecBegin, ArrayRef<uint8_t> &SecData,
3032                 bool &IsSupported) {
3033   if (SecData.size() < sizeof(Elf_Mips_Options<ELFT>))
3034     return createError("the .MIPS.options section has an invalid size (0x" +
3035                        Twine::utohexstr(SecData.size()) + ")");
3036 
3037   const Elf_Mips_Options<ELFT> *O =
3038       reinterpret_cast<const Elf_Mips_Options<ELFT> *>(SecData.data());
3039   const uint8_t Size = O->size;
3040   if (Size > SecData.size()) {
3041     const uint64_t Offset = SecData.data() - SecBegin;
3042     const uint64_t SecSize = Offset + SecData.size();
3043     return createError("a descriptor of size 0x" + Twine::utohexstr(Size) +
3044                        " at offset 0x" + Twine::utohexstr(Offset) +
3045                        " goes past the end of the .MIPS.options "
3046                        "section of size 0x" +
3047                        Twine::utohexstr(SecSize));
3048   }
3049 
3050   IsSupported = O->kind == ODK_REGINFO;
3051   const size_t ExpectedSize =
3052       sizeof(Elf_Mips_Options<ELFT>) + sizeof(Elf_Mips_RegInfo<ELFT>);
3053 
3054   if (IsSupported)
3055     if (Size < ExpectedSize)
3056       return createError(
3057           "a .MIPS.options entry of kind " +
3058           Twine(getElfMipsOptionsOdkType(O->kind)) +
3059           " has an invalid size (0x" + Twine::utohexstr(Size) +
3060           "), the expected size is 0x" + Twine::utohexstr(ExpectedSize));
3061 
3062   SecData = SecData.drop_front(Size);
3063   return O;
3064 }
3065 
3066 template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
3067   const Elf_Shdr *MipsOpts = findSectionByName(".MIPS.options");
3068   if (!MipsOpts) {
3069     W.startLine() << "There is no .MIPS.options section in the file.\n";
3070     return;
3071   }
3072 
3073   DictScope GS(W, "MIPS Options");
3074 
3075   ArrayRef<uint8_t> Data =
3076       unwrapOrError(ObjF.getFileName(), Obj.getSectionContents(*MipsOpts));
3077   const uint8_t *const SecBegin = Data.begin();
3078   while (!Data.empty()) {
3079     bool IsSupported;
3080     Expected<const Elf_Mips_Options<ELFT> *> OptsOrErr =
3081         readMipsOptions<ELFT>(SecBegin, Data, IsSupported);
3082     if (!OptsOrErr) {
3083       reportUniqueWarning(OptsOrErr.takeError());
3084       break;
3085     }
3086 
3087     unsigned Kind = (*OptsOrErr)->kind;
3088     const char *Type = getElfMipsOptionsOdkType(Kind);
3089     if (!IsSupported) {
3090       W.startLine() << "Unsupported MIPS options tag: " << Type << " (" << Kind
3091                     << ")\n";
3092       continue;
3093     }
3094 
3095     DictScope GS(W, Type);
3096     if (Kind == ODK_REGINFO)
3097       printMipsReginfoData(W, (*OptsOrErr)->getRegInfo());
3098     else
3099       llvm_unreachable("unexpected .MIPS.options section descriptor kind");
3100   }
3101 }
3102 
3103 template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
3104   const Elf_Shdr *StackMapSection = findSectionByName(".llvm_stackmaps");
3105   if (!StackMapSection)
3106     return;
3107 
3108   auto Warn = [&](Error &&E) {
3109     this->reportUniqueWarning("unable to read the stack map from " +
3110                               describe(*StackMapSection) + ": " +
3111                               toString(std::move(E)));
3112   };
3113 
3114   Expected<ArrayRef<uint8_t>> ContentOrErr =
3115       Obj.getSectionContents(*StackMapSection);
3116   if (!ContentOrErr) {
3117     Warn(ContentOrErr.takeError());
3118     return;
3119   }
3120 
3121   if (Error E = StackMapParser<ELFT::TargetEndianness>::validateHeader(
3122           *ContentOrErr)) {
3123     Warn(std::move(E));
3124     return;
3125   }
3126 
3127   prettyPrintStackMap(W, StackMapParser<ELFT::TargetEndianness>(*ContentOrErr));
3128 }
3129 
3130 template <class ELFT>
3131 void ELFDumper<ELFT>::printReloc(const Relocation<ELFT> &R, unsigned RelIndex,
3132                                  const Elf_Shdr &Sec, const Elf_Shdr *SymTab) {
3133   Expected<RelSymbol<ELFT>> Target = getRelocationTarget(R, SymTab);
3134   if (!Target)
3135     reportUniqueWarning("unable to print relocation " + Twine(RelIndex) +
3136                         " in " + describe(Sec) + ": " +
3137                         toString(Target.takeError()));
3138   else
3139     printRelRelaReloc(R, *Target);
3140 }
3141 
3142 static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
3143                                StringRef Str2) {
3144   OS.PadToColumn(2u);
3145   OS << Str1;
3146   OS.PadToColumn(37u);
3147   OS << Str2 << "\n";
3148   OS.flush();
3149 }
3150 
3151 template <class ELFT>
3152 static std::string getSectionHeadersNumString(const ELFFile<ELFT> &Obj,
3153                                               StringRef FileName) {
3154   const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();
3155   if (ElfHeader.e_shnum != 0)
3156     return to_string(ElfHeader.e_shnum);
3157 
3158   Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
3159   if (!ArrOrErr) {
3160     // In this case we can ignore an error, because we have already reported a
3161     // warning about the broken section header table earlier.
3162     consumeError(ArrOrErr.takeError());
3163     return "<?>";
3164   }
3165 
3166   if (ArrOrErr->empty())
3167     return "0";
3168   return "0 (" + to_string((*ArrOrErr)[0].sh_size) + ")";
3169 }
3170 
3171 template <class ELFT>
3172 static std::string getSectionHeaderTableIndexString(const ELFFile<ELFT> &Obj,
3173                                                     StringRef FileName) {
3174   const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();
3175   if (ElfHeader.e_shstrndx != SHN_XINDEX)
3176     return to_string(ElfHeader.e_shstrndx);
3177 
3178   Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
3179   if (!ArrOrErr) {
3180     // In this case we can ignore an error, because we have already reported a
3181     // warning about the broken section header table earlier.
3182     consumeError(ArrOrErr.takeError());
3183     return "<?>";
3184   }
3185 
3186   if (ArrOrErr->empty())
3187     return "65535 (corrupt: out of range)";
3188   return to_string(ElfHeader.e_shstrndx) + " (" +
3189          to_string((*ArrOrErr)[0].sh_link) + ")";
3190 }
3191 
3192 static const EnumEntry<unsigned> *getObjectFileEnumEntry(unsigned Type) {
3193   auto It = llvm::find_if(ElfObjectFileType, [&](const EnumEntry<unsigned> &E) {
3194     return E.Value == Type;
3195   });
3196   if (It != makeArrayRef(ElfObjectFileType).end())
3197     return It;
3198   return nullptr;
3199 }
3200 
3201 template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() {
3202   const Elf_Ehdr &e = this->Obj.getHeader();
3203   OS << "ELF Header:\n";
3204   OS << "  Magic:  ";
3205   std::string Str;
3206   for (int i = 0; i < ELF::EI_NIDENT; i++)
3207     OS << format(" %02x", static_cast<int>(e.e_ident[i]));
3208   OS << "\n";
3209   Str = printEnum(e.e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
3210   printFields(OS, "Class:", Str);
3211   Str = printEnum(e.e_ident[ELF::EI_DATA], makeArrayRef(ElfDataEncoding));
3212   printFields(OS, "Data:", Str);
3213   OS.PadToColumn(2u);
3214   OS << "Version:";
3215   OS.PadToColumn(37u);
3216   OS << to_hexString(e.e_ident[ELF::EI_VERSION]);
3217   if (e.e_version == ELF::EV_CURRENT)
3218     OS << " (current)";
3219   OS << "\n";
3220   Str = printEnum(e.e_ident[ELF::EI_OSABI], makeArrayRef(ElfOSABI));
3221   printFields(OS, "OS/ABI:", Str);
3222   printFields(OS,
3223               "ABI Version:", std::to_string(e.e_ident[ELF::EI_ABIVERSION]));
3224 
3225   if (const EnumEntry<unsigned> *E = getObjectFileEnumEntry(e.e_type)) {
3226     Str = E->AltName.str();
3227   } else {
3228     if (e.e_type >= ET_LOPROC)
3229       Str = "Processor Specific: (" + to_hexString(e.e_type, false) + ")";
3230     else if (e.e_type >= ET_LOOS)
3231       Str = "OS Specific: (" + to_hexString(e.e_type, false) + ")";
3232     else
3233       Str = "<unknown>: " + to_hexString(e.e_type, false);
3234   }
3235   printFields(OS, "Type:", Str);
3236 
3237   Str = printEnum(e.e_machine, makeArrayRef(ElfMachineType));
3238   printFields(OS, "Machine:", Str);
3239   Str = "0x" + to_hexString(e.e_version);
3240   printFields(OS, "Version:", Str);
3241   Str = "0x" + to_hexString(e.e_entry);
3242   printFields(OS, "Entry point address:", Str);
3243   Str = to_string(e.e_phoff) + " (bytes into file)";
3244   printFields(OS, "Start of program headers:", Str);
3245   Str = to_string(e.e_shoff) + " (bytes into file)";
3246   printFields(OS, "Start of section headers:", Str);
3247   std::string ElfFlags;
3248   if (e.e_machine == EM_MIPS)
3249     ElfFlags =
3250         printFlags(e.e_flags, makeArrayRef(ElfHeaderMipsFlags),
3251                    unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
3252                    unsigned(ELF::EF_MIPS_MACH));
3253   else if (e.e_machine == EM_RISCV)
3254     ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderRISCVFlags));
3255   else if (e.e_machine == EM_AVR)
3256     ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderAVRFlags),
3257                           unsigned(ELF::EF_AVR_ARCH_MASK));
3258   Str = "0x" + to_hexString(e.e_flags);
3259   if (!ElfFlags.empty())
3260     Str = Str + ", " + ElfFlags;
3261   printFields(OS, "Flags:", Str);
3262   Str = to_string(e.e_ehsize) + " (bytes)";
3263   printFields(OS, "Size of this header:", Str);
3264   Str = to_string(e.e_phentsize) + " (bytes)";
3265   printFields(OS, "Size of program headers:", Str);
3266   Str = to_string(e.e_phnum);
3267   printFields(OS, "Number of program headers:", Str);
3268   Str = to_string(e.e_shentsize) + " (bytes)";
3269   printFields(OS, "Size of section headers:", Str);
3270   Str = getSectionHeadersNumString(this->Obj, this->FileName);
3271   printFields(OS, "Number of section headers:", Str);
3272   Str = getSectionHeaderTableIndexString(this->Obj, this->FileName);
3273   printFields(OS, "Section header string table index:", Str);
3274 }
3275 
3276 template <class ELFT> std::vector<GroupSection> ELFDumper<ELFT>::getGroups() {
3277   auto GetSignature = [&](const Elf_Sym &Sym, unsigned SymNdx,
3278                           const Elf_Shdr &Symtab) -> StringRef {
3279     Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(Symtab);
3280     if (!StrTableOrErr) {
3281       reportUniqueWarning("unable to get the string table for " +
3282                           describe(Symtab) + ": " +
3283                           toString(StrTableOrErr.takeError()));
3284       return "<?>";
3285     }
3286 
3287     StringRef Strings = *StrTableOrErr;
3288     if (Sym.st_name >= Strings.size()) {
3289       reportUniqueWarning("unable to get the name of the symbol with index " +
3290                           Twine(SymNdx) + ": st_name (0x" +
3291                           Twine::utohexstr(Sym.st_name) +
3292                           ") is past the end of the string table of size 0x" +
3293                           Twine::utohexstr(Strings.size()));
3294       return "<?>";
3295     }
3296 
3297     return StrTableOrErr->data() + Sym.st_name;
3298   };
3299 
3300   std::vector<GroupSection> Ret;
3301   uint64_t I = 0;
3302   for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
3303     ++I;
3304     if (Sec.sh_type != ELF::SHT_GROUP)
3305       continue;
3306 
3307     StringRef Signature = "<?>";
3308     if (Expected<const Elf_Shdr *> SymtabOrErr = Obj.getSection(Sec.sh_link)) {
3309       if (Expected<const Elf_Sym *> SymOrErr =
3310               Obj.template getEntry<Elf_Sym>(**SymtabOrErr, Sec.sh_info))
3311         Signature = GetSignature(**SymOrErr, Sec.sh_info, **SymtabOrErr);
3312       else
3313         reportUniqueWarning("unable to get the signature symbol for " +
3314                             describe(Sec) + ": " +
3315                             toString(SymOrErr.takeError()));
3316     } else {
3317       reportUniqueWarning("unable to get the symbol table for " +
3318                           describe(Sec) + ": " +
3319                           toString(SymtabOrErr.takeError()));
3320     }
3321 
3322     ArrayRef<Elf_Word> Data;
3323     if (Expected<ArrayRef<Elf_Word>> ContentsOrErr =
3324             Obj.template getSectionContentsAsArray<Elf_Word>(Sec)) {
3325       if (ContentsOrErr->empty())
3326         reportUniqueWarning("unable to read the section group flag from the " +
3327                             describe(Sec) + ": the section is empty");
3328       else
3329         Data = *ContentsOrErr;
3330     } else {
3331       reportUniqueWarning("unable to get the content of the " + describe(Sec) +
3332                           ": " + toString(ContentsOrErr.takeError()));
3333     }
3334 
3335     Ret.push_back({getPrintableSectionName(Sec),
3336                    maybeDemangle(Signature),
3337                    Sec.sh_name,
3338                    I - 1,
3339                    Sec.sh_link,
3340                    Sec.sh_info,
3341                    Data.empty() ? Elf_Word(0) : Data[0],
3342                    {}});
3343 
3344     if (Data.empty())
3345       continue;
3346 
3347     std::vector<GroupMember> &GM = Ret.back().Members;
3348     for (uint32_t Ndx : Data.slice(1)) {
3349       if (Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(Ndx)) {
3350         GM.push_back({getPrintableSectionName(**SecOrErr), Ndx});
3351       } else {
3352         reportUniqueWarning("unable to get the section with index " +
3353                             Twine(Ndx) + " when dumping the " + describe(Sec) +
3354                             ": " + toString(SecOrErr.takeError()));
3355         GM.push_back({"<?>", Ndx});
3356       }
3357     }
3358   }
3359   return Ret;
3360 }
3361 
3362 static DenseMap<uint64_t, const GroupSection *>
3363 mapSectionsToGroups(ArrayRef<GroupSection> Groups) {
3364   DenseMap<uint64_t, const GroupSection *> Ret;
3365   for (const GroupSection &G : Groups)
3366     for (const GroupMember &GM : G.Members)
3367       Ret.insert({GM.Index, &G});
3368   return Ret;
3369 }
3370 
3371 template <class ELFT> void GNUELFDumper<ELFT>::printGroupSections() {
3372   std::vector<GroupSection> V = this->getGroups();
3373   DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
3374   for (const GroupSection &G : V) {
3375     OS << "\n"
3376        << getGroupType(G.Type) << " group section ["
3377        << format_decimal(G.Index, 5) << "] `" << G.Name << "' [" << G.Signature
3378        << "] contains " << G.Members.size() << " sections:\n"
3379        << "   [Index]    Name\n";
3380     for (const GroupMember &GM : G.Members) {
3381       const GroupSection *MainGroup = Map[GM.Index];
3382       if (MainGroup != &G)
3383         this->reportUniqueWarning(
3384             "section with index " + Twine(GM.Index) +
3385             ", included in the group section with index " +
3386             Twine(MainGroup->Index) +
3387             ", was also found in the group section with index " +
3388             Twine(G.Index));
3389       OS << "   [" << format_decimal(GM.Index, 5) << "]   " << GM.Name << "\n";
3390     }
3391   }
3392 
3393   if (V.empty())
3394     OS << "There are no section groups in this file.\n";
3395 }
3396 
3397 template <class ELFT>
3398 void GNUELFDumper<ELFT>::printRelrReloc(const Elf_Relr &R) {
3399   OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8)) << "\n";
3400 }
3401 
3402 template <class ELFT>
3403 void GNUELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,
3404                                            const RelSymbol<ELFT> &RelSym) {
3405   // First two fields are bit width dependent. The rest of them are fixed width.
3406   unsigned Bias = ELFT::Is64Bits ? 8 : 0;
3407   Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
3408   unsigned Width = ELFT::Is64Bits ? 16 : 8;
3409 
3410   Fields[0].Str = to_string(format_hex_no_prefix(R.Offset, Width));
3411   Fields[1].Str = to_string(format_hex_no_prefix(R.Info, Width));
3412 
3413   SmallString<32> RelocName;
3414   this->Obj.getRelocationTypeName(R.Type, RelocName);
3415   Fields[2].Str = RelocName.c_str();
3416 
3417   if (RelSym.Sym)
3418     Fields[3].Str =
3419         to_string(format_hex_no_prefix(RelSym.Sym->getValue(), Width));
3420 
3421   Fields[4].Str = std::string(RelSym.Name);
3422   for (const Field &F : Fields)
3423     printField(F);
3424 
3425   std::string Addend;
3426   if (Optional<int64_t> A = R.Addend) {
3427     int64_t RelAddend = *A;
3428     if (!RelSym.Name.empty()) {
3429       if (RelAddend < 0) {
3430         Addend = " - ";
3431         RelAddend = std::abs(RelAddend);
3432       } else {
3433         Addend = " + ";
3434       }
3435     }
3436     Addend += to_hexString(RelAddend, false);
3437   }
3438   OS << Addend << "\n";
3439 }
3440 
3441 template <class ELFT>
3442 static void printRelocHeaderFields(formatted_raw_ostream &OS, unsigned SType) {
3443   bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA;
3444   bool IsRelr = SType == ELF::SHT_RELR || SType == ELF::SHT_ANDROID_RELR;
3445   if (ELFT::Is64Bits)
3446     OS << "    ";
3447   else
3448     OS << " ";
3449   if (IsRelr && opts::RawRelr)
3450     OS << "Data  ";
3451   else
3452     OS << "Offset";
3453   if (ELFT::Is64Bits)
3454     OS << "             Info             Type"
3455        << "               Symbol's Value  Symbol's Name";
3456   else
3457     OS << "     Info    Type                Sym. Value  Symbol's Name";
3458   if (IsRela)
3459     OS << " + Addend";
3460   OS << "\n";
3461 }
3462 
3463 template <class ELFT>
3464 void GNUELFDumper<ELFT>::printDynamicRelocHeader(unsigned Type, StringRef Name,
3465                                                  const DynRegionInfo &Reg) {
3466   uint64_t Offset = Reg.Addr - this->Obj.base();
3467   OS << "\n'" << Name.str().c_str() << "' relocation section at offset 0x"
3468      << to_hexString(Offset, false) << " contains " << Reg.Size << " bytes:\n";
3469   printRelocHeaderFields<ELFT>(OS, Type);
3470 }
3471 
3472 template <class ELFT>
3473 static bool isRelocationSec(const typename ELFT::Shdr &Sec) {
3474   return Sec.sh_type == ELF::SHT_REL || Sec.sh_type == ELF::SHT_RELA ||
3475          Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_ANDROID_REL ||
3476          Sec.sh_type == ELF::SHT_ANDROID_RELA ||
3477          Sec.sh_type == ELF::SHT_ANDROID_RELR;
3478 }
3479 
3480 template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
3481   auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected<size_t> {
3482     // Android's packed relocation section needs to be unpacked first
3483     // to get the actual number of entries.
3484     if (Sec.sh_type == ELF::SHT_ANDROID_REL ||
3485         Sec.sh_type == ELF::SHT_ANDROID_RELA) {
3486       Expected<std::vector<typename ELFT::Rela>> RelasOrErr =
3487           this->Obj.android_relas(Sec);
3488       if (!RelasOrErr)
3489         return RelasOrErr.takeError();
3490       return RelasOrErr->size();
3491     }
3492 
3493     if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR ||
3494                            Sec.sh_type == ELF::SHT_ANDROID_RELR)) {
3495       Expected<Elf_Relr_Range> RelrsOrErr = this->Obj.relrs(Sec);
3496       if (!RelrsOrErr)
3497         return RelrsOrErr.takeError();
3498       return this->Obj.decode_relrs(*RelrsOrErr).size();
3499     }
3500 
3501     return Sec.getEntityCount();
3502   };
3503 
3504   bool HasRelocSections = false;
3505   for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
3506     if (!isRelocationSec<ELFT>(Sec))
3507       continue;
3508     HasRelocSections = true;
3509 
3510     std::string EntriesNum = "<?>";
3511     if (Expected<size_t> NumOrErr = GetEntriesNum(Sec))
3512       EntriesNum = std::to_string(*NumOrErr);
3513     else
3514       this->reportUniqueWarning("unable to get the number of relocations in " +
3515                                 this->describe(Sec) + ": " +
3516                                 toString(NumOrErr.takeError()));
3517 
3518     uintX_t Offset = Sec.sh_offset;
3519     StringRef Name = this->getPrintableSectionName(Sec);
3520     OS << "\nRelocation section '" << Name << "' at offset 0x"
3521        << to_hexString(Offset, false) << " contains " << EntriesNum
3522        << " entries:\n";
3523     printRelocHeaderFields<ELFT>(OS, Sec.sh_type);
3524     this->printRelocationsHelper(Sec);
3525   }
3526   if (!HasRelocSections)
3527     OS << "\nThere are no relocations in this file.\n";
3528 }
3529 
3530 // Print the offset of a particular section from anyone of the ranges:
3531 // [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].
3532 // If 'Type' does not fall within any of those ranges, then a string is
3533 // returned as '<unknown>' followed by the type value.
3534 static std::string getSectionTypeOffsetString(unsigned Type) {
3535   if (Type >= SHT_LOOS && Type <= SHT_HIOS)
3536     return "LOOS+0x" + to_hexString(Type - SHT_LOOS);
3537   else if (Type >= SHT_LOPROC && Type <= SHT_HIPROC)
3538     return "LOPROC+0x" + to_hexString(Type - SHT_LOPROC);
3539   else if (Type >= SHT_LOUSER && Type <= SHT_HIUSER)
3540     return "LOUSER+0x" + to_hexString(Type - SHT_LOUSER);
3541   return "0x" + to_hexString(Type) + ": <unknown>";
3542 }
3543 
3544 static std::string getSectionTypeString(unsigned Machine, unsigned Type) {
3545   StringRef Name = getELFSectionTypeName(Machine, Type);
3546 
3547   // Handle SHT_GNU_* type names.
3548   if (Name.startswith("SHT_GNU_")) {
3549     if (Name == "SHT_GNU_HASH")
3550       return "GNU_HASH";
3551     // E.g. SHT_GNU_verneed -> VERNEED.
3552     return Name.drop_front(8).upper();
3553   }
3554 
3555   if (Name == "SHT_SYMTAB_SHNDX")
3556     return "SYMTAB SECTION INDICES";
3557 
3558   if (Name.startswith("SHT_"))
3559     return Name.drop_front(4).str();
3560   return getSectionTypeOffsetString(Type);
3561 }
3562 
3563 static void printSectionDescription(formatted_raw_ostream &OS,
3564                                     unsigned EMachine) {
3565   OS << "Key to Flags:\n";
3566   OS << "  W (write), A (alloc), X (execute), M (merge), S (strings), I "
3567         "(info),\n";
3568   OS << "  L (link order), O (extra OS processing required), G (group), T "
3569         "(TLS),\n";
3570   OS << "  C (compressed), x (unknown), o (OS specific), E (exclude),\n";
3571   OS << "  R (retain)";
3572 
3573   if (EMachine == EM_X86_64)
3574     OS << ", l (large)";
3575   else if (EMachine == EM_ARM)
3576     OS << ", y (purecode)";
3577 
3578   OS << ", p (processor specific)\n";
3579 }
3580 
3581 template <class ELFT> void GNUELFDumper<ELFT>::printSectionHeaders() {
3582   unsigned Bias = ELFT::Is64Bits ? 0 : 8;
3583   ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections());
3584   OS << "There are " << to_string(Sections.size())
3585      << " section headers, starting at offset "
3586      << "0x" << to_hexString(this->Obj.getHeader().e_shoff, false) << ":\n\n";
3587   OS << "Section Headers:\n";
3588   Field Fields[11] = {
3589       {"[Nr]", 2},        {"Name", 7},        {"Type", 25},
3590       {"Address", 41},    {"Off", 58 - Bias}, {"Size", 65 - Bias},
3591       {"ES", 72 - Bias},  {"Flg", 75 - Bias}, {"Lk", 79 - Bias},
3592       {"Inf", 82 - Bias}, {"Al", 86 - Bias}};
3593   for (const Field &F : Fields)
3594     printField(F);
3595   OS << "\n";
3596 
3597   StringRef SecStrTable;
3598   if (Expected<StringRef> SecStrTableOrErr =
3599           this->Obj.getSectionStringTable(Sections, this->WarningHandler))
3600     SecStrTable = *SecStrTableOrErr;
3601   else
3602     this->reportUniqueWarning(SecStrTableOrErr.takeError());
3603 
3604   size_t SectionIndex = 0;
3605   for (const Elf_Shdr &Sec : Sections) {
3606     Fields[0].Str = to_string(SectionIndex);
3607     if (SecStrTable.empty())
3608       Fields[1].Str = "<no-strings>";
3609     else
3610       Fields[1].Str = std::string(unwrapOrError<StringRef>(
3611           this->FileName, this->Obj.getSectionName(Sec, SecStrTable)));
3612     Fields[2].Str =
3613         getSectionTypeString(this->Obj.getHeader().e_machine, Sec.sh_type);
3614     Fields[3].Str =
3615         to_string(format_hex_no_prefix(Sec.sh_addr, ELFT::Is64Bits ? 16 : 8));
3616     Fields[4].Str = to_string(format_hex_no_prefix(Sec.sh_offset, 6));
3617     Fields[5].Str = to_string(format_hex_no_prefix(Sec.sh_size, 6));
3618     Fields[6].Str = to_string(format_hex_no_prefix(Sec.sh_entsize, 2));
3619     Fields[7].Str = getGNUFlags(this->Obj.getHeader().e_machine, Sec.sh_flags);
3620     Fields[8].Str = to_string(Sec.sh_link);
3621     Fields[9].Str = to_string(Sec.sh_info);
3622     Fields[10].Str = to_string(Sec.sh_addralign);
3623 
3624     OS.PadToColumn(Fields[0].Column);
3625     OS << "[" << right_justify(Fields[0].Str, 2) << "]";
3626     for (int i = 1; i < 7; i++)
3627       printField(Fields[i]);
3628     OS.PadToColumn(Fields[7].Column);
3629     OS << right_justify(Fields[7].Str, 3);
3630     OS.PadToColumn(Fields[8].Column);
3631     OS << right_justify(Fields[8].Str, 2);
3632     OS.PadToColumn(Fields[9].Column);
3633     OS << right_justify(Fields[9].Str, 3);
3634     OS.PadToColumn(Fields[10].Column);
3635     OS << right_justify(Fields[10].Str, 2);
3636     OS << "\n";
3637     ++SectionIndex;
3638   }
3639   printSectionDescription(OS, this->Obj.getHeader().e_machine);
3640 }
3641 
3642 template <class ELFT>
3643 void GNUELFDumper<ELFT>::printSymtabMessage(const Elf_Shdr *Symtab,
3644                                             size_t Entries,
3645                                             bool NonVisibilityBitsUsed) const {
3646   StringRef Name;
3647   if (Symtab)
3648     Name = this->getPrintableSectionName(*Symtab);
3649   if (!Name.empty())
3650     OS << "\nSymbol table '" << Name << "'";
3651   else
3652     OS << "\nSymbol table for image";
3653   OS << " contains " << Entries << " entries:\n";
3654 
3655   if (ELFT::Is64Bits)
3656     OS << "   Num:    Value          Size Type    Bind   Vis";
3657   else
3658     OS << "   Num:    Value  Size Type    Bind   Vis";
3659 
3660   if (NonVisibilityBitsUsed)
3661     OS << "             ";
3662   OS << "       Ndx Name\n";
3663 }
3664 
3665 template <class ELFT>
3666 std::string
3667 GNUELFDumper<ELFT>::getSymbolSectionNdx(const Elf_Sym &Symbol,
3668                                         unsigned SymIndex,
3669                                         DataRegion<Elf_Word> ShndxTable) const {
3670   unsigned SectionIndex = Symbol.st_shndx;
3671   switch (SectionIndex) {
3672   case ELF::SHN_UNDEF:
3673     return "UND";
3674   case ELF::SHN_ABS:
3675     return "ABS";
3676   case ELF::SHN_COMMON:
3677     return "COM";
3678   case ELF::SHN_XINDEX: {
3679     Expected<uint32_t> IndexOrErr =
3680         object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex, ShndxTable);
3681     if (!IndexOrErr) {
3682       assert(Symbol.st_shndx == SHN_XINDEX &&
3683              "getExtendedSymbolTableIndex should only fail due to an invalid "
3684              "SHT_SYMTAB_SHNDX table/reference");
3685       this->reportUniqueWarning(IndexOrErr.takeError());
3686       return "RSV[0xffff]";
3687     }
3688     return to_string(format_decimal(*IndexOrErr, 3));
3689   }
3690   default:
3691     // Find if:
3692     // Processor specific
3693     if (SectionIndex >= ELF::SHN_LOPROC && SectionIndex <= ELF::SHN_HIPROC)
3694       return std::string("PRC[0x") +
3695              to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
3696     // OS specific
3697     if (SectionIndex >= ELF::SHN_LOOS && SectionIndex <= ELF::SHN_HIOS)
3698       return std::string("OS[0x") +
3699              to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
3700     // Architecture reserved:
3701     if (SectionIndex >= ELF::SHN_LORESERVE &&
3702         SectionIndex <= ELF::SHN_HIRESERVE)
3703       return std::string("RSV[0x") +
3704              to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
3705     // A normal section with an index
3706     return to_string(format_decimal(SectionIndex, 3));
3707   }
3708 }
3709 
3710 template <class ELFT>
3711 void GNUELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
3712                                      DataRegion<Elf_Word> ShndxTable,
3713                                      Optional<StringRef> StrTable,
3714                                      bool IsDynamic,
3715                                      bool NonVisibilityBitsUsed) const {
3716   unsigned Bias = ELFT::Is64Bits ? 8 : 0;
3717   Field Fields[8] = {0,         8,         17 + Bias, 23 + Bias,
3718                      31 + Bias, 38 + Bias, 48 + Bias, 51 + Bias};
3719   Fields[0].Str = to_string(format_decimal(SymIndex, 6)) + ":";
3720   Fields[1].Str =
3721       to_string(format_hex_no_prefix(Symbol.st_value, ELFT::Is64Bits ? 16 : 8));
3722   Fields[2].Str = to_string(format_decimal(Symbol.st_size, 5));
3723 
3724   unsigned char SymbolType = Symbol.getType();
3725   if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&
3726       SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
3727     Fields[3].Str = printEnum(SymbolType, makeArrayRef(AMDGPUSymbolTypes));
3728   else
3729     Fields[3].Str = printEnum(SymbolType, makeArrayRef(ElfSymbolTypes));
3730 
3731   Fields[4].Str =
3732       printEnum(Symbol.getBinding(), makeArrayRef(ElfSymbolBindings));
3733   Fields[5].Str =
3734       printEnum(Symbol.getVisibility(), makeArrayRef(ElfSymbolVisibilities));
3735 
3736   if (Symbol.st_other & ~0x3) {
3737     if (this->Obj.getHeader().e_machine == ELF::EM_AARCH64) {
3738       uint8_t Other = Symbol.st_other & ~0x3;
3739       if (Other & STO_AARCH64_VARIANT_PCS) {
3740         Other &= ~STO_AARCH64_VARIANT_PCS;
3741         Fields[5].Str += " [VARIANT_PCS";
3742         if (Other != 0)
3743           Fields[5].Str.append(" | " + to_hexString(Other, false));
3744         Fields[5].Str.append("]");
3745       }
3746     } else {
3747       Fields[5].Str +=
3748           " [<other: " + to_string(format_hex(Symbol.st_other, 2)) + ">]";
3749     }
3750   }
3751 
3752   Fields[6].Column += NonVisibilityBitsUsed ? 13 : 0;
3753   Fields[6].Str = getSymbolSectionNdx(Symbol, SymIndex, ShndxTable);
3754 
3755   Fields[7].Str = this->getFullSymbolName(Symbol, SymIndex, ShndxTable,
3756                                           StrTable, IsDynamic);
3757   for (const Field &Entry : Fields)
3758     printField(Entry);
3759   OS << "\n";
3760 }
3761 
3762 template <class ELFT>
3763 void GNUELFDumper<ELFT>::printHashedSymbol(const Elf_Sym *Symbol,
3764                                            unsigned SymIndex,
3765                                            DataRegion<Elf_Word> ShndxTable,
3766                                            StringRef StrTable,
3767                                            uint32_t Bucket) {
3768   unsigned Bias = ELFT::Is64Bits ? 8 : 0;
3769   Field Fields[9] = {0,         6,         11,        20 + Bias, 25 + Bias,
3770                      34 + Bias, 41 + Bias, 49 + Bias, 53 + Bias};
3771   Fields[0].Str = to_string(format_decimal(SymIndex, 5));
3772   Fields[1].Str = to_string(format_decimal(Bucket, 3)) + ":";
3773 
3774   Fields[2].Str = to_string(
3775       format_hex_no_prefix(Symbol->st_value, ELFT::Is64Bits ? 16 : 8));
3776   Fields[3].Str = to_string(format_decimal(Symbol->st_size, 5));
3777 
3778   unsigned char SymbolType = Symbol->getType();
3779   if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&
3780       SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
3781     Fields[4].Str = printEnum(SymbolType, makeArrayRef(AMDGPUSymbolTypes));
3782   else
3783     Fields[4].Str = printEnum(SymbolType, makeArrayRef(ElfSymbolTypes));
3784 
3785   Fields[5].Str =
3786       printEnum(Symbol->getBinding(), makeArrayRef(ElfSymbolBindings));
3787   Fields[6].Str =
3788       printEnum(Symbol->getVisibility(), makeArrayRef(ElfSymbolVisibilities));
3789   Fields[7].Str = getSymbolSectionNdx(*Symbol, SymIndex, ShndxTable);
3790   Fields[8].Str =
3791       this->getFullSymbolName(*Symbol, SymIndex, ShndxTable, StrTable, true);
3792 
3793   for (const Field &Entry : Fields)
3794     printField(Entry);
3795   OS << "\n";
3796 }
3797 
3798 template <class ELFT>
3799 void GNUELFDumper<ELFT>::printSymbols(bool PrintSymbols,
3800                                       bool PrintDynamicSymbols) {
3801   if (!PrintSymbols && !PrintDynamicSymbols)
3802     return;
3803   // GNU readelf prints both the .dynsym and .symtab with --symbols.
3804   this->printSymbolsHelper(true);
3805   if (PrintSymbols)
3806     this->printSymbolsHelper(false);
3807 }
3808 
3809 template <class ELFT>
3810 void GNUELFDumper<ELFT>::printHashTableSymbols(const Elf_Hash &SysVHash) {
3811   if (this->DynamicStringTable.empty())
3812     return;
3813 
3814   if (ELFT::Is64Bits)
3815     OS << "  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name";
3816   else
3817     OS << "  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name";
3818   OS << "\n";
3819 
3820   Elf_Sym_Range DynSyms = this->dynamic_symbols();
3821   const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];
3822   if (!FirstSym) {
3823     this->reportUniqueWarning(
3824         Twine("unable to print symbols for the .hash table: the "
3825               "dynamic symbol table ") +
3826         (this->DynSymRegion ? "is empty" : "was not found"));
3827     return;
3828   }
3829 
3830   DataRegion<Elf_Word> ShndxTable(
3831       (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
3832   auto Buckets = SysVHash.buckets();
3833   auto Chains = SysVHash.chains();
3834   for (uint32_t Buc = 0; Buc < SysVHash.nbucket; Buc++) {
3835     if (Buckets[Buc] == ELF::STN_UNDEF)
3836       continue;
3837     std::vector<bool> Visited(SysVHash.nchain);
3838     for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash.nchain; Ch = Chains[Ch]) {
3839       if (Ch == ELF::STN_UNDEF)
3840         break;
3841 
3842       if (Visited[Ch]) {
3843         this->reportUniqueWarning(".hash section is invalid: bucket " +
3844                                   Twine(Ch) +
3845                                   ": a cycle was detected in the linked chain");
3846         break;
3847       }
3848 
3849       printHashedSymbol(FirstSym + Ch, Ch, ShndxTable, this->DynamicStringTable,
3850                         Buc);
3851       Visited[Ch] = true;
3852     }
3853   }
3854 }
3855 
3856 template <class ELFT>
3857 void GNUELFDumper<ELFT>::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) {
3858   if (this->DynamicStringTable.empty())
3859     return;
3860 
3861   Elf_Sym_Range DynSyms = this->dynamic_symbols();
3862   const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];
3863   if (!FirstSym) {
3864     this->reportUniqueWarning(
3865         Twine("unable to print symbols for the .gnu.hash table: the "
3866               "dynamic symbol table ") +
3867         (this->DynSymRegion ? "is empty" : "was not found"));
3868     return;
3869   }
3870 
3871   auto GetSymbol = [&](uint64_t SymIndex,
3872                        uint64_t SymsTotal) -> const Elf_Sym * {
3873     if (SymIndex >= SymsTotal) {
3874       this->reportUniqueWarning(
3875           "unable to print hashed symbol with index " + Twine(SymIndex) +
3876           ", which is greater than or equal to the number of dynamic symbols "
3877           "(" +
3878           Twine::utohexstr(SymsTotal) + ")");
3879       return nullptr;
3880     }
3881     return FirstSym + SymIndex;
3882   };
3883 
3884   Expected<ArrayRef<Elf_Word>> ValuesOrErr =
3885       getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHash);
3886   ArrayRef<Elf_Word> Values;
3887   if (!ValuesOrErr)
3888     this->reportUniqueWarning("unable to get hash values for the SHT_GNU_HASH "
3889                               "section: " +
3890                               toString(ValuesOrErr.takeError()));
3891   else
3892     Values = *ValuesOrErr;
3893 
3894   DataRegion<Elf_Word> ShndxTable(
3895       (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
3896   ArrayRef<Elf_Word> Buckets = GnuHash.buckets();
3897   for (uint32_t Buc = 0; Buc < GnuHash.nbuckets; Buc++) {
3898     if (Buckets[Buc] == ELF::STN_UNDEF)
3899       continue;
3900     uint32_t Index = Buckets[Buc];
3901     // Print whole chain.
3902     while (true) {
3903       uint32_t SymIndex = Index++;
3904       if (const Elf_Sym *Sym = GetSymbol(SymIndex, DynSyms.size()))
3905         printHashedSymbol(Sym, SymIndex, ShndxTable, this->DynamicStringTable,
3906                           Buc);
3907       else
3908         break;
3909 
3910       if (SymIndex < GnuHash.symndx) {
3911         this->reportUniqueWarning(
3912             "unable to read the hash value for symbol with index " +
3913             Twine(SymIndex) +
3914             ", which is less than the index of the first hashed symbol (" +
3915             Twine(GnuHash.symndx) + ")");
3916         break;
3917       }
3918 
3919        // Chain ends at symbol with stopper bit.
3920       if ((Values[SymIndex - GnuHash.symndx] & 1) == 1)
3921         break;
3922     }
3923   }
3924 }
3925 
3926 template <class ELFT> void GNUELFDumper<ELFT>::printHashSymbols() {
3927   if (this->HashTable) {
3928     OS << "\n Symbol table of .hash for image:\n";
3929     if (Error E = checkHashTable<ELFT>(*this, this->HashTable))
3930       this->reportUniqueWarning(std::move(E));
3931     else
3932       printHashTableSymbols(*this->HashTable);
3933   }
3934 
3935   // Try printing the .gnu.hash table.
3936   if (this->GnuHashTable) {
3937     OS << "\n Symbol table of .gnu.hash for image:\n";
3938     if (ELFT::Is64Bits)
3939       OS << "  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name";
3940     else
3941       OS << "  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name";
3942     OS << "\n";
3943 
3944     if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable))
3945       this->reportUniqueWarning(std::move(E));
3946     else
3947       printGnuHashTableSymbols(*this->GnuHashTable);
3948   }
3949 }
3950 
3951 template <class ELFT> void GNUELFDumper<ELFT>::printSectionDetails() {
3952   ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections());
3953   OS << "There are " << to_string(Sections.size())
3954      << " section headers, starting at offset "
3955      << "0x" << to_hexString(this->Obj.getHeader().e_shoff, false) << ":\n\n";
3956 
3957   OS << "Section Headers:\n";
3958 
3959   auto PrintFields = [&](ArrayRef<Field> V) {
3960     for (const Field &F : V)
3961       printField(F);
3962     OS << "\n";
3963   };
3964 
3965   PrintFields({{"[Nr]", 2}, {"Name", 7}});
3966 
3967   constexpr bool Is64 = ELFT::Is64Bits;
3968   PrintFields({{"Type", 7},
3969                {Is64 ? "Address" : "Addr", 23},
3970                {"Off", Is64 ? 40 : 32},
3971                {"Size", Is64 ? 47 : 39},
3972                {"ES", Is64 ? 54 : 46},
3973                {"Lk", Is64 ? 59 : 51},
3974                {"Inf", Is64 ? 62 : 54},
3975                {"Al", Is64 ? 66 : 57}});
3976   PrintFields({{"Flags", 7}});
3977 
3978   StringRef SecStrTable;
3979   if (Expected<StringRef> SecStrTableOrErr =
3980           this->Obj.getSectionStringTable(Sections, this->WarningHandler))
3981     SecStrTable = *SecStrTableOrErr;
3982   else
3983     this->reportUniqueWarning(SecStrTableOrErr.takeError());
3984 
3985   size_t SectionIndex = 0;
3986   const unsigned AddrSize = Is64 ? 16 : 8;
3987   for (const Elf_Shdr &S : Sections) {
3988     StringRef Name = "<?>";
3989     if (Expected<StringRef> NameOrErr =
3990             this->Obj.getSectionName(S, SecStrTable))
3991       Name = *NameOrErr;
3992     else
3993       this->reportUniqueWarning(NameOrErr.takeError());
3994 
3995     OS.PadToColumn(2);
3996     OS << "[" << right_justify(to_string(SectionIndex), 2) << "]";
3997     PrintFields({{Name, 7}});
3998     PrintFields(
3999         {{getSectionTypeString(this->Obj.getHeader().e_machine, S.sh_type), 7},
4000          {to_string(format_hex_no_prefix(S.sh_addr, AddrSize)), 23},
4001          {to_string(format_hex_no_prefix(S.sh_offset, 6)), Is64 ? 39 : 32},
4002          {to_string(format_hex_no_prefix(S.sh_size, 6)), Is64 ? 47 : 39},
4003          {to_string(format_hex_no_prefix(S.sh_entsize, 2)), Is64 ? 54 : 46},
4004          {to_string(S.sh_link), Is64 ? 59 : 51},
4005          {to_string(S.sh_info), Is64 ? 63 : 55},
4006          {to_string(S.sh_addralign), Is64 ? 66 : 58}});
4007 
4008     OS.PadToColumn(7);
4009     OS << "[" << to_string(format_hex_no_prefix(S.sh_flags, AddrSize)) << "]: ";
4010 
4011     DenseMap<unsigned, StringRef> FlagToName = {
4012         {SHF_WRITE, "WRITE"},           {SHF_ALLOC, "ALLOC"},
4013         {SHF_EXECINSTR, "EXEC"},        {SHF_MERGE, "MERGE"},
4014         {SHF_STRINGS, "STRINGS"},       {SHF_INFO_LINK, "INFO LINK"},
4015         {SHF_LINK_ORDER, "LINK ORDER"}, {SHF_OS_NONCONFORMING, "OS NONCONF"},
4016         {SHF_GROUP, "GROUP"},           {SHF_TLS, "TLS"},
4017         {SHF_COMPRESSED, "COMPRESSED"}, {SHF_EXCLUDE, "EXCLUDE"}};
4018 
4019     uint64_t Flags = S.sh_flags;
4020     uint64_t UnknownFlags = 0;
4021     ListSeparator LS;
4022     while (Flags) {
4023       // Take the least significant bit as a flag.
4024       uint64_t Flag = Flags & -Flags;
4025       Flags -= Flag;
4026 
4027       auto It = FlagToName.find(Flag);
4028       if (It != FlagToName.end())
4029         OS << LS << It->second;
4030       else
4031         UnknownFlags |= Flag;
4032     }
4033 
4034     auto PrintUnknownFlags = [&](uint64_t Mask, StringRef Name) {
4035       uint64_t FlagsToPrint = UnknownFlags & Mask;
4036       if (!FlagsToPrint)
4037         return;
4038 
4039       OS << LS << Name << " ("
4040          << to_string(format_hex_no_prefix(FlagsToPrint, AddrSize)) << ")";
4041       UnknownFlags &= ~Mask;
4042     };
4043 
4044     PrintUnknownFlags(SHF_MASKOS, "OS");
4045     PrintUnknownFlags(SHF_MASKPROC, "PROC");
4046     PrintUnknownFlags(uint64_t(-1), "UNKNOWN");
4047 
4048     OS << "\n";
4049     ++SectionIndex;
4050   }
4051 }
4052 
4053 static inline std::string printPhdrFlags(unsigned Flag) {
4054   std::string Str;
4055   Str = (Flag & PF_R) ? "R" : " ";
4056   Str += (Flag & PF_W) ? "W" : " ";
4057   Str += (Flag & PF_X) ? "E" : " ";
4058   return Str;
4059 }
4060 
4061 template <class ELFT>
4062 static bool checkTLSSections(const typename ELFT::Phdr &Phdr,
4063                              const typename ELFT::Shdr &Sec) {
4064   if (Sec.sh_flags & ELF::SHF_TLS) {
4065     // .tbss must only be shown in the PT_TLS segment.
4066     if (Sec.sh_type == ELF::SHT_NOBITS)
4067       return Phdr.p_type == ELF::PT_TLS;
4068 
4069     // SHF_TLS sections are only shown in PT_TLS, PT_LOAD or PT_GNU_RELRO
4070     // segments.
4071     return (Phdr.p_type == ELF::PT_TLS) || (Phdr.p_type == ELF::PT_LOAD) ||
4072            (Phdr.p_type == ELF::PT_GNU_RELRO);
4073   }
4074 
4075   // PT_TLS must only have SHF_TLS sections.
4076   return Phdr.p_type != ELF::PT_TLS;
4077 }
4078 
4079 template <class ELFT>
4080 static bool checkOffsets(const typename ELFT::Phdr &Phdr,
4081                          const typename ELFT::Shdr &Sec) {
4082   // SHT_NOBITS sections don't need to have an offset inside the segment.
4083   if (Sec.sh_type == ELF::SHT_NOBITS)
4084     return true;
4085 
4086   if (Sec.sh_offset < Phdr.p_offset)
4087     return false;
4088 
4089   // Only non-empty sections can be at the end of a segment.
4090   if (Sec.sh_size == 0)
4091     return (Sec.sh_offset + 1 <= Phdr.p_offset + Phdr.p_filesz);
4092   return Sec.sh_offset + Sec.sh_size <= Phdr.p_offset + Phdr.p_filesz;
4093 }
4094 
4095 // Check that an allocatable section belongs to a virtual address
4096 // space of a segment.
4097 template <class ELFT>
4098 static bool checkVMA(const typename ELFT::Phdr &Phdr,
4099                      const typename ELFT::Shdr &Sec) {
4100   if (!(Sec.sh_flags & ELF::SHF_ALLOC))
4101     return true;
4102 
4103   if (Sec.sh_addr < Phdr.p_vaddr)
4104     return false;
4105 
4106   bool IsTbss =
4107       (Sec.sh_type == ELF::SHT_NOBITS) && ((Sec.sh_flags & ELF::SHF_TLS) != 0);
4108   // .tbss is special, it only has memory in PT_TLS and has NOBITS properties.
4109   bool IsTbssInNonTLS = IsTbss && Phdr.p_type != ELF::PT_TLS;
4110   // Only non-empty sections can be at the end of a segment.
4111   if (Sec.sh_size == 0 || IsTbssInNonTLS)
4112     return Sec.sh_addr + 1 <= Phdr.p_vaddr + Phdr.p_memsz;
4113   return Sec.sh_addr + Sec.sh_size <= Phdr.p_vaddr + Phdr.p_memsz;
4114 }
4115 
4116 template <class ELFT>
4117 static bool checkPTDynamic(const typename ELFT::Phdr &Phdr,
4118                            const typename ELFT::Shdr &Sec) {
4119   if (Phdr.p_type != ELF::PT_DYNAMIC || Phdr.p_memsz == 0 || Sec.sh_size != 0)
4120     return true;
4121 
4122   // We get here when we have an empty section. Only non-empty sections can be
4123   // at the start or at the end of PT_DYNAMIC.
4124   // Is section within the phdr both based on offset and VMA?
4125   bool CheckOffset = (Sec.sh_type == ELF::SHT_NOBITS) ||
4126                      (Sec.sh_offset > Phdr.p_offset &&
4127                       Sec.sh_offset < Phdr.p_offset + Phdr.p_filesz);
4128   bool CheckVA = !(Sec.sh_flags & ELF::SHF_ALLOC) ||
4129                  (Sec.sh_addr > Phdr.p_vaddr && Sec.sh_addr < Phdr.p_memsz);
4130   return CheckOffset && CheckVA;
4131 }
4132 
4133 template <class ELFT>
4134 void GNUELFDumper<ELFT>::printProgramHeaders(
4135     bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {
4136   if (PrintProgramHeaders)
4137     printProgramHeaders();
4138 
4139   // Display the section mapping along with the program headers, unless
4140   // -section-mapping is explicitly set to false.
4141   if (PrintSectionMapping != cl::BOU_FALSE)
4142     printSectionMapping();
4143 }
4144 
4145 template <class ELFT> void GNUELFDumper<ELFT>::printProgramHeaders() {
4146   unsigned Bias = ELFT::Is64Bits ? 8 : 0;
4147   const Elf_Ehdr &Header = this->Obj.getHeader();
4148   Field Fields[8] = {2,         17,        26,        37 + Bias,
4149                      48 + Bias, 56 + Bias, 64 + Bias, 68 + Bias};
4150   OS << "\nElf file type is "
4151      << printEnum(Header.e_type, makeArrayRef(ElfObjectFileType)) << "\n"
4152      << "Entry point " << format_hex(Header.e_entry, 3) << "\n"
4153      << "There are " << Header.e_phnum << " program headers,"
4154      << " starting at offset " << Header.e_phoff << "\n\n"
4155      << "Program Headers:\n";
4156   if (ELFT::Is64Bits)
4157     OS << "  Type           Offset   VirtAddr           PhysAddr         "
4158        << "  FileSiz  MemSiz   Flg Align\n";
4159   else
4160     OS << "  Type           Offset   VirtAddr   PhysAddr   FileSiz "
4161        << "MemSiz  Flg Align\n";
4162 
4163   unsigned Width = ELFT::Is64Bits ? 18 : 10;
4164   unsigned SizeWidth = ELFT::Is64Bits ? 8 : 7;
4165 
4166   Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
4167   if (!PhdrsOrErr) {
4168     this->reportUniqueWarning("unable to dump program headers: " +
4169                               toString(PhdrsOrErr.takeError()));
4170     return;
4171   }
4172 
4173   for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
4174     Fields[0].Str = getGNUPtType(Header.e_machine, Phdr.p_type);
4175     Fields[1].Str = to_string(format_hex(Phdr.p_offset, 8));
4176     Fields[2].Str = to_string(format_hex(Phdr.p_vaddr, Width));
4177     Fields[3].Str = to_string(format_hex(Phdr.p_paddr, Width));
4178     Fields[4].Str = to_string(format_hex(Phdr.p_filesz, SizeWidth));
4179     Fields[5].Str = to_string(format_hex(Phdr.p_memsz, SizeWidth));
4180     Fields[6].Str = printPhdrFlags(Phdr.p_flags);
4181     Fields[7].Str = to_string(format_hex(Phdr.p_align, 1));
4182     for (const Field &F : Fields)
4183       printField(F);
4184     if (Phdr.p_type == ELF::PT_INTERP) {
4185       OS << "\n";
4186       auto ReportBadInterp = [&](const Twine &Msg) {
4187         this->reportUniqueWarning(
4188             "unable to read program interpreter name at offset 0x" +
4189             Twine::utohexstr(Phdr.p_offset) + ": " + Msg);
4190       };
4191 
4192       if (Phdr.p_offset >= this->Obj.getBufSize()) {
4193         ReportBadInterp("it goes past the end of the file (0x" +
4194                         Twine::utohexstr(this->Obj.getBufSize()) + ")");
4195         continue;
4196       }
4197 
4198       const char *Data =
4199           reinterpret_cast<const char *>(this->Obj.base()) + Phdr.p_offset;
4200       size_t MaxSize = this->Obj.getBufSize() - Phdr.p_offset;
4201       size_t Len = strnlen(Data, MaxSize);
4202       if (Len == MaxSize) {
4203         ReportBadInterp("it is not null-terminated");
4204         continue;
4205       }
4206 
4207       OS << "      [Requesting program interpreter: ";
4208       OS << StringRef(Data, Len) << "]";
4209     }
4210     OS << "\n";
4211   }
4212 }
4213 
4214 template <class ELFT> void GNUELFDumper<ELFT>::printSectionMapping() {
4215   OS << "\n Section to Segment mapping:\n  Segment Sections...\n";
4216   DenseSet<const Elf_Shdr *> BelongsToSegment;
4217   int Phnum = 0;
4218 
4219   Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
4220   if (!PhdrsOrErr) {
4221     this->reportUniqueWarning(
4222         "can't read program headers to build section to segment mapping: " +
4223         toString(PhdrsOrErr.takeError()));
4224     return;
4225   }
4226 
4227   for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
4228     std::string Sections;
4229     OS << format("   %2.2d     ", Phnum++);
4230     // Check if each section is in a segment and then print mapping.
4231     for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
4232       if (Sec.sh_type == ELF::SHT_NULL)
4233         continue;
4234 
4235       // readelf additionally makes sure it does not print zero sized sections
4236       // at end of segments and for PT_DYNAMIC both start and end of section
4237       // .tbss must only be shown in PT_TLS section.
4238       if (checkTLSSections<ELFT>(Phdr, Sec) && checkOffsets<ELFT>(Phdr, Sec) &&
4239           checkVMA<ELFT>(Phdr, Sec) && checkPTDynamic<ELFT>(Phdr, Sec)) {
4240         Sections +=
4241             unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() +
4242             " ";
4243         BelongsToSegment.insert(&Sec);
4244       }
4245     }
4246     OS << Sections << "\n";
4247     OS.flush();
4248   }
4249 
4250   // Display sections that do not belong to a segment.
4251   std::string Sections;
4252   for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
4253     if (BelongsToSegment.find(&Sec) == BelongsToSegment.end())
4254       Sections +=
4255           unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() +
4256           ' ';
4257   }
4258   if (!Sections.empty()) {
4259     OS << "   None  " << Sections << '\n';
4260     OS.flush();
4261   }
4262 }
4263 
4264 namespace {
4265 
4266 template <class ELFT>
4267 RelSymbol<ELFT> getSymbolForReloc(const ELFDumper<ELFT> &Dumper,
4268                                   const Relocation<ELFT> &Reloc) {
4269   using Elf_Sym = typename ELFT::Sym;
4270   auto WarnAndReturn = [&](const Elf_Sym *Sym,
4271                            const Twine &Reason) -> RelSymbol<ELFT> {
4272     Dumper.reportUniqueWarning(
4273         "unable to get name of the dynamic symbol with index " +
4274         Twine(Reloc.Symbol) + ": " + Reason);
4275     return {Sym, "<corrupt>"};
4276   };
4277 
4278   ArrayRef<Elf_Sym> Symbols = Dumper.dynamic_symbols();
4279   const Elf_Sym *FirstSym = Symbols.begin();
4280   if (!FirstSym)
4281     return WarnAndReturn(nullptr, "no dynamic symbol table found");
4282 
4283   // We might have an object without a section header. In this case the size of
4284   // Symbols is zero, because there is no way to know the size of the dynamic
4285   // table. We should allow this case and not print a warning.
4286   if (!Symbols.empty() && Reloc.Symbol >= Symbols.size())
4287     return WarnAndReturn(
4288         nullptr,
4289         "index is greater than or equal to the number of dynamic symbols (" +
4290             Twine(Symbols.size()) + ")");
4291 
4292   const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
4293   const uint64_t FileSize = Obj.getBufSize();
4294   const uint64_t SymOffset = ((const uint8_t *)FirstSym - Obj.base()) +
4295                              (uint64_t)Reloc.Symbol * sizeof(Elf_Sym);
4296   if (SymOffset + sizeof(Elf_Sym) > FileSize)
4297     return WarnAndReturn(nullptr, "symbol at 0x" + Twine::utohexstr(SymOffset) +
4298                                       " goes past the end of the file (0x" +
4299                                       Twine::utohexstr(FileSize) + ")");
4300 
4301   const Elf_Sym *Sym = FirstSym + Reloc.Symbol;
4302   Expected<StringRef> ErrOrName = Sym->getName(Dumper.getDynamicStringTable());
4303   if (!ErrOrName)
4304     return WarnAndReturn(Sym, toString(ErrOrName.takeError()));
4305 
4306   return {Sym == FirstSym ? nullptr : Sym, maybeDemangle(*ErrOrName)};
4307 }
4308 } // namespace
4309 
4310 template <class ELFT>
4311 static size_t getMaxDynamicTagSize(const ELFFile<ELFT> &Obj,
4312                                    typename ELFT::DynRange Tags) {
4313   size_t Max = 0;
4314   for (const typename ELFT::Dyn &Dyn : Tags)
4315     Max = std::max(Max, Obj.getDynamicTagAsString(Dyn.d_tag).size());
4316   return Max;
4317 }
4318 
4319 template <class ELFT> void GNUELFDumper<ELFT>::printDynamicTable() {
4320   Elf_Dyn_Range Table = this->dynamic_table();
4321   if (Table.empty())
4322     return;
4323 
4324   OS << "Dynamic section at offset "
4325      << format_hex(reinterpret_cast<const uint8_t *>(this->DynamicTable.Addr) -
4326                        this->Obj.base(),
4327                    1)
4328      << " contains " << Table.size() << " entries:\n";
4329 
4330   // The type name is surrounded with round brackets, hence add 2.
4331   size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table) + 2;
4332   // The "Name/Value" column should be indented from the "Type" column by N
4333   // spaces, where N = MaxTagSize - length of "Type" (4) + trailing
4334   // space (1) = 3.
4335   OS << "  Tag" + std::string(ELFT::Is64Bits ? 16 : 8, ' ') + "Type"
4336      << std::string(MaxTagSize - 3, ' ') << "Name/Value\n";
4337 
4338   std::string ValueFmt = " %-" + std::to_string(MaxTagSize) + "s ";
4339   for (auto Entry : Table) {
4340     uintX_t Tag = Entry.getTag();
4341     std::string Type =
4342         std::string("(") + this->Obj.getDynamicTagAsString(Tag).c_str() + ")";
4343     std::string Value = this->getDynamicEntry(Tag, Entry.getVal());
4344     OS << "  " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10)
4345        << format(ValueFmt.c_str(), Type.c_str()) << Value << "\n";
4346   }
4347 }
4348 
4349 template <class ELFT> void GNUELFDumper<ELFT>::printDynamicRelocations() {
4350   this->printDynamicRelocationsHelper();
4351 }
4352 
4353 template <class ELFT>
4354 void ELFDumper<ELFT>::printDynamicReloc(const Relocation<ELFT> &R) {
4355   printRelRelaReloc(R, getSymbolForReloc(*this, R));
4356 }
4357 
4358 template <class ELFT>
4359 void ELFDumper<ELFT>::printRelocationsHelper(const Elf_Shdr &Sec) {
4360   this->forEachRelocationDo(
4361       Sec, opts::RawRelr,
4362       [&](const Relocation<ELFT> &R, unsigned Ndx, const Elf_Shdr &Sec,
4363           const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); },
4364       [&](const Elf_Relr &R) { printRelrReloc(R); });
4365 }
4366 
4367 template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocationsHelper() {
4368   const bool IsMips64EL = this->Obj.isMips64EL();
4369   if (this->DynRelaRegion.Size > 0) {
4370     printDynamicRelocHeader(ELF::SHT_RELA, "RELA", this->DynRelaRegion);
4371     for (const Elf_Rela &Rela :
4372          this->DynRelaRegion.template getAsArrayRef<Elf_Rela>())
4373       printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL));
4374   }
4375 
4376   if (this->DynRelRegion.Size > 0) {
4377     printDynamicRelocHeader(ELF::SHT_REL, "REL", this->DynRelRegion);
4378     for (const Elf_Rel &Rel :
4379          this->DynRelRegion.template getAsArrayRef<Elf_Rel>())
4380       printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));
4381   }
4382 
4383   if (this->DynRelrRegion.Size > 0) {
4384     printDynamicRelocHeader(ELF::SHT_REL, "RELR", this->DynRelrRegion);
4385     Elf_Relr_Range Relrs =
4386         this->DynRelrRegion.template getAsArrayRef<Elf_Relr>();
4387     for (const Elf_Rel &Rel : Obj.decode_relrs(Relrs))
4388       printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));
4389   }
4390 
4391   if (this->DynPLTRelRegion.Size) {
4392     if (this->DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) {
4393       printDynamicRelocHeader(ELF::SHT_RELA, "PLT", this->DynPLTRelRegion);
4394       for (const Elf_Rela &Rela :
4395            this->DynPLTRelRegion.template getAsArrayRef<Elf_Rela>())
4396         printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL));
4397     } else {
4398       printDynamicRelocHeader(ELF::SHT_REL, "PLT", this->DynPLTRelRegion);
4399       for (const Elf_Rel &Rel :
4400            this->DynPLTRelRegion.template getAsArrayRef<Elf_Rel>())
4401         printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));
4402     }
4403   }
4404 }
4405 
4406 template <class ELFT>
4407 void GNUELFDumper<ELFT>::printGNUVersionSectionProlog(
4408     const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum) {
4409   // Don't inline the SecName, because it might report a warning to stderr and
4410   // corrupt the output.
4411   StringRef SecName = this->getPrintableSectionName(Sec);
4412   OS << Label << " section '" << SecName << "' "
4413      << "contains " << EntriesNum << " entries:\n";
4414 
4415   StringRef LinkedSecName = "<corrupt>";
4416   if (Expected<const typename ELFT::Shdr *> LinkedSecOrErr =
4417           this->Obj.getSection(Sec.sh_link))
4418     LinkedSecName = this->getPrintableSectionName(**LinkedSecOrErr);
4419   else
4420     this->reportUniqueWarning("invalid section linked to " +
4421                               this->describe(Sec) + ": " +
4422                               toString(LinkedSecOrErr.takeError()));
4423 
4424   OS << " Addr: " << format_hex_no_prefix(Sec.sh_addr, 16)
4425      << "  Offset: " << format_hex(Sec.sh_offset, 8)
4426      << "  Link: " << Sec.sh_link << " (" << LinkedSecName << ")\n";
4427 }
4428 
4429 template <class ELFT>
4430 void GNUELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) {
4431   if (!Sec)
4432     return;
4433 
4434   printGNUVersionSectionProlog(*Sec, "Version symbols",
4435                                Sec->sh_size / sizeof(Elf_Versym));
4436   Expected<ArrayRef<Elf_Versym>> VerTableOrErr =
4437       this->getVersionTable(*Sec, /*SymTab=*/nullptr,
4438                             /*StrTab=*/nullptr, /*SymTabSec=*/nullptr);
4439   if (!VerTableOrErr) {
4440     this->reportUniqueWarning(VerTableOrErr.takeError());
4441     return;
4442   }
4443 
4444   SmallVector<Optional<VersionEntry>, 0> *VersionMap = nullptr;
4445   if (Expected<SmallVector<Optional<VersionEntry>, 0> *> MapOrErr =
4446           this->getVersionMap())
4447     VersionMap = *MapOrErr;
4448   else
4449     this->reportUniqueWarning(MapOrErr.takeError());
4450 
4451   ArrayRef<Elf_Versym> VerTable = *VerTableOrErr;
4452   std::vector<StringRef> Versions;
4453   for (size_t I = 0, E = VerTable.size(); I < E; ++I) {
4454     unsigned Ndx = VerTable[I].vs_index;
4455     if (Ndx == VER_NDX_LOCAL || Ndx == VER_NDX_GLOBAL) {
4456       Versions.emplace_back(Ndx == VER_NDX_LOCAL ? "*local*" : "*global*");
4457       continue;
4458     }
4459 
4460     if (!VersionMap) {
4461       Versions.emplace_back("<corrupt>");
4462       continue;
4463     }
4464 
4465     bool IsDefault;
4466     Expected<StringRef> NameOrErr = this->Obj.getSymbolVersionByIndex(
4467         Ndx, IsDefault, *VersionMap, /*IsSymHidden=*/None);
4468     if (!NameOrErr) {
4469       this->reportUniqueWarning("unable to get a version for entry " +
4470                                 Twine(I) + " of " + this->describe(*Sec) +
4471                                 ": " + toString(NameOrErr.takeError()));
4472       Versions.emplace_back("<corrupt>");
4473       continue;
4474     }
4475     Versions.emplace_back(*NameOrErr);
4476   }
4477 
4478   // readelf prints 4 entries per line.
4479   uint64_t Entries = VerTable.size();
4480   for (uint64_t VersymRow = 0; VersymRow < Entries; VersymRow += 4) {
4481     OS << "  " << format_hex_no_prefix(VersymRow, 3) << ":";
4482     for (uint64_t I = 0; (I < 4) && (I + VersymRow) < Entries; ++I) {
4483       unsigned Ndx = VerTable[VersymRow + I].vs_index;
4484       OS << format("%4x%c", Ndx & VERSYM_VERSION,
4485                    Ndx & VERSYM_HIDDEN ? 'h' : ' ');
4486       OS << left_justify("(" + std::string(Versions[VersymRow + I]) + ")", 13);
4487     }
4488     OS << '\n';
4489   }
4490   OS << '\n';
4491 }
4492 
4493 static std::string versionFlagToString(unsigned Flags) {
4494   if (Flags == 0)
4495     return "none";
4496 
4497   std::string Ret;
4498   auto AddFlag = [&Ret, &Flags](unsigned Flag, StringRef Name) {
4499     if (!(Flags & Flag))
4500       return;
4501     if (!Ret.empty())
4502       Ret += " | ";
4503     Ret += Name;
4504     Flags &= ~Flag;
4505   };
4506 
4507   AddFlag(VER_FLG_BASE, "BASE");
4508   AddFlag(VER_FLG_WEAK, "WEAK");
4509   AddFlag(VER_FLG_INFO, "INFO");
4510   AddFlag(~0, "<unknown>");
4511   return Ret;
4512 }
4513 
4514 template <class ELFT>
4515 void GNUELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) {
4516   if (!Sec)
4517     return;
4518 
4519   printGNUVersionSectionProlog(*Sec, "Version definition", Sec->sh_info);
4520 
4521   Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec);
4522   if (!V) {
4523     this->reportUniqueWarning(V.takeError());
4524     return;
4525   }
4526 
4527   for (const VerDef &Def : *V) {
4528     OS << format("  0x%04x: Rev: %u  Flags: %s  Index: %u  Cnt: %u  Name: %s\n",
4529                  Def.Offset, Def.Version,
4530                  versionFlagToString(Def.Flags).c_str(), Def.Ndx, Def.Cnt,
4531                  Def.Name.data());
4532     unsigned I = 0;
4533     for (const VerdAux &Aux : Def.AuxV)
4534       OS << format("  0x%04x: Parent %u: %s\n", Aux.Offset, ++I,
4535                    Aux.Name.data());
4536   }
4537 
4538   OS << '\n';
4539 }
4540 
4541 template <class ELFT>
4542 void GNUELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) {
4543   if (!Sec)
4544     return;
4545 
4546   unsigned VerneedNum = Sec->sh_info;
4547   printGNUVersionSectionProlog(*Sec, "Version needs", VerneedNum);
4548 
4549   Expected<std::vector<VerNeed>> V =
4550       this->Obj.getVersionDependencies(*Sec, this->WarningHandler);
4551   if (!V) {
4552     this->reportUniqueWarning(V.takeError());
4553     return;
4554   }
4555 
4556   for (const VerNeed &VN : *V) {
4557     OS << format("  0x%04x: Version: %u  File: %s  Cnt: %u\n", VN.Offset,
4558                  VN.Version, VN.File.data(), VN.Cnt);
4559     for (const VernAux &Aux : VN.AuxV)
4560       OS << format("  0x%04x:   Name: %s  Flags: %s  Version: %u\n", Aux.Offset,
4561                    Aux.Name.data(), versionFlagToString(Aux.Flags).c_str(),
4562                    Aux.Other);
4563   }
4564   OS << '\n';
4565 }
4566 
4567 template <class ELFT>
4568 void GNUELFDumper<ELFT>::printHashHistogram(const Elf_Hash &HashTable) {
4569   size_t NBucket = HashTable.nbucket;
4570   size_t NChain = HashTable.nchain;
4571   ArrayRef<Elf_Word> Buckets = HashTable.buckets();
4572   ArrayRef<Elf_Word> Chains = HashTable.chains();
4573   size_t TotalSyms = 0;
4574   // If hash table is correct, we have at least chains with 0 length
4575   size_t MaxChain = 1;
4576   size_t CumulativeNonZero = 0;
4577 
4578   if (NChain == 0 || NBucket == 0)
4579     return;
4580 
4581   std::vector<size_t> ChainLen(NBucket, 0);
4582   // Go over all buckets and and note chain lengths of each bucket (total
4583   // unique chain lengths).
4584   for (size_t B = 0; B < NBucket; B++) {
4585     std::vector<bool> Visited(NChain);
4586     for (size_t C = Buckets[B]; C < NChain; C = Chains[C]) {
4587       if (C == ELF::STN_UNDEF)
4588         break;
4589       if (Visited[C]) {
4590         this->reportUniqueWarning(".hash section is invalid: bucket " +
4591                                   Twine(C) +
4592                                   ": a cycle was detected in the linked chain");
4593         break;
4594       }
4595       Visited[C] = true;
4596       if (MaxChain <= ++ChainLen[B])
4597         MaxChain++;
4598     }
4599     TotalSyms += ChainLen[B];
4600   }
4601 
4602   if (!TotalSyms)
4603     return;
4604 
4605   std::vector<size_t> Count(MaxChain, 0);
4606   // Count how long is the chain for each bucket
4607   for (size_t B = 0; B < NBucket; B++)
4608     ++Count[ChainLen[B]];
4609   // Print Number of buckets with each chain lengths and their cumulative
4610   // coverage of the symbols
4611   OS << "Histogram for bucket list length (total of " << NBucket
4612      << " buckets)\n"
4613      << " Length  Number     % of total  Coverage\n";
4614   for (size_t I = 0; I < MaxChain; I++) {
4615     CumulativeNonZero += Count[I] * I;
4616     OS << format("%7lu  %-10lu (%5.1f%%)     %5.1f%%\n", I, Count[I],
4617                  (Count[I] * 100.0) / NBucket,
4618                  (CumulativeNonZero * 100.0) / TotalSyms);
4619   }
4620 }
4621 
4622 template <class ELFT>
4623 void GNUELFDumper<ELFT>::printGnuHashHistogram(
4624     const Elf_GnuHash &GnuHashTable) {
4625   Expected<ArrayRef<Elf_Word>> ChainsOrErr =
4626       getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHashTable);
4627   if (!ChainsOrErr) {
4628     this->reportUniqueWarning("unable to print the GNU hash table histogram: " +
4629                               toString(ChainsOrErr.takeError()));
4630     return;
4631   }
4632 
4633   ArrayRef<Elf_Word> Chains = *ChainsOrErr;
4634   size_t Symndx = GnuHashTable.symndx;
4635   size_t TotalSyms = 0;
4636   size_t MaxChain = 1;
4637   size_t CumulativeNonZero = 0;
4638 
4639   size_t NBucket = GnuHashTable.nbuckets;
4640   if (Chains.empty() || NBucket == 0)
4641     return;
4642 
4643   ArrayRef<Elf_Word> Buckets = GnuHashTable.buckets();
4644   std::vector<size_t> ChainLen(NBucket, 0);
4645   for (size_t B = 0; B < NBucket; B++) {
4646     if (!Buckets[B])
4647       continue;
4648     size_t Len = 1;
4649     for (size_t C = Buckets[B] - Symndx;
4650          C < Chains.size() && (Chains[C] & 1) == 0; C++)
4651       if (MaxChain < ++Len)
4652         MaxChain++;
4653     ChainLen[B] = Len;
4654     TotalSyms += Len;
4655   }
4656   MaxChain++;
4657 
4658   if (!TotalSyms)
4659     return;
4660 
4661   std::vector<size_t> Count(MaxChain, 0);
4662   for (size_t B = 0; B < NBucket; B++)
4663     ++Count[ChainLen[B]];
4664   // Print Number of buckets with each chain lengths and their cumulative
4665   // coverage of the symbols
4666   OS << "Histogram for `.gnu.hash' bucket list length (total of " << NBucket
4667      << " buckets)\n"
4668      << " Length  Number     % of total  Coverage\n";
4669   for (size_t I = 0; I < MaxChain; I++) {
4670     CumulativeNonZero += Count[I] * I;
4671     OS << format("%7lu  %-10lu (%5.1f%%)     %5.1f%%\n", I, Count[I],
4672                  (Count[I] * 100.0) / NBucket,
4673                  (CumulativeNonZero * 100.0) / TotalSyms);
4674   }
4675 }
4676 
4677 // Hash histogram shows statistics of how efficient the hash was for the
4678 // dynamic symbol table. The table shows the number of hash buckets for
4679 // different lengths of chains as an absolute number and percentage of the total
4680 // buckets, and the cumulative coverage of symbols for each set of buckets.
4681 template <class ELFT> void GNUELFDumper<ELFT>::printHashHistograms() {
4682   // Print histogram for the .hash section.
4683   if (this->HashTable) {
4684     if (Error E = checkHashTable<ELFT>(*this, this->HashTable))
4685       this->reportUniqueWarning(std::move(E));
4686     else
4687       printHashHistogram(*this->HashTable);
4688   }
4689 
4690   // Print histogram for the .gnu.hash section.
4691   if (this->GnuHashTable) {
4692     if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable))
4693       this->reportUniqueWarning(std::move(E));
4694     else
4695       printGnuHashHistogram(*this->GnuHashTable);
4696   }
4697 }
4698 
4699 template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() {
4700   OS << "GNUStyle::printCGProfile not implemented\n";
4701 }
4702 
4703 template <class ELFT> void GNUELFDumper<ELFT>::printBBAddrMaps() {
4704   OS << "GNUStyle::printBBAddrMaps not implemented\n";
4705 }
4706 
4707 static Expected<std::vector<uint64_t>> toULEB128Array(ArrayRef<uint8_t> Data) {
4708   std::vector<uint64_t> Ret;
4709   const uint8_t *Cur = Data.begin();
4710   const uint8_t *End = Data.end();
4711   while (Cur != End) {
4712     unsigned Size;
4713     const char *Err;
4714     Ret.push_back(decodeULEB128(Cur, &Size, End, &Err));
4715     if (Err)
4716       return createError(Err);
4717     Cur += Size;
4718   }
4719   return Ret;
4720 }
4721 
4722 template <class ELFT>
4723 static Expected<std::vector<uint64_t>>
4724 decodeAddrsigSection(const ELFFile<ELFT> &Obj, const typename ELFT::Shdr &Sec) {
4725   Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Sec);
4726   if (!ContentsOrErr)
4727     return ContentsOrErr.takeError();
4728 
4729   if (Expected<std::vector<uint64_t>> SymsOrErr =
4730           toULEB128Array(*ContentsOrErr))
4731     return *SymsOrErr;
4732   else
4733     return createError("unable to decode " + describe(Obj, Sec) + ": " +
4734                        toString(SymsOrErr.takeError()));
4735 }
4736 
4737 template <class ELFT> void GNUELFDumper<ELFT>::printAddrsig() {
4738   if (!this->DotAddrsigSec)
4739     return;
4740 
4741   Expected<std::vector<uint64_t>> SymsOrErr =
4742       decodeAddrsigSection(this->Obj, *this->DotAddrsigSec);
4743   if (!SymsOrErr) {
4744     this->reportUniqueWarning(SymsOrErr.takeError());
4745     return;
4746   }
4747 
4748   StringRef Name = this->getPrintableSectionName(*this->DotAddrsigSec);
4749   OS << "\nAddress-significant symbols section '" << Name << "'"
4750      << " contains " << SymsOrErr->size() << " entries:\n";
4751   OS << "   Num: Name\n";
4752 
4753   Field Fields[2] = {0, 8};
4754   size_t SymIndex = 0;
4755   for (uint64_t Sym : *SymsOrErr) {
4756     Fields[0].Str = to_string(format_decimal(++SymIndex, 6)) + ":";
4757     Fields[1].Str = this->getStaticSymbolName(Sym);
4758     for (const Field &Entry : Fields)
4759       printField(Entry);
4760     OS << "\n";
4761   }
4762 }
4763 
4764 template <typename ELFT>
4765 static std::string getGNUProperty(uint32_t Type, uint32_t DataSize,
4766                                   ArrayRef<uint8_t> Data) {
4767   std::string str;
4768   raw_string_ostream OS(str);
4769   uint32_t PrData;
4770   auto DumpBit = [&](uint32_t Flag, StringRef Name) {
4771     if (PrData & Flag) {
4772       PrData &= ~Flag;
4773       OS << Name;
4774       if (PrData)
4775         OS << ", ";
4776     }
4777   };
4778 
4779   switch (Type) {
4780   default:
4781     OS << format("<application-specific type 0x%x>", Type);
4782     return OS.str();
4783   case GNU_PROPERTY_STACK_SIZE: {
4784     OS << "stack size: ";
4785     if (DataSize == sizeof(typename ELFT::uint))
4786       OS << formatv("{0:x}",
4787                     (uint64_t)(*(const typename ELFT::Addr *)Data.data()));
4788     else
4789       OS << format("<corrupt length: 0x%x>", DataSize);
4790     return OS.str();
4791   }
4792   case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
4793     OS << "no copy on protected";
4794     if (DataSize)
4795       OS << format(" <corrupt length: 0x%x>", DataSize);
4796     return OS.str();
4797   case GNU_PROPERTY_AARCH64_FEATURE_1_AND:
4798   case GNU_PROPERTY_X86_FEATURE_1_AND:
4799     OS << ((Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) ? "aarch64 feature: "
4800                                                         : "x86 feature: ");
4801     if (DataSize != 4) {
4802       OS << format("<corrupt length: 0x%x>", DataSize);
4803       return OS.str();
4804     }
4805     PrData = support::endian::read32<ELFT::TargetEndianness>(Data.data());
4806     if (PrData == 0) {
4807       OS << "<None>";
4808       return OS.str();
4809     }
4810     if (Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
4811       DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI");
4812       DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC");
4813     } else {
4814       DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT");
4815       DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK");
4816     }
4817     if (PrData)
4818       OS << format("<unknown flags: 0x%x>", PrData);
4819     return OS.str();
4820   case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
4821   case GNU_PROPERTY_X86_FEATURE_2_USED:
4822     OS << "x86 feature "
4823        << (Type == GNU_PROPERTY_X86_FEATURE_2_NEEDED ? "needed: " : "used: ");
4824     if (DataSize != 4) {
4825       OS << format("<corrupt length: 0x%x>", DataSize);
4826       return OS.str();
4827     }
4828     PrData = support::endian::read32<ELFT::TargetEndianness>(Data.data());
4829     if (PrData == 0) {
4830       OS << "<None>";
4831       return OS.str();
4832     }
4833     DumpBit(GNU_PROPERTY_X86_FEATURE_2_X86, "x86");
4834     DumpBit(GNU_PROPERTY_X86_FEATURE_2_X87, "x87");
4835     DumpBit(GNU_PROPERTY_X86_FEATURE_2_MMX, "MMX");
4836     DumpBit(GNU_PROPERTY_X86_FEATURE_2_XMM, "XMM");
4837     DumpBit(GNU_PROPERTY_X86_FEATURE_2_YMM, "YMM");
4838     DumpBit(GNU_PROPERTY_X86_FEATURE_2_ZMM, "ZMM");
4839     DumpBit(GNU_PROPERTY_X86_FEATURE_2_FXSR, "FXSR");
4840     DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVE, "XSAVE");
4841     DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT, "XSAVEOPT");
4842     DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEC, "XSAVEC");
4843     if (PrData)
4844       OS << format("<unknown flags: 0x%x>", PrData);
4845     return OS.str();
4846   case GNU_PROPERTY_X86_ISA_1_NEEDED:
4847   case GNU_PROPERTY_X86_ISA_1_USED:
4848     OS << "x86 ISA "
4849        << (Type == GNU_PROPERTY_X86_ISA_1_NEEDED ? "needed: " : "used: ");
4850     if (DataSize != 4) {
4851       OS << format("<corrupt length: 0x%x>", DataSize);
4852       return OS.str();
4853     }
4854     PrData = support::endian::read32<ELFT::TargetEndianness>(Data.data());
4855     if (PrData == 0) {
4856       OS << "<None>";
4857       return OS.str();
4858     }
4859     DumpBit(GNU_PROPERTY_X86_ISA_1_BASELINE, "x86-64-baseline");
4860     DumpBit(GNU_PROPERTY_X86_ISA_1_V2, "x86-64-v2");
4861     DumpBit(GNU_PROPERTY_X86_ISA_1_V3, "x86-64-v3");
4862     DumpBit(GNU_PROPERTY_X86_ISA_1_V4, "x86-64-v4");
4863     if (PrData)
4864       OS << format("<unknown flags: 0x%x>", PrData);
4865     return OS.str();
4866   }
4867 }
4868 
4869 template <typename ELFT>
4870 static SmallVector<std::string, 4> getGNUPropertyList(ArrayRef<uint8_t> Arr) {
4871   using Elf_Word = typename ELFT::Word;
4872 
4873   SmallVector<std::string, 4> Properties;
4874   while (Arr.size() >= 8) {
4875     uint32_t Type = *reinterpret_cast<const Elf_Word *>(Arr.data());
4876     uint32_t DataSize = *reinterpret_cast<const Elf_Word *>(Arr.data() + 4);
4877     Arr = Arr.drop_front(8);
4878 
4879     // Take padding size into account if present.
4880     uint64_t PaddedSize = alignTo(DataSize, sizeof(typename ELFT::uint));
4881     std::string str;
4882     raw_string_ostream OS(str);
4883     if (Arr.size() < PaddedSize) {
4884       OS << format("<corrupt type (0x%x) datasz: 0x%x>", Type, DataSize);
4885       Properties.push_back(OS.str());
4886       break;
4887     }
4888     Properties.push_back(
4889         getGNUProperty<ELFT>(Type, DataSize, Arr.take_front(PaddedSize)));
4890     Arr = Arr.drop_front(PaddedSize);
4891   }
4892 
4893   if (!Arr.empty())
4894     Properties.push_back("<corrupted GNU_PROPERTY_TYPE_0>");
4895 
4896   return Properties;
4897 }
4898 
4899 struct GNUAbiTag {
4900   std::string OSName;
4901   std::string ABI;
4902   bool IsValid;
4903 };
4904 
4905 template <typename ELFT> static GNUAbiTag getGNUAbiTag(ArrayRef<uint8_t> Desc) {
4906   typedef typename ELFT::Word Elf_Word;
4907 
4908   ArrayRef<Elf_Word> Words(reinterpret_cast<const Elf_Word *>(Desc.begin()),
4909                            reinterpret_cast<const Elf_Word *>(Desc.end()));
4910 
4911   if (Words.size() < 4)
4912     return {"", "", /*IsValid=*/false};
4913 
4914   static const char *OSNames[] = {
4915       "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable", "NaCl",
4916   };
4917   StringRef OSName = "Unknown";
4918   if (Words[0] < array_lengthof(OSNames))
4919     OSName = OSNames[Words[0]];
4920   uint32_t Major = Words[1], Minor = Words[2], Patch = Words[3];
4921   std::string str;
4922   raw_string_ostream ABI(str);
4923   ABI << Major << "." << Minor << "." << Patch;
4924   return {std::string(OSName), ABI.str(), /*IsValid=*/true};
4925 }
4926 
4927 static std::string getGNUBuildId(ArrayRef<uint8_t> Desc) {
4928   std::string str;
4929   raw_string_ostream OS(str);
4930   for (uint8_t B : Desc)
4931     OS << format_hex_no_prefix(B, 2);
4932   return OS.str();
4933 }
4934 
4935 static StringRef getGNUGoldVersion(ArrayRef<uint8_t> Desc) {
4936   return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
4937 }
4938 
4939 template <typename ELFT>
4940 static bool printGNUNote(raw_ostream &OS, uint32_t NoteType,
4941                          ArrayRef<uint8_t> Desc) {
4942   // Return true if we were able to pretty-print the note, false otherwise.
4943   switch (NoteType) {
4944   default:
4945     return false;
4946   case ELF::NT_GNU_ABI_TAG: {
4947     const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
4948     if (!AbiTag.IsValid)
4949       OS << "    <corrupt GNU_ABI_TAG>";
4950     else
4951       OS << "    OS: " << AbiTag.OSName << ", ABI: " << AbiTag.ABI;
4952     break;
4953   }
4954   case ELF::NT_GNU_BUILD_ID: {
4955     OS << "    Build ID: " << getGNUBuildId(Desc);
4956     break;
4957   }
4958   case ELF::NT_GNU_GOLD_VERSION:
4959     OS << "    Version: " << getGNUGoldVersion(Desc);
4960     break;
4961   case ELF::NT_GNU_PROPERTY_TYPE_0:
4962     OS << "    Properties:";
4963     for (const std::string &Property : getGNUPropertyList<ELFT>(Desc))
4964       OS << "    " << Property << "\n";
4965     break;
4966   }
4967   OS << '\n';
4968   return true;
4969 }
4970 
4971 static const EnumEntry<unsigned> FreeBSDFeatureCtlFlags[] = {
4972     {"ASLR_DISABLE", NT_FREEBSD_FCTL_ASLR_DISABLE},
4973     {"PROTMAX_DISABLE", NT_FREEBSD_FCTL_PROTMAX_DISABLE},
4974     {"STKGAP_DISABLE", NT_FREEBSD_FCTL_STKGAP_DISABLE},
4975     {"WXNEEDED", NT_FREEBSD_FCTL_WXNEEDED},
4976     {"LA48", NT_FREEBSD_FCTL_LA48},
4977     {"ASG_DISABLE", NT_FREEBSD_FCTL_ASG_DISABLE},
4978 };
4979 
4980 struct FreeBSDNote {
4981   std::string Type;
4982   std::string Value;
4983 };
4984 
4985 template <typename ELFT>
4986 static Optional<FreeBSDNote>
4987 getFreeBSDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc, bool IsCore) {
4988   if (IsCore)
4989     return None; // No pretty-printing yet.
4990   switch (NoteType) {
4991   case ELF::NT_FREEBSD_ABI_TAG:
4992     if (Desc.size() != 4)
4993       return None;
4994     return FreeBSDNote{
4995         "ABI tag",
4996         utostr(support::endian::read32<ELFT::TargetEndianness>(Desc.data()))};
4997   case ELF::NT_FREEBSD_ARCH_TAG:
4998     return FreeBSDNote{"Arch tag", toStringRef(Desc).str()};
4999   case ELF::NT_FREEBSD_FEATURE_CTL: {
5000     if (Desc.size() != 4)
5001       return None;
5002     unsigned Value =
5003         support::endian::read32<ELFT::TargetEndianness>(Desc.data());
5004     std::string FlagsStr;
5005     raw_string_ostream OS(FlagsStr);
5006     printFlags(Value, makeArrayRef(FreeBSDFeatureCtlFlags), OS);
5007     if (OS.str().empty())
5008       OS << "0x" << utohexstr(Value);
5009     else
5010       OS << "(0x" << utohexstr(Value) << ")";
5011     return FreeBSDNote{"Feature flags", OS.str()};
5012   }
5013   default:
5014     return None;
5015   }
5016 }
5017 
5018 struct AMDNote {
5019   std::string Type;
5020   std::string Value;
5021 };
5022 
5023 template <typename ELFT>
5024 static AMDNote getAMDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
5025   switch (NoteType) {
5026   default:
5027     return {"", ""};
5028   case ELF::NT_AMD_HSA_CODE_OBJECT_VERSION: {
5029     struct CodeObjectVersion {
5030       uint32_t MajorVersion;
5031       uint32_t MinorVersion;
5032     };
5033     if (Desc.size() != sizeof(CodeObjectVersion))
5034       return {"AMD HSA Code Object Version",
5035               "Invalid AMD HSA Code Object Version"};
5036     std::string VersionString;
5037     raw_string_ostream StrOS(VersionString);
5038     auto Version = reinterpret_cast<const CodeObjectVersion *>(Desc.data());
5039     StrOS << "[Major: " << Version->MajorVersion
5040           << ", Minor: " << Version->MinorVersion << "]";
5041     return {"AMD HSA Code Object Version", VersionString};
5042   }
5043   case ELF::NT_AMD_HSA_HSAIL: {
5044     struct HSAILProperties {
5045       uint32_t HSAILMajorVersion;
5046       uint32_t HSAILMinorVersion;
5047       uint8_t Profile;
5048       uint8_t MachineModel;
5049       uint8_t DefaultFloatRound;
5050     };
5051     if (Desc.size() != sizeof(HSAILProperties))
5052       return {"AMD HSA HSAIL Properties", "Invalid AMD HSA HSAIL Properties"};
5053     auto Properties = reinterpret_cast<const HSAILProperties *>(Desc.data());
5054     std::string HSAILPropetiesString;
5055     raw_string_ostream StrOS(HSAILPropetiesString);
5056     StrOS << "[HSAIL Major: " << Properties->HSAILMajorVersion
5057           << ", HSAIL Minor: " << Properties->HSAILMinorVersion
5058           << ", Profile: " << Properties->Profile
5059           << ", Machine Model: " << Properties->MachineModel
5060           << ", Default Float Round: " << Properties->DefaultFloatRound << "]";
5061     return {"AMD HSA HSAIL Properties", HSAILPropetiesString};
5062   }
5063   case ELF::NT_AMD_HSA_ISA_VERSION: {
5064     struct IsaVersion {
5065       uint16_t VendorNameSize;
5066       uint16_t ArchitectureNameSize;
5067       uint32_t Major;
5068       uint32_t Minor;
5069       uint32_t Stepping;
5070     };
5071     if (Desc.size() < sizeof(IsaVersion))
5072       return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"};
5073     auto Isa = reinterpret_cast<const IsaVersion *>(Desc.data());
5074     if (Desc.size() < sizeof(IsaVersion) +
5075                           Isa->VendorNameSize + Isa->ArchitectureNameSize ||
5076         Isa->VendorNameSize == 0 || Isa->ArchitectureNameSize == 0)
5077       return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"};
5078     std::string IsaString;
5079     raw_string_ostream StrOS(IsaString);
5080     StrOS << "[Vendor: "
5081           << StringRef((const char*)Desc.data() + sizeof(IsaVersion), Isa->VendorNameSize - 1)
5082           << ", Architecture: "
5083           << StringRef((const char*)Desc.data() + sizeof(IsaVersion) + Isa->VendorNameSize,
5084                        Isa->ArchitectureNameSize - 1)
5085           << ", Major: " << Isa->Major << ", Minor: " << Isa->Minor
5086           << ", Stepping: " << Isa->Stepping << "]";
5087     return {"AMD HSA ISA Version", IsaString};
5088   }
5089   case ELF::NT_AMD_HSA_METADATA: {
5090     if (Desc.size() == 0)
5091       return {"AMD HSA Metadata", ""};
5092     return {
5093         "AMD HSA Metadata",
5094         std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size() - 1)};
5095   }
5096   case ELF::NT_AMD_HSA_ISA_NAME: {
5097     if (Desc.size() == 0)
5098       return {"AMD HSA ISA Name", ""};
5099     return {
5100         "AMD HSA ISA Name",
5101         std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size())};
5102   }
5103   case ELF::NT_AMD_PAL_METADATA: {
5104     struct PALMetadata {
5105       uint32_t Key;
5106       uint32_t Value;
5107     };
5108     auto Isa = reinterpret_cast<const PALMetadata *>(Desc.data());
5109     std::string MetadataString;
5110     raw_string_ostream StrOS(MetadataString);
5111     for (size_t I = 0, E = Desc.size() / sizeof(PALMetadata); I < E; ++E) {
5112       StrOS << "[" << Isa[I].Key << ": " << Isa[I].Value << "]";
5113     }
5114     return {"AMD PAL Metadata", MetadataString};
5115   }
5116   }
5117 }
5118 
5119 struct AMDGPUNote {
5120   std::string Type;
5121   std::string Value;
5122 };
5123 
5124 template <typename ELFT>
5125 static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
5126   switch (NoteType) {
5127   default:
5128     return {"", ""};
5129   case ELF::NT_AMDGPU_METADATA: {
5130     StringRef MsgPackString =
5131         StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
5132     msgpack::Document MsgPackDoc;
5133     if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false))
5134       return {"", ""};
5135 
5136     AMDGPU::HSAMD::V3::MetadataVerifier Verifier(true);
5137     std::string MetadataString;
5138     if (!Verifier.verify(MsgPackDoc.getRoot()))
5139       MetadataString = "Invalid AMDGPU Metadata\n";
5140 
5141     raw_string_ostream StrOS(MetadataString);
5142     if (MsgPackDoc.getRoot().isScalar()) {
5143       // TODO: passing a scalar root to toYAML() asserts:
5144       // (PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar &&
5145       //    "plain scalar documents are not supported")
5146       // To avoid this crash we print the raw data instead.
5147       return {"", ""};
5148     }
5149     MsgPackDoc.toYAML(StrOS);
5150     return {"AMDGPU Metadata", StrOS.str()};
5151   }
5152   }
5153 }
5154 
5155 struct CoreFileMapping {
5156   uint64_t Start, End, Offset;
5157   StringRef Filename;
5158 };
5159 
5160 struct CoreNote {
5161   uint64_t PageSize;
5162   std::vector<CoreFileMapping> Mappings;
5163 };
5164 
5165 static Expected<CoreNote> readCoreNote(DataExtractor Desc) {
5166   // Expected format of the NT_FILE note description:
5167   // 1. # of file mappings (call it N)
5168   // 2. Page size
5169   // 3. N (start, end, offset) triples
5170   // 4. N packed filenames (null delimited)
5171   // Each field is an Elf_Addr, except for filenames which are char* strings.
5172 
5173   CoreNote Ret;
5174   const int Bytes = Desc.getAddressSize();
5175 
5176   if (!Desc.isValidOffsetForAddress(2))
5177     return createError("the note of size 0x" + Twine::utohexstr(Desc.size()) +
5178                        " is too short, expected at least 0x" +
5179                        Twine::utohexstr(Bytes * 2));
5180   if (Desc.getData().back() != 0)
5181     return createError("the note is not NUL terminated");
5182 
5183   uint64_t DescOffset = 0;
5184   uint64_t FileCount = Desc.getAddress(&DescOffset);
5185   Ret.PageSize = Desc.getAddress(&DescOffset);
5186 
5187   if (!Desc.isValidOffsetForAddress(3 * FileCount * Bytes))
5188     return createError("unable to read file mappings (found " +
5189                        Twine(FileCount) + "): the note of size 0x" +
5190                        Twine::utohexstr(Desc.size()) + " is too short");
5191 
5192   uint64_t FilenamesOffset = 0;
5193   DataExtractor Filenames(
5194       Desc.getData().drop_front(DescOffset + 3 * FileCount * Bytes),
5195       Desc.isLittleEndian(), Desc.getAddressSize());
5196 
5197   Ret.Mappings.resize(FileCount);
5198   size_t I = 0;
5199   for (CoreFileMapping &Mapping : Ret.Mappings) {
5200     ++I;
5201     if (!Filenames.isValidOffsetForDataOfSize(FilenamesOffset, 1))
5202       return createError(
5203           "unable to read the file name for the mapping with index " +
5204           Twine(I) + ": the note of size 0x" + Twine::utohexstr(Desc.size()) +
5205           " is truncated");
5206     Mapping.Start = Desc.getAddress(&DescOffset);
5207     Mapping.End = Desc.getAddress(&DescOffset);
5208     Mapping.Offset = Desc.getAddress(&DescOffset);
5209     Mapping.Filename = Filenames.getCStrRef(&FilenamesOffset);
5210   }
5211 
5212   return Ret;
5213 }
5214 
5215 template <typename ELFT>
5216 static void printCoreNote(raw_ostream &OS, const CoreNote &Note) {
5217   // Length of "0x<address>" string.
5218   const int FieldWidth = ELFT::Is64Bits ? 18 : 10;
5219 
5220   OS << "    Page size: " << format_decimal(Note.PageSize, 0) << '\n';
5221   OS << "    " << right_justify("Start", FieldWidth) << "  "
5222      << right_justify("End", FieldWidth) << "  "
5223      << right_justify("Page Offset", FieldWidth) << '\n';
5224   for (const CoreFileMapping &Mapping : Note.Mappings) {
5225     OS << "    " << format_hex(Mapping.Start, FieldWidth) << "  "
5226        << format_hex(Mapping.End, FieldWidth) << "  "
5227        << format_hex(Mapping.Offset, FieldWidth) << "\n        "
5228        << Mapping.Filename << '\n';
5229   }
5230 }
5231 
5232 static const NoteType GenericNoteTypes[] = {
5233     {ELF::NT_VERSION, "NT_VERSION (version)"},
5234     {ELF::NT_ARCH, "NT_ARCH (architecture)"},
5235     {ELF::NT_GNU_BUILD_ATTRIBUTE_OPEN, "OPEN"},
5236     {ELF::NT_GNU_BUILD_ATTRIBUTE_FUNC, "func"},
5237 };
5238 
5239 static const NoteType GNUNoteTypes[] = {
5240     {ELF::NT_GNU_ABI_TAG, "NT_GNU_ABI_TAG (ABI version tag)"},
5241     {ELF::NT_GNU_HWCAP, "NT_GNU_HWCAP (DSO-supplied software HWCAP info)"},
5242     {ELF::NT_GNU_BUILD_ID, "NT_GNU_BUILD_ID (unique build ID bitstring)"},
5243     {ELF::NT_GNU_GOLD_VERSION, "NT_GNU_GOLD_VERSION (gold version)"},
5244     {ELF::NT_GNU_PROPERTY_TYPE_0, "NT_GNU_PROPERTY_TYPE_0 (property note)"},
5245 };
5246 
5247 static const NoteType FreeBSDCoreNoteTypes[] = {
5248     {ELF::NT_FREEBSD_THRMISC, "NT_THRMISC (thrmisc structure)"},
5249     {ELF::NT_FREEBSD_PROCSTAT_PROC, "NT_PROCSTAT_PROC (proc data)"},
5250     {ELF::NT_FREEBSD_PROCSTAT_FILES, "NT_PROCSTAT_FILES (files data)"},
5251     {ELF::NT_FREEBSD_PROCSTAT_VMMAP, "NT_PROCSTAT_VMMAP (vmmap data)"},
5252     {ELF::NT_FREEBSD_PROCSTAT_GROUPS, "NT_PROCSTAT_GROUPS (groups data)"},
5253     {ELF::NT_FREEBSD_PROCSTAT_UMASK, "NT_PROCSTAT_UMASK (umask data)"},
5254     {ELF::NT_FREEBSD_PROCSTAT_RLIMIT, "NT_PROCSTAT_RLIMIT (rlimit data)"},
5255     {ELF::NT_FREEBSD_PROCSTAT_OSREL, "NT_PROCSTAT_OSREL (osreldate data)"},
5256     {ELF::NT_FREEBSD_PROCSTAT_PSSTRINGS,
5257      "NT_PROCSTAT_PSSTRINGS (ps_strings data)"},
5258     {ELF::NT_FREEBSD_PROCSTAT_AUXV, "NT_PROCSTAT_AUXV (auxv data)"},
5259 };
5260 
5261 static const NoteType FreeBSDNoteTypes[] = {
5262     {ELF::NT_FREEBSD_ABI_TAG, "NT_FREEBSD_ABI_TAG (ABI version tag)"},
5263     {ELF::NT_FREEBSD_NOINIT_TAG, "NT_FREEBSD_NOINIT_TAG (no .init tag)"},
5264     {ELF::NT_FREEBSD_ARCH_TAG, "NT_FREEBSD_ARCH_TAG (architecture tag)"},
5265     {ELF::NT_FREEBSD_FEATURE_CTL,
5266      "NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)"},
5267 };
5268 
5269 static const NoteType AMDNoteTypes[] = {
5270     {ELF::NT_AMD_HSA_CODE_OBJECT_VERSION,
5271      "NT_AMD_HSA_CODE_OBJECT_VERSION (AMD HSA Code Object Version)"},
5272     {ELF::NT_AMD_HSA_HSAIL, "NT_AMD_HSA_HSAIL (AMD HSA HSAIL Properties)"},
5273     {ELF::NT_AMD_HSA_ISA_VERSION, "NT_AMD_HSA_ISA_VERSION (AMD HSA ISA Version)"},
5274     {ELF::NT_AMD_HSA_METADATA, "NT_AMD_HSA_METADATA (AMD HSA Metadata)"},
5275     {ELF::NT_AMD_HSA_ISA_NAME, "NT_AMD_HSA_ISA_NAME (AMD HSA ISA Name)"},
5276     {ELF::NT_AMD_PAL_METADATA, "NT_AMD_PAL_METADATA (AMD PAL Metadata)"},
5277 };
5278 
5279 static const NoteType AMDGPUNoteTypes[] = {
5280     {ELF::NT_AMDGPU_METADATA, "NT_AMDGPU_METADATA (AMDGPU Metadata)"},
5281 };
5282 
5283 static const NoteType CoreNoteTypes[] = {
5284     {ELF::NT_PRSTATUS, "NT_PRSTATUS (prstatus structure)"},
5285     {ELF::NT_FPREGSET, "NT_FPREGSET (floating point registers)"},
5286     {ELF::NT_PRPSINFO, "NT_PRPSINFO (prpsinfo structure)"},
5287     {ELF::NT_TASKSTRUCT, "NT_TASKSTRUCT (task structure)"},
5288     {ELF::NT_AUXV, "NT_AUXV (auxiliary vector)"},
5289     {ELF::NT_PSTATUS, "NT_PSTATUS (pstatus structure)"},
5290     {ELF::NT_FPREGS, "NT_FPREGS (floating point registers)"},
5291     {ELF::NT_PSINFO, "NT_PSINFO (psinfo structure)"},
5292     {ELF::NT_LWPSTATUS, "NT_LWPSTATUS (lwpstatus_t structure)"},
5293     {ELF::NT_LWPSINFO, "NT_LWPSINFO (lwpsinfo_t structure)"},
5294     {ELF::NT_WIN32PSTATUS, "NT_WIN32PSTATUS (win32_pstatus structure)"},
5295 
5296     {ELF::NT_PPC_VMX, "NT_PPC_VMX (ppc Altivec registers)"},
5297     {ELF::NT_PPC_VSX, "NT_PPC_VSX (ppc VSX registers)"},
5298     {ELF::NT_PPC_TAR, "NT_PPC_TAR (ppc TAR register)"},
5299     {ELF::NT_PPC_PPR, "NT_PPC_PPR (ppc PPR register)"},
5300     {ELF::NT_PPC_DSCR, "NT_PPC_DSCR (ppc DSCR register)"},
5301     {ELF::NT_PPC_EBB, "NT_PPC_EBB (ppc EBB registers)"},
5302     {ELF::NT_PPC_PMU, "NT_PPC_PMU (ppc PMU registers)"},
5303     {ELF::NT_PPC_TM_CGPR, "NT_PPC_TM_CGPR (ppc checkpointed GPR registers)"},
5304     {ELF::NT_PPC_TM_CFPR,
5305      "NT_PPC_TM_CFPR (ppc checkpointed floating point registers)"},
5306     {ELF::NT_PPC_TM_CVMX,
5307      "NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)"},
5308     {ELF::NT_PPC_TM_CVSX, "NT_PPC_TM_CVSX (ppc checkpointed VSX registers)"},
5309     {ELF::NT_PPC_TM_SPR, "NT_PPC_TM_SPR (ppc TM special purpose registers)"},
5310     {ELF::NT_PPC_TM_CTAR, "NT_PPC_TM_CTAR (ppc checkpointed TAR register)"},
5311     {ELF::NT_PPC_TM_CPPR, "NT_PPC_TM_CPPR (ppc checkpointed PPR register)"},
5312     {ELF::NT_PPC_TM_CDSCR, "NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)"},
5313 
5314     {ELF::NT_386_TLS, "NT_386_TLS (x86 TLS information)"},
5315     {ELF::NT_386_IOPERM, "NT_386_IOPERM (x86 I/O permissions)"},
5316     {ELF::NT_X86_XSTATE, "NT_X86_XSTATE (x86 XSAVE extended state)"},
5317 
5318     {ELF::NT_S390_HIGH_GPRS, "NT_S390_HIGH_GPRS (s390 upper register halves)"},
5319     {ELF::NT_S390_TIMER, "NT_S390_TIMER (s390 timer register)"},
5320     {ELF::NT_S390_TODCMP, "NT_S390_TODCMP (s390 TOD comparator register)"},
5321     {ELF::NT_S390_TODPREG, "NT_S390_TODPREG (s390 TOD programmable register)"},
5322     {ELF::NT_S390_CTRS, "NT_S390_CTRS (s390 control registers)"},
5323     {ELF::NT_S390_PREFIX, "NT_S390_PREFIX (s390 prefix register)"},
5324     {ELF::NT_S390_LAST_BREAK,
5325      "NT_S390_LAST_BREAK (s390 last breaking event address)"},
5326     {ELF::NT_S390_SYSTEM_CALL,
5327      "NT_S390_SYSTEM_CALL (s390 system call restart data)"},
5328     {ELF::NT_S390_TDB, "NT_S390_TDB (s390 transaction diagnostic block)"},
5329     {ELF::NT_S390_VXRS_LOW,
5330      "NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)"},
5331     {ELF::NT_S390_VXRS_HIGH, "NT_S390_VXRS_HIGH (s390 vector registers 16-31)"},
5332     {ELF::NT_S390_GS_CB, "NT_S390_GS_CB (s390 guarded-storage registers)"},
5333     {ELF::NT_S390_GS_BC,
5334      "NT_S390_GS_BC (s390 guarded-storage broadcast control)"},
5335 
5336     {ELF::NT_ARM_VFP, "NT_ARM_VFP (arm VFP registers)"},
5337     {ELF::NT_ARM_TLS, "NT_ARM_TLS (AArch TLS registers)"},
5338     {ELF::NT_ARM_HW_BREAK,
5339      "NT_ARM_HW_BREAK (AArch hardware breakpoint registers)"},
5340     {ELF::NT_ARM_HW_WATCH,
5341      "NT_ARM_HW_WATCH (AArch hardware watchpoint registers)"},
5342 
5343     {ELF::NT_FILE, "NT_FILE (mapped files)"},
5344     {ELF::NT_PRXFPREG, "NT_PRXFPREG (user_xfpregs structure)"},
5345     {ELF::NT_SIGINFO, "NT_SIGINFO (siginfo_t data)"},
5346 };
5347 
5348 template <class ELFT>
5349 StringRef getNoteTypeName(const typename ELFT::Note &Note, unsigned ELFType) {
5350   uint32_t Type = Note.getType();
5351   auto FindNote = [&](ArrayRef<NoteType> V) -> StringRef {
5352     for (const NoteType &N : V)
5353       if (N.ID == Type)
5354         return N.Name;
5355     return "";
5356   };
5357 
5358   StringRef Name = Note.getName();
5359   if (Name == "GNU")
5360     return FindNote(GNUNoteTypes);
5361   if (Name == "FreeBSD") {
5362     if (ELFType == ELF::ET_CORE) {
5363       // FreeBSD also places the generic core notes in the FreeBSD namespace.
5364       StringRef Result = FindNote(FreeBSDCoreNoteTypes);
5365       if (!Result.empty())
5366         return Result;
5367       return FindNote(CoreNoteTypes);
5368     } else {
5369       return FindNote(FreeBSDNoteTypes);
5370     }
5371   }
5372   if (Name == "AMD")
5373     return FindNote(AMDNoteTypes);
5374   if (Name == "AMDGPU")
5375     return FindNote(AMDGPUNoteTypes);
5376 
5377   if (ELFType == ELF::ET_CORE)
5378     return FindNote(CoreNoteTypes);
5379   return FindNote(GenericNoteTypes);
5380 }
5381 
5382 template <class ELFT>
5383 static void printNotesHelper(
5384     const ELFDumper<ELFT> &Dumper,
5385     llvm::function_ref<void(Optional<StringRef>, typename ELFT::Off,
5386                             typename ELFT::Addr)>
5387         StartNotesFn,
5388     llvm::function_ref<Error(const typename ELFT::Note &, bool)> ProcessNoteFn,
5389     llvm::function_ref<void()> FinishNotesFn) {
5390   const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
5391   bool IsCoreFile = Obj.getHeader().e_type == ELF::ET_CORE;
5392 
5393   ArrayRef<typename ELFT::Shdr> Sections = cantFail(Obj.sections());
5394   if (!IsCoreFile && !Sections.empty()) {
5395     for (const typename ELFT::Shdr &S : Sections) {
5396       if (S.sh_type != SHT_NOTE)
5397         continue;
5398       StartNotesFn(expectedToOptional(Obj.getSectionName(S)), S.sh_offset,
5399                    S.sh_size);
5400       Error Err = Error::success();
5401       size_t I = 0;
5402       for (const typename ELFT::Note Note : Obj.notes(S, Err)) {
5403         if (Error E = ProcessNoteFn(Note, IsCoreFile))
5404           Dumper.reportUniqueWarning(
5405               "unable to read note with index " + Twine(I) + " from the " +
5406               describe(Obj, S) + ": " + toString(std::move(E)));
5407         ++I;
5408       }
5409       if (Err)
5410         Dumper.reportUniqueWarning("unable to read notes from the " +
5411                                    describe(Obj, S) + ": " +
5412                                    toString(std::move(Err)));
5413       FinishNotesFn();
5414     }
5415     return;
5416   }
5417 
5418   Expected<ArrayRef<typename ELFT::Phdr>> PhdrsOrErr = Obj.program_headers();
5419   if (!PhdrsOrErr) {
5420     Dumper.reportUniqueWarning(
5421         "unable to read program headers to locate the PT_NOTE segment: " +
5422         toString(PhdrsOrErr.takeError()));
5423     return;
5424   }
5425 
5426   for (size_t I = 0, E = (*PhdrsOrErr).size(); I != E; ++I) {
5427     const typename ELFT::Phdr &P = (*PhdrsOrErr)[I];
5428     if (P.p_type != PT_NOTE)
5429       continue;
5430     StartNotesFn(/*SecName=*/None, P.p_offset, P.p_filesz);
5431     Error Err = Error::success();
5432     size_t Index = 0;
5433     for (const typename ELFT::Note Note : Obj.notes(P, Err)) {
5434       if (Error E = ProcessNoteFn(Note, IsCoreFile))
5435         Dumper.reportUniqueWarning("unable to read note with index " +
5436                                    Twine(Index) +
5437                                    " from the PT_NOTE segment with index " +
5438                                    Twine(I) + ": " + toString(std::move(E)));
5439       ++Index;
5440     }
5441     if (Err)
5442       Dumper.reportUniqueWarning(
5443           "unable to read notes from the PT_NOTE segment with index " +
5444           Twine(I) + ": " + toString(std::move(Err)));
5445     FinishNotesFn();
5446   }
5447 }
5448 
5449 template <class ELFT> void GNUELFDumper<ELFT>::printNotes() {
5450   bool IsFirstHeader = true;
5451   auto PrintHeader = [&](Optional<StringRef> SecName,
5452                          const typename ELFT::Off Offset,
5453                          const typename ELFT::Addr Size) {
5454     // Print a newline between notes sections to match GNU readelf.
5455     if (!IsFirstHeader) {
5456       OS << '\n';
5457     } else {
5458       IsFirstHeader = false;
5459     }
5460 
5461     OS << "Displaying notes found ";
5462 
5463     if (SecName)
5464       OS << "in: " << *SecName << "\n";
5465     else
5466       OS << "at file offset " << format_hex(Offset, 10) << " with length "
5467          << format_hex(Size, 10) << ":\n";
5468 
5469     OS << "  Owner                Data size \tDescription\n";
5470   };
5471 
5472   auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {
5473     StringRef Name = Note.getName();
5474     ArrayRef<uint8_t> Descriptor = Note.getDesc();
5475     Elf_Word Type = Note.getType();
5476 
5477     // Print the note owner/type.
5478     OS << "  " << left_justify(Name, 20) << ' '
5479        << format_hex(Descriptor.size(), 10) << '\t';
5480 
5481     StringRef NoteType =
5482         getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type);
5483     if (!NoteType.empty())
5484       OS << NoteType << '\n';
5485     else
5486       OS << "Unknown note type: (" << format_hex(Type, 10) << ")\n";
5487 
5488     // Print the description, or fallback to printing raw bytes for unknown
5489     // owners/if we fail to pretty-print the contents.
5490     if (Name == "GNU") {
5491       if (printGNUNote<ELFT>(OS, Type, Descriptor))
5492         return Error::success();
5493     } else if (Name == "FreeBSD") {
5494       if (Optional<FreeBSDNote> N =
5495               getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {
5496         OS << "    " << N->Type << ": " << N->Value << '\n';
5497         return Error::success();
5498       }
5499     } else if (Name == "AMD") {
5500       const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
5501       if (!N.Type.empty()) {
5502         OS << "    " << N.Type << ":\n        " << N.Value << '\n';
5503         return Error::success();
5504       }
5505     } else if (Name == "AMDGPU") {
5506       const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
5507       if (!N.Type.empty()) {
5508         OS << "    " << N.Type << ":\n        " << N.Value << '\n';
5509         return Error::success();
5510       }
5511     } else if (Name == "CORE") {
5512       if (Type == ELF::NT_FILE) {
5513         DataExtractor DescExtractor(Descriptor,
5514                                     ELFT::TargetEndianness == support::little,
5515                                     sizeof(Elf_Addr));
5516         if (Expected<CoreNote> NoteOrErr = readCoreNote(DescExtractor)) {
5517           printCoreNote<ELFT>(OS, *NoteOrErr);
5518           return Error::success();
5519         } else {
5520           return NoteOrErr.takeError();
5521         }
5522       }
5523     }
5524     if (!Descriptor.empty()) {
5525       OS << "   description data:";
5526       for (uint8_t B : Descriptor)
5527         OS << " " << format("%02x", B);
5528       OS << '\n';
5529     }
5530     return Error::success();
5531   };
5532 
5533   printNotesHelper(*this, PrintHeader, ProcessNote, []() {});
5534 }
5535 
5536 template <class ELFT> void GNUELFDumper<ELFT>::printELFLinkerOptions() {
5537   OS << "printELFLinkerOptions not implemented!\n";
5538 }
5539 
5540 template <class ELFT>
5541 void ELFDumper<ELFT>::printDependentLibsHelper(
5542     function_ref<void(const Elf_Shdr &)> OnSectionStart,
5543     function_ref<void(StringRef, uint64_t)> OnLibEntry) {
5544   auto Warn = [this](unsigned SecNdx, StringRef Msg) {
5545     this->reportUniqueWarning("SHT_LLVM_DEPENDENT_LIBRARIES section at index " +
5546                               Twine(SecNdx) + " is broken: " + Msg);
5547   };
5548 
5549   unsigned I = -1;
5550   for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) {
5551     ++I;
5552     if (Shdr.sh_type != ELF::SHT_LLVM_DEPENDENT_LIBRARIES)
5553       continue;
5554 
5555     OnSectionStart(Shdr);
5556 
5557     Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Shdr);
5558     if (!ContentsOrErr) {
5559       Warn(I, toString(ContentsOrErr.takeError()));
5560       continue;
5561     }
5562 
5563     ArrayRef<uint8_t> Contents = *ContentsOrErr;
5564     if (!Contents.empty() && Contents.back() != 0) {
5565       Warn(I, "the content is not null-terminated");
5566       continue;
5567     }
5568 
5569     for (const uint8_t *I = Contents.begin(), *E = Contents.end(); I < E;) {
5570       StringRef Lib((const char *)I);
5571       OnLibEntry(Lib, I - Contents.begin());
5572       I += Lib.size() + 1;
5573     }
5574   }
5575 }
5576 
5577 template <class ELFT>
5578 void ELFDumper<ELFT>::forEachRelocationDo(
5579     const Elf_Shdr &Sec, bool RawRelr,
5580     llvm::function_ref<void(const Relocation<ELFT> &, unsigned,
5581                             const Elf_Shdr &, const Elf_Shdr *)>
5582         RelRelaFn,
5583     llvm::function_ref<void(const Elf_Relr &)> RelrFn) {
5584   auto Warn = [&](Error &&E,
5585                   const Twine &Prefix = "unable to read relocations from") {
5586     this->reportUniqueWarning(Prefix + " " + describe(Sec) + ": " +
5587                               toString(std::move(E)));
5588   };
5589 
5590   // SHT_RELR/SHT_ANDROID_RELR sections do not have an associated symbol table.
5591   // For them we should not treat the value of the sh_link field as an index of
5592   // a symbol table.
5593   const Elf_Shdr *SymTab;
5594   if (Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_RELR) {
5595     Expected<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Sec.sh_link);
5596     if (!SymTabOrErr) {
5597       Warn(SymTabOrErr.takeError(), "unable to locate a symbol table for");
5598       return;
5599     }
5600     SymTab = *SymTabOrErr;
5601   }
5602 
5603   unsigned RelNdx = 0;
5604   const bool IsMips64EL = this->Obj.isMips64EL();
5605   switch (Sec.sh_type) {
5606   case ELF::SHT_REL:
5607     if (Expected<Elf_Rel_Range> RangeOrErr = Obj.rels(Sec)) {
5608       for (const Elf_Rel &R : *RangeOrErr)
5609         RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);
5610     } else {
5611       Warn(RangeOrErr.takeError());
5612     }
5613     break;
5614   case ELF::SHT_RELA:
5615     if (Expected<Elf_Rela_Range> RangeOrErr = Obj.relas(Sec)) {
5616       for (const Elf_Rela &R : *RangeOrErr)
5617         RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);
5618     } else {
5619       Warn(RangeOrErr.takeError());
5620     }
5621     break;
5622   case ELF::SHT_RELR:
5623   case ELF::SHT_ANDROID_RELR: {
5624     Expected<Elf_Relr_Range> RangeOrErr = Obj.relrs(Sec);
5625     if (!RangeOrErr) {
5626       Warn(RangeOrErr.takeError());
5627       break;
5628     }
5629     if (RawRelr) {
5630       for (const Elf_Relr &R : *RangeOrErr)
5631         RelrFn(R);
5632       break;
5633     }
5634 
5635     for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr))
5636       RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec,
5637                 /*SymTab=*/nullptr);
5638     break;
5639   }
5640   case ELF::SHT_ANDROID_REL:
5641   case ELF::SHT_ANDROID_RELA:
5642     if (Expected<std::vector<Elf_Rela>> RelasOrErr = Obj.android_relas(Sec)) {
5643       for (const Elf_Rela &R : *RelasOrErr)
5644         RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);
5645     } else {
5646       Warn(RelasOrErr.takeError());
5647     }
5648     break;
5649   }
5650 }
5651 
5652 template <class ELFT>
5653 StringRef ELFDumper<ELFT>::getPrintableSectionName(const Elf_Shdr &Sec) const {
5654   StringRef Name = "<?>";
5655   if (Expected<StringRef> SecNameOrErr =
5656           Obj.getSectionName(Sec, this->WarningHandler))
5657     Name = *SecNameOrErr;
5658   else
5659     this->reportUniqueWarning("unable to get the name of " + describe(Sec) +
5660                               ": " + toString(SecNameOrErr.takeError()));
5661   return Name;
5662 }
5663 
5664 template <class ELFT> void GNUELFDumper<ELFT>::printDependentLibs() {
5665   bool SectionStarted = false;
5666   struct NameOffset {
5667     StringRef Name;
5668     uint64_t Offset;
5669   };
5670   std::vector<NameOffset> SecEntries;
5671   NameOffset Current;
5672   auto PrintSection = [&]() {
5673     OS << "Dependent libraries section " << Current.Name << " at offset "
5674        << format_hex(Current.Offset, 1) << " contains " << SecEntries.size()
5675        << " entries:\n";
5676     for (NameOffset Entry : SecEntries)
5677       OS << "  [" << format("%6" PRIx64, Entry.Offset) << "]  " << Entry.Name
5678          << "\n";
5679     OS << "\n";
5680     SecEntries.clear();
5681   };
5682 
5683   auto OnSectionStart = [&](const Elf_Shdr &Shdr) {
5684     if (SectionStarted)
5685       PrintSection();
5686     SectionStarted = true;
5687     Current.Offset = Shdr.sh_offset;
5688     Current.Name = this->getPrintableSectionName(Shdr);
5689   };
5690   auto OnLibEntry = [&](StringRef Lib, uint64_t Offset) {
5691     SecEntries.push_back(NameOffset{Lib, Offset});
5692   };
5693 
5694   this->printDependentLibsHelper(OnSectionStart, OnLibEntry);
5695   if (SectionStarted)
5696     PrintSection();
5697 }
5698 
5699 template <class ELFT>
5700 bool ELFDumper<ELFT>::printFunctionStackSize(
5701     uint64_t SymValue, Optional<const Elf_Shdr *> FunctionSec,
5702     const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) {
5703   uint32_t FuncSymIndex = 0;
5704   if (this->DotSymtabSec) {
5705     if (Expected<Elf_Sym_Range> SymsOrError = Obj.symbols(this->DotSymtabSec)) {
5706       uint32_t Index = (uint32_t)-1;
5707       for (const Elf_Sym &Sym : *SymsOrError) {
5708         ++Index;
5709 
5710         if (Sym.st_shndx == ELF::SHN_UNDEF || Sym.getType() != ELF::STT_FUNC)
5711           continue;
5712 
5713         if (Expected<uint64_t> SymAddrOrErr =
5714                 ObjF.toSymbolRef(this->DotSymtabSec, Index).getAddress()) {
5715           if (SymValue != *SymAddrOrErr)
5716             continue;
5717         } else {
5718           std::string Name = this->getStaticSymbolName(Index);
5719           reportUniqueWarning("unable to get address of symbol '" + Name +
5720                               "': " + toString(SymAddrOrErr.takeError()));
5721           break;
5722         }
5723 
5724         // Check if the symbol is in the right section. FunctionSec == None
5725         // means "any section".
5726         if (FunctionSec) {
5727           if (Expected<const Elf_Shdr *> SecOrErr =
5728                   Obj.getSection(Sym, this->DotSymtabSec,
5729                                  this->getShndxTable(this->DotSymtabSec))) {
5730             if (*FunctionSec != *SecOrErr)
5731               continue;
5732           } else {
5733             std::string Name = this->getStaticSymbolName(Index);
5734             // Note: it is impossible to trigger this error currently, it is
5735             // untested.
5736             reportUniqueWarning("unable to get section of symbol '" + Name +
5737                                 "': " + toString(SecOrErr.takeError()));
5738             break;
5739           }
5740         }
5741 
5742         FuncSymIndex = Index;
5743         break;
5744       }
5745     } else {
5746       reportUniqueWarning("unable to read the symbol table: " +
5747                           toString(SymsOrError.takeError()));
5748     }
5749   }
5750 
5751   std::string FuncName = "?";
5752   if (!FuncSymIndex)
5753     reportUniqueWarning(
5754         "could not identify function symbol for stack size entry in " +
5755         describe(StackSizeSec));
5756   else
5757     FuncName = this->getStaticSymbolName(FuncSymIndex);
5758 
5759   // Extract the size. The expectation is that Offset is pointing to the right
5760   // place, i.e. past the function address.
5761   Error Err = Error::success();
5762   uint64_t StackSize = Data.getULEB128(Offset, &Err);
5763   if (Err) {
5764     reportUniqueWarning("could not extract a valid stack size from " +
5765                         describe(StackSizeSec) + ": " +
5766                         toString(std::move(Err)));
5767     return false;
5768   }
5769   printStackSizeEntry(StackSize, FuncName);
5770   return true;
5771 }
5772 
5773 template <class ELFT>
5774 void GNUELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,
5775                                              StringRef FuncName) {
5776   OS.PadToColumn(2);
5777   OS << format_decimal(Size, 11);
5778   OS.PadToColumn(18);
5779   OS << FuncName << "\n";
5780 }
5781 
5782 template <class ELFT>
5783 void ELFDumper<ELFT>::printStackSize(const Relocation<ELFT> &R,
5784                                      const Elf_Shdr &RelocSec, unsigned Ndx,
5785                                      const Elf_Shdr *SymTab,
5786                                      const Elf_Shdr *FunctionSec,
5787                                      const Elf_Shdr &StackSizeSec,
5788                                      const RelocationResolver &Resolver,
5789                                      DataExtractor Data) {
5790   // This function ignores potentially erroneous input, unless it is directly
5791   // related to stack size reporting.
5792   const Elf_Sym *Sym = nullptr;
5793   Expected<RelSymbol<ELFT>> TargetOrErr = this->getRelocationTarget(R, SymTab);
5794   if (!TargetOrErr)
5795     reportUniqueWarning("unable to get the target of relocation with index " +
5796                         Twine(Ndx) + " in " + describe(RelocSec) + ": " +
5797                         toString(TargetOrErr.takeError()));
5798   else
5799     Sym = TargetOrErr->Sym;
5800 
5801   uint64_t RelocSymValue = 0;
5802   if (Sym) {
5803     Expected<const Elf_Shdr *> SectionOrErr =
5804         this->Obj.getSection(*Sym, SymTab, this->getShndxTable(SymTab));
5805     if (!SectionOrErr) {
5806       reportUniqueWarning(
5807           "cannot identify the section for relocation symbol '" +
5808           (*TargetOrErr).Name + "': " + toString(SectionOrErr.takeError()));
5809     } else if (*SectionOrErr != FunctionSec) {
5810       reportUniqueWarning("relocation symbol '" + (*TargetOrErr).Name +
5811                           "' is not in the expected section");
5812       // Pretend that the symbol is in the correct section and report its
5813       // stack size anyway.
5814       FunctionSec = *SectionOrErr;
5815     }
5816 
5817     RelocSymValue = Sym->st_value;
5818   }
5819 
5820   uint64_t Offset = R.Offset;
5821   if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {
5822     reportUniqueWarning("found invalid relocation offset (0x" +
5823                         Twine::utohexstr(Offset) + ") into " +
5824                         describe(StackSizeSec) +
5825                         " while trying to extract a stack size entry");
5826     return;
5827   }
5828 
5829   uint64_t SymValue =
5830       Resolver(R.Type, Offset, RelocSymValue, Data.getAddress(&Offset),
5831                R.Addend.getValueOr(0));
5832   this->printFunctionStackSize(SymValue, FunctionSec, StackSizeSec, Data,
5833                                &Offset);
5834 }
5835 
5836 template <class ELFT>
5837 void ELFDumper<ELFT>::printNonRelocatableStackSizes(
5838     std::function<void()> PrintHeader) {
5839   // This function ignores potentially erroneous input, unless it is directly
5840   // related to stack size reporting.
5841   for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
5842     if (this->getPrintableSectionName(Sec) != ".stack_sizes")
5843       continue;
5844     PrintHeader();
5845     ArrayRef<uint8_t> Contents =
5846         unwrapOrError(this->FileName, Obj.getSectionContents(Sec));
5847     DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr));
5848     uint64_t Offset = 0;
5849     while (Offset < Contents.size()) {
5850       // The function address is followed by a ULEB representing the stack
5851       // size. Check for an extra byte before we try to process the entry.
5852       if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {
5853         reportUniqueWarning(
5854             describe(Sec) +
5855             " ended while trying to extract a stack size entry");
5856         break;
5857       }
5858       uint64_t SymValue = Data.getAddress(&Offset);
5859       if (!printFunctionStackSize(SymValue, /*FunctionSec=*/None, Sec, Data,
5860                                   &Offset))
5861         break;
5862     }
5863   }
5864 }
5865 
5866 template <class ELFT>
5867 void ELFDumper<ELFT>::printRelocatableStackSizes(
5868     std::function<void()> PrintHeader) {
5869   // Build a map between stack size sections and their corresponding relocation
5870   // sections.
5871   llvm::MapVector<const Elf_Shdr *, const Elf_Shdr *> StackSizeRelocMap;
5872   for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
5873     StringRef SectionName;
5874     if (Expected<StringRef> NameOrErr = Obj.getSectionName(Sec))
5875       SectionName = *NameOrErr;
5876     else
5877       consumeError(NameOrErr.takeError());
5878 
5879     // A stack size section that we haven't encountered yet is mapped to the
5880     // null section until we find its corresponding relocation section.
5881     if (SectionName == ".stack_sizes")
5882       if (StackSizeRelocMap
5883               .insert(std::make_pair(&Sec, (const Elf_Shdr *)nullptr))
5884               .second)
5885         continue;
5886 
5887     // Check relocation sections if they are relocating contents of a
5888     // stack sizes section.
5889     if (Sec.sh_type != ELF::SHT_RELA && Sec.sh_type != ELF::SHT_REL)
5890       continue;
5891 
5892     Expected<const Elf_Shdr *> RelSecOrErr = Obj.getSection(Sec.sh_info);
5893     if (!RelSecOrErr) {
5894       reportUniqueWarning(describe(Sec) +
5895                           ": failed to get a relocated section: " +
5896                           toString(RelSecOrErr.takeError()));
5897       continue;
5898     }
5899 
5900     const Elf_Shdr *ContentsSec = *RelSecOrErr;
5901     if (this->getPrintableSectionName(**RelSecOrErr) != ".stack_sizes")
5902       continue;
5903 
5904     // Insert a mapping from the stack sizes section to its relocation section.
5905     StackSizeRelocMap[ContentsSec] = &Sec;
5906   }
5907 
5908   for (const auto &StackSizeMapEntry : StackSizeRelocMap) {
5909     PrintHeader();
5910     const Elf_Shdr *StackSizesELFSec = StackSizeMapEntry.first;
5911     const Elf_Shdr *RelocSec = StackSizeMapEntry.second;
5912 
5913     // Warn about stack size sections without a relocation section.
5914     if (!RelocSec) {
5915       reportWarning(createError(".stack_sizes (" + describe(*StackSizesELFSec) +
5916                                 ") does not have a corresponding "
5917                                 "relocation section"),
5918                     FileName);
5919       continue;
5920     }
5921 
5922     // A .stack_sizes section header's sh_link field is supposed to point
5923     // to the section that contains the functions whose stack sizes are
5924     // described in it.
5925     const Elf_Shdr *FunctionSec = unwrapOrError(
5926         this->FileName, Obj.getSection(StackSizesELFSec->sh_link));
5927 
5928     SupportsRelocation IsSupportedFn;
5929     RelocationResolver Resolver;
5930     std::tie(IsSupportedFn, Resolver) = getRelocationResolver(this->ObjF);
5931     ArrayRef<uint8_t> Contents =
5932         unwrapOrError(this->FileName, Obj.getSectionContents(*StackSizesELFSec));
5933     DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr));
5934 
5935     forEachRelocationDo(
5936         *RelocSec, /*RawRelr=*/false,
5937         [&](const Relocation<ELFT> &R, unsigned Ndx, const Elf_Shdr &Sec,
5938             const Elf_Shdr *SymTab) {
5939           if (!IsSupportedFn || !IsSupportedFn(R.Type)) {
5940             reportUniqueWarning(
5941                 describe(*RelocSec) +
5942                 " contains an unsupported relocation with index " + Twine(Ndx) +
5943                 ": " + Obj.getRelocationTypeName(R.Type));
5944             return;
5945           }
5946 
5947           this->printStackSize(R, *RelocSec, Ndx, SymTab, FunctionSec,
5948                                *StackSizesELFSec, Resolver, Data);
5949         },
5950         [](const Elf_Relr &) {
5951           llvm_unreachable("can't get here, because we only support "
5952                            "SHT_REL/SHT_RELA sections");
5953         });
5954   }
5955 }
5956 
5957 template <class ELFT>
5958 void GNUELFDumper<ELFT>::printStackSizes() {
5959   bool HeaderHasBeenPrinted = false;
5960   auto PrintHeader = [&]() {
5961     if (HeaderHasBeenPrinted)
5962       return;
5963     OS << "\nStack Sizes:\n";
5964     OS.PadToColumn(9);
5965     OS << "Size";
5966     OS.PadToColumn(18);
5967     OS << "Function\n";
5968     HeaderHasBeenPrinted = true;
5969   };
5970 
5971   // For non-relocatable objects, look directly for sections whose name starts
5972   // with .stack_sizes and process the contents.
5973   if (this->Obj.getHeader().e_type == ELF::ET_REL)
5974     this->printRelocatableStackSizes(PrintHeader);
5975   else
5976     this->printNonRelocatableStackSizes(PrintHeader);
5977 }
5978 
5979 template <class ELFT>
5980 void GNUELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
5981   size_t Bias = ELFT::Is64Bits ? 8 : 0;
5982   auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {
5983     OS.PadToColumn(2);
5984     OS << format_hex_no_prefix(Parser.getGotAddress(E), 8 + Bias);
5985     OS.PadToColumn(11 + Bias);
5986     OS << format_decimal(Parser.getGotOffset(E), 6) << "(gp)";
5987     OS.PadToColumn(22 + Bias);
5988     OS << format_hex_no_prefix(*E, 8 + Bias);
5989     OS.PadToColumn(31 + 2 * Bias);
5990     OS << Purpose << "\n";
5991   };
5992 
5993   OS << (Parser.IsStatic ? "Static GOT:\n" : "Primary GOT:\n");
5994   OS << " Canonical gp value: "
5995      << format_hex_no_prefix(Parser.getGp(), 8 + Bias) << "\n\n";
5996 
5997   OS << " Reserved entries:\n";
5998   if (ELFT::Is64Bits)
5999     OS << "           Address     Access          Initial Purpose\n";
6000   else
6001     OS << "   Address     Access  Initial Purpose\n";
6002   PrintEntry(Parser.getGotLazyResolver(), "Lazy resolver");
6003   if (Parser.getGotModulePointer())
6004     PrintEntry(Parser.getGotModulePointer(), "Module pointer (GNU extension)");
6005 
6006   if (!Parser.getLocalEntries().empty()) {
6007     OS << "\n";
6008     OS << " Local entries:\n";
6009     if (ELFT::Is64Bits)
6010       OS << "           Address     Access          Initial\n";
6011     else
6012       OS << "   Address     Access  Initial\n";
6013     for (auto &E : Parser.getLocalEntries())
6014       PrintEntry(&E, "");
6015   }
6016 
6017   if (Parser.IsStatic)
6018     return;
6019 
6020   if (!Parser.getGlobalEntries().empty()) {
6021     OS << "\n";
6022     OS << " Global entries:\n";
6023     if (ELFT::Is64Bits)
6024       OS << "           Address     Access          Initial         Sym.Val."
6025          << " Type    Ndx Name\n";
6026     else
6027       OS << "   Address     Access  Initial Sym.Val. Type    Ndx Name\n";
6028 
6029     DataRegion<Elf_Word> ShndxTable(
6030         (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
6031     for (auto &E : Parser.getGlobalEntries()) {
6032       const Elf_Sym &Sym = *Parser.getGotSym(&E);
6033       const Elf_Sym &FirstSym = this->dynamic_symbols()[0];
6034       std::string SymName = this->getFullSymbolName(
6035           Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false);
6036 
6037       OS.PadToColumn(2);
6038       OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias));
6039       OS.PadToColumn(11 + Bias);
6040       OS << to_string(format_decimal(Parser.getGotOffset(&E), 6)) + "(gp)";
6041       OS.PadToColumn(22 + Bias);
6042       OS << to_string(format_hex_no_prefix(E, 8 + Bias));
6043       OS.PadToColumn(31 + 2 * Bias);
6044       OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias));
6045       OS.PadToColumn(40 + 3 * Bias);
6046       OS << printEnum(Sym.getType(), makeArrayRef(ElfSymbolTypes));
6047       OS.PadToColumn(48 + 3 * Bias);
6048       OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(),
6049                                 ShndxTable);
6050       OS.PadToColumn(52 + 3 * Bias);
6051       OS << SymName << "\n";
6052     }
6053   }
6054 
6055   if (!Parser.getOtherEntries().empty())
6056     OS << "\n Number of TLS and multi-GOT entries "
6057        << Parser.getOtherEntries().size() << "\n";
6058 }
6059 
6060 template <class ELFT>
6061 void GNUELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
6062   size_t Bias = ELFT::Is64Bits ? 8 : 0;
6063   auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {
6064     OS.PadToColumn(2);
6065     OS << format_hex_no_prefix(Parser.getPltAddress(E), 8 + Bias);
6066     OS.PadToColumn(11 + Bias);
6067     OS << format_hex_no_prefix(*E, 8 + Bias);
6068     OS.PadToColumn(20 + 2 * Bias);
6069     OS << Purpose << "\n";
6070   };
6071 
6072   OS << "PLT GOT:\n\n";
6073 
6074   OS << " Reserved entries:\n";
6075   OS << "   Address  Initial Purpose\n";
6076   PrintEntry(Parser.getPltLazyResolver(), "PLT lazy resolver");
6077   if (Parser.getPltModulePointer())
6078     PrintEntry(Parser.getPltModulePointer(), "Module pointer");
6079 
6080   if (!Parser.getPltEntries().empty()) {
6081     OS << "\n";
6082     OS << " Entries:\n";
6083     OS << "   Address  Initial Sym.Val. Type    Ndx Name\n";
6084     DataRegion<Elf_Word> ShndxTable(
6085         (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
6086     for (auto &E : Parser.getPltEntries()) {
6087       const Elf_Sym &Sym = *Parser.getPltSym(&E);
6088       const Elf_Sym &FirstSym = *cantFail(
6089           this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));
6090       std::string SymName = this->getFullSymbolName(
6091           Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false);
6092 
6093       OS.PadToColumn(2);
6094       OS << to_string(format_hex_no_prefix(Parser.getPltAddress(&E), 8 + Bias));
6095       OS.PadToColumn(11 + Bias);
6096       OS << to_string(format_hex_no_prefix(E, 8 + Bias));
6097       OS.PadToColumn(20 + 2 * Bias);
6098       OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias));
6099       OS.PadToColumn(29 + 3 * Bias);
6100       OS << printEnum(Sym.getType(), makeArrayRef(ElfSymbolTypes));
6101       OS.PadToColumn(37 + 3 * Bias);
6102       OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(),
6103                                 ShndxTable);
6104       OS.PadToColumn(41 + 3 * Bias);
6105       OS << SymName << "\n";
6106     }
6107   }
6108 }
6109 
6110 template <class ELFT>
6111 Expected<const Elf_Mips_ABIFlags<ELFT> *>
6112 getMipsAbiFlagsSection(const ELFDumper<ELFT> &Dumper) {
6113   const typename ELFT::Shdr *Sec = Dumper.findSectionByName(".MIPS.abiflags");
6114   if (Sec == nullptr)
6115     return nullptr;
6116 
6117   constexpr StringRef ErrPrefix = "unable to read the .MIPS.abiflags section: ";
6118   Expected<ArrayRef<uint8_t>> DataOrErr =
6119       Dumper.getElfObject().getELFFile().getSectionContents(*Sec);
6120   if (!DataOrErr)
6121     return createError(ErrPrefix + toString(DataOrErr.takeError()));
6122 
6123   if (DataOrErr->size() != sizeof(Elf_Mips_ABIFlags<ELFT>))
6124     return createError(ErrPrefix + "it has a wrong size (" +
6125         Twine(DataOrErr->size()) + ")");
6126   return reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(DataOrErr->data());
6127 }
6128 
6129 template <class ELFT> void GNUELFDumper<ELFT>::printMipsABIFlags() {
6130   const Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
6131   if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =
6132           getMipsAbiFlagsSection(*this))
6133     Flags = *SecOrErr;
6134   else
6135     this->reportUniqueWarning(SecOrErr.takeError());
6136   if (!Flags)
6137     return;
6138 
6139   OS << "MIPS ABI Flags Version: " << Flags->version << "\n\n";
6140   OS << "ISA: MIPS" << int(Flags->isa_level);
6141   if (Flags->isa_rev > 1)
6142     OS << "r" << int(Flags->isa_rev);
6143   OS << "\n";
6144   OS << "GPR size: " << getMipsRegisterSize(Flags->gpr_size) << "\n";
6145   OS << "CPR1 size: " << getMipsRegisterSize(Flags->cpr1_size) << "\n";
6146   OS << "CPR2 size: " << getMipsRegisterSize(Flags->cpr2_size) << "\n";
6147   OS << "FP ABI: " << printEnum(Flags->fp_abi, makeArrayRef(ElfMipsFpABIType))
6148      << "\n";
6149   OS << "ISA Extension: "
6150      << printEnum(Flags->isa_ext, makeArrayRef(ElfMipsISAExtType)) << "\n";
6151   if (Flags->ases == 0)
6152     OS << "ASEs: None\n";
6153   else
6154     // FIXME: Print each flag on a separate line.
6155     OS << "ASEs: " << printFlags(Flags->ases, makeArrayRef(ElfMipsASEFlags))
6156        << "\n";
6157   OS << "FLAGS 1: " << format_hex_no_prefix(Flags->flags1, 8, false) << "\n";
6158   OS << "FLAGS 2: " << format_hex_no_prefix(Flags->flags2, 8, false) << "\n";
6159   OS << "\n";
6160 }
6161 
6162 template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() {
6163   const Elf_Ehdr &E = this->Obj.getHeader();
6164   {
6165     DictScope D(W, "ElfHeader");
6166     {
6167       DictScope D(W, "Ident");
6168       W.printBinary("Magic", makeArrayRef(E.e_ident).slice(ELF::EI_MAG0, 4));
6169       W.printEnum("Class", E.e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
6170       W.printEnum("DataEncoding", E.e_ident[ELF::EI_DATA],
6171                   makeArrayRef(ElfDataEncoding));
6172       W.printNumber("FileVersion", E.e_ident[ELF::EI_VERSION]);
6173 
6174       auto OSABI = makeArrayRef(ElfOSABI);
6175       if (E.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH &&
6176           E.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) {
6177         switch (E.e_machine) {
6178         case ELF::EM_AMDGPU:
6179           OSABI = makeArrayRef(AMDGPUElfOSABI);
6180           break;
6181         case ELF::EM_ARM:
6182           OSABI = makeArrayRef(ARMElfOSABI);
6183           break;
6184         case ELF::EM_TI_C6000:
6185           OSABI = makeArrayRef(C6000ElfOSABI);
6186           break;
6187         }
6188       }
6189       W.printEnum("OS/ABI", E.e_ident[ELF::EI_OSABI], OSABI);
6190       W.printNumber("ABIVersion", E.e_ident[ELF::EI_ABIVERSION]);
6191       W.printBinary("Unused", makeArrayRef(E.e_ident).slice(ELF::EI_PAD));
6192     }
6193 
6194     std::string TypeStr;
6195     if (const EnumEntry<unsigned> *Ent = getObjectFileEnumEntry(E.e_type)) {
6196       TypeStr = Ent->Name.str();
6197     } else {
6198       if (E.e_type >= ET_LOPROC)
6199         TypeStr = "Processor Specific";
6200       else if (E.e_type >= ET_LOOS)
6201         TypeStr = "OS Specific";
6202       else
6203         TypeStr = "Unknown";
6204     }
6205     W.printString("Type", TypeStr + " (0x" + to_hexString(E.e_type) + ")");
6206 
6207     W.printEnum("Machine", E.e_machine, makeArrayRef(ElfMachineType));
6208     W.printNumber("Version", E.e_version);
6209     W.printHex("Entry", E.e_entry);
6210     W.printHex("ProgramHeaderOffset", E.e_phoff);
6211     W.printHex("SectionHeaderOffset", E.e_shoff);
6212     if (E.e_machine == EM_MIPS)
6213       W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderMipsFlags),
6214                    unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
6215                    unsigned(ELF::EF_MIPS_MACH));
6216     else if (E.e_machine == EM_AMDGPU) {
6217       switch (E.e_ident[ELF::EI_ABIVERSION]) {
6218       default:
6219         W.printHex("Flags", E.e_flags);
6220         break;
6221       case 0:
6222         // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags.
6223         LLVM_FALLTHROUGH;
6224       case ELF::ELFABIVERSION_AMDGPU_HSA_V3:
6225         W.printFlags("Flags", E.e_flags,
6226                      makeArrayRef(ElfHeaderAMDGPUFlagsABIVersion3),
6227                      unsigned(ELF::EF_AMDGPU_MACH));
6228         break;
6229       case ELF::ELFABIVERSION_AMDGPU_HSA_V4:
6230         W.printFlags("Flags", E.e_flags,
6231                      makeArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),
6232                      unsigned(ELF::EF_AMDGPU_MACH),
6233                      unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),
6234                      unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4));
6235         break;
6236       }
6237     } else if (E.e_machine == EM_RISCV)
6238       W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderRISCVFlags));
6239     else if (E.e_machine == EM_AVR)
6240       W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderAVRFlags),
6241                    unsigned(ELF::EF_AVR_ARCH_MASK));
6242     else
6243       W.printFlags("Flags", E.e_flags);
6244     W.printNumber("HeaderSize", E.e_ehsize);
6245     W.printNumber("ProgramHeaderEntrySize", E.e_phentsize);
6246     W.printNumber("ProgramHeaderCount", E.e_phnum);
6247     W.printNumber("SectionHeaderEntrySize", E.e_shentsize);
6248     W.printString("SectionHeaderCount",
6249                   getSectionHeadersNumString(this->Obj, this->FileName));
6250     W.printString("StringTableSectionIndex",
6251                   getSectionHeaderTableIndexString(this->Obj, this->FileName));
6252   }
6253 }
6254 
6255 template <class ELFT> void LLVMELFDumper<ELFT>::printGroupSections() {
6256   DictScope Lists(W, "Groups");
6257   std::vector<GroupSection> V = this->getGroups();
6258   DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
6259   for (const GroupSection &G : V) {
6260     DictScope D(W, "Group");
6261     W.printNumber("Name", G.Name, G.ShName);
6262     W.printNumber("Index", G.Index);
6263     W.printNumber("Link", G.Link);
6264     W.printNumber("Info", G.Info);
6265     W.printHex("Type", getGroupType(G.Type), G.Type);
6266     W.startLine() << "Signature: " << G.Signature << "\n";
6267 
6268     ListScope L(W, "Section(s) in group");
6269     for (const GroupMember &GM : G.Members) {
6270       const GroupSection *MainGroup = Map[GM.Index];
6271       if (MainGroup != &G)
6272         this->reportUniqueWarning(
6273             "section with index " + Twine(GM.Index) +
6274             ", included in the group section with index " +
6275             Twine(MainGroup->Index) +
6276             ", was also found in the group section with index " +
6277             Twine(G.Index));
6278       W.startLine() << GM.Name << " (" << GM.Index << ")\n";
6279     }
6280   }
6281 
6282   if (V.empty())
6283     W.startLine() << "There are no group sections in the file.\n";
6284 }
6285 
6286 template <class ELFT> void LLVMELFDumper<ELFT>::printRelocations() {
6287   ListScope D(W, "Relocations");
6288 
6289   for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
6290     if (!isRelocationSec<ELFT>(Sec))
6291       continue;
6292 
6293     StringRef Name = this->getPrintableSectionName(Sec);
6294     unsigned SecNdx = &Sec - &cantFail(this->Obj.sections()).front();
6295     W.startLine() << "Section (" << SecNdx << ") " << Name << " {\n";
6296     W.indent();
6297     this->printRelocationsHelper(Sec);
6298     W.unindent();
6299     W.startLine() << "}\n";
6300   }
6301 }
6302 
6303 template <class ELFT>
6304 void LLVMELFDumper<ELFT>::printRelrReloc(const Elf_Relr &R) {
6305   W.startLine() << W.hex(R) << "\n";
6306 }
6307 
6308 template <class ELFT>
6309 void LLVMELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,
6310                                             const RelSymbol<ELFT> &RelSym) {
6311   StringRef SymbolName = RelSym.Name;
6312   SmallString<32> RelocName;
6313   this->Obj.getRelocationTypeName(R.Type, RelocName);
6314 
6315   if (opts::ExpandRelocs) {
6316     DictScope Group(W, "Relocation");
6317     W.printHex("Offset", R.Offset);
6318     W.printNumber("Type", RelocName, R.Type);
6319     W.printNumber("Symbol", !SymbolName.empty() ? SymbolName : "-", R.Symbol);
6320     if (R.Addend)
6321       W.printHex("Addend", (uintX_t)*R.Addend);
6322   } else {
6323     raw_ostream &OS = W.startLine();
6324     OS << W.hex(R.Offset) << " " << RelocName << " "
6325        << (!SymbolName.empty() ? SymbolName : "-");
6326     if (R.Addend)
6327       OS << " " << W.hex((uintX_t)*R.Addend);
6328     OS << "\n";
6329   }
6330 }
6331 
6332 template <class ELFT> void LLVMELFDumper<ELFT>::printSectionHeaders() {
6333   ListScope SectionsD(W, "Sections");
6334 
6335   int SectionIndex = -1;
6336   std::vector<EnumEntry<unsigned>> FlagsList =
6337       getSectionFlagsForTarget(this->Obj.getHeader().e_machine);
6338   for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
6339     DictScope SectionD(W, "Section");
6340     W.printNumber("Index", ++SectionIndex);
6341     W.printNumber("Name", this->getPrintableSectionName(Sec), Sec.sh_name);
6342     W.printHex("Type",
6343                object::getELFSectionTypeName(this->Obj.getHeader().e_machine,
6344                                              Sec.sh_type),
6345                Sec.sh_type);
6346     W.printFlags("Flags", Sec.sh_flags, makeArrayRef(FlagsList));
6347     W.printHex("Address", Sec.sh_addr);
6348     W.printHex("Offset", Sec.sh_offset);
6349     W.printNumber("Size", Sec.sh_size);
6350     W.printNumber("Link", Sec.sh_link);
6351     W.printNumber("Info", Sec.sh_info);
6352     W.printNumber("AddressAlignment", Sec.sh_addralign);
6353     W.printNumber("EntrySize", Sec.sh_entsize);
6354 
6355     if (opts::SectionRelocations) {
6356       ListScope D(W, "Relocations");
6357       this->printRelocationsHelper(Sec);
6358     }
6359 
6360     if (opts::SectionSymbols) {
6361       ListScope D(W, "Symbols");
6362       if (this->DotSymtabSec) {
6363         StringRef StrTable = unwrapOrError(
6364             this->FileName,
6365             this->Obj.getStringTableForSymtab(*this->DotSymtabSec));
6366         ArrayRef<Elf_Word> ShndxTable = this->getShndxTable(this->DotSymtabSec);
6367 
6368         typename ELFT::SymRange Symbols = unwrapOrError(
6369             this->FileName, this->Obj.symbols(this->DotSymtabSec));
6370         for (const Elf_Sym &Sym : Symbols) {
6371           const Elf_Shdr *SymSec = unwrapOrError(
6372               this->FileName,
6373               this->Obj.getSection(Sym, this->DotSymtabSec, ShndxTable));
6374           if (SymSec == &Sec)
6375             printSymbol(Sym, &Sym - &Symbols[0], ShndxTable, StrTable, false,
6376                         false);
6377         }
6378       }
6379     }
6380 
6381     if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
6382       ArrayRef<uint8_t> Data =
6383           unwrapOrError(this->FileName, this->Obj.getSectionContents(Sec));
6384       W.printBinaryBlock(
6385           "SectionData",
6386           StringRef(reinterpret_cast<const char *>(Data.data()), Data.size()));
6387     }
6388   }
6389 }
6390 
6391 template <class ELFT>
6392 void LLVMELFDumper<ELFT>::printSymbolSection(
6393     const Elf_Sym &Symbol, unsigned SymIndex,
6394     DataRegion<Elf_Word> ShndxTable) const {
6395   auto GetSectionSpecialType = [&]() -> Optional<StringRef> {
6396     if (Symbol.isUndefined())
6397       return StringRef("Undefined");
6398     if (Symbol.isProcessorSpecific())
6399       return StringRef("Processor Specific");
6400     if (Symbol.isOSSpecific())
6401       return StringRef("Operating System Specific");
6402     if (Symbol.isAbsolute())
6403       return StringRef("Absolute");
6404     if (Symbol.isCommon())
6405       return StringRef("Common");
6406     if (Symbol.isReserved() && Symbol.st_shndx != SHN_XINDEX)
6407       return StringRef("Reserved");
6408     return None;
6409   };
6410 
6411   if (Optional<StringRef> Type = GetSectionSpecialType()) {
6412     W.printHex("Section", *Type, Symbol.st_shndx);
6413     return;
6414   }
6415 
6416   Expected<unsigned> SectionIndex =
6417       this->getSymbolSectionIndex(Symbol, SymIndex, ShndxTable);
6418   if (!SectionIndex) {
6419     assert(Symbol.st_shndx == SHN_XINDEX &&
6420            "getSymbolSectionIndex should only fail due to an invalid "
6421            "SHT_SYMTAB_SHNDX table/reference");
6422     this->reportUniqueWarning(SectionIndex.takeError());
6423     W.printHex("Section", "Reserved", SHN_XINDEX);
6424     return;
6425   }
6426 
6427   Expected<StringRef> SectionName =
6428       this->getSymbolSectionName(Symbol, *SectionIndex);
6429   if (!SectionName) {
6430     // Don't report an invalid section name if the section headers are missing.
6431     // In such situations, all sections will be "invalid".
6432     if (!this->ObjF.sections().empty())
6433       this->reportUniqueWarning(SectionName.takeError());
6434     else
6435       consumeError(SectionName.takeError());
6436     W.printHex("Section", "<?>", *SectionIndex);
6437   } else {
6438     W.printHex("Section", *SectionName, *SectionIndex);
6439   }
6440 }
6441 
6442 template <class ELFT>
6443 void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
6444                                       DataRegion<Elf_Word> ShndxTable,
6445                                       Optional<StringRef> StrTable,
6446                                       bool IsDynamic,
6447                                       bool /*NonVisibilityBitsUsed*/) const {
6448   std::string FullSymbolName = this->getFullSymbolName(
6449       Symbol, SymIndex, ShndxTable, StrTable, IsDynamic);
6450   unsigned char SymbolType = Symbol.getType();
6451 
6452   DictScope D(W, "Symbol");
6453   W.printNumber("Name", FullSymbolName, Symbol.st_name);
6454   W.printHex("Value", Symbol.st_value);
6455   W.printNumber("Size", Symbol.st_size);
6456   W.printEnum("Binding", Symbol.getBinding(), makeArrayRef(ElfSymbolBindings));
6457   if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&
6458       SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
6459     W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
6460   else
6461     W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
6462   if (Symbol.st_other == 0)
6463     // Usually st_other flag is zero. Do not pollute the output
6464     // by flags enumeration in that case.
6465     W.printNumber("Other", 0);
6466   else {
6467     std::vector<EnumEntry<unsigned>> SymOtherFlags(std::begin(ElfSymOtherFlags),
6468                                                    std::end(ElfSymOtherFlags));
6469     if (this->Obj.getHeader().e_machine == EM_MIPS) {
6470       // Someones in their infinite wisdom decided to make STO_MIPS_MIPS16
6471       // flag overlapped with other ST_MIPS_xxx flags. So consider both
6472       // cases separately.
6473       if ((Symbol.st_other & STO_MIPS_MIPS16) == STO_MIPS_MIPS16)
6474         SymOtherFlags.insert(SymOtherFlags.end(),
6475                              std::begin(ElfMips16SymOtherFlags),
6476                              std::end(ElfMips16SymOtherFlags));
6477       else
6478         SymOtherFlags.insert(SymOtherFlags.end(),
6479                              std::begin(ElfMipsSymOtherFlags),
6480                              std::end(ElfMipsSymOtherFlags));
6481     } else if (this->Obj.getHeader().e_machine == EM_AARCH64) {
6482       SymOtherFlags.insert(SymOtherFlags.end(),
6483                            std::begin(ElfAArch64SymOtherFlags),
6484                            std::end(ElfAArch64SymOtherFlags));
6485     }
6486     W.printFlags("Other", Symbol.st_other, makeArrayRef(SymOtherFlags), 0x3u);
6487   }
6488   printSymbolSection(Symbol, SymIndex, ShndxTable);
6489 }
6490 
6491 template <class ELFT>
6492 void LLVMELFDumper<ELFT>::printSymbols(bool PrintSymbols,
6493                                        bool PrintDynamicSymbols) {
6494   if (PrintSymbols) {
6495     ListScope Group(W, "Symbols");
6496     this->printSymbolsHelper(false);
6497   }
6498   if (PrintDynamicSymbols) {
6499     ListScope Group(W, "DynamicSymbols");
6500     this->printSymbolsHelper(true);
6501   }
6502 }
6503 
6504 template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicTable() {
6505   Elf_Dyn_Range Table = this->dynamic_table();
6506   if (Table.empty())
6507     return;
6508 
6509   W.startLine() << "DynamicSection [ (" << Table.size() << " entries)\n";
6510 
6511   size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table);
6512   // The "Name/Value" column should be indented from the "Type" column by N
6513   // spaces, where N = MaxTagSize - length of "Type" (4) + trailing
6514   // space (1) = -3.
6515   W.startLine() << "  Tag" << std::string(ELFT::Is64Bits ? 16 : 8, ' ')
6516                 << "Type" << std::string(MaxTagSize - 3, ' ') << "Name/Value\n";
6517 
6518   std::string ValueFmt = "%-" + std::to_string(MaxTagSize) + "s ";
6519   for (auto Entry : Table) {
6520     uintX_t Tag = Entry.getTag();
6521     std::string Value = this->getDynamicEntry(Tag, Entry.getVal());
6522     W.startLine() << "  " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10, true)
6523                   << " "
6524                   << format(ValueFmt.c_str(),
6525                             this->Obj.getDynamicTagAsString(Tag).c_str())
6526                   << Value << "\n";
6527   }
6528   W.startLine() << "]\n";
6529 }
6530 
6531 template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicRelocations() {
6532   W.startLine() << "Dynamic Relocations {\n";
6533   W.indent();
6534   this->printDynamicRelocationsHelper();
6535   W.unindent();
6536   W.startLine() << "}\n";
6537 }
6538 
6539 template <class ELFT>
6540 void LLVMELFDumper<ELFT>::printProgramHeaders(
6541     bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {
6542   if (PrintProgramHeaders)
6543     printProgramHeaders();
6544   if (PrintSectionMapping == cl::BOU_TRUE)
6545     printSectionMapping();
6546 }
6547 
6548 template <class ELFT> void LLVMELFDumper<ELFT>::printProgramHeaders() {
6549   ListScope L(W, "ProgramHeaders");
6550 
6551   Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
6552   if (!PhdrsOrErr) {
6553     this->reportUniqueWarning("unable to dump program headers: " +
6554                               toString(PhdrsOrErr.takeError()));
6555     return;
6556   }
6557 
6558   for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
6559     DictScope P(W, "ProgramHeader");
6560     StringRef Type =
6561         segmentTypeToString(this->Obj.getHeader().e_machine, Phdr.p_type);
6562 
6563     W.printHex("Type", Type.empty() ? "Unknown" : Type, Phdr.p_type);
6564     W.printHex("Offset", Phdr.p_offset);
6565     W.printHex("VirtualAddress", Phdr.p_vaddr);
6566     W.printHex("PhysicalAddress", Phdr.p_paddr);
6567     W.printNumber("FileSize", Phdr.p_filesz);
6568     W.printNumber("MemSize", Phdr.p_memsz);
6569     W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags));
6570     W.printNumber("Alignment", Phdr.p_align);
6571   }
6572 }
6573 
6574 template <class ELFT>
6575 void LLVMELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) {
6576   ListScope SS(W, "VersionSymbols");
6577   if (!Sec)
6578     return;
6579 
6580   StringRef StrTable;
6581   ArrayRef<Elf_Sym> Syms;
6582   const Elf_Shdr *SymTabSec;
6583   Expected<ArrayRef<Elf_Versym>> VerTableOrErr =
6584       this->getVersionTable(*Sec, &Syms, &StrTable, &SymTabSec);
6585   if (!VerTableOrErr) {
6586     this->reportUniqueWarning(VerTableOrErr.takeError());
6587     return;
6588   }
6589 
6590   if (StrTable.empty() || Syms.empty() || Syms.size() != VerTableOrErr->size())
6591     return;
6592 
6593   ArrayRef<Elf_Word> ShNdxTable = this->getShndxTable(SymTabSec);
6594   for (size_t I = 0, E = Syms.size(); I < E; ++I) {
6595     DictScope S(W, "Symbol");
6596     W.printNumber("Version", (*VerTableOrErr)[I].vs_index & VERSYM_VERSION);
6597     W.printString("Name",
6598                   this->getFullSymbolName(Syms[I], I, ShNdxTable, StrTable,
6599                                           /*IsDynamic=*/true));
6600   }
6601 }
6602 
6603 static const EnumEntry<unsigned> SymVersionFlags[] = {
6604     {"Base", "BASE", VER_FLG_BASE},
6605     {"Weak", "WEAK", VER_FLG_WEAK},
6606     {"Info", "INFO", VER_FLG_INFO}};
6607 
6608 template <class ELFT>
6609 void LLVMELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) {
6610   ListScope SD(W, "VersionDefinitions");
6611   if (!Sec)
6612     return;
6613 
6614   Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec);
6615   if (!V) {
6616     this->reportUniqueWarning(V.takeError());
6617     return;
6618   }
6619 
6620   for (const VerDef &D : *V) {
6621     DictScope Def(W, "Definition");
6622     W.printNumber("Version", D.Version);
6623     W.printFlags("Flags", D.Flags, makeArrayRef(SymVersionFlags));
6624     W.printNumber("Index", D.Ndx);
6625     W.printNumber("Hash", D.Hash);
6626     W.printString("Name", D.Name.c_str());
6627     W.printList(
6628         "Predecessors", D.AuxV,
6629         [](raw_ostream &OS, const VerdAux &Aux) { OS << Aux.Name.c_str(); });
6630   }
6631 }
6632 
6633 template <class ELFT>
6634 void LLVMELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) {
6635   ListScope SD(W, "VersionRequirements");
6636   if (!Sec)
6637     return;
6638 
6639   Expected<std::vector<VerNeed>> V =
6640       this->Obj.getVersionDependencies(*Sec, this->WarningHandler);
6641   if (!V) {
6642     this->reportUniqueWarning(V.takeError());
6643     return;
6644   }
6645 
6646   for (const VerNeed &VN : *V) {
6647     DictScope Entry(W, "Dependency");
6648     W.printNumber("Version", VN.Version);
6649     W.printNumber("Count", VN.Cnt);
6650     W.printString("FileName", VN.File.c_str());
6651 
6652     ListScope L(W, "Entries");
6653     for (const VernAux &Aux : VN.AuxV) {
6654       DictScope Entry(W, "Entry");
6655       W.printNumber("Hash", Aux.Hash);
6656       W.printFlags("Flags", Aux.Flags, makeArrayRef(SymVersionFlags));
6657       W.printNumber("Index", Aux.Other);
6658       W.printString("Name", Aux.Name.c_str());
6659     }
6660   }
6661 }
6662 
6663 template <class ELFT> void LLVMELFDumper<ELFT>::printHashHistograms() {
6664   W.startLine() << "Hash Histogram not implemented!\n";
6665 }
6666 
6667 template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
6668   ListScope L(W, "CGProfile");
6669   if (!this->DotCGProfileSec)
6670     return;
6671 
6672   Expected<ArrayRef<Elf_CGProfile>> CGProfileOrErr =
6673       this->Obj.template getSectionContentsAsArray<Elf_CGProfile>(
6674           *this->DotCGProfileSec);
6675   if (!CGProfileOrErr) {
6676     this->reportUniqueWarning(
6677         "unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: " +
6678         toString(CGProfileOrErr.takeError()));
6679     return;
6680   }
6681 
6682   for (const Elf_CGProfile &CGPE : *CGProfileOrErr) {
6683     DictScope D(W, "CGProfileEntry");
6684     W.printNumber("From", this->getStaticSymbolName(CGPE.cgp_from),
6685                   CGPE.cgp_from);
6686     W.printNumber("To", this->getStaticSymbolName(CGPE.cgp_to),
6687                   CGPE.cgp_to);
6688     W.printNumber("Weight", CGPE.cgp_weight);
6689   }
6690 }
6691 
6692 template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() {
6693   for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
6694     if (Sec.sh_type != SHT_LLVM_BB_ADDR_MAP)
6695       continue;
6696     ListScope L(W, "BBAddrMap");
6697     Expected<std::vector<Elf_BBAddrMap>> BBAddrMapOrErr =
6698         this->Obj.decodeBBAddrMap(Sec);
6699     if (!BBAddrMapOrErr) {
6700       this->reportUniqueWarning("unable to dump " + this->describe(Sec) + ": " +
6701                                 toString(BBAddrMapOrErr.takeError()));
6702       continue;
6703     }
6704     for (const Elf_BBAddrMap &AM : *BBAddrMapOrErr) {
6705       DictScope D(W, "Function");
6706       W.printHex("At", AM.Addr);
6707       ListScope L(W, "BB entries");
6708       for (const typename Elf_BBAddrMap::BBEntry &BBE : AM.BBEntries) {
6709         DictScope L(W);
6710         W.printHex("Offset", BBE.Offset);
6711         W.printHex("Size", BBE.Size);
6712         W.printBoolean("HasReturn", BBE.HasReturn);
6713         W.printBoolean("HasTailCall", BBE.HasTailCall);
6714         W.printBoolean("IsEHPad", BBE.IsEHPad);
6715         W.printBoolean("CanFallThrough", BBE.CanFallThrough);
6716       }
6717     }
6718   }
6719 }
6720 
6721 template <class ELFT> void LLVMELFDumper<ELFT>::printAddrsig() {
6722   ListScope L(W, "Addrsig");
6723   if (!this->DotAddrsigSec)
6724     return;
6725 
6726   Expected<std::vector<uint64_t>> SymsOrErr =
6727       decodeAddrsigSection(this->Obj, *this->DotAddrsigSec);
6728   if (!SymsOrErr) {
6729     this->reportUniqueWarning(SymsOrErr.takeError());
6730     return;
6731   }
6732 
6733   for (uint64_t Sym : *SymsOrErr)
6734     W.printNumber("Sym", this->getStaticSymbolName(Sym), Sym);
6735 }
6736 
6737 template <typename ELFT>
6738 static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
6739                                   ScopedPrinter &W) {
6740   // Return true if we were able to pretty-print the note, false otherwise.
6741   switch (NoteType) {
6742   default:
6743     return false;
6744   case ELF::NT_GNU_ABI_TAG: {
6745     const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
6746     if (!AbiTag.IsValid) {
6747       W.printString("ABI", "<corrupt GNU_ABI_TAG>");
6748       return false;
6749     } else {
6750       W.printString("OS", AbiTag.OSName);
6751       W.printString("ABI", AbiTag.ABI);
6752     }
6753     break;
6754   }
6755   case ELF::NT_GNU_BUILD_ID: {
6756     W.printString("Build ID", getGNUBuildId(Desc));
6757     break;
6758   }
6759   case ELF::NT_GNU_GOLD_VERSION:
6760     W.printString("Version", getGNUGoldVersion(Desc));
6761     break;
6762   case ELF::NT_GNU_PROPERTY_TYPE_0:
6763     ListScope D(W, "Property");
6764     for (const std::string &Property : getGNUPropertyList<ELFT>(Desc))
6765       W.printString(Property);
6766     break;
6767   }
6768   return true;
6769 }
6770 
6771 static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {
6772   W.printNumber("Page Size", Note.PageSize);
6773   for (const CoreFileMapping &Mapping : Note.Mappings) {
6774     ListScope D(W, "Mapping");
6775     W.printHex("Start", Mapping.Start);
6776     W.printHex("End", Mapping.End);
6777     W.printHex("Offset", Mapping.Offset);
6778     W.printString("Filename", Mapping.Filename);
6779   }
6780 }
6781 
6782 template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {
6783   ListScope L(W, "Notes");
6784 
6785   std::unique_ptr<DictScope> NoteScope;
6786   auto StartNotes = [&](Optional<StringRef> SecName,
6787                         const typename ELFT::Off Offset,
6788                         const typename ELFT::Addr Size) {
6789     NoteScope = std::make_unique<DictScope>(W, "NoteSection");
6790     W.printString("Name", SecName ? *SecName : "<?>");
6791     W.printHex("Offset", Offset);
6792     W.printHex("Size", Size);
6793   };
6794 
6795   auto EndNotes = [&] { NoteScope.reset(); };
6796 
6797   auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {
6798     DictScope D2(W, "Note");
6799     StringRef Name = Note.getName();
6800     ArrayRef<uint8_t> Descriptor = Note.getDesc();
6801     Elf_Word Type = Note.getType();
6802 
6803     // Print the note owner/type.
6804     W.printString("Owner", Name);
6805     W.printHex("Data size", Descriptor.size());
6806 
6807     StringRef NoteType =
6808         getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type);
6809     if (!NoteType.empty())
6810       W.printString("Type", NoteType);
6811     else
6812       W.printString("Type",
6813                     "Unknown (" + to_string(format_hex(Type, 10)) + ")");
6814 
6815     // Print the description, or fallback to printing raw bytes for unknown
6816     // owners/if we fail to pretty-print the contents.
6817     if (Name == "GNU") {
6818       if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W))
6819         return Error::success();
6820     } else if (Name == "FreeBSD") {
6821       if (Optional<FreeBSDNote> N =
6822               getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {
6823         W.printString(N->Type, N->Value);
6824         return Error::success();
6825       }
6826     } else if (Name == "AMD") {
6827       const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
6828       if (!N.Type.empty()) {
6829         W.printString(N.Type, N.Value);
6830         return Error::success();
6831       }
6832     } else if (Name == "AMDGPU") {
6833       const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
6834       if (!N.Type.empty()) {
6835         W.printString(N.Type, N.Value);
6836         return Error::success();
6837       }
6838     } else if (Name == "CORE") {
6839       if (Type == ELF::NT_FILE) {
6840         DataExtractor DescExtractor(Descriptor,
6841                                     ELFT::TargetEndianness == support::little,
6842                                     sizeof(Elf_Addr));
6843         if (Expected<CoreNote> N = readCoreNote(DescExtractor)) {
6844           printCoreNoteLLVMStyle(*N, W);
6845           return Error::success();
6846         } else {
6847           return N.takeError();
6848         }
6849       }
6850     }
6851     if (!Descriptor.empty()) {
6852       W.printBinaryBlock("Description data", Descriptor);
6853     }
6854     return Error::success();
6855   };
6856 
6857   printNotesHelper(*this, StartNotes, ProcessNote, EndNotes);
6858 }
6859 
6860 template <class ELFT> void LLVMELFDumper<ELFT>::printELFLinkerOptions() {
6861   ListScope L(W, "LinkerOptions");
6862 
6863   unsigned I = -1;
6864   for (const Elf_Shdr &Shdr : cantFail(this->Obj.sections())) {
6865     ++I;
6866     if (Shdr.sh_type != ELF::SHT_LLVM_LINKER_OPTIONS)
6867       continue;
6868 
6869     Expected<ArrayRef<uint8_t>> ContentsOrErr =
6870         this->Obj.getSectionContents(Shdr);
6871     if (!ContentsOrErr) {
6872       this->reportUniqueWarning("unable to read the content of the "
6873                                 "SHT_LLVM_LINKER_OPTIONS section: " +
6874                                 toString(ContentsOrErr.takeError()));
6875       continue;
6876     }
6877     if (ContentsOrErr->empty())
6878       continue;
6879 
6880     if (ContentsOrErr->back() != 0) {
6881       this->reportUniqueWarning("SHT_LLVM_LINKER_OPTIONS section at index " +
6882                                 Twine(I) +
6883                                 " is broken: the "
6884                                 "content is not null-terminated");
6885       continue;
6886     }
6887 
6888     SmallVector<StringRef, 16> Strings;
6889     toStringRef(ContentsOrErr->drop_back()).split(Strings, '\0');
6890     if (Strings.size() % 2 != 0) {
6891       this->reportUniqueWarning(
6892           "SHT_LLVM_LINKER_OPTIONS section at index " + Twine(I) +
6893           " is broken: an incomplete "
6894           "key-value pair was found. The last possible key was: \"" +
6895           Strings.back() + "\"");
6896       continue;
6897     }
6898 
6899     for (size_t I = 0; I < Strings.size(); I += 2)
6900       W.printString(Strings[I], Strings[I + 1]);
6901   }
6902 }
6903 
6904 template <class ELFT> void LLVMELFDumper<ELFT>::printDependentLibs() {
6905   ListScope L(W, "DependentLibs");
6906   this->printDependentLibsHelper(
6907       [](const Elf_Shdr &) {},
6908       [this](StringRef Lib, uint64_t) { W.printString(Lib); });
6909 }
6910 
6911 template <class ELFT> void LLVMELFDumper<ELFT>::printStackSizes() {
6912   ListScope L(W, "StackSizes");
6913   if (this->Obj.getHeader().e_type == ELF::ET_REL)
6914     this->printRelocatableStackSizes([]() {});
6915   else
6916     this->printNonRelocatableStackSizes([]() {});
6917 }
6918 
6919 template <class ELFT>
6920 void LLVMELFDumper<ELFT>::printStackSizeEntry(uint64_t Size, StringRef FuncName) {
6921   DictScope D(W, "Entry");
6922   W.printString("Function", FuncName);
6923   W.printHex("Size", Size);
6924 }
6925 
6926 template <class ELFT>
6927 void LLVMELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
6928   auto PrintEntry = [&](const Elf_Addr *E) {
6929     W.printHex("Address", Parser.getGotAddress(E));
6930     W.printNumber("Access", Parser.getGotOffset(E));
6931     W.printHex("Initial", *E);
6932   };
6933 
6934   DictScope GS(W, Parser.IsStatic ? "Static GOT" : "Primary GOT");
6935 
6936   W.printHex("Canonical gp value", Parser.getGp());
6937   {
6938     ListScope RS(W, "Reserved entries");
6939     {
6940       DictScope D(W, "Entry");
6941       PrintEntry(Parser.getGotLazyResolver());
6942       W.printString("Purpose", StringRef("Lazy resolver"));
6943     }
6944 
6945     if (Parser.getGotModulePointer()) {
6946       DictScope D(W, "Entry");
6947       PrintEntry(Parser.getGotModulePointer());
6948       W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
6949     }
6950   }
6951   {
6952     ListScope LS(W, "Local entries");
6953     for (auto &E : Parser.getLocalEntries()) {
6954       DictScope D(W, "Entry");
6955       PrintEntry(&E);
6956     }
6957   }
6958 
6959   if (Parser.IsStatic)
6960     return;
6961 
6962   {
6963     ListScope GS(W, "Global entries");
6964     for (auto &E : Parser.getGlobalEntries()) {
6965       DictScope D(W, "Entry");
6966 
6967       PrintEntry(&E);
6968 
6969       const Elf_Sym &Sym = *Parser.getGotSym(&E);
6970       W.printHex("Value", Sym.st_value);
6971       W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes));
6972 
6973       const unsigned SymIndex = &Sym - this->dynamic_symbols().begin();
6974       DataRegion<Elf_Word> ShndxTable(
6975           (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
6976       printSymbolSection(Sym, SymIndex, ShndxTable);
6977 
6978       std::string SymName = this->getFullSymbolName(
6979           Sym, SymIndex, ShndxTable, this->DynamicStringTable, true);
6980       W.printNumber("Name", SymName, Sym.st_name);
6981     }
6982   }
6983 
6984   W.printNumber("Number of TLS and multi-GOT entries",
6985                 uint64_t(Parser.getOtherEntries().size()));
6986 }
6987 
6988 template <class ELFT>
6989 void LLVMELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
6990   auto PrintEntry = [&](const Elf_Addr *E) {
6991     W.printHex("Address", Parser.getPltAddress(E));
6992     W.printHex("Initial", *E);
6993   };
6994 
6995   DictScope GS(W, "PLT GOT");
6996 
6997   {
6998     ListScope RS(W, "Reserved entries");
6999     {
7000       DictScope D(W, "Entry");
7001       PrintEntry(Parser.getPltLazyResolver());
7002       W.printString("Purpose", StringRef("PLT lazy resolver"));
7003     }
7004 
7005     if (auto E = Parser.getPltModulePointer()) {
7006       DictScope D(W, "Entry");
7007       PrintEntry(E);
7008       W.printString("Purpose", StringRef("Module pointer"));
7009     }
7010   }
7011   {
7012     ListScope LS(W, "Entries");
7013     DataRegion<Elf_Word> ShndxTable(
7014         (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
7015     for (auto &E : Parser.getPltEntries()) {
7016       DictScope D(W, "Entry");
7017       PrintEntry(&E);
7018 
7019       const Elf_Sym &Sym = *Parser.getPltSym(&E);
7020       W.printHex("Value", Sym.st_value);
7021       W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes));
7022       printSymbolSection(Sym, &Sym - this->dynamic_symbols().begin(),
7023                          ShndxTable);
7024 
7025       const Elf_Sym *FirstSym = cantFail(
7026           this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));
7027       std::string SymName = this->getFullSymbolName(
7028           Sym, &Sym - FirstSym, ShndxTable, Parser.getPltStrTable(), true);
7029       W.printNumber("Name", SymName, Sym.st_name);
7030     }
7031   }
7032 }
7033 
7034 template <class ELFT> void LLVMELFDumper<ELFT>::printMipsABIFlags() {
7035   const Elf_Mips_ABIFlags<ELFT> *Flags;
7036   if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =
7037           getMipsAbiFlagsSection(*this)) {
7038     Flags = *SecOrErr;
7039     if (!Flags) {
7040       W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
7041       return;
7042     }
7043   } else {
7044     this->reportUniqueWarning(SecOrErr.takeError());
7045     return;
7046   }
7047 
7048   raw_ostream &OS = W.getOStream();
7049   DictScope GS(W, "MIPS ABI Flags");
7050 
7051   W.printNumber("Version", Flags->version);
7052   W.startLine() << "ISA: ";
7053   if (Flags->isa_rev <= 1)
7054     OS << format("MIPS%u", Flags->isa_level);
7055   else
7056     OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev);
7057   OS << "\n";
7058   W.printEnum("ISA Extension", Flags->isa_ext, makeArrayRef(ElfMipsISAExtType));
7059   W.printFlags("ASEs", Flags->ases, makeArrayRef(ElfMipsASEFlags));
7060   W.printEnum("FP ABI", Flags->fp_abi, makeArrayRef(ElfMipsFpABIType));
7061   W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size));
7062   W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size));
7063   W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size));
7064   W.printFlags("Flags 1", Flags->flags1, makeArrayRef(ElfMipsFlags1));
7065   W.printHex("Flags 2", Flags->flags2);
7066 }
7067