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