llvm-project

Форк
0
8347 строк · 302.5 Кб
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/BitVector.h"
21
#include "llvm/ADT/DenseMap.h"
22
#include "llvm/ADT/DenseSet.h"
23
#include "llvm/ADT/MapVector.h"
24
#include "llvm/ADT/STLExtras.h"
25
#include "llvm/ADT/SmallString.h"
26
#include "llvm/ADT/SmallVector.h"
27
#include "llvm/ADT/StringExtras.h"
28
#include "llvm/ADT/StringRef.h"
29
#include "llvm/ADT/Twine.h"
30
#include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h"
31
#include "llvm/BinaryFormat/ELF.h"
32
#include "llvm/BinaryFormat/MsgPackDocument.h"
33
#include "llvm/Demangle/Demangle.h"
34
#include "llvm/Object/Archive.h"
35
#include "llvm/Object/ELF.h"
36
#include "llvm/Object/ELFObjectFile.h"
37
#include "llvm/Object/ELFTypes.h"
38
#include "llvm/Object/Error.h"
39
#include "llvm/Object/ObjectFile.h"
40
#include "llvm/Object/RelocationResolver.h"
41
#include "llvm/Object/StackMapParser.h"
42
#include "llvm/Support/AMDGPUMetadata.h"
43
#include "llvm/Support/ARMAttributeParser.h"
44
#include "llvm/Support/ARMBuildAttributes.h"
45
#include "llvm/Support/Casting.h"
46
#include "llvm/Support/Compiler.h"
47
#include "llvm/Support/Endian.h"
48
#include "llvm/Support/ErrorHandling.h"
49
#include "llvm/Support/Format.h"
50
#include "llvm/Support/FormatVariadic.h"
51
#include "llvm/Support/FormattedStream.h"
52
#include "llvm/Support/HexagonAttributeParser.h"
53
#include "llvm/Support/LEB128.h"
54
#include "llvm/Support/MSP430AttributeParser.h"
55
#include "llvm/Support/MSP430Attributes.h"
56
#include "llvm/Support/MathExtras.h"
57
#include "llvm/Support/MipsABIFlags.h"
58
#include "llvm/Support/RISCVAttributeParser.h"
59
#include "llvm/Support/RISCVAttributes.h"
60
#include "llvm/Support/ScopedPrinter.h"
61
#include "llvm/Support/SystemZ/zOSSupport.h"
62
#include "llvm/Support/raw_ostream.h"
63
#include <algorithm>
64
#include <array>
65
#include <cinttypes>
66
#include <cstddef>
67
#include <cstdint>
68
#include <cstdlib>
69
#include <iterator>
70
#include <memory>
71
#include <optional>
72
#include <string>
73
#include <system_error>
74
#include <vector>
75

76
using namespace llvm;
77
using namespace llvm::object;
78
using namespace llvm::support;
79
using namespace ELF;
80

81
#define LLVM_READOBJ_ENUM_CASE(ns, enum)                                       \
82
  case ns::enum:                                                               \
83
    return #enum;
84

85
#define ENUM_ENT(enum, altName)                                                \
86
  { #enum, altName, ELF::enum }
87

88
#define ENUM_ENT_1(enum)                                                       \
89
  { #enum, #enum, ELF::enum }
90

91
namespace {
92

93
template <class ELFT> struct RelSymbol {
94
  RelSymbol(const typename ELFT::Sym *S, StringRef N)
95
      : Sym(S), Name(N.str()) {}
96
  const typename ELFT::Sym *Sym;
97
  std::string Name;
98
};
99

100
/// Represents a contiguous uniform range in the file. We cannot just create a
101
/// range directly because when creating one of these from the .dynamic table
102
/// the size, entity size and virtual address are different entries in arbitrary
103
/// order (DT_REL, DT_RELSZ, DT_RELENT for example).
104
struct DynRegionInfo {
105
  DynRegionInfo(const Binary &Owner, const ObjDumper &D)
106
      : Obj(&Owner), Dumper(&D) {}
107
  DynRegionInfo(const Binary &Owner, const ObjDumper &D, const uint8_t *A,
108
                uint64_t S, uint64_t ES)
109
      : Addr(A), Size(S), EntSize(ES), Obj(&Owner), Dumper(&D) {}
110

111
  /// Address in current address space.
112
  const uint8_t *Addr = nullptr;
113
  /// Size in bytes of the region.
114
  uint64_t Size = 0;
115
  /// Size of each entity in the region.
116
  uint64_t EntSize = 0;
117

118
  /// Owner object. Used for error reporting.
119
  const Binary *Obj;
120
  /// Dumper used for error reporting.
121
  const ObjDumper *Dumper;
122
  /// Error prefix. Used for error reporting to provide more information.
123
  std::string Context;
124
  /// Region size name. Used for error reporting.
125
  StringRef SizePrintName = "size";
126
  /// Entry size name. Used for error reporting. If this field is empty, errors
127
  /// will not mention the entry size.
128
  StringRef EntSizePrintName = "entry size";
129

130
  template <typename Type> ArrayRef<Type> getAsArrayRef() const {
131
    const Type *Start = reinterpret_cast<const Type *>(Addr);
132
    if (!Start)
133
      return {Start, Start};
134

135
    const uint64_t Offset =
136
        Addr - (const uint8_t *)Obj->getMemoryBufferRef().getBufferStart();
137
    const uint64_t ObjSize = Obj->getMemoryBufferRef().getBufferSize();
138

139
    if (Size > ObjSize - Offset) {
140
      Dumper->reportUniqueWarning(
141
          "unable to read data at 0x" + Twine::utohexstr(Offset) +
142
          " of size 0x" + Twine::utohexstr(Size) + " (" + SizePrintName +
143
          "): it goes past the end of the file of size 0x" +
144
          Twine::utohexstr(ObjSize));
145
      return {Start, Start};
146
    }
147

148
    if (EntSize == sizeof(Type) && (Size % EntSize == 0))
149
      return {Start, Start + (Size / EntSize)};
150

151
    std::string Msg;
152
    if (!Context.empty())
153
      Msg += Context + " has ";
154

155
    Msg += ("invalid " + SizePrintName + " (0x" + Twine::utohexstr(Size) + ")")
156
               .str();
157
    if (!EntSizePrintName.empty())
158
      Msg +=
159
          (" or " + EntSizePrintName + " (0x" + Twine::utohexstr(EntSize) + ")")
160
              .str();
161

162
    Dumper->reportUniqueWarning(Msg);
163
    return {Start, Start};
164
  }
165
};
166

167
struct GroupMember {
168
  StringRef Name;
169
  uint64_t Index;
170
};
171

172
struct GroupSection {
173
  StringRef Name;
174
  std::string Signature;
175
  uint64_t ShName;
176
  uint64_t Index;
177
  uint32_t Link;
178
  uint32_t Info;
179
  uint32_t Type;
180
  std::vector<GroupMember> Members;
181
};
182

183
namespace {
184

185
struct NoteType {
186
  uint32_t ID;
187
  StringRef Name;
188
};
189

190
} // namespace
191

192
template <class ELFT> class Relocation {
193
public:
194
  Relocation(const typename ELFT::Rel &R, bool IsMips64EL)
195
      : Type(R.getType(IsMips64EL)), Symbol(R.getSymbol(IsMips64EL)),
196
        Offset(R.r_offset), Info(R.r_info) {}
197

198
  Relocation(const typename ELFT::Rela &R, bool IsMips64EL)
199
      : Relocation((const typename ELFT::Rel &)R, IsMips64EL) {
200
    Addend = R.r_addend;
201
  }
202

203
  uint32_t Type;
204
  uint32_t Symbol;
205
  typename ELFT::uint Offset;
206
  typename ELFT::uint Info;
207
  std::optional<int64_t> Addend;
208
};
209

210
template <class ELFT> class MipsGOTParser;
211

212
template <typename ELFT> class ELFDumper : public ObjDumper {
213
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
214

215
public:
216
  ELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer);
217

218
  void printUnwindInfo() override;
219
  void printNeededLibraries() override;
220
  void printHashTable() override;
221
  void printGnuHashTable() override;
222
  void printLoadName() override;
223
  void printVersionInfo() override;
224
  void printArchSpecificInfo() override;
225
  void printStackMap() const override;
226
  void printMemtag() override;
227
  ArrayRef<uint8_t> getMemtagGlobalsSectionContents(uint64_t ExpectedAddr);
228

229
  // Hash histogram shows statistics of how efficient the hash was for the
230
  // dynamic symbol table. The table shows the number of hash buckets for
231
  // different lengths of chains as an absolute number and percentage of the
232
  // total buckets, and the cumulative coverage of symbols for each set of
233
  // buckets.
234
  void printHashHistograms() override;
235

236
  const object::ELFObjectFile<ELFT> &getElfObject() const { return ObjF; };
237

238
  std::string describe(const Elf_Shdr &Sec) const;
239

240
  unsigned getHashTableEntSize() const {
241
    // EM_S390 and ELF::EM_ALPHA platforms use 8-bytes entries in SHT_HASH
242
    // sections. This violates the ELF specification.
243
    if (Obj.getHeader().e_machine == ELF::EM_S390 ||
244
        Obj.getHeader().e_machine == ELF::EM_ALPHA)
245
      return 8;
246
    return 4;
247
  }
248

249
  std::vector<EnumEntry<unsigned>>
250
  getOtherFlagsFromSymbol(const Elf_Ehdr &Header, const Elf_Sym &Symbol) const;
251

252
  Elf_Dyn_Range dynamic_table() const {
253
    // A valid .dynamic section contains an array of entries terminated
254
    // with a DT_NULL entry. However, sometimes the section content may
255
    // continue past the DT_NULL entry, so to dump the section correctly,
256
    // we first find the end of the entries by iterating over them.
257
    Elf_Dyn_Range Table = DynamicTable.template getAsArrayRef<Elf_Dyn>();
258

259
    size_t Size = 0;
260
    while (Size < Table.size())
261
      if (Table[Size++].getTag() == DT_NULL)
262
        break;
263

264
    return Table.slice(0, Size);
265
  }
266

267
  Elf_Sym_Range dynamic_symbols() const {
268
    if (!DynSymRegion)
269
      return Elf_Sym_Range();
270
    return DynSymRegion->template getAsArrayRef<Elf_Sym>();
271
  }
272

273
  const Elf_Shdr *findSectionByName(StringRef Name) const;
274

275
  StringRef getDynamicStringTable() const { return DynamicStringTable; }
276

277
protected:
278
  virtual void printVersionSymbolSection(const Elf_Shdr *Sec) = 0;
279
  virtual void printVersionDefinitionSection(const Elf_Shdr *Sec) = 0;
280
  virtual void printVersionDependencySection(const Elf_Shdr *Sec) = 0;
281

282
  void
283
  printDependentLibsHelper(function_ref<void(const Elf_Shdr &)> OnSectionStart,
284
                           function_ref<void(StringRef, uint64_t)> OnLibEntry);
285

286
  virtual void printRelRelaReloc(const Relocation<ELFT> &R,
287
                                 const RelSymbol<ELFT> &RelSym) = 0;
288
  virtual void printDynamicRelocHeader(unsigned Type, StringRef Name,
289
                                       const DynRegionInfo &Reg) {}
290
  void printReloc(const Relocation<ELFT> &R, unsigned RelIndex,
291
                  const Elf_Shdr &Sec, const Elf_Shdr *SymTab);
292
  void printDynamicReloc(const Relocation<ELFT> &R);
293
  void printDynamicRelocationsHelper();
294
  void printRelocationsHelper(const Elf_Shdr &Sec);
295
  void forEachRelocationDo(
296
      const Elf_Shdr &Sec,
297
      llvm::function_ref<void(const Relocation<ELFT> &, unsigned,
298
                              const Elf_Shdr &, const Elf_Shdr *)>
299
          RelRelaFn);
300

301
  virtual void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset,
302
                                  bool NonVisibilityBitsUsed,
303
                                  bool ExtraSymInfo) const {};
304
  virtual void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
305
                           DataRegion<Elf_Word> ShndxTable,
306
                           std::optional<StringRef> StrTable, bool IsDynamic,
307
                           bool NonVisibilityBitsUsed,
308
                           bool ExtraSymInfo) const = 0;
309

310
  virtual void printMipsABIFlags() = 0;
311
  virtual void printMipsGOT(const MipsGOTParser<ELFT> &Parser) = 0;
312
  virtual void printMipsPLT(const MipsGOTParser<ELFT> &Parser) = 0;
313

314
  virtual void printMemtag(
315
      const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,
316
      const ArrayRef<uint8_t> AndroidNoteDesc,
317
      const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) = 0;
318

319
  virtual void printHashHistogram(const Elf_Hash &HashTable) const;
320
  virtual void printGnuHashHistogram(const Elf_GnuHash &GnuHashTable) const;
321
  virtual void printHashHistogramStats(size_t NBucket, size_t MaxChain,
322
                                       size_t TotalSyms, ArrayRef<size_t> Count,
323
                                       bool IsGnu) const = 0;
324

325
  Expected<ArrayRef<Elf_Versym>>
326
  getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,
327
                  StringRef *StrTab, const Elf_Shdr **SymTabSec) const;
328
  StringRef getPrintableSectionName(const Elf_Shdr &Sec) const;
329

330
  std::vector<GroupSection> getGroups();
331

332
  // Returns the function symbol index for the given address. Matches the
333
  // symbol's section with FunctionSec when specified.
334
  // Returns std::nullopt if no function symbol can be found for the address or
335
  // in case it is not defined in the specified section.
336
  SmallVector<uint32_t> getSymbolIndexesForFunctionAddress(
337
      uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec);
338
  bool printFunctionStackSize(uint64_t SymValue,
339
                              std::optional<const Elf_Shdr *> FunctionSec,
340
                              const Elf_Shdr &StackSizeSec, DataExtractor Data,
341
                              uint64_t *Offset);
342
  void printStackSize(const Relocation<ELFT> &R, const Elf_Shdr &RelocSec,
343
                      unsigned Ndx, const Elf_Shdr *SymTab,
344
                      const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec,
345
                      const RelocationResolver &Resolver, DataExtractor Data);
346
  virtual void printStackSizeEntry(uint64_t Size,
347
                                   ArrayRef<std::string> FuncNames) = 0;
348

349
  void printRelocatableStackSizes(std::function<void()> PrintHeader);
350
  void printNonRelocatableStackSizes(std::function<void()> PrintHeader);
351

352
  const object::ELFObjectFile<ELFT> &ObjF;
353
  const ELFFile<ELFT> &Obj;
354
  StringRef FileName;
355

356
  Expected<DynRegionInfo> createDRI(uint64_t Offset, uint64_t Size,
357
                                    uint64_t EntSize) {
358
    if (Offset + Size < Offset || Offset + Size > Obj.getBufSize())
359
      return createError("offset (0x" + Twine::utohexstr(Offset) +
360
                         ") + size (0x" + Twine::utohexstr(Size) +
361
                         ") is greater than the file size (0x" +
362
                         Twine::utohexstr(Obj.getBufSize()) + ")");
363
    return DynRegionInfo(ObjF, *this, Obj.base() + Offset, Size, EntSize);
364
  }
365

366
  void printAttributes(unsigned, std::unique_ptr<ELFAttributeParser>,
367
                       llvm::endianness);
368
  void printMipsReginfo();
369
  void printMipsOptions();
370

371
  std::pair<const Elf_Phdr *, const Elf_Shdr *> findDynamic();
372
  void loadDynamicTable();
373
  void parseDynamicTable();
374

375
  Expected<StringRef> getSymbolVersion(const Elf_Sym &Sym,
376
                                       bool &IsDefault) const;
377
  Expected<SmallVector<std::optional<VersionEntry>, 0> *> getVersionMap() const;
378

379
  DynRegionInfo DynRelRegion;
380
  DynRegionInfo DynRelaRegion;
381
  DynRegionInfo DynCrelRegion;
382
  DynRegionInfo DynRelrRegion;
383
  DynRegionInfo DynPLTRelRegion;
384
  std::optional<DynRegionInfo> DynSymRegion;
385
  DynRegionInfo DynSymTabShndxRegion;
386
  DynRegionInfo DynamicTable;
387
  StringRef DynamicStringTable;
388
  const Elf_Hash *HashTable = nullptr;
389
  const Elf_GnuHash *GnuHashTable = nullptr;
390
  const Elf_Shdr *DotSymtabSec = nullptr;
391
  const Elf_Shdr *DotDynsymSec = nullptr;
392
  const Elf_Shdr *DotAddrsigSec = nullptr;
393
  DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
394
  std::optional<uint64_t> SONameOffset;
395
  std::optional<DenseMap<uint64_t, std::vector<uint32_t>>> AddressToIndexMap;
396

397
  const Elf_Shdr *SymbolVersionSection = nullptr;   // .gnu.version
398
  const Elf_Shdr *SymbolVersionNeedSection = nullptr; // .gnu.version_r
399
  const Elf_Shdr *SymbolVersionDefSection = nullptr; // .gnu.version_d
400

401
  std::string getFullSymbolName(const Elf_Sym &Symbol, unsigned SymIndex,
402
                                DataRegion<Elf_Word> ShndxTable,
403
                                std::optional<StringRef> StrTable,
404
                                bool IsDynamic) const;
405
  Expected<unsigned>
406
  getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex,
407
                        DataRegion<Elf_Word> ShndxTable) const;
408
  Expected<StringRef> getSymbolSectionName(const Elf_Sym &Symbol,
409
                                           unsigned SectionIndex) const;
410
  std::string getStaticSymbolName(uint32_t Index) const;
411
  StringRef getDynamicString(uint64_t Value) const;
412

413
  std::pair<Elf_Sym_Range, std::optional<StringRef>> getSymtabAndStrtab() const;
414
  void printSymbolsHelper(bool IsDynamic, bool ExtraSymInfo) const;
415
  std::string getDynamicEntry(uint64_t Type, uint64_t Value) const;
416

417
  Expected<RelSymbol<ELFT>> getRelocationTarget(const Relocation<ELFT> &R,
418
                                                const Elf_Shdr *SymTab) const;
419

420
  ArrayRef<Elf_Word> getShndxTable(const Elf_Shdr *Symtab) const;
421

422
private:
423
  mutable SmallVector<std::optional<VersionEntry>, 0> VersionMap;
424
};
425

426
template <class ELFT>
427
std::string ELFDumper<ELFT>::describe(const Elf_Shdr &Sec) const {
428
  return ::describe(Obj, Sec);
429
}
430

431
namespace {
432

433
template <class ELFT> struct SymtabLink {
434
  typename ELFT::SymRange Symbols;
435
  StringRef StringTable;
436
  const typename ELFT::Shdr *SymTab;
437
};
438

439
// Returns the linked symbol table, symbols and associated string table for a
440
// given section.
441
template <class ELFT>
442
Expected<SymtabLink<ELFT>> getLinkAsSymtab(const ELFFile<ELFT> &Obj,
443
                                           const typename ELFT::Shdr &Sec,
444
                                           unsigned ExpectedType) {
445
  Expected<const typename ELFT::Shdr *> SymtabOrErr =
446
      Obj.getSection(Sec.sh_link);
447
  if (!SymtabOrErr)
448
    return createError("invalid section linked to " + describe(Obj, Sec) +
449
                       ": " + toString(SymtabOrErr.takeError()));
450

451
  if ((*SymtabOrErr)->sh_type != ExpectedType)
452
    return createError(
453
        "invalid section linked to " + describe(Obj, Sec) + ": expected " +
454
        object::getELFSectionTypeName(Obj.getHeader().e_machine, ExpectedType) +
455
        ", but got " +
456
        object::getELFSectionTypeName(Obj.getHeader().e_machine,
457
                                      (*SymtabOrErr)->sh_type));
458

459
  Expected<StringRef> StrTabOrErr = Obj.getLinkAsStrtab(**SymtabOrErr);
460
  if (!StrTabOrErr)
461
    return createError(
462
        "can't get a string table for the symbol table linked to " +
463
        describe(Obj, Sec) + ": " + toString(StrTabOrErr.takeError()));
464

465
  Expected<typename ELFT::SymRange> SymsOrErr = Obj.symbols(*SymtabOrErr);
466
  if (!SymsOrErr)
467
    return createError("unable to read symbols from the " + describe(Obj, Sec) +
468
                       ": " + toString(SymsOrErr.takeError()));
469

470
  return SymtabLink<ELFT>{*SymsOrErr, *StrTabOrErr, *SymtabOrErr};
471
}
472

473
} // namespace
474

475
template <class ELFT>
476
Expected<ArrayRef<typename ELFT::Versym>>
477
ELFDumper<ELFT>::getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,
478
                                 StringRef *StrTab,
479
                                 const Elf_Shdr **SymTabSec) const {
480
  assert((!SymTab && !StrTab && !SymTabSec) || (SymTab && StrTab && SymTabSec));
481
  if (reinterpret_cast<uintptr_t>(Obj.base() + Sec.sh_offset) %
482
          sizeof(uint16_t) !=
483
      0)
484
    return createError("the " + describe(Sec) + " is misaligned");
485

486
  Expected<ArrayRef<Elf_Versym>> VersionsOrErr =
487
      Obj.template getSectionContentsAsArray<Elf_Versym>(Sec);
488
  if (!VersionsOrErr)
489
    return createError("cannot read content of " + describe(Sec) + ": " +
490
                       toString(VersionsOrErr.takeError()));
491

492
  Expected<SymtabLink<ELFT>> SymTabOrErr =
493
      getLinkAsSymtab(Obj, Sec, SHT_DYNSYM);
494
  if (!SymTabOrErr) {
495
    reportUniqueWarning(SymTabOrErr.takeError());
496
    return *VersionsOrErr;
497
  }
498

499
  if (SymTabOrErr->Symbols.size() != VersionsOrErr->size())
500
    reportUniqueWarning(describe(Sec) + ": the number of entries (" +
501
                        Twine(VersionsOrErr->size()) +
502
                        ") does not match the number of symbols (" +
503
                        Twine(SymTabOrErr->Symbols.size()) +
504
                        ") in the symbol table with index " +
505
                        Twine(Sec.sh_link));
506

507
  if (SymTab) {
508
    *SymTab = SymTabOrErr->Symbols;
509
    *StrTab = SymTabOrErr->StringTable;
510
    *SymTabSec = SymTabOrErr->SymTab;
511
  }
512
  return *VersionsOrErr;
513
}
514

515
template <class ELFT>
516
std::pair<typename ELFDumper<ELFT>::Elf_Sym_Range, std::optional<StringRef>>
517
ELFDumper<ELFT>::getSymtabAndStrtab() const {
518
  assert(DotSymtabSec);
519
  Elf_Sym_Range Syms(nullptr, nullptr);
520
  std::optional<StringRef> StrTable;
521
  if (Expected<StringRef> StrTableOrErr =
522
          Obj.getStringTableForSymtab(*DotSymtabSec))
523
    StrTable = *StrTableOrErr;
524
  else
525
    reportUniqueWarning(
526
        "unable to get the string table for the SHT_SYMTAB section: " +
527
        toString(StrTableOrErr.takeError()));
528

529
  if (Expected<Elf_Sym_Range> SymsOrErr = Obj.symbols(DotSymtabSec))
530
    Syms = *SymsOrErr;
531
  else
532
    reportUniqueWarning("unable to read symbols from the SHT_SYMTAB section: " +
533
                        toString(SymsOrErr.takeError()));
534
  return {Syms, StrTable};
535
}
536

537
template <class ELFT>
538
void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic,
539
                                         bool ExtraSymInfo) const {
540
  std::optional<StringRef> StrTable;
541
  size_t Entries = 0;
542
  Elf_Sym_Range Syms(nullptr, nullptr);
543
  const Elf_Shdr *SymtabSec = IsDynamic ? DotDynsymSec : DotSymtabSec;
544

545
  if (IsDynamic) {
546
    StrTable = DynamicStringTable;
547
    Syms = dynamic_symbols();
548
    Entries = Syms.size();
549
  } else if (DotSymtabSec) {
550
    std::tie(Syms, StrTable) = getSymtabAndStrtab();
551
    Entries = DotSymtabSec->getEntityCount();
552
  }
553
  if (Syms.empty())
554
    return;
555

556
  // The st_other field has 2 logical parts. The first two bits hold the symbol
557
  // visibility (STV_*) and the remainder hold other platform-specific values.
558
  bool NonVisibilityBitsUsed =
559
      llvm::any_of(Syms, [](const Elf_Sym &S) { return S.st_other & ~0x3; });
560

561
  DataRegion<Elf_Word> ShndxTable =
562
      IsDynamic ? DataRegion<Elf_Word>(
563
                      (const Elf_Word *)this->DynSymTabShndxRegion.Addr,
564
                      this->getElfObject().getELFFile().end())
565
                : DataRegion<Elf_Word>(this->getShndxTable(SymtabSec));
566

567
  printSymtabMessage(SymtabSec, Entries, NonVisibilityBitsUsed, ExtraSymInfo);
568
  for (const Elf_Sym &Sym : Syms)
569
    printSymbol(Sym, &Sym - Syms.begin(), ShndxTable, StrTable, IsDynamic,
570
                NonVisibilityBitsUsed, ExtraSymInfo);
571
}
572

573
template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {
574
  formatted_raw_ostream &OS;
575

576
public:
577
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
578

579
  GNUELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)
580
      : ELFDumper<ELFT>(ObjF, Writer),
581
        OS(static_cast<formatted_raw_ostream &>(Writer.getOStream())) {
582
    assert(&this->W.getOStream() == &llvm::fouts());
583
  }
584

585
  void printFileSummary(StringRef FileStr, ObjectFile &Obj,
586
                        ArrayRef<std::string> InputFilenames,
587
                        const Archive *A) override;
588
  void printFileHeaders() override;
589
  void printGroupSections() override;
590
  void printRelocations() override;
591
  void printSectionHeaders() override;
592
  void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,
593
                    bool ExtraSymInfo) override;
594
  void printHashSymbols() override;
595
  void printSectionDetails() override;
596
  void printDependentLibs() override;
597
  void printDynamicTable() override;
598
  void printDynamicRelocations() override;
599
  void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset,
600
                          bool NonVisibilityBitsUsed,
601
                          bool ExtraSymInfo) const override;
602
  void printProgramHeaders(bool PrintProgramHeaders,
603
                           cl::boolOrDefault PrintSectionMapping) override;
604
  void printVersionSymbolSection(const Elf_Shdr *Sec) override;
605
  void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
606
  void printVersionDependencySection(const Elf_Shdr *Sec) override;
607
  void printCGProfile() override;
608
  void printBBAddrMaps(bool PrettyPGOAnalysis) override;
609
  void printAddrsig() override;
610
  void printNotes() override;
611
  void printELFLinkerOptions() override;
612
  void printStackSizes() override;
613
  void printMemtag(
614
      const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,
615
      const ArrayRef<uint8_t> AndroidNoteDesc,
616
      const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) override;
617
  void printHashHistogramStats(size_t NBucket, size_t MaxChain,
618
                               size_t TotalSyms, ArrayRef<size_t> Count,
619
                               bool IsGnu) const override;
620

621
private:
622
  void printHashTableSymbols(const Elf_Hash &HashTable);
623
  void printGnuHashTableSymbols(const Elf_GnuHash &GnuHashTable);
624

625
  struct Field {
626
    std::string Str;
627
    unsigned Column;
628

629
    Field(StringRef S, unsigned Col) : Str(std::string(S)), Column(Col) {}
630
    Field(unsigned Col) : Column(Col) {}
631
  };
632

633
  template <typename T, typename TEnum>
634
  std::string printFlags(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues,
635
                         TEnum EnumMask1 = {}, TEnum EnumMask2 = {},
636
                         TEnum EnumMask3 = {}) const {
637
    std::string Str;
638
    for (const EnumEntry<TEnum> &Flag : EnumValues) {
639
      if (Flag.Value == 0)
640
        continue;
641

642
      TEnum EnumMask{};
643
      if (Flag.Value & EnumMask1)
644
        EnumMask = EnumMask1;
645
      else if (Flag.Value & EnumMask2)
646
        EnumMask = EnumMask2;
647
      else if (Flag.Value & EnumMask3)
648
        EnumMask = EnumMask3;
649
      bool IsEnum = (Flag.Value & EnumMask) != 0;
650
      if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
651
          (IsEnum && (Value & EnumMask) == Flag.Value)) {
652
        if (!Str.empty())
653
          Str += ", ";
654
        Str += Flag.AltName;
655
      }
656
    }
657
    return Str;
658
  }
659

660
  formatted_raw_ostream &printField(struct Field F) const {
661
    if (F.Column != 0)
662
      OS.PadToColumn(F.Column);
663
    OS << F.Str;
664
    OS.flush();
665
    return OS;
666
  }
667
  void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex,
668
                         DataRegion<Elf_Word> ShndxTable, StringRef StrTable,
669
                         uint32_t Bucket);
670
  void printRelr(const Elf_Shdr &Sec);
671
  void printRelRelaReloc(const Relocation<ELFT> &R,
672
                         const RelSymbol<ELFT> &RelSym) override;
673
  void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
674
                   DataRegion<Elf_Word> ShndxTable,
675
                   std::optional<StringRef> StrTable, bool IsDynamic,
676
                   bool NonVisibilityBitsUsed,
677
                   bool ExtraSymInfo) const override;
678
  void printDynamicRelocHeader(unsigned Type, StringRef Name,
679
                               const DynRegionInfo &Reg) override;
680

681
  std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex,
682
                                  DataRegion<Elf_Word> ShndxTable,
683
                                  bool ExtraSymInfo = false) const;
684
  void printProgramHeaders() override;
685
  void printSectionMapping() override;
686
  void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec,
687
                                    const Twine &Label, unsigned EntriesNum);
688

689
  void printStackSizeEntry(uint64_t Size,
690
                           ArrayRef<std::string> FuncNames) override;
691

692
  void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
693
  void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
694
  void printMipsABIFlags() override;
695
};
696

697
template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> {
698
public:
699
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
700

701
  LLVMELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)
702
      : ELFDumper<ELFT>(ObjF, Writer), W(Writer) {}
703

704
  void printFileHeaders() override;
705
  void printGroupSections() override;
706
  void printRelocations() override;
707
  void printSectionHeaders() override;
708
  void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,
709
                    bool ExtraSymInfo) override;
710
  void printDependentLibs() override;
711
  void printDynamicTable() override;
712
  void printDynamicRelocations() override;
713
  void printProgramHeaders(bool PrintProgramHeaders,
714
                           cl::boolOrDefault PrintSectionMapping) override;
715
  void printVersionSymbolSection(const Elf_Shdr *Sec) override;
716
  void printVersionDefinitionSection(const Elf_Shdr *Sec) override;
717
  void printVersionDependencySection(const Elf_Shdr *Sec) override;
718
  void printCGProfile() override;
719
  void printBBAddrMaps(bool PrettyPGOAnalysis) override;
720
  void printAddrsig() override;
721
  void printNotes() override;
722
  void printELFLinkerOptions() override;
723
  void printStackSizes() override;
724
  void printMemtag(
725
      const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,
726
      const ArrayRef<uint8_t> AndroidNoteDesc,
727
      const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) override;
728
  void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex,
729
                          DataRegion<Elf_Word> ShndxTable) const;
730
  void printHashHistogramStats(size_t NBucket, size_t MaxChain,
731
                               size_t TotalSyms, ArrayRef<size_t> Count,
732
                               bool IsGnu) const override;
733

734
private:
735
  void printRelRelaReloc(const Relocation<ELFT> &R,
736
                         const RelSymbol<ELFT> &RelSym) override;
737

738
  void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
739
                   DataRegion<Elf_Word> ShndxTable,
740
                   std::optional<StringRef> StrTable, bool IsDynamic,
741
                   bool /*NonVisibilityBitsUsed*/,
742
                   bool /*ExtraSymInfo*/) const override;
743
  void printProgramHeaders() override;
744
  void printSectionMapping() override {}
745
  void printStackSizeEntry(uint64_t Size,
746
                           ArrayRef<std::string> FuncNames) override;
747

748
  void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
749
  void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
750
  void printMipsABIFlags() override;
751
  virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const;
752

753
protected:
754
  virtual std::string getGroupSectionHeaderName() const;
755
  void printSymbolOtherField(const Elf_Sym &Symbol) const;
756
  virtual void printExpandedRelRelaReloc(const Relocation<ELFT> &R,
757
                                         StringRef SymbolName,
758
                                         StringRef RelocName);
759
  virtual void printDefaultRelRelaReloc(const Relocation<ELFT> &R,
760
                                        StringRef SymbolName,
761
                                        StringRef RelocName);
762
  virtual void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name,
763
                                          const unsigned SecNdx);
764
  virtual void printSectionGroupMembers(StringRef Name, uint64_t Idx) const;
765
  virtual void printEmptyGroupMessage() const;
766

767
  ScopedPrinter &W;
768
};
769

770
// JSONELFDumper shares most of the same implementation as LLVMELFDumper except
771
// it uses a JSONScopedPrinter.
772
template <typename ELFT> class JSONELFDumper : public LLVMELFDumper<ELFT> {
773
public:
774
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
775

776
  JSONELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer)
777
      : LLVMELFDumper<ELFT>(ObjF, Writer) {}
778

779
  std::string getGroupSectionHeaderName() const override;
780

781
  void printFileSummary(StringRef FileStr, ObjectFile &Obj,
782
                        ArrayRef<std::string> InputFilenames,
783
                        const Archive *A) override;
784
  virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const override;
785

786
  void printDefaultRelRelaReloc(const Relocation<ELFT> &R,
787
                                StringRef SymbolName,
788
                                StringRef RelocName) override;
789

790
  void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name,
791
                                  const unsigned SecNdx) override;
792

793
  void printSectionGroupMembers(StringRef Name, uint64_t Idx) const override;
794

795
  void printEmptyGroupMessage() const override;
796

797
  void printDynamicTable() override;
798

799
private:
800
  void printAuxillaryDynamicTableEntryInfo(const Elf_Dyn &Entry);
801

802
  std::unique_ptr<DictScope> FileScope;
803
};
804

805
} // end anonymous namespace
806

807
namespace llvm {
808

809
template <class ELFT>
810
static std::unique_ptr<ObjDumper>
811
createELFDumper(const ELFObjectFile<ELFT> &Obj, ScopedPrinter &Writer) {
812
  if (opts::Output == opts::GNU)
813
    return std::make_unique<GNUELFDumper<ELFT>>(Obj, Writer);
814
  else if (opts::Output == opts::JSON)
815
    return std::make_unique<JSONELFDumper<ELFT>>(Obj, Writer);
816
  return std::make_unique<LLVMELFDumper<ELFT>>(Obj, Writer);
817
}
818

819
std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj,
820
                                           ScopedPrinter &Writer) {
821
  // Little-endian 32-bit
822
  if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(&Obj))
823
    return createELFDumper(*ELFObj, Writer);
824

825
  // Big-endian 32-bit
826
  if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(&Obj))
827
    return createELFDumper(*ELFObj, Writer);
828

829
  // Little-endian 64-bit
830
  if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(&Obj))
831
    return createELFDumper(*ELFObj, Writer);
832

833
  // Big-endian 64-bit
834
  return createELFDumper(*cast<ELF64BEObjectFile>(&Obj), Writer);
835
}
836

837
} // end namespace llvm
838

839
template <class ELFT>
840
Expected<SmallVector<std::optional<VersionEntry>, 0> *>
841
ELFDumper<ELFT>::getVersionMap() const {
842
  // If the VersionMap has already been loaded or if there is no dynamic symtab
843
  // or version table, there is nothing to do.
844
  if (!VersionMap.empty() || !DynSymRegion || !SymbolVersionSection)
845
    return &VersionMap;
846

847
  Expected<SmallVector<std::optional<VersionEntry>, 0>> MapOrErr =
848
      Obj.loadVersionMap(SymbolVersionNeedSection, SymbolVersionDefSection);
849
  if (MapOrErr)
850
    VersionMap = *MapOrErr;
851
  else
852
    return MapOrErr.takeError();
853

854
  return &VersionMap;
855
}
856

857
template <typename ELFT>
858
Expected<StringRef> ELFDumper<ELFT>::getSymbolVersion(const Elf_Sym &Sym,
859
                                                      bool &IsDefault) const {
860
  // This is a dynamic symbol. Look in the GNU symbol version table.
861
  if (!SymbolVersionSection) {
862
    // No version table.
863
    IsDefault = false;
864
    return "";
865
  }
866

867
  assert(DynSymRegion && "DynSymRegion has not been initialised");
868
  // Determine the position in the symbol table of this entry.
869
  size_t EntryIndex = (reinterpret_cast<uintptr_t>(&Sym) -
870
                       reinterpret_cast<uintptr_t>(DynSymRegion->Addr)) /
871
                      sizeof(Elf_Sym);
872

873
  // Get the corresponding version index entry.
874
  Expected<const Elf_Versym *> EntryOrErr =
875
      Obj.template getEntry<Elf_Versym>(*SymbolVersionSection, EntryIndex);
876
  if (!EntryOrErr)
877
    return EntryOrErr.takeError();
878

879
  unsigned Version = (*EntryOrErr)->vs_index;
880
  if (Version == VER_NDX_LOCAL || Version == VER_NDX_GLOBAL) {
881
    IsDefault = false;
882
    return "";
883
  }
884

885
  Expected<SmallVector<std::optional<VersionEntry>, 0> *> MapOrErr =
886
      getVersionMap();
887
  if (!MapOrErr)
888
    return MapOrErr.takeError();
889

890
  return Obj.getSymbolVersionByIndex(Version, IsDefault, **MapOrErr,
891
                                     Sym.st_shndx == ELF::SHN_UNDEF);
892
}
893

894
template <typename ELFT>
895
Expected<RelSymbol<ELFT>>
896
ELFDumper<ELFT>::getRelocationTarget(const Relocation<ELFT> &R,
897
                                     const Elf_Shdr *SymTab) const {
898
  if (R.Symbol == 0)
899
    return RelSymbol<ELFT>(nullptr, "");
900

901
  Expected<const Elf_Sym *> SymOrErr =
902
      Obj.template getEntry<Elf_Sym>(*SymTab, R.Symbol);
903
  if (!SymOrErr)
904
    return createError("unable to read an entry with index " + Twine(R.Symbol) +
905
                       " from " + describe(*SymTab) + ": " +
906
                       toString(SymOrErr.takeError()));
907
  const Elf_Sym *Sym = *SymOrErr;
908
  if (!Sym)
909
    return RelSymbol<ELFT>(nullptr, "");
910

911
  Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(*SymTab);
912
  if (!StrTableOrErr)
913
    return StrTableOrErr.takeError();
914

915
  const Elf_Sym *FirstSym =
916
      cantFail(Obj.template getEntry<Elf_Sym>(*SymTab, 0));
917
  std::string SymbolName =
918
      getFullSymbolName(*Sym, Sym - FirstSym, getShndxTable(SymTab),
919
                        *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM);
920
  return RelSymbol<ELFT>(Sym, SymbolName);
921
}
922

923
template <typename ELFT>
924
ArrayRef<typename ELFT::Word>
925
ELFDumper<ELFT>::getShndxTable(const Elf_Shdr *Symtab) const {
926
  if (Symtab) {
927
    auto It = ShndxTables.find(Symtab);
928
    if (It != ShndxTables.end())
929
      return It->second;
930
  }
931
  return {};
932
}
933

934
static std::string maybeDemangle(StringRef Name) {
935
  return opts::Demangle ? demangle(Name) : Name.str();
936
}
937

938
template <typename ELFT>
939
std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
940
  auto Warn = [&](Error E) -> std::string {
941
    reportUniqueWarning("unable to read the name of symbol with index " +
942
                        Twine(Index) + ": " + toString(std::move(E)));
943
    return "<?>";
944
  };
945

946
  Expected<const typename ELFT::Sym *> SymOrErr =
947
      Obj.getSymbol(DotSymtabSec, Index);
948
  if (!SymOrErr)
949
    return Warn(SymOrErr.takeError());
950

951
  Expected<StringRef> StrTabOrErr = Obj.getStringTableForSymtab(*DotSymtabSec);
952
  if (!StrTabOrErr)
953
    return Warn(StrTabOrErr.takeError());
954

955
  Expected<StringRef> NameOrErr = (*SymOrErr)->getName(*StrTabOrErr);
956
  if (!NameOrErr)
957
    return Warn(NameOrErr.takeError());
958
  return maybeDemangle(*NameOrErr);
959
}
960

961
template <typename ELFT>
962
std::string ELFDumper<ELFT>::getFullSymbolName(
963
    const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable,
964
    std::optional<StringRef> StrTable, bool IsDynamic) const {
965
  if (!StrTable)
966
    return "<?>";
967

968
  std::string SymbolName;
969
  if (Expected<StringRef> NameOrErr = Symbol.getName(*StrTable)) {
970
    SymbolName = maybeDemangle(*NameOrErr);
971
  } else {
972
    reportUniqueWarning(NameOrErr.takeError());
973
    return "<?>";
974
  }
975

976
  if (SymbolName.empty() && Symbol.getType() == ELF::STT_SECTION) {
977
    Expected<unsigned> SectionIndex =
978
        getSymbolSectionIndex(Symbol, SymIndex, ShndxTable);
979
    if (!SectionIndex) {
980
      reportUniqueWarning(SectionIndex.takeError());
981
      return "<?>";
982
    }
983
    Expected<StringRef> NameOrErr = getSymbolSectionName(Symbol, *SectionIndex);
984
    if (!NameOrErr) {
985
      reportUniqueWarning(NameOrErr.takeError());
986
      return ("<section " + Twine(*SectionIndex) + ">").str();
987
    }
988
    return std::string(*NameOrErr);
989
  }
990

991
  if (!IsDynamic)
992
    return SymbolName;
993

994
  bool IsDefault;
995
  Expected<StringRef> VersionOrErr = getSymbolVersion(Symbol, IsDefault);
996
  if (!VersionOrErr) {
997
    reportUniqueWarning(VersionOrErr.takeError());
998
    return SymbolName + "@<corrupt>";
999
  }
1000

1001
  if (!VersionOrErr->empty()) {
1002
    SymbolName += (IsDefault ? "@@" : "@");
1003
    SymbolName += *VersionOrErr;
1004
  }
1005
  return SymbolName;
1006
}
1007

1008
template <typename ELFT>
1009
Expected<unsigned>
1010
ELFDumper<ELFT>::getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex,
1011
                                       DataRegion<Elf_Word> ShndxTable) const {
1012
  unsigned Ndx = Symbol.st_shndx;
1013
  if (Ndx == SHN_XINDEX)
1014
    return object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex,
1015
                                                     ShndxTable);
1016
  if (Ndx != SHN_UNDEF && Ndx < SHN_LORESERVE)
1017
    return Ndx;
1018

1019
  auto CreateErr = [&](const Twine &Name,
1020
                       std::optional<unsigned> Offset = std::nullopt) {
1021
    std::string Desc;
1022
    if (Offset)
1023
      Desc = (Name + "+0x" + Twine::utohexstr(*Offset)).str();
1024
    else
1025
      Desc = Name.str();
1026
    return createError(
1027
        "unable to get section index for symbol with st_shndx = 0x" +
1028
        Twine::utohexstr(Ndx) + " (" + Desc + ")");
1029
  };
1030

1031
  if (Ndx >= ELF::SHN_LOPROC && Ndx <= ELF::SHN_HIPROC)
1032
    return CreateErr("SHN_LOPROC", Ndx - ELF::SHN_LOPROC);
1033
  if (Ndx >= ELF::SHN_LOOS && Ndx <= ELF::SHN_HIOS)
1034
    return CreateErr("SHN_LOOS", Ndx - ELF::SHN_LOOS);
1035
  if (Ndx == ELF::SHN_UNDEF)
1036
    return CreateErr("SHN_UNDEF");
1037
  if (Ndx == ELF::SHN_ABS)
1038
    return CreateErr("SHN_ABS");
1039
  if (Ndx == ELF::SHN_COMMON)
1040
    return CreateErr("SHN_COMMON");
1041
  return CreateErr("SHN_LORESERVE", Ndx - SHN_LORESERVE);
1042
}
1043

1044
template <typename ELFT>
1045
Expected<StringRef>
1046
ELFDumper<ELFT>::getSymbolSectionName(const Elf_Sym &Symbol,
1047
                                      unsigned SectionIndex) const {
1048
  Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(SectionIndex);
1049
  if (!SecOrErr)
1050
    return SecOrErr.takeError();
1051
  return Obj.getSectionName(**SecOrErr);
1052
}
1053

1054
template <class ELFO>
1055
static const typename ELFO::Elf_Shdr *
1056
findNotEmptySectionByAddress(const ELFO &Obj, StringRef FileName,
1057
                             uint64_t Addr) {
1058
  for (const typename ELFO::Elf_Shdr &Shdr : cantFail(Obj.sections()))
1059
    if (Shdr.sh_addr == Addr && Shdr.sh_size > 0)
1060
      return &Shdr;
1061
  return nullptr;
1062
}
1063

1064
const EnumEntry<unsigned> ElfClass[] = {
1065
  {"None",   "none",   ELF::ELFCLASSNONE},
1066
  {"32-bit", "ELF32",  ELF::ELFCLASS32},
1067
  {"64-bit", "ELF64",  ELF::ELFCLASS64},
1068
};
1069

1070
const EnumEntry<unsigned> ElfDataEncoding[] = {
1071
  {"None",         "none",                          ELF::ELFDATANONE},
1072
  {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB},
1073
  {"BigEndian",    "2's complement, big endian",    ELF::ELFDATA2MSB},
1074
};
1075

1076
const EnumEntry<unsigned> ElfObjectFileType[] = {
1077
  {"None",         "NONE (none)",              ELF::ET_NONE},
1078
  {"Relocatable",  "REL (Relocatable file)",   ELF::ET_REL},
1079
  {"Executable",   "EXEC (Executable file)",   ELF::ET_EXEC},
1080
  {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN},
1081
  {"Core",         "CORE (Core file)",         ELF::ET_CORE},
1082
};
1083

1084
const EnumEntry<unsigned> ElfOSABI[] = {
1085
  {"SystemV",      "UNIX - System V",      ELF::ELFOSABI_NONE},
1086
  {"HPUX",         "UNIX - HP-UX",         ELF::ELFOSABI_HPUX},
1087
  {"NetBSD",       "UNIX - NetBSD",        ELF::ELFOSABI_NETBSD},
1088
  {"GNU/Linux",    "UNIX - GNU",           ELF::ELFOSABI_LINUX},
1089
  {"GNU/Hurd",     "GNU/Hurd",             ELF::ELFOSABI_HURD},
1090
  {"Solaris",      "UNIX - Solaris",       ELF::ELFOSABI_SOLARIS},
1091
  {"AIX",          "UNIX - AIX",           ELF::ELFOSABI_AIX},
1092
  {"IRIX",         "UNIX - IRIX",          ELF::ELFOSABI_IRIX},
1093
  {"FreeBSD",      "UNIX - FreeBSD",       ELF::ELFOSABI_FREEBSD},
1094
  {"TRU64",        "UNIX - TRU64",         ELF::ELFOSABI_TRU64},
1095
  {"Modesto",      "Novell - Modesto",     ELF::ELFOSABI_MODESTO},
1096
  {"OpenBSD",      "UNIX - OpenBSD",       ELF::ELFOSABI_OPENBSD},
1097
  {"OpenVMS",      "VMS - OpenVMS",        ELF::ELFOSABI_OPENVMS},
1098
  {"NSK",          "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK},
1099
  {"AROS",         "AROS",                 ELF::ELFOSABI_AROS},
1100
  {"FenixOS",      "FenixOS",              ELF::ELFOSABI_FENIXOS},
1101
  {"CloudABI",     "CloudABI",             ELF::ELFOSABI_CLOUDABI},
1102
  {"CUDA",         "NVIDIA - CUDA",        ELF::ELFOSABI_CUDA},
1103
  {"Standalone",   "Standalone App",       ELF::ELFOSABI_STANDALONE}
1104
};
1105

1106
const EnumEntry<unsigned> AMDGPUElfOSABI[] = {
1107
  {"AMDGPU_HSA",    "AMDGPU - HSA",    ELF::ELFOSABI_AMDGPU_HSA},
1108
  {"AMDGPU_PAL",    "AMDGPU - PAL",    ELF::ELFOSABI_AMDGPU_PAL},
1109
  {"AMDGPU_MESA3D", "AMDGPU - MESA3D", ELF::ELFOSABI_AMDGPU_MESA3D}
1110
};
1111

1112
const EnumEntry<unsigned> ARMElfOSABI[] = {
1113
    {"ARM", "ARM", ELF::ELFOSABI_ARM},
1114
    {"ARM FDPIC", "ARM FDPIC", ELF::ELFOSABI_ARM_FDPIC},
1115
};
1116

1117
const EnumEntry<unsigned> C6000ElfOSABI[] = {
1118
  {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI},
1119
  {"C6000_LINUX",  "Linux C6000",      ELF::ELFOSABI_C6000_LINUX}
1120
};
1121

1122
const EnumEntry<unsigned> ElfMachineType[] = {
1123
  ENUM_ENT(EM_NONE,          "None"),
1124
  ENUM_ENT(EM_M32,           "WE32100"),
1125
  ENUM_ENT(EM_SPARC,         "Sparc"),
1126
  ENUM_ENT(EM_386,           "Intel 80386"),
1127
  ENUM_ENT(EM_68K,           "MC68000"),
1128
  ENUM_ENT(EM_88K,           "MC88000"),
1129
  ENUM_ENT(EM_IAMCU,         "EM_IAMCU"),
1130
  ENUM_ENT(EM_860,           "Intel 80860"),
1131
  ENUM_ENT(EM_MIPS,          "MIPS R3000"),
1132
  ENUM_ENT(EM_S370,          "IBM System/370"),
1133
  ENUM_ENT(EM_MIPS_RS3_LE,   "MIPS R3000 little-endian"),
1134
  ENUM_ENT(EM_PARISC,        "HPPA"),
1135
  ENUM_ENT(EM_VPP500,        "Fujitsu VPP500"),
1136
  ENUM_ENT(EM_SPARC32PLUS,   "Sparc v8+"),
1137
  ENUM_ENT(EM_960,           "Intel 80960"),
1138
  ENUM_ENT(EM_PPC,           "PowerPC"),
1139
  ENUM_ENT(EM_PPC64,         "PowerPC64"),
1140
  ENUM_ENT(EM_S390,          "IBM S/390"),
1141
  ENUM_ENT(EM_SPU,           "SPU"),
1142
  ENUM_ENT(EM_V800,          "NEC V800 series"),
1143
  ENUM_ENT(EM_FR20,          "Fujistsu FR20"),
1144
  ENUM_ENT(EM_RH32,          "TRW RH-32"),
1145
  ENUM_ENT(EM_RCE,           "Motorola RCE"),
1146
  ENUM_ENT(EM_ARM,           "ARM"),
1147
  ENUM_ENT(EM_ALPHA,         "EM_ALPHA"),
1148
  ENUM_ENT(EM_SH,            "Hitachi SH"),
1149
  ENUM_ENT(EM_SPARCV9,       "Sparc v9"),
1150
  ENUM_ENT(EM_TRICORE,       "Siemens Tricore"),
1151
  ENUM_ENT(EM_ARC,           "ARC"),
1152
  ENUM_ENT(EM_H8_300,        "Hitachi H8/300"),
1153
  ENUM_ENT(EM_H8_300H,       "Hitachi H8/300H"),
1154
  ENUM_ENT(EM_H8S,           "Hitachi H8S"),
1155
  ENUM_ENT(EM_H8_500,        "Hitachi H8/500"),
1156
  ENUM_ENT(EM_IA_64,         "Intel IA-64"),
1157
  ENUM_ENT(EM_MIPS_X,        "Stanford MIPS-X"),
1158
  ENUM_ENT(EM_COLDFIRE,      "Motorola Coldfire"),
1159
  ENUM_ENT(EM_68HC12,        "Motorola MC68HC12 Microcontroller"),
1160
  ENUM_ENT(EM_MMA,           "Fujitsu Multimedia Accelerator"),
1161
  ENUM_ENT(EM_PCP,           "Siemens PCP"),
1162
  ENUM_ENT(EM_NCPU,          "Sony nCPU embedded RISC processor"),
1163
  ENUM_ENT(EM_NDR1,          "Denso NDR1 microprocesspr"),
1164
  ENUM_ENT(EM_STARCORE,      "Motorola Star*Core processor"),
1165
  ENUM_ENT(EM_ME16,          "Toyota ME16 processor"),
1166
  ENUM_ENT(EM_ST100,         "STMicroelectronics ST100 processor"),
1167
  ENUM_ENT(EM_TINYJ,         "Advanced Logic Corp. TinyJ embedded processor"),
1168
  ENUM_ENT(EM_X86_64,        "Advanced Micro Devices X86-64"),
1169
  ENUM_ENT(EM_PDSP,          "Sony DSP processor"),
1170
  ENUM_ENT(EM_PDP10,         "Digital Equipment Corp. PDP-10"),
1171
  ENUM_ENT(EM_PDP11,         "Digital Equipment Corp. PDP-11"),
1172
  ENUM_ENT(EM_FX66,          "Siemens FX66 microcontroller"),
1173
  ENUM_ENT(EM_ST9PLUS,       "STMicroelectronics ST9+ 8/16 bit microcontroller"),
1174
  ENUM_ENT(EM_ST7,           "STMicroelectronics ST7 8-bit microcontroller"),
1175
  ENUM_ENT(EM_68HC16,        "Motorola MC68HC16 Microcontroller"),
1176
  ENUM_ENT(EM_68HC11,        "Motorola MC68HC11 Microcontroller"),
1177
  ENUM_ENT(EM_68HC08,        "Motorola MC68HC08 Microcontroller"),
1178
  ENUM_ENT(EM_68HC05,        "Motorola MC68HC05 Microcontroller"),
1179
  ENUM_ENT(EM_SVX,           "Silicon Graphics SVx"),
1180
  ENUM_ENT(EM_ST19,          "STMicroelectronics ST19 8-bit microcontroller"),
1181
  ENUM_ENT(EM_VAX,           "Digital VAX"),
1182
  ENUM_ENT(EM_CRIS,          "Axis Communications 32-bit embedded processor"),
1183
  ENUM_ENT(EM_JAVELIN,       "Infineon Technologies 32-bit embedded cpu"),
1184
  ENUM_ENT(EM_FIREPATH,      "Element 14 64-bit DSP processor"),
1185
  ENUM_ENT(EM_ZSP,           "LSI Logic's 16-bit DSP processor"),
1186
  ENUM_ENT(EM_MMIX,          "Donald Knuth's educational 64-bit processor"),
1187
  ENUM_ENT(EM_HUANY,         "Harvard Universitys's machine-independent object format"),
1188
  ENUM_ENT(EM_PRISM,         "Vitesse Prism"),
1189
  ENUM_ENT(EM_AVR,           "Atmel AVR 8-bit microcontroller"),
1190
  ENUM_ENT(EM_FR30,          "Fujitsu FR30"),
1191
  ENUM_ENT(EM_D10V,          "Mitsubishi D10V"),
1192
  ENUM_ENT(EM_D30V,          "Mitsubishi D30V"),
1193
  ENUM_ENT(EM_V850,          "NEC v850"),
1194
  ENUM_ENT(EM_M32R,          "Renesas M32R (formerly Mitsubishi M32r)"),
1195
  ENUM_ENT(EM_MN10300,       "Matsushita MN10300"),
1196
  ENUM_ENT(EM_MN10200,       "Matsushita MN10200"),
1197
  ENUM_ENT(EM_PJ,            "picoJava"),
1198
  ENUM_ENT(EM_OPENRISC,      "OpenRISC 32-bit embedded processor"),
1199
  ENUM_ENT(EM_ARC_COMPACT,   "EM_ARC_COMPACT"),
1200
  ENUM_ENT(EM_XTENSA,        "Tensilica Xtensa Processor"),
1201
  ENUM_ENT(EM_VIDEOCORE,     "Alphamosaic VideoCore processor"),
1202
  ENUM_ENT(EM_TMM_GPP,       "Thompson Multimedia General Purpose Processor"),
1203
  ENUM_ENT(EM_NS32K,         "National Semiconductor 32000 series"),
1204
  ENUM_ENT(EM_TPC,           "Tenor Network TPC processor"),
1205
  ENUM_ENT(EM_SNP1K,         "EM_SNP1K"),
1206
  ENUM_ENT(EM_ST200,         "STMicroelectronics ST200 microcontroller"),
1207
  ENUM_ENT(EM_IP2K,          "Ubicom IP2xxx 8-bit microcontrollers"),
1208
  ENUM_ENT(EM_MAX,           "MAX Processor"),
1209
  ENUM_ENT(EM_CR,            "National Semiconductor CompactRISC"),
1210
  ENUM_ENT(EM_F2MC16,        "Fujitsu F2MC16"),
1211
  ENUM_ENT(EM_MSP430,        "Texas Instruments msp430 microcontroller"),
1212
  ENUM_ENT(EM_BLACKFIN,      "Analog Devices Blackfin"),
1213
  ENUM_ENT(EM_SE_C33,        "S1C33 Family of Seiko Epson processors"),
1214
  ENUM_ENT(EM_SEP,           "Sharp embedded microprocessor"),
1215
  ENUM_ENT(EM_ARCA,          "Arca RISC microprocessor"),
1216
  ENUM_ENT(EM_UNICORE,       "Unicore"),
1217
  ENUM_ENT(EM_EXCESS,        "eXcess 16/32/64-bit configurable embedded CPU"),
1218
  ENUM_ENT(EM_DXP,           "Icera Semiconductor Inc. Deep Execution Processor"),
1219
  ENUM_ENT(EM_ALTERA_NIOS2,  "Altera Nios"),
1220
  ENUM_ENT(EM_CRX,           "National Semiconductor CRX microprocessor"),
1221
  ENUM_ENT(EM_XGATE,         "Motorola XGATE embedded processor"),
1222
  ENUM_ENT(EM_C166,          "Infineon Technologies xc16x"),
1223
  ENUM_ENT(EM_M16C,          "Renesas M16C"),
1224
  ENUM_ENT(EM_DSPIC30F,      "Microchip Technology dsPIC30F Digital Signal Controller"),
1225
  ENUM_ENT(EM_CE,            "Freescale Communication Engine RISC core"),
1226
  ENUM_ENT(EM_M32C,          "Renesas M32C"),
1227
  ENUM_ENT(EM_TSK3000,       "Altium TSK3000 core"),
1228
  ENUM_ENT(EM_RS08,          "Freescale RS08 embedded processor"),
1229
  ENUM_ENT(EM_SHARC,         "EM_SHARC"),
1230
  ENUM_ENT(EM_ECOG2,         "Cyan Technology eCOG2 microprocessor"),
1231
  ENUM_ENT(EM_SCORE7,        "SUNPLUS S+Core"),
1232
  ENUM_ENT(EM_DSP24,         "New Japan Radio (NJR) 24-bit DSP Processor"),
1233
  ENUM_ENT(EM_VIDEOCORE3,    "Broadcom VideoCore III processor"),
1234
  ENUM_ENT(EM_LATTICEMICO32, "Lattice Mico32"),
1235
  ENUM_ENT(EM_SE_C17,        "Seiko Epson C17 family"),
1236
  ENUM_ENT(EM_TI_C6000,      "Texas Instruments TMS320C6000 DSP family"),
1237
  ENUM_ENT(EM_TI_C2000,      "Texas Instruments TMS320C2000 DSP family"),
1238
  ENUM_ENT(EM_TI_C5500,      "Texas Instruments TMS320C55x DSP family"),
1239
  ENUM_ENT(EM_MMDSP_PLUS,    "STMicroelectronics 64bit VLIW Data Signal Processor"),
1240
  ENUM_ENT(EM_CYPRESS_M8C,   "Cypress M8C microprocessor"),
1241
  ENUM_ENT(EM_R32C,          "Renesas R32C series microprocessors"),
1242
  ENUM_ENT(EM_TRIMEDIA,      "NXP Semiconductors TriMedia architecture family"),
1243
  ENUM_ENT(EM_HEXAGON,       "Qualcomm Hexagon"),
1244
  ENUM_ENT(EM_8051,          "Intel 8051 and variants"),
1245
  ENUM_ENT(EM_STXP7X,        "STMicroelectronics STxP7x family"),
1246
  ENUM_ENT(EM_NDS32,         "Andes Technology compact code size embedded RISC processor family"),
1247
  ENUM_ENT(EM_ECOG1,         "Cyan Technology eCOG1 microprocessor"),
1248
  // FIXME: Following EM_ECOG1X definitions is dead code since EM_ECOG1X has
1249
  //        an identical number to EM_ECOG1.
1250
  ENUM_ENT(EM_ECOG1X,        "Cyan Technology eCOG1X family"),
1251
  ENUM_ENT(EM_MAXQ30,        "Dallas Semiconductor MAXQ30 Core microcontrollers"),
1252
  ENUM_ENT(EM_XIMO16,        "New Japan Radio (NJR) 16-bit DSP Processor"),
1253
  ENUM_ENT(EM_MANIK,         "M2000 Reconfigurable RISC Microprocessor"),
1254
  ENUM_ENT(EM_CRAYNV2,       "Cray Inc. NV2 vector architecture"),
1255
  ENUM_ENT(EM_RX,            "Renesas RX"),
1256
  ENUM_ENT(EM_METAG,         "Imagination Technologies Meta processor architecture"),
1257
  ENUM_ENT(EM_MCST_ELBRUS,   "MCST Elbrus general purpose hardware architecture"),
1258
  ENUM_ENT(EM_ECOG16,        "Cyan Technology eCOG16 family"),
1259
  ENUM_ENT(EM_CR16,          "National Semiconductor CompactRISC 16-bit processor"),
1260
  ENUM_ENT(EM_ETPU,          "Freescale Extended Time Processing Unit"),
1261
  ENUM_ENT(EM_SLE9X,         "Infineon Technologies SLE9X core"),
1262
  ENUM_ENT(EM_L10M,          "EM_L10M"),
1263
  ENUM_ENT(EM_K10M,          "EM_K10M"),
1264
  ENUM_ENT(EM_AARCH64,       "AArch64"),
1265
  ENUM_ENT(EM_AVR32,         "Atmel Corporation 32-bit microprocessor family"),
1266
  ENUM_ENT(EM_STM8,          "STMicroeletronics STM8 8-bit microcontroller"),
1267
  ENUM_ENT(EM_TILE64,        "Tilera TILE64 multicore architecture family"),
1268
  ENUM_ENT(EM_TILEPRO,       "Tilera TILEPro multicore architecture family"),
1269
  ENUM_ENT(EM_MICROBLAZE,    "Xilinx MicroBlaze 32-bit RISC soft processor core"),
1270
  ENUM_ENT(EM_CUDA,          "NVIDIA CUDA architecture"),
1271
  ENUM_ENT(EM_TILEGX,        "Tilera TILE-Gx multicore architecture family"),
1272
  ENUM_ENT(EM_CLOUDSHIELD,   "EM_CLOUDSHIELD"),
1273
  ENUM_ENT(EM_COREA_1ST,     "EM_COREA_1ST"),
1274
  ENUM_ENT(EM_COREA_2ND,     "EM_COREA_2ND"),
1275
  ENUM_ENT(EM_ARC_COMPACT2,  "EM_ARC_COMPACT2"),
1276
  ENUM_ENT(EM_OPEN8,         "EM_OPEN8"),
1277
  ENUM_ENT(EM_RL78,          "Renesas RL78"),
1278
  ENUM_ENT(EM_VIDEOCORE5,    "Broadcom VideoCore V processor"),
1279
  ENUM_ENT(EM_78KOR,         "EM_78KOR"),
1280
  ENUM_ENT(EM_56800EX,       "EM_56800EX"),
1281
  ENUM_ENT(EM_AMDGPU,        "EM_AMDGPU"),
1282
  ENUM_ENT(EM_RISCV,         "RISC-V"),
1283
  ENUM_ENT(EM_LANAI,         "EM_LANAI"),
1284
  ENUM_ENT(EM_BPF,           "EM_BPF"),
1285
  ENUM_ENT(EM_VE,            "NEC SX-Aurora Vector Engine"),
1286
  ENUM_ENT(EM_LOONGARCH,     "LoongArch"),
1287
};
1288

1289
const EnumEntry<unsigned> ElfSymbolBindings[] = {
1290
    {"Local",  "LOCAL",  ELF::STB_LOCAL},
1291
    {"Global", "GLOBAL", ELF::STB_GLOBAL},
1292
    {"Weak",   "WEAK",   ELF::STB_WEAK},
1293
    {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE}};
1294

1295
const EnumEntry<unsigned> ElfSymbolVisibilities[] = {
1296
    {"DEFAULT",   "DEFAULT",   ELF::STV_DEFAULT},
1297
    {"INTERNAL",  "INTERNAL",  ELF::STV_INTERNAL},
1298
    {"HIDDEN",    "HIDDEN",    ELF::STV_HIDDEN},
1299
    {"PROTECTED", "PROTECTED", ELF::STV_PROTECTED}};
1300

1301
const EnumEntry<unsigned> AMDGPUSymbolTypes[] = {
1302
  { "AMDGPU_HSA_KERNEL",            ELF::STT_AMDGPU_HSA_KERNEL }
1303
};
1304

1305
static const char *getGroupType(uint32_t Flag) {
1306
  if (Flag & ELF::GRP_COMDAT)
1307
    return "COMDAT";
1308
  else
1309
    return "(unknown)";
1310
}
1311

1312
const EnumEntry<unsigned> ElfSectionFlags[] = {
1313
  ENUM_ENT(SHF_WRITE,            "W"),
1314
  ENUM_ENT(SHF_ALLOC,            "A"),
1315
  ENUM_ENT(SHF_EXECINSTR,        "X"),
1316
  ENUM_ENT(SHF_MERGE,            "M"),
1317
  ENUM_ENT(SHF_STRINGS,          "S"),
1318
  ENUM_ENT(SHF_INFO_LINK,        "I"),
1319
  ENUM_ENT(SHF_LINK_ORDER,       "L"),
1320
  ENUM_ENT(SHF_OS_NONCONFORMING, "O"),
1321
  ENUM_ENT(SHF_GROUP,            "G"),
1322
  ENUM_ENT(SHF_TLS,              "T"),
1323
  ENUM_ENT(SHF_COMPRESSED,       "C"),
1324
  ENUM_ENT(SHF_EXCLUDE,          "E"),
1325
};
1326

1327
const EnumEntry<unsigned> ElfGNUSectionFlags[] = {
1328
  ENUM_ENT(SHF_GNU_RETAIN, "R")
1329
};
1330

1331
const EnumEntry<unsigned> ElfSolarisSectionFlags[] = {
1332
  ENUM_ENT(SHF_SUNW_NODISCARD, "R")
1333
};
1334

1335
const EnumEntry<unsigned> ElfXCoreSectionFlags[] = {
1336
  ENUM_ENT(XCORE_SHF_CP_SECTION, ""),
1337
  ENUM_ENT(XCORE_SHF_DP_SECTION, "")
1338
};
1339

1340
const EnumEntry<unsigned> ElfARMSectionFlags[] = {
1341
  ENUM_ENT(SHF_ARM_PURECODE, "y")
1342
};
1343

1344
const EnumEntry<unsigned> ElfHexagonSectionFlags[] = {
1345
  ENUM_ENT(SHF_HEX_GPREL, "")
1346
};
1347

1348
const EnumEntry<unsigned> ElfMipsSectionFlags[] = {
1349
  ENUM_ENT(SHF_MIPS_NODUPES, ""),
1350
  ENUM_ENT(SHF_MIPS_NAMES,   ""),
1351
  ENUM_ENT(SHF_MIPS_LOCAL,   ""),
1352
  ENUM_ENT(SHF_MIPS_NOSTRIP, ""),
1353
  ENUM_ENT(SHF_MIPS_GPREL,   ""),
1354
  ENUM_ENT(SHF_MIPS_MERGE,   ""),
1355
  ENUM_ENT(SHF_MIPS_ADDR,    ""),
1356
  ENUM_ENT(SHF_MIPS_STRING,  "")
1357
};
1358

1359
const EnumEntry<unsigned> ElfX86_64SectionFlags[] = {
1360
  ENUM_ENT(SHF_X86_64_LARGE, "l")
1361
};
1362

1363
static std::vector<EnumEntry<unsigned>>
1364
getSectionFlagsForTarget(unsigned EOSAbi, unsigned EMachine) {
1365
  std::vector<EnumEntry<unsigned>> Ret(std::begin(ElfSectionFlags),
1366
                                       std::end(ElfSectionFlags));
1367
  switch (EOSAbi) {
1368
  case ELFOSABI_SOLARIS:
1369
    Ret.insert(Ret.end(), std::begin(ElfSolarisSectionFlags),
1370
               std::end(ElfSolarisSectionFlags));
1371
    break;
1372
  default:
1373
    Ret.insert(Ret.end(), std::begin(ElfGNUSectionFlags),
1374
               std::end(ElfGNUSectionFlags));
1375
    break;
1376
  }
1377
  switch (EMachine) {
1378
  case EM_ARM:
1379
    Ret.insert(Ret.end(), std::begin(ElfARMSectionFlags),
1380
               std::end(ElfARMSectionFlags));
1381
    break;
1382
  case EM_HEXAGON:
1383
    Ret.insert(Ret.end(), std::begin(ElfHexagonSectionFlags),
1384
               std::end(ElfHexagonSectionFlags));
1385
    break;
1386
  case EM_MIPS:
1387
    Ret.insert(Ret.end(), std::begin(ElfMipsSectionFlags),
1388
               std::end(ElfMipsSectionFlags));
1389
    break;
1390
  case EM_X86_64:
1391
    Ret.insert(Ret.end(), std::begin(ElfX86_64SectionFlags),
1392
               std::end(ElfX86_64SectionFlags));
1393
    break;
1394
  case EM_XCORE:
1395
    Ret.insert(Ret.end(), std::begin(ElfXCoreSectionFlags),
1396
               std::end(ElfXCoreSectionFlags));
1397
    break;
1398
  default:
1399
    break;
1400
  }
1401
  return Ret;
1402
}
1403

1404
static std::string getGNUFlags(unsigned EOSAbi, unsigned EMachine,
1405
                               uint64_t Flags) {
1406
  // Here we are trying to build the flags string in the same way as GNU does.
1407
  // It is not that straightforward. Imagine we have sh_flags == 0x90000000.
1408
  // SHF_EXCLUDE ("E") has a value of 0x80000000 and SHF_MASKPROC is 0xf0000000.
1409
  // GNU readelf will not print "E" or "Ep" in this case, but will print just
1410
  // "p". It only will print "E" when no other processor flag is set.
1411
  std::string Str;
1412
  bool HasUnknownFlag = false;
1413
  bool HasOSFlag = false;
1414
  bool HasProcFlag = false;
1415
  std::vector<EnumEntry<unsigned>> FlagsList =
1416
      getSectionFlagsForTarget(EOSAbi, EMachine);
1417
  while (Flags) {
1418
    // Take the least significant bit as a flag.
1419
    uint64_t Flag = Flags & -Flags;
1420
    Flags -= Flag;
1421

1422
    // Find the flag in the known flags list.
1423
    auto I = llvm::find_if(FlagsList, [=](const EnumEntry<unsigned> &E) {
1424
      // Flags with empty names are not printed in GNU style output.
1425
      return E.Value == Flag && !E.AltName.empty();
1426
    });
1427
    if (I != FlagsList.end()) {
1428
      Str += I->AltName;
1429
      continue;
1430
    }
1431

1432
    // If we did not find a matching regular flag, then we deal with an OS
1433
    // specific flag, processor specific flag or an unknown flag.
1434
    if (Flag & ELF::SHF_MASKOS) {
1435
      HasOSFlag = true;
1436
      Flags &= ~ELF::SHF_MASKOS;
1437
    } else if (Flag & ELF::SHF_MASKPROC) {
1438
      HasProcFlag = true;
1439
      // Mask off all the processor-specific bits. This removes the SHF_EXCLUDE
1440
      // bit if set so that it doesn't also get printed.
1441
      Flags &= ~ELF::SHF_MASKPROC;
1442
    } else {
1443
      HasUnknownFlag = true;
1444
    }
1445
  }
1446

1447
  // "o", "p" and "x" are printed last.
1448
  if (HasOSFlag)
1449
    Str += "o";
1450
  if (HasProcFlag)
1451
    Str += "p";
1452
  if (HasUnknownFlag)
1453
    Str += "x";
1454
  return Str;
1455
}
1456

1457
static StringRef segmentTypeToString(unsigned Arch, unsigned Type) {
1458
  // Check potentially overlapped processor-specific program header type.
1459
  switch (Arch) {
1460
  case ELF::EM_ARM:
1461
    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); }
1462
    break;
1463
  case ELF::EM_MIPS:
1464
  case ELF::EM_MIPS_RS3_LE:
1465
    switch (Type) {
1466
      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
1467
      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
1468
      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
1469
      LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);
1470
    }
1471
    break;
1472
  case ELF::EM_RISCV:
1473
    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_RISCV_ATTRIBUTES); }
1474
  }
1475

1476
  switch (Type) {
1477
    LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL);
1478
    LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD);
1479
    LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
1480
    LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP);
1481
    LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE);
1482
    LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB);
1483
    LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR);
1484
    LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS);
1485

1486
    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
1487
    LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
1488

1489
    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
1490
    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
1491
    LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_PROPERTY);
1492

1493
    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_MUTABLE);
1494
    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE);
1495
    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED);
1496
    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_NOBTCFI);
1497
    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_SYSCALLS);
1498
    LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA);
1499
  default:
1500
    return "";
1501
  }
1502
}
1503

1504
static std::string getGNUPtType(unsigned Arch, unsigned Type) {
1505
  StringRef Seg = segmentTypeToString(Arch, Type);
1506
  if (Seg.empty())
1507
    return std::string("<unknown>: ") + to_string(format_hex(Type, 1));
1508

1509
  // E.g. "PT_ARM_EXIDX" -> "EXIDX".
1510
  if (Seg.consume_front("PT_ARM_"))
1511
    return Seg.str();
1512

1513
  // E.g. "PT_MIPS_REGINFO" -> "REGINFO".
1514
  if (Seg.consume_front("PT_MIPS_"))
1515
    return Seg.str();
1516

1517
  // E.g. "PT_RISCV_ATTRIBUTES"
1518
  if (Seg.consume_front("PT_RISCV_"))
1519
    return Seg.str();
1520

1521
  // E.g. "PT_LOAD" -> "LOAD".
1522
  assert(Seg.starts_with("PT_"));
1523
  return Seg.drop_front(3).str();
1524
}
1525

1526
const EnumEntry<unsigned> ElfSegmentFlags[] = {
1527
  LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
1528
  LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
1529
  LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
1530
};
1531

1532
const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
1533
  ENUM_ENT(EF_MIPS_NOREORDER, "noreorder"),
1534
  ENUM_ENT(EF_MIPS_PIC, "pic"),
1535
  ENUM_ENT(EF_MIPS_CPIC, "cpic"),
1536
  ENUM_ENT(EF_MIPS_ABI2, "abi2"),
1537
  ENUM_ENT(EF_MIPS_32BITMODE, "32bitmode"),
1538
  ENUM_ENT(EF_MIPS_FP64, "fp64"),
1539
  ENUM_ENT(EF_MIPS_NAN2008, "nan2008"),
1540
  ENUM_ENT(EF_MIPS_ABI_O32, "o32"),
1541
  ENUM_ENT(EF_MIPS_ABI_O64, "o64"),
1542
  ENUM_ENT(EF_MIPS_ABI_EABI32, "eabi32"),
1543
  ENUM_ENT(EF_MIPS_ABI_EABI64, "eabi64"),
1544
  ENUM_ENT(EF_MIPS_MACH_3900, "3900"),
1545
  ENUM_ENT(EF_MIPS_MACH_4010, "4010"),
1546
  ENUM_ENT(EF_MIPS_MACH_4100, "4100"),
1547
  ENUM_ENT(EF_MIPS_MACH_4650, "4650"),
1548
  ENUM_ENT(EF_MIPS_MACH_4120, "4120"),
1549
  ENUM_ENT(EF_MIPS_MACH_4111, "4111"),
1550
  ENUM_ENT(EF_MIPS_MACH_SB1, "sb1"),
1551
  ENUM_ENT(EF_MIPS_MACH_OCTEON, "octeon"),
1552
  ENUM_ENT(EF_MIPS_MACH_XLR, "xlr"),
1553
  ENUM_ENT(EF_MIPS_MACH_OCTEON2, "octeon2"),
1554
  ENUM_ENT(EF_MIPS_MACH_OCTEON3, "octeon3"),
1555
  ENUM_ENT(EF_MIPS_MACH_5400, "5400"),
1556
  ENUM_ENT(EF_MIPS_MACH_5900, "5900"),
1557
  ENUM_ENT(EF_MIPS_MACH_5500, "5500"),
1558
  ENUM_ENT(EF_MIPS_MACH_9000, "9000"),
1559
  ENUM_ENT(EF_MIPS_MACH_LS2E, "loongson-2e"),
1560
  ENUM_ENT(EF_MIPS_MACH_LS2F, "loongson-2f"),
1561
  ENUM_ENT(EF_MIPS_MACH_LS3A, "loongson-3a"),
1562
  ENUM_ENT(EF_MIPS_MICROMIPS, "micromips"),
1563
  ENUM_ENT(EF_MIPS_ARCH_ASE_M16, "mips16"),
1564
  ENUM_ENT(EF_MIPS_ARCH_ASE_MDMX, "mdmx"),
1565
  ENUM_ENT(EF_MIPS_ARCH_1, "mips1"),
1566
  ENUM_ENT(EF_MIPS_ARCH_2, "mips2"),
1567
  ENUM_ENT(EF_MIPS_ARCH_3, "mips3"),
1568
  ENUM_ENT(EF_MIPS_ARCH_4, "mips4"),
1569
  ENUM_ENT(EF_MIPS_ARCH_5, "mips5"),
1570
  ENUM_ENT(EF_MIPS_ARCH_32, "mips32"),
1571
  ENUM_ENT(EF_MIPS_ARCH_64, "mips64"),
1572
  ENUM_ENT(EF_MIPS_ARCH_32R2, "mips32r2"),
1573
  ENUM_ENT(EF_MIPS_ARCH_64R2, "mips64r2"),
1574
  ENUM_ENT(EF_MIPS_ARCH_32R6, "mips32r6"),
1575
  ENUM_ENT(EF_MIPS_ARCH_64R6, "mips64r6")
1576
};
1577

1578
// clang-format off
1579
#define AMDGPU_MACH_ENUM_ENTS                                                  \
1580
  ENUM_ENT(EF_AMDGPU_MACH_NONE, "none"),                                       \
1581
  ENUM_ENT(EF_AMDGPU_MACH_R600_R600, "r600"),                                  \
1582
  ENUM_ENT(EF_AMDGPU_MACH_R600_R630, "r630"),                                  \
1583
  ENUM_ENT(EF_AMDGPU_MACH_R600_RS880, "rs880"),                                \
1584
  ENUM_ENT(EF_AMDGPU_MACH_R600_RV670, "rv670"),                                \
1585
  ENUM_ENT(EF_AMDGPU_MACH_R600_RV710, "rv710"),                                \
1586
  ENUM_ENT(EF_AMDGPU_MACH_R600_RV730, "rv730"),                                \
1587
  ENUM_ENT(EF_AMDGPU_MACH_R600_RV770, "rv770"),                                \
1588
  ENUM_ENT(EF_AMDGPU_MACH_R600_CEDAR, "cedar"),                                \
1589
  ENUM_ENT(EF_AMDGPU_MACH_R600_CYPRESS, "cypress"),                            \
1590
  ENUM_ENT(EF_AMDGPU_MACH_R600_JUNIPER, "juniper"),                            \
1591
  ENUM_ENT(EF_AMDGPU_MACH_R600_REDWOOD, "redwood"),                            \
1592
  ENUM_ENT(EF_AMDGPU_MACH_R600_SUMO, "sumo"),                                  \
1593
  ENUM_ENT(EF_AMDGPU_MACH_R600_BARTS, "barts"),                                \
1594
  ENUM_ENT(EF_AMDGPU_MACH_R600_CAICOS, "caicos"),                              \
1595
  ENUM_ENT(EF_AMDGPU_MACH_R600_CAYMAN, "cayman"),                              \
1596
  ENUM_ENT(EF_AMDGPU_MACH_R600_TURKS, "turks"),                                \
1597
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600"),                            \
1598
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601"),                            \
1599
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602"),                            \
1600
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700"),                            \
1601
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701"),                            \
1602
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702"),                            \
1603
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703"),                            \
1604
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704"),                            \
1605
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705"),                            \
1606
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801"),                            \
1607
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802"),                            \
1608
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803"),                            \
1609
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805"),                            \
1610
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810"),                            \
1611
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900"),                            \
1612
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902"),                            \
1613
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904"),                            \
1614
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906"),                            \
1615
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908"),                            \
1616
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909"),                            \
1617
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a"),                            \
1618
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c"),                            \
1619
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940"),                            \
1620
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX941, "gfx941"),                            \
1621
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX942, "gfx942"),                            \
1622
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010"),                          \
1623
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011"),                          \
1624
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012"),                          \
1625
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013"),                          \
1626
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030"),                          \
1627
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031"),                          \
1628
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032"),                          \
1629
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033"),                          \
1630
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034"),                          \
1631
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035"),                          \
1632
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036"),                          \
1633
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100"),                          \
1634
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101"),                          \
1635
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102"),                          \
1636
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1103, "gfx1103"),                          \
1637
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1150, "gfx1150"),                          \
1638
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1151, "gfx1151"),                          \
1639
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1152, "gfx1152"),                          \
1640
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1200, "gfx1200"),                          \
1641
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1201, "gfx1201"),                          \
1642
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC, "gfx9-generic"),                \
1643
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC, "gfx10-1-generic"),          \
1644
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC, "gfx10-3-generic"),          \
1645
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC, "gfx11-generic"),              \
1646
  ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC, "gfx12-generic")
1647
// clang-format on
1648

1649
const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion3[] = {
1650
    AMDGPU_MACH_ENUM_ENTS,
1651
    ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_V3, "xnack"),
1652
    ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_V3, "sramecc"),
1653
};
1654

1655
const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion4[] = {
1656
    AMDGPU_MACH_ENUM_ENTS,
1657
    ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_ANY_V4, "xnack"),
1658
    ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_OFF_V4, "xnack-"),
1659
    ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_ON_V4, "xnack+"),
1660
    ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_ANY_V4, "sramecc"),
1661
    ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_OFF_V4, "sramecc-"),
1662
    ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_ON_V4, "sramecc+"),
1663
};
1664

1665
const EnumEntry<unsigned> ElfHeaderNVPTXFlags[] = {
1666
    ENUM_ENT(EF_CUDA_SM20, "sm_20"), ENUM_ENT(EF_CUDA_SM21, "sm_21"),
1667
    ENUM_ENT(EF_CUDA_SM30, "sm_30"), ENUM_ENT(EF_CUDA_SM32, "sm_32"),
1668
    ENUM_ENT(EF_CUDA_SM35, "sm_35"), ENUM_ENT(EF_CUDA_SM37, "sm_37"),
1669
    ENUM_ENT(EF_CUDA_SM50, "sm_50"), ENUM_ENT(EF_CUDA_SM52, "sm_52"),
1670
    ENUM_ENT(EF_CUDA_SM53, "sm_53"), ENUM_ENT(EF_CUDA_SM60, "sm_60"),
1671
    ENUM_ENT(EF_CUDA_SM61, "sm_61"), ENUM_ENT(EF_CUDA_SM62, "sm_62"),
1672
    ENUM_ENT(EF_CUDA_SM70, "sm_70"), ENUM_ENT(EF_CUDA_SM72, "sm_72"),
1673
    ENUM_ENT(EF_CUDA_SM75, "sm_75"), ENUM_ENT(EF_CUDA_SM80, "sm_80"),
1674
    ENUM_ENT(EF_CUDA_SM86, "sm_86"), ENUM_ENT(EF_CUDA_SM87, "sm_87"),
1675
    ENUM_ENT(EF_CUDA_SM89, "sm_89"), ENUM_ENT(EF_CUDA_SM90, "sm_90"),
1676
};
1677

1678
const EnumEntry<unsigned> ElfHeaderRISCVFlags[] = {
1679
  ENUM_ENT(EF_RISCV_RVC, "RVC"),
1680
  ENUM_ENT(EF_RISCV_FLOAT_ABI_SINGLE, "single-float ABI"),
1681
  ENUM_ENT(EF_RISCV_FLOAT_ABI_DOUBLE, "double-float ABI"),
1682
  ENUM_ENT(EF_RISCV_FLOAT_ABI_QUAD, "quad-float ABI"),
1683
  ENUM_ENT(EF_RISCV_RVE, "RVE"),
1684
  ENUM_ENT(EF_RISCV_TSO, "TSO"),
1685
};
1686

1687
const EnumEntry<unsigned> ElfHeaderAVRFlags[] = {
1688
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR1),
1689
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR2),
1690
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR25),
1691
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR3),
1692
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR31),
1693
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR35),
1694
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR4),
1695
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR5),
1696
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR51),
1697
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR6),
1698
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVRTINY),
1699
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA1),
1700
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA2),
1701
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA3),
1702
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA4),
1703
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA5),
1704
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA6),
1705
  LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA7),
1706
  ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"),
1707
};
1708

1709
const EnumEntry<unsigned> ElfHeaderLoongArchFlags[] = {
1710
  ENUM_ENT(EF_LOONGARCH_ABI_SOFT_FLOAT, "SOFT-FLOAT"),
1711
  ENUM_ENT(EF_LOONGARCH_ABI_SINGLE_FLOAT, "SINGLE-FLOAT"),
1712
  ENUM_ENT(EF_LOONGARCH_ABI_DOUBLE_FLOAT, "DOUBLE-FLOAT"),
1713
  ENUM_ENT(EF_LOONGARCH_OBJABI_V0, "OBJ-v0"),
1714
  ENUM_ENT(EF_LOONGARCH_OBJABI_V1, "OBJ-v1"),
1715
};
1716

1717
static const EnumEntry<unsigned> ElfHeaderXtensaFlags[] = {
1718
  LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_MACH_NONE),
1719
  LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_INSN),
1720
  LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_LIT)
1721
};
1722

1723
const EnumEntry<unsigned> ElfSymOtherFlags[] = {
1724
  LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL),
1725
  LLVM_READOBJ_ENUM_ENT(ELF, STV_HIDDEN),
1726
  LLVM_READOBJ_ENUM_ENT(ELF, STV_PROTECTED)
1727
};
1728

1729
const EnumEntry<unsigned> ElfMipsSymOtherFlags[] = {
1730
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
1731
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
1732
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PIC),
1733
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MICROMIPS)
1734
};
1735

1736
const EnumEntry<unsigned> ElfAArch64SymOtherFlags[] = {
1737
  LLVM_READOBJ_ENUM_ENT(ELF, STO_AARCH64_VARIANT_PCS)
1738
};
1739

1740
const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = {
1741
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
1742
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
1743
  LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16)
1744
};
1745

1746
const EnumEntry<unsigned> ElfRISCVSymOtherFlags[] = {
1747
    LLVM_READOBJ_ENUM_ENT(ELF, STO_RISCV_VARIANT_CC)};
1748

1749
static const char *getElfMipsOptionsOdkType(unsigned Odk) {
1750
  switch (Odk) {
1751
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_NULL);
1752
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_REGINFO);
1753
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_EXCEPTIONS);
1754
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAD);
1755
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWPATCH);
1756
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_FILL);
1757
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_TAGS);
1758
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWAND);
1759
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWOR);
1760
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_GP_GROUP);
1761
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_IDENT);
1762
  LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAGESIZE);
1763
  default:
1764
    return "Unknown";
1765
  }
1766
}
1767

1768
template <typename ELFT>
1769
std::pair<const typename ELFT::Phdr *, const typename ELFT::Shdr *>
1770
ELFDumper<ELFT>::findDynamic() {
1771
  // Try to locate the PT_DYNAMIC header.
1772
  const Elf_Phdr *DynamicPhdr = nullptr;
1773
  if (Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = Obj.program_headers()) {
1774
    for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
1775
      if (Phdr.p_type != ELF::PT_DYNAMIC)
1776
        continue;
1777
      DynamicPhdr = &Phdr;
1778
      break;
1779
    }
1780
  } else {
1781
    reportUniqueWarning(
1782
        "unable to read program headers to locate the PT_DYNAMIC segment: " +
1783
        toString(PhdrsOrErr.takeError()));
1784
  }
1785

1786
  // Try to locate the .dynamic section in the sections header table.
1787
  const Elf_Shdr *DynamicSec = nullptr;
1788
  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
1789
    if (Sec.sh_type != ELF::SHT_DYNAMIC)
1790
      continue;
1791
    DynamicSec = &Sec;
1792
    break;
1793
  }
1794

1795
  if (DynamicPhdr && ((DynamicPhdr->p_offset + DynamicPhdr->p_filesz >
1796
                       ObjF.getMemoryBufferRef().getBufferSize()) ||
1797
                      (DynamicPhdr->p_offset + DynamicPhdr->p_filesz <
1798
                       DynamicPhdr->p_offset))) {
1799
    reportUniqueWarning(
1800
        "PT_DYNAMIC segment offset (0x" +
1801
        Twine::utohexstr(DynamicPhdr->p_offset) + ") + file size (0x" +
1802
        Twine::utohexstr(DynamicPhdr->p_filesz) +
1803
        ") exceeds the size of the file (0x" +
1804
        Twine::utohexstr(ObjF.getMemoryBufferRef().getBufferSize()) + ")");
1805
    // Don't use the broken dynamic header.
1806
    DynamicPhdr = nullptr;
1807
  }
1808

1809
  if (DynamicPhdr && DynamicSec) {
1810
    if (DynamicSec->sh_addr + DynamicSec->sh_size >
1811
            DynamicPhdr->p_vaddr + DynamicPhdr->p_memsz ||
1812
        DynamicSec->sh_addr < DynamicPhdr->p_vaddr)
1813
      reportUniqueWarning(describe(*DynamicSec) +
1814
                          " is not contained within the "
1815
                          "PT_DYNAMIC segment");
1816

1817
    if (DynamicSec->sh_addr != DynamicPhdr->p_vaddr)
1818
      reportUniqueWarning(describe(*DynamicSec) + " is not at the start of "
1819
                                                  "PT_DYNAMIC segment");
1820
  }
1821

1822
  return std::make_pair(DynamicPhdr, DynamicSec);
1823
}
1824

1825
template <typename ELFT>
1826
void ELFDumper<ELFT>::loadDynamicTable() {
1827
  const Elf_Phdr *DynamicPhdr;
1828
  const Elf_Shdr *DynamicSec;
1829
  std::tie(DynamicPhdr, DynamicSec) = findDynamic();
1830
  if (!DynamicPhdr && !DynamicSec)
1831
    return;
1832

1833
  DynRegionInfo FromPhdr(ObjF, *this);
1834
  bool IsPhdrTableValid = false;
1835
  if (DynamicPhdr) {
1836
    // Use cantFail(), because p_offset/p_filesz fields of a PT_DYNAMIC are
1837
    // validated in findDynamic() and so createDRI() is not expected to fail.
1838
    FromPhdr = cantFail(createDRI(DynamicPhdr->p_offset, DynamicPhdr->p_filesz,
1839
                                  sizeof(Elf_Dyn)));
1840
    FromPhdr.SizePrintName = "PT_DYNAMIC size";
1841
    FromPhdr.EntSizePrintName = "";
1842
    IsPhdrTableValid = !FromPhdr.template getAsArrayRef<Elf_Dyn>().empty();
1843
  }
1844

1845
  // Locate the dynamic table described in a section header.
1846
  // Ignore sh_entsize and use the expected value for entry size explicitly.
1847
  // This allows us to dump dynamic sections with a broken sh_entsize
1848
  // field.
1849
  DynRegionInfo FromSec(ObjF, *this);
1850
  bool IsSecTableValid = false;
1851
  if (DynamicSec) {
1852
    Expected<DynRegionInfo> RegOrErr =
1853
        createDRI(DynamicSec->sh_offset, DynamicSec->sh_size, sizeof(Elf_Dyn));
1854
    if (RegOrErr) {
1855
      FromSec = *RegOrErr;
1856
      FromSec.Context = describe(*DynamicSec);
1857
      FromSec.EntSizePrintName = "";
1858
      IsSecTableValid = !FromSec.template getAsArrayRef<Elf_Dyn>().empty();
1859
    } else {
1860
      reportUniqueWarning("unable to read the dynamic table from " +
1861
                          describe(*DynamicSec) + ": " +
1862
                          toString(RegOrErr.takeError()));
1863
    }
1864
  }
1865

1866
  // When we only have information from one of the SHT_DYNAMIC section header or
1867
  // PT_DYNAMIC program header, just use that.
1868
  if (!DynamicPhdr || !DynamicSec) {
1869
    if ((DynamicPhdr && IsPhdrTableValid) || (DynamicSec && IsSecTableValid)) {
1870
      DynamicTable = DynamicPhdr ? FromPhdr : FromSec;
1871
      parseDynamicTable();
1872
    } else {
1873
      reportUniqueWarning("no valid dynamic table was found");
1874
    }
1875
    return;
1876
  }
1877

1878
  // At this point we have tables found from the section header and from the
1879
  // dynamic segment. Usually they match, but we have to do sanity checks to
1880
  // verify that.
1881

1882
  if (FromPhdr.Addr != FromSec.Addr)
1883
    reportUniqueWarning("SHT_DYNAMIC section header and PT_DYNAMIC "
1884
                        "program header disagree about "
1885
                        "the location of the dynamic table");
1886

1887
  if (!IsPhdrTableValid && !IsSecTableValid) {
1888
    reportUniqueWarning("no valid dynamic table was found");
1889
    return;
1890
  }
1891

1892
  // Information in the PT_DYNAMIC program header has priority over the
1893
  // information in a section header.
1894
  if (IsPhdrTableValid) {
1895
    if (!IsSecTableValid)
1896
      reportUniqueWarning(
1897
          "SHT_DYNAMIC dynamic table is invalid: PT_DYNAMIC will be used");
1898
    DynamicTable = FromPhdr;
1899
  } else {
1900
    reportUniqueWarning(
1901
        "PT_DYNAMIC dynamic table is invalid: SHT_DYNAMIC will be used");
1902
    DynamicTable = FromSec;
1903
  }
1904

1905
  parseDynamicTable();
1906
}
1907

1908
template <typename ELFT>
1909
ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> &O,
1910
                           ScopedPrinter &Writer)
1911
    : ObjDumper(Writer, O.getFileName()), ObjF(O), Obj(O.getELFFile()),
1912
      FileName(O.getFileName()), DynRelRegion(O, *this),
1913
      DynRelaRegion(O, *this), DynCrelRegion(O, *this), DynRelrRegion(O, *this),
1914
      DynPLTRelRegion(O, *this), DynSymTabShndxRegion(O, *this),
1915
      DynamicTable(O, *this) {
1916
  if (!O.IsContentValid())
1917
    return;
1918

1919
  typename ELFT::ShdrRange Sections = cantFail(Obj.sections());
1920
  for (const Elf_Shdr &Sec : Sections) {
1921
    switch (Sec.sh_type) {
1922
    case ELF::SHT_SYMTAB:
1923
      if (!DotSymtabSec)
1924
        DotSymtabSec = &Sec;
1925
      break;
1926
    case ELF::SHT_DYNSYM:
1927
      if (!DotDynsymSec)
1928
        DotDynsymSec = &Sec;
1929

1930
      if (!DynSymRegion) {
1931
        Expected<DynRegionInfo> RegOrErr =
1932
            createDRI(Sec.sh_offset, Sec.sh_size, Sec.sh_entsize);
1933
        if (RegOrErr) {
1934
          DynSymRegion = *RegOrErr;
1935
          DynSymRegion->Context = describe(Sec);
1936

1937
          if (Expected<StringRef> E = Obj.getStringTableForSymtab(Sec))
1938
            DynamicStringTable = *E;
1939
          else
1940
            reportUniqueWarning("unable to get the string table for the " +
1941
                                describe(Sec) + ": " + toString(E.takeError()));
1942
        } else {
1943
          reportUniqueWarning("unable to read dynamic symbols from " +
1944
                              describe(Sec) + ": " +
1945
                              toString(RegOrErr.takeError()));
1946
        }
1947
      }
1948
      break;
1949
    case ELF::SHT_SYMTAB_SHNDX: {
1950
      uint32_t SymtabNdx = Sec.sh_link;
1951
      if (SymtabNdx >= Sections.size()) {
1952
        reportUniqueWarning(
1953
            "unable to get the associated symbol table for " + describe(Sec) +
1954
            ": sh_link (" + Twine(SymtabNdx) +
1955
            ") is greater than or equal to the total number of sections (" +
1956
            Twine(Sections.size()) + ")");
1957
        continue;
1958
      }
1959

1960
      if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
1961
              Obj.getSHNDXTable(Sec)) {
1962
        if (!ShndxTables.insert({&Sections[SymtabNdx], *ShndxTableOrErr})
1963
                 .second)
1964
          reportUniqueWarning(
1965
              "multiple SHT_SYMTAB_SHNDX sections are linked to " +
1966
              describe(Sec));
1967
      } else {
1968
        reportUniqueWarning(ShndxTableOrErr.takeError());
1969
      }
1970
      break;
1971
    }
1972
    case ELF::SHT_GNU_versym:
1973
      if (!SymbolVersionSection)
1974
        SymbolVersionSection = &Sec;
1975
      break;
1976
    case ELF::SHT_GNU_verdef:
1977
      if (!SymbolVersionDefSection)
1978
        SymbolVersionDefSection = &Sec;
1979
      break;
1980
    case ELF::SHT_GNU_verneed:
1981
      if (!SymbolVersionNeedSection)
1982
        SymbolVersionNeedSection = &Sec;
1983
      break;
1984
    case ELF::SHT_LLVM_ADDRSIG:
1985
      if (!DotAddrsigSec)
1986
        DotAddrsigSec = &Sec;
1987
      break;
1988
    }
1989
  }
1990

1991
  loadDynamicTable();
1992
}
1993

1994
template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() {
1995
  auto toMappedAddr = [&](uint64_t Tag, uint64_t VAddr) -> const uint8_t * {
1996
    auto MappedAddrOrError = Obj.toMappedAddr(VAddr, [&](const Twine &Msg) {
1997
      this->reportUniqueWarning(Msg);
1998
      return Error::success();
1999
    });
2000
    if (!MappedAddrOrError) {
2001
      this->reportUniqueWarning("unable to parse DT_" +
2002
                                Obj.getDynamicTagAsString(Tag) + ": " +
2003
                                llvm::toString(MappedAddrOrError.takeError()));
2004
      return nullptr;
2005
    }
2006
    return MappedAddrOrError.get();
2007
  };
2008

2009
  const char *StringTableBegin = nullptr;
2010
  uint64_t StringTableSize = 0;
2011
  std::optional<DynRegionInfo> DynSymFromTable;
2012
  for (const Elf_Dyn &Dyn : dynamic_table()) {
2013
    if (Obj.getHeader().e_machine == EM_AARCH64) {
2014
      switch (Dyn.d_tag) {
2015
      case ELF::DT_AARCH64_AUTH_RELRSZ:
2016
        DynRelrRegion.Size = Dyn.getVal();
2017
        DynRelrRegion.SizePrintName = "DT_AARCH64_AUTH_RELRSZ value";
2018
        continue;
2019
      case ELF::DT_AARCH64_AUTH_RELRENT:
2020
        DynRelrRegion.EntSize = Dyn.getVal();
2021
        DynRelrRegion.EntSizePrintName = "DT_AARCH64_AUTH_RELRENT value";
2022
        continue;
2023
      }
2024
    }
2025
    switch (Dyn.d_tag) {
2026
    case ELF::DT_HASH:
2027
      HashTable = reinterpret_cast<const Elf_Hash *>(
2028
          toMappedAddr(Dyn.getTag(), Dyn.getPtr()));
2029
      break;
2030
    case ELF::DT_GNU_HASH:
2031
      GnuHashTable = reinterpret_cast<const Elf_GnuHash *>(
2032
          toMappedAddr(Dyn.getTag(), Dyn.getPtr()));
2033
      break;
2034
    case ELF::DT_STRTAB:
2035
      StringTableBegin = reinterpret_cast<const char *>(
2036
          toMappedAddr(Dyn.getTag(), Dyn.getPtr()));
2037
      break;
2038
    case ELF::DT_STRSZ:
2039
      StringTableSize = Dyn.getVal();
2040
      break;
2041
    case ELF::DT_SYMTAB: {
2042
      // If we can't map the DT_SYMTAB value to an address (e.g. when there are
2043
      // no program headers), we ignore its value.
2044
      if (const uint8_t *VA = toMappedAddr(Dyn.getTag(), Dyn.getPtr())) {
2045
        DynSymFromTable.emplace(ObjF, *this);
2046
        DynSymFromTable->Addr = VA;
2047
        DynSymFromTable->EntSize = sizeof(Elf_Sym);
2048
        DynSymFromTable->EntSizePrintName = "";
2049
      }
2050
      break;
2051
    }
2052
    case ELF::DT_SYMENT: {
2053
      uint64_t Val = Dyn.getVal();
2054
      if (Val != sizeof(Elf_Sym))
2055
        this->reportUniqueWarning("DT_SYMENT value of 0x" +
2056
                                  Twine::utohexstr(Val) +
2057
                                  " is not the size of a symbol (0x" +
2058
                                  Twine::utohexstr(sizeof(Elf_Sym)) + ")");
2059
      break;
2060
    }
2061
    case ELF::DT_RELA:
2062
      DynRelaRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
2063
      break;
2064
    case ELF::DT_RELASZ:
2065
      DynRelaRegion.Size = Dyn.getVal();
2066
      DynRelaRegion.SizePrintName = "DT_RELASZ value";
2067
      break;
2068
    case ELF::DT_RELAENT:
2069
      DynRelaRegion.EntSize = Dyn.getVal();
2070
      DynRelaRegion.EntSizePrintName = "DT_RELAENT value";
2071
      break;
2072
    case ELF::DT_CREL:
2073
      DynCrelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
2074
      break;
2075
    case ELF::DT_SONAME:
2076
      SONameOffset = Dyn.getVal();
2077
      break;
2078
    case ELF::DT_REL:
2079
      DynRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
2080
      break;
2081
    case ELF::DT_RELSZ:
2082
      DynRelRegion.Size = Dyn.getVal();
2083
      DynRelRegion.SizePrintName = "DT_RELSZ value";
2084
      break;
2085
    case ELF::DT_RELENT:
2086
      DynRelRegion.EntSize = Dyn.getVal();
2087
      DynRelRegion.EntSizePrintName = "DT_RELENT value";
2088
      break;
2089
    case ELF::DT_RELR:
2090
    case ELF::DT_ANDROID_RELR:
2091
    case ELF::DT_AARCH64_AUTH_RELR:
2092
      DynRelrRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
2093
      break;
2094
    case ELF::DT_RELRSZ:
2095
    case ELF::DT_ANDROID_RELRSZ:
2096
    case ELF::DT_AARCH64_AUTH_RELRSZ:
2097
      DynRelrRegion.Size = Dyn.getVal();
2098
      DynRelrRegion.SizePrintName = Dyn.d_tag == ELF::DT_RELRSZ
2099
                                        ? "DT_RELRSZ value"
2100
                                        : "DT_ANDROID_RELRSZ value";
2101
      break;
2102
    case ELF::DT_RELRENT:
2103
    case ELF::DT_ANDROID_RELRENT:
2104
    case ELF::DT_AARCH64_AUTH_RELRENT:
2105
      DynRelrRegion.EntSize = Dyn.getVal();
2106
      DynRelrRegion.EntSizePrintName = Dyn.d_tag == ELF::DT_RELRENT
2107
                                           ? "DT_RELRENT value"
2108
                                           : "DT_ANDROID_RELRENT value";
2109
      break;
2110
    case ELF::DT_PLTREL:
2111
      if (Dyn.getVal() == DT_REL)
2112
        DynPLTRelRegion.EntSize = sizeof(Elf_Rel);
2113
      else if (Dyn.getVal() == DT_RELA)
2114
        DynPLTRelRegion.EntSize = sizeof(Elf_Rela);
2115
      else if (Dyn.getVal() == DT_CREL)
2116
        DynPLTRelRegion.EntSize = 1;
2117
      else
2118
        reportUniqueWarning(Twine("unknown DT_PLTREL value of ") +
2119
                            Twine((uint64_t)Dyn.getVal()));
2120
      DynPLTRelRegion.EntSizePrintName = "PLTREL entry size";
2121
      break;
2122
    case ELF::DT_JMPREL:
2123
      DynPLTRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
2124
      break;
2125
    case ELF::DT_PLTRELSZ:
2126
      DynPLTRelRegion.Size = Dyn.getVal();
2127
      DynPLTRelRegion.SizePrintName = "DT_PLTRELSZ value";
2128
      break;
2129
    case ELF::DT_SYMTAB_SHNDX:
2130
      DynSymTabShndxRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
2131
      DynSymTabShndxRegion.EntSize = sizeof(Elf_Word);
2132
      break;
2133
    }
2134
  }
2135

2136
  if (StringTableBegin) {
2137
    const uint64_t FileSize = Obj.getBufSize();
2138
    const uint64_t Offset = (const uint8_t *)StringTableBegin - Obj.base();
2139
    if (StringTableSize > FileSize - Offset)
2140
      reportUniqueWarning(
2141
          "the dynamic string table at 0x" + Twine::utohexstr(Offset) +
2142
          " goes past the end of the file (0x" + Twine::utohexstr(FileSize) +
2143
          ") with DT_STRSZ = 0x" + Twine::utohexstr(StringTableSize));
2144
    else
2145
      DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
2146
  }
2147

2148
  const bool IsHashTableSupported = getHashTableEntSize() == 4;
2149
  if (DynSymRegion) {
2150
    // Often we find the information about the dynamic symbol table
2151
    // location in the SHT_DYNSYM section header. However, the value in
2152
    // DT_SYMTAB has priority, because it is used by dynamic loaders to
2153
    // locate .dynsym at runtime. The location we find in the section header
2154
    // and the location we find here should match.
2155
    if (DynSymFromTable && DynSymFromTable->Addr != DynSymRegion->Addr)
2156
      reportUniqueWarning(
2157
          createError("SHT_DYNSYM section header and DT_SYMTAB disagree about "
2158
                      "the location of the dynamic symbol table"));
2159

2160
    // According to the ELF gABI: "The number of symbol table entries should
2161
    // equal nchain". Check to see if the DT_HASH hash table nchain value
2162
    // conflicts with the number of symbols in the dynamic symbol table
2163
    // according to the section header.
2164
    if (HashTable && IsHashTableSupported) {
2165
      if (DynSymRegion->EntSize == 0)
2166
        reportUniqueWarning("SHT_DYNSYM section has sh_entsize == 0");
2167
      else if (HashTable->nchain != DynSymRegion->Size / DynSymRegion->EntSize)
2168
        reportUniqueWarning(
2169
            "hash table nchain (" + Twine(HashTable->nchain) +
2170
            ") differs from symbol count derived from SHT_DYNSYM section "
2171
            "header (" +
2172
            Twine(DynSymRegion->Size / DynSymRegion->EntSize) + ")");
2173
    }
2174
  }
2175

2176
  // Delay the creation of the actual dynamic symbol table until now, so that
2177
  // checks can always be made against the section header-based properties,
2178
  // without worrying about tag order.
2179
  if (DynSymFromTable) {
2180
    if (!DynSymRegion) {
2181
      DynSymRegion = DynSymFromTable;
2182
    } else {
2183
      DynSymRegion->Addr = DynSymFromTable->Addr;
2184
      DynSymRegion->EntSize = DynSymFromTable->EntSize;
2185
      DynSymRegion->EntSizePrintName = DynSymFromTable->EntSizePrintName;
2186
    }
2187
  }
2188

2189
  // Derive the dynamic symbol table size from the DT_HASH hash table, if
2190
  // present.
2191
  if (HashTable && IsHashTableSupported && DynSymRegion) {
2192
    const uint64_t FileSize = Obj.getBufSize();
2193
    const uint64_t DerivedSize =
2194
        (uint64_t)HashTable->nchain * DynSymRegion->EntSize;
2195
    const uint64_t Offset = (const uint8_t *)DynSymRegion->Addr - Obj.base();
2196
    if (DerivedSize > FileSize - Offset)
2197
      reportUniqueWarning(
2198
          "the size (0x" + Twine::utohexstr(DerivedSize) +
2199
          ") of the dynamic symbol table at 0x" + Twine::utohexstr(Offset) +
2200
          ", derived from the hash table, goes past the end of the file (0x" +
2201
          Twine::utohexstr(FileSize) + ") and will be ignored");
2202
    else
2203
      DynSymRegion->Size = HashTable->nchain * DynSymRegion->EntSize;
2204
  }
2205
}
2206

2207
template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
2208
  // Dump version symbol section.
2209
  printVersionSymbolSection(SymbolVersionSection);
2210

2211
  // Dump version definition section.
2212
  printVersionDefinitionSection(SymbolVersionDefSection);
2213

2214
  // Dump version dependency section.
2215
  printVersionDependencySection(SymbolVersionNeedSection);
2216
}
2217

2218
#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum)                                 \
2219
  { #enum, prefix##_##enum }
2220

2221
const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
2222
  LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
2223
  LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
2224
  LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
2225
  LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
2226
  LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
2227
};
2228

2229
const EnumEntry<unsigned> ElfDynamicDTFlags1[] = {
2230
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW),
2231
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL),
2232
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP),
2233
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE),
2234
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR),
2235
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST),
2236
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN),
2237
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN),
2238
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT),
2239
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS),
2240
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE),
2241
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB),
2242
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP),
2243
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT),
2244
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE),
2245
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE),
2246
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELPND),
2247
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT),
2248
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF),
2249
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS),
2250
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR),
2251
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED),
2252
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC),
2253
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE),
2254
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT),
2255
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON),
2256
  LLVM_READOBJ_DT_FLAG_ENT(DF_1, PIE),
2257
};
2258

2259
const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
2260
  LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
2261
  LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
2262
  LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
2263
  LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
2264
  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
2265
  LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
2266
  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
2267
  LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
2268
  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
2269
  LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
2270
  LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
2271
  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
2272
  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
2273
  LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
2274
  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
2275
  LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
2276
};
2277

2278
#undef LLVM_READOBJ_DT_FLAG_ENT
2279

2280
template <typename T, typename TFlag>
2281
void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
2282
  SmallVector<EnumEntry<TFlag>, 10> SetFlags;
2283
  for (const EnumEntry<TFlag> &Flag : Flags)
2284
    if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value)
2285
      SetFlags.push_back(Flag);
2286

2287
  for (const EnumEntry<TFlag> &Flag : SetFlags)
2288
    OS << Flag.Name << " ";
2289
}
2290

2291
template <class ELFT>
2292
const typename ELFT::Shdr *
2293
ELFDumper<ELFT>::findSectionByName(StringRef Name) const {
2294
  for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) {
2295
    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Shdr)) {
2296
      if (*NameOrErr == Name)
2297
        return &Shdr;
2298
    } else {
2299
      reportUniqueWarning("unable to read the name of " + describe(Shdr) +
2300
                          ": " + toString(NameOrErr.takeError()));
2301
    }
2302
  }
2303
  return nullptr;
2304
}
2305

2306
template <class ELFT>
2307
std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type,
2308
                                             uint64_t Value) const {
2309
  auto FormatHexValue = [](uint64_t V) {
2310
    std::string Str;
2311
    raw_string_ostream OS(Str);
2312
    const char *ConvChar =
2313
        (opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64;
2314
    OS << format(ConvChar, V);
2315
    return OS.str();
2316
  };
2317

2318
  auto FormatFlags = [](uint64_t V,
2319
                        llvm::ArrayRef<llvm::EnumEntry<unsigned int>> Array) {
2320
    std::string Str;
2321
    raw_string_ostream OS(Str);
2322
    printFlags(V, Array, OS);
2323
    return OS.str();
2324
  };
2325

2326
  // Handle custom printing of architecture specific tags
2327
  switch (Obj.getHeader().e_machine) {
2328
  case EM_AARCH64:
2329
    switch (Type) {
2330
    case DT_AARCH64_BTI_PLT:
2331
    case DT_AARCH64_PAC_PLT:
2332
    case DT_AARCH64_VARIANT_PCS:
2333
    case DT_AARCH64_MEMTAG_GLOBALSSZ:
2334
      return std::to_string(Value);
2335
    case DT_AARCH64_MEMTAG_MODE:
2336
      switch (Value) {
2337
        case 0:
2338
          return "Synchronous (0)";
2339
        case 1:
2340
          return "Asynchronous (1)";
2341
        default:
2342
          return (Twine("Unknown (") + Twine(Value) + ")").str();
2343
      }
2344
    case DT_AARCH64_MEMTAG_HEAP:
2345
    case DT_AARCH64_MEMTAG_STACK:
2346
      switch (Value) {
2347
        case 0:
2348
          return "Disabled (0)";
2349
        case 1:
2350
          return "Enabled (1)";
2351
        default:
2352
          return (Twine("Unknown (") + Twine(Value) + ")").str();
2353
      }
2354
    case DT_AARCH64_MEMTAG_GLOBALS:
2355
      return (Twine("0x") + utohexstr(Value, /*LowerCase=*/true)).str();
2356
    default:
2357
      break;
2358
    }
2359
    break;
2360
  case EM_HEXAGON:
2361
    switch (Type) {
2362
    case DT_HEXAGON_VER:
2363
      return std::to_string(Value);
2364
    case DT_HEXAGON_SYMSZ:
2365
    case DT_HEXAGON_PLT:
2366
      return FormatHexValue(Value);
2367
    default:
2368
      break;
2369
    }
2370
    break;
2371
  case EM_MIPS:
2372
    switch (Type) {
2373
    case DT_MIPS_RLD_VERSION:
2374
    case DT_MIPS_LOCAL_GOTNO:
2375
    case DT_MIPS_SYMTABNO:
2376
    case DT_MIPS_UNREFEXTNO:
2377
      return std::to_string(Value);
2378
    case DT_MIPS_TIME_STAMP:
2379
    case DT_MIPS_ICHECKSUM:
2380
    case DT_MIPS_IVERSION:
2381
    case DT_MIPS_BASE_ADDRESS:
2382
    case DT_MIPS_MSYM:
2383
    case DT_MIPS_CONFLICT:
2384
    case DT_MIPS_LIBLIST:
2385
    case DT_MIPS_CONFLICTNO:
2386
    case DT_MIPS_LIBLISTNO:
2387
    case DT_MIPS_GOTSYM:
2388
    case DT_MIPS_HIPAGENO:
2389
    case DT_MIPS_RLD_MAP:
2390
    case DT_MIPS_DELTA_CLASS:
2391
    case DT_MIPS_DELTA_CLASS_NO:
2392
    case DT_MIPS_DELTA_INSTANCE:
2393
    case DT_MIPS_DELTA_RELOC:
2394
    case DT_MIPS_DELTA_RELOC_NO:
2395
    case DT_MIPS_DELTA_SYM:
2396
    case DT_MIPS_DELTA_SYM_NO:
2397
    case DT_MIPS_DELTA_CLASSSYM:
2398
    case DT_MIPS_DELTA_CLASSSYM_NO:
2399
    case DT_MIPS_CXX_FLAGS:
2400
    case DT_MIPS_PIXIE_INIT:
2401
    case DT_MIPS_SYMBOL_LIB:
2402
    case DT_MIPS_LOCALPAGE_GOTIDX:
2403
    case DT_MIPS_LOCAL_GOTIDX:
2404
    case DT_MIPS_HIDDEN_GOTIDX:
2405
    case DT_MIPS_PROTECTED_GOTIDX:
2406
    case DT_MIPS_OPTIONS:
2407
    case DT_MIPS_INTERFACE:
2408
    case DT_MIPS_DYNSTR_ALIGN:
2409
    case DT_MIPS_INTERFACE_SIZE:
2410
    case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:
2411
    case DT_MIPS_PERF_SUFFIX:
2412
    case DT_MIPS_COMPACT_SIZE:
2413
    case DT_MIPS_GP_VALUE:
2414
    case DT_MIPS_AUX_DYNAMIC:
2415
    case DT_MIPS_PLTGOT:
2416
    case DT_MIPS_RWPLT:
2417
    case DT_MIPS_RLD_MAP_REL:
2418
    case DT_MIPS_XHASH:
2419
      return FormatHexValue(Value);
2420
    case DT_MIPS_FLAGS:
2421
      return FormatFlags(Value, ArrayRef(ElfDynamicDTMipsFlags));
2422
    default:
2423
      break;
2424
    }
2425
    break;
2426
  default:
2427
    break;
2428
  }
2429

2430
  switch (Type) {
2431
  case DT_PLTREL:
2432
    if (Value == DT_REL)
2433
      return "REL";
2434
    if (Value == DT_RELA)
2435
      return "RELA";
2436
    if (Value == DT_CREL)
2437
      return "CREL";
2438
    [[fallthrough]];
2439
  case DT_PLTGOT:
2440
  case DT_HASH:
2441
  case DT_STRTAB:
2442
  case DT_SYMTAB:
2443
  case DT_RELA:
2444
  case DT_INIT:
2445
  case DT_FINI:
2446
  case DT_REL:
2447
  case DT_JMPREL:
2448
  case DT_INIT_ARRAY:
2449
  case DT_FINI_ARRAY:
2450
  case DT_PREINIT_ARRAY:
2451
  case DT_DEBUG:
2452
  case DT_CREL:
2453
  case DT_VERDEF:
2454
  case DT_VERNEED:
2455
  case DT_VERSYM:
2456
  case DT_GNU_HASH:
2457
  case DT_NULL:
2458
    return FormatHexValue(Value);
2459
  case DT_RELACOUNT:
2460
  case DT_RELCOUNT:
2461
  case DT_VERDEFNUM:
2462
  case DT_VERNEEDNUM:
2463
    return std::to_string(Value);
2464
  case DT_PLTRELSZ:
2465
  case DT_RELASZ:
2466
  case DT_RELAENT:
2467
  case DT_STRSZ:
2468
  case DT_SYMENT:
2469
  case DT_RELSZ:
2470
  case DT_RELENT:
2471
  case DT_INIT_ARRAYSZ:
2472
  case DT_FINI_ARRAYSZ:
2473
  case DT_PREINIT_ARRAYSZ:
2474
  case DT_RELRSZ:
2475
  case DT_RELRENT:
2476
  case DT_AARCH64_AUTH_RELRSZ:
2477
  case DT_AARCH64_AUTH_RELRENT:
2478
  case DT_ANDROID_RELSZ:
2479
  case DT_ANDROID_RELASZ:
2480
    return std::to_string(Value) + " (bytes)";
2481
  case DT_NEEDED:
2482
  case DT_SONAME:
2483
  case DT_AUXILIARY:
2484
  case DT_USED:
2485
  case DT_FILTER:
2486
  case DT_RPATH:
2487
  case DT_RUNPATH: {
2488
    const std::map<uint64_t, const char *> TagNames = {
2489
        {DT_NEEDED, "Shared library"},       {DT_SONAME, "Library soname"},
2490
        {DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"},
2491
        {DT_FILTER, "Filter library"},       {DT_RPATH, "Library rpath"},
2492
        {DT_RUNPATH, "Library runpath"},
2493
    };
2494

2495
    return (Twine(TagNames.at(Type)) + ": [" + getDynamicString(Value) + "]")
2496
        .str();
2497
  }
2498
  case DT_FLAGS:
2499
    return FormatFlags(Value, ArrayRef(ElfDynamicDTFlags));
2500
  case DT_FLAGS_1:
2501
    return FormatFlags(Value, ArrayRef(ElfDynamicDTFlags1));
2502
  default:
2503
    return FormatHexValue(Value);
2504
  }
2505
}
2506

2507
template <class ELFT>
2508
StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
2509
  if (DynamicStringTable.empty() && !DynamicStringTable.data()) {
2510
    reportUniqueWarning("string table was not found");
2511
    return "<?>";
2512
  }
2513

2514
  auto WarnAndReturn = [this](const Twine &Msg, uint64_t Offset) {
2515
    reportUniqueWarning("string table at offset 0x" + Twine::utohexstr(Offset) +
2516
                        Msg);
2517
    return "<?>";
2518
  };
2519

2520
  const uint64_t FileSize = Obj.getBufSize();
2521
  const uint64_t Offset =
2522
      (const uint8_t *)DynamicStringTable.data() - Obj.base();
2523
  if (DynamicStringTable.size() > FileSize - Offset)
2524
    return WarnAndReturn(" with size 0x" +
2525
                             Twine::utohexstr(DynamicStringTable.size()) +
2526
                             " goes past the end of the file (0x" +
2527
                             Twine::utohexstr(FileSize) + ")",
2528
                         Offset);
2529

2530
  if (Value >= DynamicStringTable.size())
2531
    return WarnAndReturn(
2532
        ": unable to read the string at 0x" + Twine::utohexstr(Offset + Value) +
2533
            ": it goes past the end of the table (0x" +
2534
            Twine::utohexstr(Offset + DynamicStringTable.size()) + ")",
2535
        Offset);
2536

2537
  if (DynamicStringTable.back() != '\0')
2538
    return WarnAndReturn(": unable to read the string at 0x" +
2539
                             Twine::utohexstr(Offset + Value) +
2540
                             ": the string table is not null-terminated",
2541
                         Offset);
2542

2543
  return DynamicStringTable.data() + Value;
2544
}
2545

2546
template <class ELFT> void ELFDumper<ELFT>::printUnwindInfo() {
2547
  DwarfCFIEH::PrinterContext<ELFT> Ctx(W, ObjF);
2548
  Ctx.printUnwindInformation();
2549
}
2550

2551
// The namespace is needed to fix the compilation with GCC older than 7.0+.
2552
namespace {
2553
template <> void ELFDumper<ELF32LE>::printUnwindInfo() {
2554
  if (Obj.getHeader().e_machine == EM_ARM) {
2555
    ARM::EHABI::PrinterContext<ELF32LE> Ctx(W, Obj, ObjF.getFileName(),
2556
                                            DotSymtabSec);
2557
    Ctx.PrintUnwindInformation();
2558
  }
2559
  DwarfCFIEH::PrinterContext<ELF32LE> Ctx(W, ObjF);
2560
  Ctx.printUnwindInformation();
2561
}
2562
} // namespace
2563

2564
template <class ELFT> void ELFDumper<ELFT>::printNeededLibraries() {
2565
  ListScope D(W, "NeededLibraries");
2566

2567
  std::vector<StringRef> Libs;
2568
  for (const auto &Entry : dynamic_table())
2569
    if (Entry.d_tag == ELF::DT_NEEDED)
2570
      Libs.push_back(getDynamicString(Entry.d_un.d_val));
2571

2572
  llvm::sort(Libs);
2573

2574
  for (StringRef L : Libs)
2575
    W.printString(L);
2576
}
2577

2578
template <class ELFT>
2579
static Error checkHashTable(const ELFDumper<ELFT> &Dumper,
2580
                            const typename ELFT::Hash *H,
2581
                            bool *IsHeaderValid = nullptr) {
2582
  const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
2583
  const uint64_t SecOffset = (const uint8_t *)H - Obj.base();
2584
  if (Dumper.getHashTableEntSize() == 8) {
2585
    auto It = llvm::find_if(ElfMachineType, [&](const EnumEntry<unsigned> &E) {
2586
      return E.Value == Obj.getHeader().e_machine;
2587
    });
2588
    if (IsHeaderValid)
2589
      *IsHeaderValid = false;
2590
    return createError("the hash table at 0x" + Twine::utohexstr(SecOffset) +
2591
                       " is not supported: it contains non-standard 8 "
2592
                       "byte entries on " +
2593
                       It->AltName + " platform");
2594
  }
2595

2596
  auto MakeError = [&](const Twine &Msg = "") {
2597
    return createError("the hash table at offset 0x" +
2598
                       Twine::utohexstr(SecOffset) +
2599
                       " goes past the end of the file (0x" +
2600
                       Twine::utohexstr(Obj.getBufSize()) + ")" + Msg);
2601
  };
2602

2603
  // Each SHT_HASH section starts from two 32-bit fields: nbucket and nchain.
2604
  const unsigned HeaderSize = 2 * sizeof(typename ELFT::Word);
2605

2606
  if (IsHeaderValid)
2607
    *IsHeaderValid = Obj.getBufSize() - SecOffset >= HeaderSize;
2608

2609
  if (Obj.getBufSize() - SecOffset < HeaderSize)
2610
    return MakeError();
2611

2612
  if (Obj.getBufSize() - SecOffset - HeaderSize <
2613
      ((uint64_t)H->nbucket + H->nchain) * sizeof(typename ELFT::Word))
2614
    return MakeError(", nbucket = " + Twine(H->nbucket) +
2615
                     ", nchain = " + Twine(H->nchain));
2616
  return Error::success();
2617
}
2618

2619
template <class ELFT>
2620
static Error checkGNUHashTable(const ELFFile<ELFT> &Obj,
2621
                               const typename ELFT::GnuHash *GnuHashTable,
2622
                               bool *IsHeaderValid = nullptr) {
2623
  const uint8_t *TableData = reinterpret_cast<const uint8_t *>(GnuHashTable);
2624
  assert(TableData >= Obj.base() && TableData < Obj.base() + Obj.getBufSize() &&
2625
         "GnuHashTable must always point to a location inside the file");
2626

2627
  uint64_t TableOffset = TableData - Obj.base();
2628
  if (IsHeaderValid)
2629
    *IsHeaderValid = TableOffset + /*Header size:*/ 16 < Obj.getBufSize();
2630
  if (TableOffset + 16 + (uint64_t)GnuHashTable->nbuckets * 4 +
2631
          (uint64_t)GnuHashTable->maskwords * sizeof(typename ELFT::Off) >=
2632
      Obj.getBufSize())
2633
    return createError("unable to dump the SHT_GNU_HASH "
2634
                       "section at 0x" +
2635
                       Twine::utohexstr(TableOffset) +
2636
                       ": it goes past the end of the file");
2637
  return Error::success();
2638
}
2639

2640
template <typename ELFT> void ELFDumper<ELFT>::printHashTable() {
2641
  DictScope D(W, "HashTable");
2642
  if (!HashTable)
2643
    return;
2644

2645
  bool IsHeaderValid;
2646
  Error Err = checkHashTable(*this, HashTable, &IsHeaderValid);
2647
  if (IsHeaderValid) {
2648
    W.printNumber("Num Buckets", HashTable->nbucket);
2649
    W.printNumber("Num Chains", HashTable->nchain);
2650
  }
2651

2652
  if (Err) {
2653
    reportUniqueWarning(std::move(Err));
2654
    return;
2655
  }
2656

2657
  W.printList("Buckets", HashTable->buckets());
2658
  W.printList("Chains", HashTable->chains());
2659
}
2660

2661
template <class ELFT>
2662
static Expected<ArrayRef<typename ELFT::Word>>
2663
getGnuHashTableChains(std::optional<DynRegionInfo> DynSymRegion,
2664
                      const typename ELFT::GnuHash *GnuHashTable) {
2665
  if (!DynSymRegion)
2666
    return createError("no dynamic symbol table found");
2667

2668
  ArrayRef<typename ELFT::Sym> DynSymTable =
2669
      DynSymRegion->template getAsArrayRef<typename ELFT::Sym>();
2670
  size_t NumSyms = DynSymTable.size();
2671
  if (!NumSyms)
2672
    return createError("the dynamic symbol table is empty");
2673

2674
  if (GnuHashTable->symndx < NumSyms)
2675
    return GnuHashTable->values(NumSyms);
2676

2677
  // A normal empty GNU hash table section produced by linker might have
2678
  // symndx set to the number of dynamic symbols + 1 (for the zero symbol)
2679
  // and have dummy null values in the Bloom filter and in the buckets
2680
  // vector (or no values at all). It happens because the value of symndx is not
2681
  // important for dynamic loaders when the GNU hash table is empty. They just
2682
  // skip the whole object during symbol lookup. In such cases, the symndx value
2683
  // is irrelevant and we should not report a warning.
2684
  ArrayRef<typename ELFT::Word> Buckets = GnuHashTable->buckets();
2685
  if (!llvm::all_of(Buckets, [](typename ELFT::Word V) { return V == 0; }))
2686
    return createError(
2687
        "the first hashed symbol index (" + Twine(GnuHashTable->symndx) +
2688
        ") is greater than or equal to the number of dynamic symbols (" +
2689
        Twine(NumSyms) + ")");
2690
  // There is no way to represent an array of (dynamic symbols count - symndx)
2691
  // length.
2692
  return ArrayRef<typename ELFT::Word>();
2693
}
2694

2695
template <typename ELFT>
2696
void ELFDumper<ELFT>::printGnuHashTable() {
2697
  DictScope D(W, "GnuHashTable");
2698
  if (!GnuHashTable)
2699
    return;
2700

2701
  bool IsHeaderValid;
2702
  Error Err = checkGNUHashTable<ELFT>(Obj, GnuHashTable, &IsHeaderValid);
2703
  if (IsHeaderValid) {
2704
    W.printNumber("Num Buckets", GnuHashTable->nbuckets);
2705
    W.printNumber("First Hashed Symbol Index", GnuHashTable->symndx);
2706
    W.printNumber("Num Mask Words", GnuHashTable->maskwords);
2707
    W.printNumber("Shift Count", GnuHashTable->shift2);
2708
  }
2709

2710
  if (Err) {
2711
    reportUniqueWarning(std::move(Err));
2712
    return;
2713
  }
2714

2715
  ArrayRef<typename ELFT::Off> BloomFilter = GnuHashTable->filter();
2716
  W.printHexList("Bloom Filter", BloomFilter);
2717

2718
  ArrayRef<Elf_Word> Buckets = GnuHashTable->buckets();
2719
  W.printList("Buckets", Buckets);
2720

2721
  Expected<ArrayRef<Elf_Word>> Chains =
2722
      getGnuHashTableChains<ELFT>(DynSymRegion, GnuHashTable);
2723
  if (!Chains) {
2724
    reportUniqueWarning("unable to dump 'Values' for the SHT_GNU_HASH "
2725
                        "section: " +
2726
                        toString(Chains.takeError()));
2727
    return;
2728
  }
2729

2730
  W.printHexList("Values", *Chains);
2731
}
2732

2733
template <typename ELFT> void ELFDumper<ELFT>::printHashHistograms() {
2734
  // Print histogram for the .hash section.
2735
  if (this->HashTable) {
2736
    if (Error E = checkHashTable<ELFT>(*this, this->HashTable))
2737
      this->reportUniqueWarning(std::move(E));
2738
    else
2739
      printHashHistogram(*this->HashTable);
2740
  }
2741

2742
  // Print histogram for the .gnu.hash section.
2743
  if (this->GnuHashTable) {
2744
    if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable))
2745
      this->reportUniqueWarning(std::move(E));
2746
    else
2747
      printGnuHashHistogram(*this->GnuHashTable);
2748
  }
2749
}
2750

2751
template <typename ELFT>
2752
void ELFDumper<ELFT>::printHashHistogram(const Elf_Hash &HashTable) const {
2753
  size_t NBucket = HashTable.nbucket;
2754
  size_t NChain = HashTable.nchain;
2755
  ArrayRef<Elf_Word> Buckets = HashTable.buckets();
2756
  ArrayRef<Elf_Word> Chains = HashTable.chains();
2757
  size_t TotalSyms = 0;
2758
  // If hash table is correct, we have at least chains with 0 length.
2759
  size_t MaxChain = 1;
2760

2761
  if (NChain == 0 || NBucket == 0)
2762
    return;
2763

2764
  std::vector<size_t> ChainLen(NBucket, 0);
2765
  // Go over all buckets and note chain lengths of each bucket (total
2766
  // unique chain lengths).
2767
  for (size_t B = 0; B < NBucket; ++B) {
2768
    BitVector Visited(NChain);
2769
    for (size_t C = Buckets[B]; C < NChain; C = Chains[C]) {
2770
      if (C == ELF::STN_UNDEF)
2771
          break;
2772
      if (Visited[C]) {
2773
          this->reportUniqueWarning(
2774
              ".hash section is invalid: bucket " + Twine(C) +
2775
              ": a cycle was detected in the linked chain");
2776
          break;
2777
      }
2778
      Visited[C] = true;
2779
      if (MaxChain <= ++ChainLen[B])
2780
          ++MaxChain;
2781
    }
2782
    TotalSyms += ChainLen[B];
2783
  }
2784

2785
  if (!TotalSyms)
2786
    return;
2787

2788
  std::vector<size_t> Count(MaxChain, 0);
2789
  // Count how long is the chain for each bucket.
2790
  for (size_t B = 0; B < NBucket; B++)
2791
    ++Count[ChainLen[B]];
2792
  // Print Number of buckets with each chain lengths and their cumulative
2793
  // coverage of the symbols.
2794
  printHashHistogramStats(NBucket, MaxChain, TotalSyms, Count, /*IsGnu=*/false);
2795
}
2796

2797
template <class ELFT>
2798
void ELFDumper<ELFT>::printGnuHashHistogram(
2799
    const Elf_GnuHash &GnuHashTable) const {
2800
  Expected<ArrayRef<Elf_Word>> ChainsOrErr =
2801
      getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHashTable);
2802
  if (!ChainsOrErr) {
2803
    this->reportUniqueWarning("unable to print the GNU hash table histogram: " +
2804
                              toString(ChainsOrErr.takeError()));
2805
    return;
2806
  }
2807

2808
  ArrayRef<Elf_Word> Chains = *ChainsOrErr;
2809
  size_t Symndx = GnuHashTable.symndx;
2810
  size_t TotalSyms = 0;
2811
  size_t MaxChain = 1;
2812

2813
  size_t NBucket = GnuHashTable.nbuckets;
2814
  if (Chains.empty() || NBucket == 0)
2815
    return;
2816

2817
  ArrayRef<Elf_Word> Buckets = GnuHashTable.buckets();
2818
  std::vector<size_t> ChainLen(NBucket, 0);
2819
  for (size_t B = 0; B < NBucket; ++B) {
2820
    if (!Buckets[B])
2821
      continue;
2822
    size_t Len = 1;
2823
    for (size_t C = Buckets[B] - Symndx;
2824
         C < Chains.size() && (Chains[C] & 1) == 0; ++C)
2825
      if (MaxChain < ++Len)
2826
          ++MaxChain;
2827
    ChainLen[B] = Len;
2828
    TotalSyms += Len;
2829
  }
2830
  ++MaxChain;
2831

2832
  if (!TotalSyms)
2833
    return;
2834

2835
  std::vector<size_t> Count(MaxChain, 0);
2836
  for (size_t B = 0; B < NBucket; ++B)
2837
    ++Count[ChainLen[B]];
2838
  // Print Number of buckets with each chain lengths and their cumulative
2839
  // coverage of the symbols.
2840
  printHashHistogramStats(NBucket, MaxChain, TotalSyms, Count, /*IsGnu=*/true);
2841
}
2842

2843
template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {
2844
  StringRef SOName = "<Not found>";
2845
  if (SONameOffset)
2846
    SOName = getDynamicString(*SONameOffset);
2847
  W.printString("LoadName", SOName);
2848
}
2849

2850
template <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() {
2851
  switch (Obj.getHeader().e_machine) {
2852
  case EM_HEXAGON:
2853
    printAttributes(ELF::SHT_HEXAGON_ATTRIBUTES,
2854
                    std::make_unique<HexagonAttributeParser>(&W),
2855
                    llvm::endianness::little);
2856
    break;
2857
  case EM_ARM:
2858
    printAttributes(
2859
        ELF::SHT_ARM_ATTRIBUTES, std::make_unique<ARMAttributeParser>(&W),
2860
        Obj.isLE() ? llvm::endianness::little : llvm::endianness::big);
2861
    break;
2862
  case EM_RISCV:
2863
    if (Obj.isLE())
2864
      printAttributes(ELF::SHT_RISCV_ATTRIBUTES,
2865
                      std::make_unique<RISCVAttributeParser>(&W),
2866
                      llvm::endianness::little);
2867
    else
2868
      reportUniqueWarning("attribute printing not implemented for big-endian "
2869
                          "RISC-V objects");
2870
    break;
2871
  case EM_MSP430:
2872
    printAttributes(ELF::SHT_MSP430_ATTRIBUTES,
2873
                    std::make_unique<MSP430AttributeParser>(&W),
2874
                    llvm::endianness::little);
2875
    break;
2876
  case EM_MIPS: {
2877
    printMipsABIFlags();
2878
    printMipsOptions();
2879
    printMipsReginfo();
2880
    MipsGOTParser<ELFT> Parser(*this);
2881
    if (Error E = Parser.findGOT(dynamic_table(), dynamic_symbols()))
2882
      reportUniqueWarning(std::move(E));
2883
    else if (!Parser.isGotEmpty())
2884
      printMipsGOT(Parser);
2885

2886
    if (Error E = Parser.findPLT(dynamic_table()))
2887
      reportUniqueWarning(std::move(E));
2888
    else if (!Parser.isPltEmpty())
2889
      printMipsPLT(Parser);
2890
    break;
2891
  }
2892
  default:
2893
    break;
2894
  }
2895
}
2896

2897
template <class ELFT>
2898
void ELFDumper<ELFT>::printAttributes(
2899
    unsigned AttrShType, std::unique_ptr<ELFAttributeParser> AttrParser,
2900
    llvm::endianness Endianness) {
2901
  assert((AttrShType != ELF::SHT_NULL) && AttrParser &&
2902
         "Incomplete ELF attribute implementation");
2903
  DictScope BA(W, "BuildAttributes");
2904
  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
2905
    if (Sec.sh_type != AttrShType)
2906
      continue;
2907

2908
    ArrayRef<uint8_t> Contents;
2909
    if (Expected<ArrayRef<uint8_t>> ContentOrErr =
2910
            Obj.getSectionContents(Sec)) {
2911
      Contents = *ContentOrErr;
2912
      if (Contents.empty()) {
2913
        reportUniqueWarning("the " + describe(Sec) + " is empty");
2914
        continue;
2915
      }
2916
    } else {
2917
      reportUniqueWarning("unable to read the content of the " + describe(Sec) +
2918
                          ": " + toString(ContentOrErr.takeError()));
2919
      continue;
2920
    }
2921

2922
    W.printHex("FormatVersion", Contents[0]);
2923

2924
    if (Error E = AttrParser->parse(Contents, Endianness))
2925
      reportUniqueWarning("unable to dump attributes from the " +
2926
                          describe(Sec) + ": " + toString(std::move(E)));
2927
  }
2928
}
2929

2930
namespace {
2931

2932
template <class ELFT> class MipsGOTParser {
2933
public:
2934
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
2935
  using Entry = typename ELFT::Addr;
2936
  using Entries = ArrayRef<Entry>;
2937

2938
  const bool IsStatic;
2939
  const ELFFile<ELFT> &Obj;
2940
  const ELFDumper<ELFT> &Dumper;
2941

2942
  MipsGOTParser(const ELFDumper<ELFT> &D);
2943
  Error findGOT(Elf_Dyn_Range DynTable, Elf_Sym_Range DynSyms);
2944
  Error findPLT(Elf_Dyn_Range DynTable);
2945

2946
  bool isGotEmpty() const { return GotEntries.empty(); }
2947
  bool isPltEmpty() const { return PltEntries.empty(); }
2948

2949
  uint64_t getGp() const;
2950

2951
  const Entry *getGotLazyResolver() const;
2952
  const Entry *getGotModulePointer() const;
2953
  const Entry *getPltLazyResolver() const;
2954
  const Entry *getPltModulePointer() const;
2955

2956
  Entries getLocalEntries() const;
2957
  Entries getGlobalEntries() const;
2958
  Entries getOtherEntries() const;
2959
  Entries getPltEntries() const;
2960

2961
  uint64_t getGotAddress(const Entry * E) const;
2962
  int64_t getGotOffset(const Entry * E) const;
2963
  const Elf_Sym *getGotSym(const Entry *E) const;
2964

2965
  uint64_t getPltAddress(const Entry * E) const;
2966
  const Elf_Sym *getPltSym(const Entry *E) const;
2967

2968
  StringRef getPltStrTable() const { return PltStrTable; }
2969
  const Elf_Shdr *getPltSymTable() const { return PltSymTable; }
2970

2971
private:
2972
  const Elf_Shdr *GotSec;
2973
  size_t LocalNum;
2974
  size_t GlobalNum;
2975

2976
  const Elf_Shdr *PltSec;
2977
  const Elf_Shdr *PltRelSec;
2978
  const Elf_Shdr *PltSymTable;
2979
  StringRef FileName;
2980

2981
  Elf_Sym_Range GotDynSyms;
2982
  StringRef PltStrTable;
2983

2984
  Entries GotEntries;
2985
  Entries PltEntries;
2986
};
2987

2988
} // end anonymous namespace
2989

2990
template <class ELFT>
2991
MipsGOTParser<ELFT>::MipsGOTParser(const ELFDumper<ELFT> &D)
2992
    : IsStatic(D.dynamic_table().empty()), Obj(D.getElfObject().getELFFile()),
2993
      Dumper(D), GotSec(nullptr), LocalNum(0), GlobalNum(0), PltSec(nullptr),
2994
      PltRelSec(nullptr), PltSymTable(nullptr),
2995
      FileName(D.getElfObject().getFileName()) {}
2996

2997
template <class ELFT>
2998
Error MipsGOTParser<ELFT>::findGOT(Elf_Dyn_Range DynTable,
2999
                                   Elf_Sym_Range DynSyms) {
3000
  // See "Global Offset Table" in Chapter 5 in the following document
3001
  // for detailed GOT description.
3002
  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
3003

3004
  // Find static GOT secton.
3005
  if (IsStatic) {
3006
    GotSec = Dumper.findSectionByName(".got");
3007
    if (!GotSec)
3008
      return Error::success();
3009

3010
    ArrayRef<uint8_t> Content =
3011
        unwrapOrError(FileName, Obj.getSectionContents(*GotSec));
3012
    GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),
3013
                         Content.size() / sizeof(Entry));
3014
    LocalNum = GotEntries.size();
3015
    return Error::success();
3016
  }
3017

3018
  // Lookup dynamic table tags which define the GOT layout.
3019
  std::optional<uint64_t> DtPltGot;
3020
  std::optional<uint64_t> DtLocalGotNum;
3021
  std::optional<uint64_t> DtGotSym;
3022
  for (const auto &Entry : DynTable) {
3023
    switch (Entry.getTag()) {
3024
    case ELF::DT_PLTGOT:
3025
      DtPltGot = Entry.getVal();
3026
      break;
3027
    case ELF::DT_MIPS_LOCAL_GOTNO:
3028
      DtLocalGotNum = Entry.getVal();
3029
      break;
3030
    case ELF::DT_MIPS_GOTSYM:
3031
      DtGotSym = Entry.getVal();
3032
      break;
3033
    }
3034
  }
3035

3036
  if (!DtPltGot && !DtLocalGotNum && !DtGotSym)
3037
    return Error::success();
3038

3039
  if (!DtPltGot)
3040
    return createError("cannot find PLTGOT dynamic tag");
3041
  if (!DtLocalGotNum)
3042
    return createError("cannot find MIPS_LOCAL_GOTNO dynamic tag");
3043
  if (!DtGotSym)
3044
    return createError("cannot find MIPS_GOTSYM dynamic tag");
3045

3046
  size_t DynSymTotal = DynSyms.size();
3047
  if (*DtGotSym > DynSymTotal)
3048
    return createError("DT_MIPS_GOTSYM value (" + Twine(*DtGotSym) +
3049
                       ") exceeds the number of dynamic symbols (" +
3050
                       Twine(DynSymTotal) + ")");
3051

3052
  GotSec = findNotEmptySectionByAddress(Obj, FileName, *DtPltGot);
3053
  if (!GotSec)
3054
    return createError("there is no non-empty GOT section at 0x" +
3055
                       Twine::utohexstr(*DtPltGot));
3056

3057
  LocalNum = *DtLocalGotNum;
3058
  GlobalNum = DynSymTotal - *DtGotSym;
3059

3060
  ArrayRef<uint8_t> Content =
3061
      unwrapOrError(FileName, Obj.getSectionContents(*GotSec));
3062
  GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()),
3063
                       Content.size() / sizeof(Entry));
3064
  GotDynSyms = DynSyms.drop_front(*DtGotSym);
3065

3066
  return Error::success();
3067
}
3068

3069
template <class ELFT>
3070
Error MipsGOTParser<ELFT>::findPLT(Elf_Dyn_Range DynTable) {
3071
  // Lookup dynamic table tags which define the PLT layout.
3072
  std::optional<uint64_t> DtMipsPltGot;
3073
  std::optional<uint64_t> DtJmpRel;
3074
  for (const auto &Entry : DynTable) {
3075
    switch (Entry.getTag()) {
3076
    case ELF::DT_MIPS_PLTGOT:
3077
      DtMipsPltGot = Entry.getVal();
3078
      break;
3079
    case ELF::DT_JMPREL:
3080
      DtJmpRel = Entry.getVal();
3081
      break;
3082
    }
3083
  }
3084

3085
  if (!DtMipsPltGot && !DtJmpRel)
3086
    return Error::success();
3087

3088
  // Find PLT section.
3089
  if (!DtMipsPltGot)
3090
    return createError("cannot find MIPS_PLTGOT dynamic tag");
3091
  if (!DtJmpRel)
3092
    return createError("cannot find JMPREL dynamic tag");
3093

3094
  PltSec = findNotEmptySectionByAddress(Obj, FileName, *DtMipsPltGot);
3095
  if (!PltSec)
3096
    return createError("there is no non-empty PLTGOT section at 0x" +
3097
                       Twine::utohexstr(*DtMipsPltGot));
3098

3099
  PltRelSec = findNotEmptySectionByAddress(Obj, FileName, *DtJmpRel);
3100
  if (!PltRelSec)
3101
    return createError("there is no non-empty RELPLT section at 0x" +
3102
                       Twine::utohexstr(*DtJmpRel));
3103

3104
  if (Expected<ArrayRef<uint8_t>> PltContentOrErr =
3105
          Obj.getSectionContents(*PltSec))
3106
    PltEntries =
3107
        Entries(reinterpret_cast<const Entry *>(PltContentOrErr->data()),
3108
                PltContentOrErr->size() / sizeof(Entry));
3109
  else
3110
    return createError("unable to read PLTGOT section content: " +
3111
                       toString(PltContentOrErr.takeError()));
3112

3113
  if (Expected<const Elf_Shdr *> PltSymTableOrErr =
3114
          Obj.getSection(PltRelSec->sh_link))
3115
    PltSymTable = *PltSymTableOrErr;
3116
  else
3117
    return createError("unable to get a symbol table linked to the " +
3118
                       describe(Obj, *PltRelSec) + ": " +
3119
                       toString(PltSymTableOrErr.takeError()));
3120

3121
  if (Expected<StringRef> StrTabOrErr =
3122
          Obj.getStringTableForSymtab(*PltSymTable))
3123
    PltStrTable = *StrTabOrErr;
3124
  else
3125
    return createError("unable to get a string table for the " +
3126
                       describe(Obj, *PltSymTable) + ": " +
3127
                       toString(StrTabOrErr.takeError()));
3128

3129
  return Error::success();
3130
}
3131

3132
template <class ELFT> uint64_t MipsGOTParser<ELFT>::getGp() const {
3133
  return GotSec->sh_addr + 0x7ff0;
3134
}
3135

3136
template <class ELFT>
3137
const typename MipsGOTParser<ELFT>::Entry *
3138
MipsGOTParser<ELFT>::getGotLazyResolver() const {
3139
  return LocalNum > 0 ? &GotEntries[0] : nullptr;
3140
}
3141

3142
template <class ELFT>
3143
const typename MipsGOTParser<ELFT>::Entry *
3144
MipsGOTParser<ELFT>::getGotModulePointer() const {
3145
  if (LocalNum < 2)
3146
    return nullptr;
3147
  const Entry &E = GotEntries[1];
3148
  if ((E >> (sizeof(Entry) * 8 - 1)) == 0)
3149
    return nullptr;
3150
  return &E;
3151
}
3152

3153
template <class ELFT>
3154
typename MipsGOTParser<ELFT>::Entries
3155
MipsGOTParser<ELFT>::getLocalEntries() const {
3156
  size_t Skip = getGotModulePointer() ? 2 : 1;
3157
  if (LocalNum - Skip <= 0)
3158
    return Entries();
3159
  return GotEntries.slice(Skip, LocalNum - Skip);
3160
}
3161

3162
template <class ELFT>
3163
typename MipsGOTParser<ELFT>::Entries
3164
MipsGOTParser<ELFT>::getGlobalEntries() const {
3165
  if (GlobalNum == 0)
3166
    return Entries();
3167
  return GotEntries.slice(LocalNum, GlobalNum);
3168
}
3169

3170
template <class ELFT>
3171
typename MipsGOTParser<ELFT>::Entries
3172
MipsGOTParser<ELFT>::getOtherEntries() const {
3173
  size_t OtherNum = GotEntries.size() - LocalNum - GlobalNum;
3174
  if (OtherNum == 0)
3175
    return Entries();
3176
  return GotEntries.slice(LocalNum + GlobalNum, OtherNum);
3177
}
3178

3179
template <class ELFT>
3180
uint64_t MipsGOTParser<ELFT>::getGotAddress(const Entry *E) const {
3181
  int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);
3182
  return GotSec->sh_addr + Offset;
3183
}
3184

3185
template <class ELFT>
3186
int64_t MipsGOTParser<ELFT>::getGotOffset(const Entry *E) const {
3187
  int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry);
3188
  return Offset - 0x7ff0;
3189
}
3190

3191
template <class ELFT>
3192
const typename MipsGOTParser<ELFT>::Elf_Sym *
3193
MipsGOTParser<ELFT>::getGotSym(const Entry *E) const {
3194
  int64_t Offset = std::distance(GotEntries.data(), E);
3195
  return &GotDynSyms[Offset - LocalNum];
3196
}
3197

3198
template <class ELFT>
3199
const typename MipsGOTParser<ELFT>::Entry *
3200
MipsGOTParser<ELFT>::getPltLazyResolver() const {
3201
  return PltEntries.empty() ? nullptr : &PltEntries[0];
3202
}
3203

3204
template <class ELFT>
3205
const typename MipsGOTParser<ELFT>::Entry *
3206
MipsGOTParser<ELFT>::getPltModulePointer() const {
3207
  return PltEntries.size() < 2 ? nullptr : &PltEntries[1];
3208
}
3209

3210
template <class ELFT>
3211
typename MipsGOTParser<ELFT>::Entries
3212
MipsGOTParser<ELFT>::getPltEntries() const {
3213
  if (PltEntries.size() <= 2)
3214
    return Entries();
3215
  return PltEntries.slice(2, PltEntries.size() - 2);
3216
}
3217

3218
template <class ELFT>
3219
uint64_t MipsGOTParser<ELFT>::getPltAddress(const Entry *E) const {
3220
  int64_t Offset = std::distance(PltEntries.data(), E) * sizeof(Entry);
3221
  return PltSec->sh_addr + Offset;
3222
}
3223

3224
template <class ELFT>
3225
const typename MipsGOTParser<ELFT>::Elf_Sym *
3226
MipsGOTParser<ELFT>::getPltSym(const Entry *E) const {
3227
  int64_t Offset = std::distance(getPltEntries().data(), E);
3228
  if (PltRelSec->sh_type == ELF::SHT_REL) {
3229
    Elf_Rel_Range Rels = unwrapOrError(FileName, Obj.rels(*PltRelSec));
3230
    return unwrapOrError(FileName,
3231
                         Obj.getRelocationSymbol(Rels[Offset], PltSymTable));
3232
  } else {
3233
    Elf_Rela_Range Rels = unwrapOrError(FileName, Obj.relas(*PltRelSec));
3234
    return unwrapOrError(FileName,
3235
                         Obj.getRelocationSymbol(Rels[Offset], PltSymTable));
3236
  }
3237
}
3238

3239
const EnumEntry<unsigned> ElfMipsISAExtType[] = {
3240
  {"None",                    Mips::AFL_EXT_NONE},
3241
  {"Broadcom SB-1",           Mips::AFL_EXT_SB1},
3242
  {"Cavium Networks Octeon",  Mips::AFL_EXT_OCTEON},
3243
  {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2},
3244
  {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP},
3245
  {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3},
3246
  {"LSI R4010",               Mips::AFL_EXT_4010},
3247
  {"Loongson 2E",             Mips::AFL_EXT_LOONGSON_2E},
3248
  {"Loongson 2F",             Mips::AFL_EXT_LOONGSON_2F},
3249
  {"Loongson 3A",             Mips::AFL_EXT_LOONGSON_3A},
3250
  {"MIPS R4650",              Mips::AFL_EXT_4650},
3251
  {"MIPS R5900",              Mips::AFL_EXT_5900},
3252
  {"MIPS R10000",             Mips::AFL_EXT_10000},
3253
  {"NEC VR4100",              Mips::AFL_EXT_4100},
3254
  {"NEC VR4111/VR4181",       Mips::AFL_EXT_4111},
3255
  {"NEC VR4120",              Mips::AFL_EXT_4120},
3256
  {"NEC VR5400",              Mips::AFL_EXT_5400},
3257
  {"NEC VR5500",              Mips::AFL_EXT_5500},
3258
  {"RMI Xlr",                 Mips::AFL_EXT_XLR},
3259
  {"Toshiba R3900",           Mips::AFL_EXT_3900}
3260
};
3261

3262
const EnumEntry<unsigned> ElfMipsASEFlags[] = {
3263
  {"DSP",                Mips::AFL_ASE_DSP},
3264
  {"DSPR2",              Mips::AFL_ASE_DSPR2},
3265
  {"Enhanced VA Scheme", Mips::AFL_ASE_EVA},
3266
  {"MCU",                Mips::AFL_ASE_MCU},
3267
  {"MDMX",               Mips::AFL_ASE_MDMX},
3268
  {"MIPS-3D",            Mips::AFL_ASE_MIPS3D},
3269
  {"MT",                 Mips::AFL_ASE_MT},
3270
  {"SmartMIPS",          Mips::AFL_ASE_SMARTMIPS},
3271
  {"VZ",                 Mips::AFL_ASE_VIRT},
3272
  {"MSA",                Mips::AFL_ASE_MSA},
3273
  {"MIPS16",             Mips::AFL_ASE_MIPS16},
3274
  {"microMIPS",          Mips::AFL_ASE_MICROMIPS},
3275
  {"XPA",                Mips::AFL_ASE_XPA},
3276
  {"CRC",                Mips::AFL_ASE_CRC},
3277
  {"GINV",               Mips::AFL_ASE_GINV},
3278
};
3279

3280
const EnumEntry<unsigned> ElfMipsFpABIType[] = {
3281
  {"Hard or soft float",                  Mips::Val_GNU_MIPS_ABI_FP_ANY},
3282
  {"Hard float (double precision)",       Mips::Val_GNU_MIPS_ABI_FP_DOUBLE},
3283
  {"Hard float (single precision)",       Mips::Val_GNU_MIPS_ABI_FP_SINGLE},
3284
  {"Soft float",                          Mips::Val_GNU_MIPS_ABI_FP_SOFT},
3285
  {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)",
3286
   Mips::Val_GNU_MIPS_ABI_FP_OLD_64},
3287
  {"Hard float (32-bit CPU, Any FPU)",    Mips::Val_GNU_MIPS_ABI_FP_XX},
3288
  {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64},
3289
  {"Hard float compat (32-bit CPU, 64-bit FPU)",
3290
   Mips::Val_GNU_MIPS_ABI_FP_64A}
3291
};
3292

3293
static const EnumEntry<unsigned> ElfMipsFlags1[] {
3294
  {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG},
3295
};
3296

3297
static int getMipsRegisterSize(uint8_t Flag) {
3298
  switch (Flag) {
3299
  case Mips::AFL_REG_NONE:
3300
    return 0;
3301
  case Mips::AFL_REG_32:
3302
    return 32;
3303
  case Mips::AFL_REG_64:
3304
    return 64;
3305
  case Mips::AFL_REG_128:
3306
    return 128;
3307
  default:
3308
    return -1;
3309
  }
3310
}
3311

3312
template <class ELFT>
3313
static void printMipsReginfoData(ScopedPrinter &W,
3314
                                 const Elf_Mips_RegInfo<ELFT> &Reginfo) {
3315
  W.printHex("GP", Reginfo.ri_gp_value);
3316
  W.printHex("General Mask", Reginfo.ri_gprmask);
3317
  W.printHex("Co-Proc Mask0", Reginfo.ri_cprmask[0]);
3318
  W.printHex("Co-Proc Mask1", Reginfo.ri_cprmask[1]);
3319
  W.printHex("Co-Proc Mask2", Reginfo.ri_cprmask[2]);
3320
  W.printHex("Co-Proc Mask3", Reginfo.ri_cprmask[3]);
3321
}
3322

3323
template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
3324
  const Elf_Shdr *RegInfoSec = findSectionByName(".reginfo");
3325
  if (!RegInfoSec) {
3326
    W.startLine() << "There is no .reginfo section in the file.\n";
3327
    return;
3328
  }
3329

3330
  Expected<ArrayRef<uint8_t>> ContentsOrErr =
3331
      Obj.getSectionContents(*RegInfoSec);
3332
  if (!ContentsOrErr) {
3333
    this->reportUniqueWarning(
3334
        "unable to read the content of the .reginfo section (" +
3335
        describe(*RegInfoSec) + "): " + toString(ContentsOrErr.takeError()));
3336
    return;
3337
  }
3338

3339
  if (ContentsOrErr->size() < sizeof(Elf_Mips_RegInfo<ELFT>)) {
3340
    this->reportUniqueWarning("the .reginfo section has an invalid size (0x" +
3341
                              Twine::utohexstr(ContentsOrErr->size()) + ")");
3342
    return;
3343
  }
3344

3345
  DictScope GS(W, "MIPS RegInfo");
3346
  printMipsReginfoData(W, *reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(
3347
                              ContentsOrErr->data()));
3348
}
3349

3350
template <class ELFT>
3351
static Expected<const Elf_Mips_Options<ELFT> *>
3352
readMipsOptions(const uint8_t *SecBegin, ArrayRef<uint8_t> &SecData,
3353
                bool &IsSupported) {
3354
  if (SecData.size() < sizeof(Elf_Mips_Options<ELFT>))
3355
    return createError("the .MIPS.options section has an invalid size (0x" +
3356
                       Twine::utohexstr(SecData.size()) + ")");
3357

3358
  const Elf_Mips_Options<ELFT> *O =
3359
      reinterpret_cast<const Elf_Mips_Options<ELFT> *>(SecData.data());
3360
  const uint8_t Size = O->size;
3361
  if (Size > SecData.size()) {
3362
    const uint64_t Offset = SecData.data() - SecBegin;
3363
    const uint64_t SecSize = Offset + SecData.size();
3364
    return createError("a descriptor of size 0x" + Twine::utohexstr(Size) +
3365
                       " at offset 0x" + Twine::utohexstr(Offset) +
3366
                       " goes past the end of the .MIPS.options "
3367
                       "section of size 0x" +
3368
                       Twine::utohexstr(SecSize));
3369
  }
3370

3371
  IsSupported = O->kind == ODK_REGINFO;
3372
  const size_t ExpectedSize =
3373
      sizeof(Elf_Mips_Options<ELFT>) + sizeof(Elf_Mips_RegInfo<ELFT>);
3374

3375
  if (IsSupported)
3376
    if (Size < ExpectedSize)
3377
      return createError(
3378
          "a .MIPS.options entry of kind " +
3379
          Twine(getElfMipsOptionsOdkType(O->kind)) +
3380
          " has an invalid size (0x" + Twine::utohexstr(Size) +
3381
          "), the expected size is 0x" + Twine::utohexstr(ExpectedSize));
3382

3383
  SecData = SecData.drop_front(Size);
3384
  return O;
3385
}
3386

3387
template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
3388
  const Elf_Shdr *MipsOpts = findSectionByName(".MIPS.options");
3389
  if (!MipsOpts) {
3390
    W.startLine() << "There is no .MIPS.options section in the file.\n";
3391
    return;
3392
  }
3393

3394
  DictScope GS(W, "MIPS Options");
3395

3396
  ArrayRef<uint8_t> Data =
3397
      unwrapOrError(ObjF.getFileName(), Obj.getSectionContents(*MipsOpts));
3398
  const uint8_t *const SecBegin = Data.begin();
3399
  while (!Data.empty()) {
3400
    bool IsSupported;
3401
    Expected<const Elf_Mips_Options<ELFT> *> OptsOrErr =
3402
        readMipsOptions<ELFT>(SecBegin, Data, IsSupported);
3403
    if (!OptsOrErr) {
3404
      reportUniqueWarning(OptsOrErr.takeError());
3405
      break;
3406
    }
3407

3408
    unsigned Kind = (*OptsOrErr)->kind;
3409
    const char *Type = getElfMipsOptionsOdkType(Kind);
3410
    if (!IsSupported) {
3411
      W.startLine() << "Unsupported MIPS options tag: " << Type << " (" << Kind
3412
                    << ")\n";
3413
      continue;
3414
    }
3415

3416
    DictScope GS(W, Type);
3417
    if (Kind == ODK_REGINFO)
3418
      printMipsReginfoData(W, (*OptsOrErr)->getRegInfo());
3419
    else
3420
      llvm_unreachable("unexpected .MIPS.options section descriptor kind");
3421
  }
3422
}
3423

3424
template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
3425
  const Elf_Shdr *StackMapSection = findSectionByName(".llvm_stackmaps");
3426
  if (!StackMapSection)
3427
    return;
3428

3429
  auto Warn = [&](Error &&E) {
3430
    this->reportUniqueWarning("unable to read the stack map from " +
3431
                              describe(*StackMapSection) + ": " +
3432
                              toString(std::move(E)));
3433
  };
3434

3435
  Expected<ArrayRef<uint8_t>> ContentOrErr =
3436
      Obj.getSectionContents(*StackMapSection);
3437
  if (!ContentOrErr) {
3438
    Warn(ContentOrErr.takeError());
3439
    return;
3440
  }
3441

3442
  if (Error E =
3443
          StackMapParser<ELFT::Endianness>::validateHeader(*ContentOrErr)) {
3444
    Warn(std::move(E));
3445
    return;
3446
  }
3447

3448
  prettyPrintStackMap(W, StackMapParser<ELFT::Endianness>(*ContentOrErr));
3449
}
3450

3451
template <class ELFT>
3452
void ELFDumper<ELFT>::printReloc(const Relocation<ELFT> &R, unsigned RelIndex,
3453
                                 const Elf_Shdr &Sec, const Elf_Shdr *SymTab) {
3454
  Expected<RelSymbol<ELFT>> Target = getRelocationTarget(R, SymTab);
3455
  if (!Target)
3456
    reportUniqueWarning("unable to print relocation " + Twine(RelIndex) +
3457
                        " in " + describe(Sec) + ": " +
3458
                        toString(Target.takeError()));
3459
  else
3460
    printRelRelaReloc(R, *Target);
3461
}
3462

3463
template <class ELFT>
3464
std::vector<EnumEntry<unsigned>>
3465
ELFDumper<ELFT>::getOtherFlagsFromSymbol(const Elf_Ehdr &Header,
3466
                                         const Elf_Sym &Symbol) const {
3467
  std::vector<EnumEntry<unsigned>> SymOtherFlags(std::begin(ElfSymOtherFlags),
3468
                                                 std::end(ElfSymOtherFlags));
3469
  if (Header.e_machine == EM_MIPS) {
3470
    // Someone in their infinite wisdom decided to make STO_MIPS_MIPS16
3471
    // flag overlap with other ST_MIPS_xxx flags. So consider both
3472
    // cases separately.
3473
    if ((Symbol.st_other & STO_MIPS_MIPS16) == STO_MIPS_MIPS16)
3474
      SymOtherFlags.insert(SymOtherFlags.end(),
3475
                           std::begin(ElfMips16SymOtherFlags),
3476
                           std::end(ElfMips16SymOtherFlags));
3477
    else
3478
      SymOtherFlags.insert(SymOtherFlags.end(),
3479
                           std::begin(ElfMipsSymOtherFlags),
3480
                           std::end(ElfMipsSymOtherFlags));
3481
  } else if (Header.e_machine == EM_AARCH64) {
3482
    SymOtherFlags.insert(SymOtherFlags.end(),
3483
                         std::begin(ElfAArch64SymOtherFlags),
3484
                         std::end(ElfAArch64SymOtherFlags));
3485
  } else if (Header.e_machine == EM_RISCV) {
3486
    SymOtherFlags.insert(SymOtherFlags.end(), std::begin(ElfRISCVSymOtherFlags),
3487
                         std::end(ElfRISCVSymOtherFlags));
3488
  }
3489
  return SymOtherFlags;
3490
}
3491

3492
static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
3493
                               StringRef Str2) {
3494
  OS.PadToColumn(2u);
3495
  OS << Str1;
3496
  OS.PadToColumn(37u);
3497
  OS << Str2 << "\n";
3498
  OS.flush();
3499
}
3500

3501
template <class ELFT>
3502
static std::string getSectionHeadersNumString(const ELFFile<ELFT> &Obj,
3503
                                              StringRef FileName) {
3504
  const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();
3505
  if (ElfHeader.e_shnum != 0)
3506
    return to_string(ElfHeader.e_shnum);
3507

3508
  Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
3509
  if (!ArrOrErr) {
3510
    // In this case we can ignore an error, because we have already reported a
3511
    // warning about the broken section header table earlier.
3512
    consumeError(ArrOrErr.takeError());
3513
    return "<?>";
3514
  }
3515

3516
  if (ArrOrErr->empty())
3517
    return "0";
3518
  return "0 (" + to_string((*ArrOrErr)[0].sh_size) + ")";
3519
}
3520

3521
template <class ELFT>
3522
static std::string getSectionHeaderTableIndexString(const ELFFile<ELFT> &Obj,
3523
                                                    StringRef FileName) {
3524
  const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();
3525
  if (ElfHeader.e_shstrndx != SHN_XINDEX)
3526
    return to_string(ElfHeader.e_shstrndx);
3527

3528
  Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
3529
  if (!ArrOrErr) {
3530
    // In this case we can ignore an error, because we have already reported a
3531
    // warning about the broken section header table earlier.
3532
    consumeError(ArrOrErr.takeError());
3533
    return "<?>";
3534
  }
3535

3536
  if (ArrOrErr->empty())
3537
    return "65535 (corrupt: out of range)";
3538
  return to_string(ElfHeader.e_shstrndx) + " (" +
3539
         to_string((*ArrOrErr)[0].sh_link) + ")";
3540
}
3541

3542
static const EnumEntry<unsigned> *getObjectFileEnumEntry(unsigned Type) {
3543
  auto It = llvm::find_if(ElfObjectFileType, [&](const EnumEntry<unsigned> &E) {
3544
    return E.Value == Type;
3545
  });
3546
  if (It != ArrayRef(ElfObjectFileType).end())
3547
    return It;
3548
  return nullptr;
3549
}
3550

3551
template <class ELFT>
3552
void GNUELFDumper<ELFT>::printFileSummary(StringRef FileStr, ObjectFile &Obj,
3553
                                          ArrayRef<std::string> InputFilenames,
3554
                                          const Archive *A) {
3555
  if (InputFilenames.size() > 1 || A) {
3556
    this->W.startLine() << "\n";
3557
    this->W.printString("File", FileStr);
3558
  }
3559
}
3560

3561
template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() {
3562
  const Elf_Ehdr &e = this->Obj.getHeader();
3563
  OS << "ELF Header:\n";
3564
  OS << "  Magic:  ";
3565
  std::string Str;
3566
  for (int i = 0; i < ELF::EI_NIDENT; i++)
3567
    OS << format(" %02x", static_cast<int>(e.e_ident[i]));
3568
  OS << "\n";
3569
  Str = enumToString(e.e_ident[ELF::EI_CLASS], ArrayRef(ElfClass));
3570
  printFields(OS, "Class:", Str);
3571
  Str = enumToString(e.e_ident[ELF::EI_DATA], ArrayRef(ElfDataEncoding));
3572
  printFields(OS, "Data:", Str);
3573
  OS.PadToColumn(2u);
3574
  OS << "Version:";
3575
  OS.PadToColumn(37u);
3576
  OS << utohexstr(e.e_ident[ELF::EI_VERSION]);
3577
  if (e.e_version == ELF::EV_CURRENT)
3578
    OS << " (current)";
3579
  OS << "\n";
3580
  auto OSABI = ArrayRef(ElfOSABI);
3581
  if (e.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH &&
3582
      e.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) {
3583
    switch (e.e_machine) {
3584
    case ELF::EM_ARM:
3585
      OSABI = ArrayRef(ARMElfOSABI);
3586
      break;
3587
    case ELF::EM_AMDGPU:
3588
      OSABI = ArrayRef(AMDGPUElfOSABI);
3589
      break;
3590
    default:
3591
      break;
3592
    }
3593
  }
3594
  Str = enumToString(e.e_ident[ELF::EI_OSABI], OSABI);
3595
  printFields(OS, "OS/ABI:", Str);
3596
  printFields(OS,
3597
              "ABI Version:", std::to_string(e.e_ident[ELF::EI_ABIVERSION]));
3598

3599
  if (const EnumEntry<unsigned> *E = getObjectFileEnumEntry(e.e_type)) {
3600
    Str = E->AltName.str();
3601
  } else {
3602
    if (e.e_type >= ET_LOPROC)
3603
      Str = "Processor Specific: (" + utohexstr(e.e_type, /*LowerCase=*/true) + ")";
3604
    else if (e.e_type >= ET_LOOS)
3605
      Str = "OS Specific: (" + utohexstr(e.e_type, /*LowerCase=*/true) + ")";
3606
    else
3607
      Str = "<unknown>: " + utohexstr(e.e_type, /*LowerCase=*/true);
3608
  }
3609
  printFields(OS, "Type:", Str);
3610

3611
  Str = enumToString(e.e_machine, ArrayRef(ElfMachineType));
3612
  printFields(OS, "Machine:", Str);
3613
  Str = "0x" + utohexstr(e.e_version);
3614
  printFields(OS, "Version:", Str);
3615
  Str = "0x" + utohexstr(e.e_entry);
3616
  printFields(OS, "Entry point address:", Str);
3617
  Str = to_string(e.e_phoff) + " (bytes into file)";
3618
  printFields(OS, "Start of program headers:", Str);
3619
  Str = to_string(e.e_shoff) + " (bytes into file)";
3620
  printFields(OS, "Start of section headers:", Str);
3621
  std::string ElfFlags;
3622
  if (e.e_machine == EM_MIPS)
3623
    ElfFlags = printFlags(
3624
        e.e_flags, ArrayRef(ElfHeaderMipsFlags), unsigned(ELF::EF_MIPS_ARCH),
3625
        unsigned(ELF::EF_MIPS_ABI), unsigned(ELF::EF_MIPS_MACH));
3626
  else if (e.e_machine == EM_RISCV)
3627
    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderRISCVFlags));
3628
  else if (e.e_machine == EM_AVR)
3629
    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderAVRFlags),
3630
                          unsigned(ELF::EF_AVR_ARCH_MASK));
3631
  else if (e.e_machine == EM_LOONGARCH)
3632
    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderLoongArchFlags),
3633
                          unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK),
3634
                          unsigned(ELF::EF_LOONGARCH_OBJABI_MASK));
3635
  else if (e.e_machine == EM_XTENSA)
3636
    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderXtensaFlags),
3637
                          unsigned(ELF::EF_XTENSA_MACH));
3638
  else if (e.e_machine == EM_CUDA)
3639
    ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderNVPTXFlags),
3640
                          unsigned(ELF::EF_CUDA_SM));
3641
  else if (e.e_machine == EM_AMDGPU) {
3642
    switch (e.e_ident[ELF::EI_ABIVERSION]) {
3643
    default:
3644
      break;
3645
    case 0:
3646
      // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags.
3647
      [[fallthrough]];
3648
    case ELF::ELFABIVERSION_AMDGPU_HSA_V3:
3649
      ElfFlags =
3650
          printFlags(e.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion3),
3651
                     unsigned(ELF::EF_AMDGPU_MACH));
3652
      break;
3653
    case ELF::ELFABIVERSION_AMDGPU_HSA_V4:
3654
    case ELF::ELFABIVERSION_AMDGPU_HSA_V5:
3655
      ElfFlags =
3656
          printFlags(e.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),
3657
                     unsigned(ELF::EF_AMDGPU_MACH),
3658
                     unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),
3659
                     unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4));
3660
      break;
3661
    case ELF::ELFABIVERSION_AMDGPU_HSA_V6: {
3662
      ElfFlags =
3663
          printFlags(e.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),
3664
                     unsigned(ELF::EF_AMDGPU_MACH),
3665
                     unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),
3666
                     unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4));
3667
      if (auto GenericV = e.e_flags & ELF::EF_AMDGPU_GENERIC_VERSION) {
3668
        ElfFlags +=
3669
            ", generic_v" +
3670
            to_string(GenericV >> ELF::EF_AMDGPU_GENERIC_VERSION_OFFSET);
3671
      }
3672
    } break;
3673
    }
3674
  }
3675
  Str = "0x" + utohexstr(e.e_flags);
3676
  if (!ElfFlags.empty())
3677
    Str = Str + ", " + ElfFlags;
3678
  printFields(OS, "Flags:", Str);
3679
  Str = to_string(e.e_ehsize) + " (bytes)";
3680
  printFields(OS, "Size of this header:", Str);
3681
  Str = to_string(e.e_phentsize) + " (bytes)";
3682
  printFields(OS, "Size of program headers:", Str);
3683
  Str = to_string(e.e_phnum);
3684
  printFields(OS, "Number of program headers:", Str);
3685
  Str = to_string(e.e_shentsize) + " (bytes)";
3686
  printFields(OS, "Size of section headers:", Str);
3687
  Str = getSectionHeadersNumString(this->Obj, this->FileName);
3688
  printFields(OS, "Number of section headers:", Str);
3689
  Str = getSectionHeaderTableIndexString(this->Obj, this->FileName);
3690
  printFields(OS, "Section header string table index:", Str);
3691
}
3692

3693
template <class ELFT> std::vector<GroupSection> ELFDumper<ELFT>::getGroups() {
3694
  auto GetSignature = [&](const Elf_Sym &Sym, unsigned SymNdx,
3695
                          const Elf_Shdr &Symtab) -> StringRef {
3696
    Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(Symtab);
3697
    if (!StrTableOrErr) {
3698
      reportUniqueWarning("unable to get the string table for " +
3699
                          describe(Symtab) + ": " +
3700
                          toString(StrTableOrErr.takeError()));
3701
      return "<?>";
3702
    }
3703

3704
    StringRef Strings = *StrTableOrErr;
3705
    if (Sym.st_name >= Strings.size()) {
3706
      reportUniqueWarning("unable to get the name of the symbol with index " +
3707
                          Twine(SymNdx) + ": st_name (0x" +
3708
                          Twine::utohexstr(Sym.st_name) +
3709
                          ") is past the end of the string table of size 0x" +
3710
                          Twine::utohexstr(Strings.size()));
3711
      return "<?>";
3712
    }
3713

3714
    return StrTableOrErr->data() + Sym.st_name;
3715
  };
3716

3717
  std::vector<GroupSection> Ret;
3718
  uint64_t I = 0;
3719
  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
3720
    ++I;
3721
    if (Sec.sh_type != ELF::SHT_GROUP)
3722
      continue;
3723

3724
    StringRef Signature = "<?>";
3725
    if (Expected<const Elf_Shdr *> SymtabOrErr = Obj.getSection(Sec.sh_link)) {
3726
      if (Expected<const Elf_Sym *> SymOrErr =
3727
              Obj.template getEntry<Elf_Sym>(**SymtabOrErr, Sec.sh_info))
3728
        Signature = GetSignature(**SymOrErr, Sec.sh_info, **SymtabOrErr);
3729
      else
3730
        reportUniqueWarning("unable to get the signature symbol for " +
3731
                            describe(Sec) + ": " +
3732
                            toString(SymOrErr.takeError()));
3733
    } else {
3734
      reportUniqueWarning("unable to get the symbol table for " +
3735
                          describe(Sec) + ": " +
3736
                          toString(SymtabOrErr.takeError()));
3737
    }
3738

3739
    ArrayRef<Elf_Word> Data;
3740
    if (Expected<ArrayRef<Elf_Word>> ContentsOrErr =
3741
            Obj.template getSectionContentsAsArray<Elf_Word>(Sec)) {
3742
      if (ContentsOrErr->empty())
3743
        reportUniqueWarning("unable to read the section group flag from the " +
3744
                            describe(Sec) + ": the section is empty");
3745
      else
3746
        Data = *ContentsOrErr;
3747
    } else {
3748
      reportUniqueWarning("unable to get the content of the " + describe(Sec) +
3749
                          ": " + toString(ContentsOrErr.takeError()));
3750
    }
3751

3752
    Ret.push_back({getPrintableSectionName(Sec),
3753
                   maybeDemangle(Signature),
3754
                   Sec.sh_name,
3755
                   I - 1,
3756
                   Sec.sh_link,
3757
                   Sec.sh_info,
3758
                   Data.empty() ? Elf_Word(0) : Data[0],
3759
                   {}});
3760

3761
    if (Data.empty())
3762
      continue;
3763

3764
    std::vector<GroupMember> &GM = Ret.back().Members;
3765
    for (uint32_t Ndx : Data.slice(1)) {
3766
      if (Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(Ndx)) {
3767
        GM.push_back({getPrintableSectionName(**SecOrErr), Ndx});
3768
      } else {
3769
        reportUniqueWarning("unable to get the section with index " +
3770
                            Twine(Ndx) + " when dumping the " + describe(Sec) +
3771
                            ": " + toString(SecOrErr.takeError()));
3772
        GM.push_back({"<?>", Ndx});
3773
      }
3774
    }
3775
  }
3776
  return Ret;
3777
}
3778

3779
static DenseMap<uint64_t, const GroupSection *>
3780
mapSectionsToGroups(ArrayRef<GroupSection> Groups) {
3781
  DenseMap<uint64_t, const GroupSection *> Ret;
3782
  for (const GroupSection &G : Groups)
3783
    for (const GroupMember &GM : G.Members)
3784
      Ret.insert({GM.Index, &G});
3785
  return Ret;
3786
}
3787

3788
template <class ELFT> void GNUELFDumper<ELFT>::printGroupSections() {
3789
  std::vector<GroupSection> V = this->getGroups();
3790
  DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
3791
  for (const GroupSection &G : V) {
3792
    OS << "\n"
3793
       << getGroupType(G.Type) << " group section ["
3794
       << format_decimal(G.Index, 5) << "] `" << G.Name << "' [" << G.Signature
3795
       << "] contains " << G.Members.size() << " sections:\n"
3796
       << "   [Index]    Name\n";
3797
    for (const GroupMember &GM : G.Members) {
3798
      const GroupSection *MainGroup = Map[GM.Index];
3799
      if (MainGroup != &G)
3800
        this->reportUniqueWarning(
3801
            "section with index " + Twine(GM.Index) +
3802
            ", included in the group section with index " +
3803
            Twine(MainGroup->Index) +
3804
            ", was also found in the group section with index " +
3805
            Twine(G.Index));
3806
      OS << "   [" << format_decimal(GM.Index, 5) << "]   " << GM.Name << "\n";
3807
    }
3808
  }
3809

3810
  if (V.empty())
3811
    OS << "There are no section groups in this file.\n";
3812
}
3813

3814
template <class ELFT>
3815
void GNUELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,
3816
                                           const RelSymbol<ELFT> &RelSym) {
3817
  // First two fields are bit width dependent. The rest of them are fixed width.
3818
  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
3819
  Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
3820
  unsigned Width = ELFT::Is64Bits ? 16 : 8;
3821

3822
  Fields[0].Str = to_string(format_hex_no_prefix(R.Offset, Width));
3823
  Fields[1].Str = to_string(format_hex_no_prefix(R.Info, Width));
3824

3825
  SmallString<32> RelocName;
3826
  this->Obj.getRelocationTypeName(R.Type, RelocName);
3827
  Fields[2].Str = RelocName.c_str();
3828

3829
  if (RelSym.Sym)
3830
    Fields[3].Str =
3831
        to_string(format_hex_no_prefix(RelSym.Sym->getValue(), Width));
3832
  if (RelSym.Sym && RelSym.Name.empty())
3833
    Fields[4].Str = "<null>";
3834
  else
3835
    Fields[4].Str = std::string(RelSym.Name);
3836

3837
  for (const Field &F : Fields)
3838
    printField(F);
3839

3840
  std::string Addend;
3841
  if (std::optional<int64_t> A = R.Addend) {
3842
    int64_t RelAddend = *A;
3843
    if (!Fields[4].Str.empty()) {
3844
      if (RelAddend < 0) {
3845
        Addend = " - ";
3846
        RelAddend = -static_cast<uint64_t>(RelAddend);
3847
      } else {
3848
        Addend = " + ";
3849
      }
3850
    }
3851
    Addend += utohexstr(RelAddend, /*LowerCase=*/true);
3852
  }
3853
  OS << Addend << "\n";
3854
}
3855

3856
template <class ELFT>
3857
static void printRelocHeaderFields(formatted_raw_ostream &OS, unsigned SType,
3858
                                   const typename ELFT::Ehdr &EHeader,
3859
                                   uint64_t CrelHdr = 0) {
3860
  bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA;
3861
  if (ELFT::Is64Bits)
3862
    OS << "    Offset             Info             Type               Symbol's "
3863
          "Value  Symbol's Name";
3864
  else
3865
    OS << " Offset     Info    Type                Sym. Value  Symbol's Name";
3866
  if (IsRela || (SType == ELF::SHT_CREL && (CrelHdr & CREL_HDR_ADDEND)))
3867
    OS << " + Addend";
3868
  OS << "\n";
3869
}
3870

3871
template <class ELFT>
3872
void GNUELFDumper<ELFT>::printDynamicRelocHeader(unsigned Type, StringRef Name,
3873
                                                 const DynRegionInfo &Reg) {
3874
  uint64_t Offset = Reg.Addr - this->Obj.base();
3875
  OS << "\n'" << Name.str().c_str() << "' relocation section at offset 0x"
3876
     << utohexstr(Offset, /*LowerCase=*/true);
3877
  if (Type != ELF::SHT_CREL)
3878
    OS << " contains " << Reg.Size << " bytes";
3879
  OS << ":\n";
3880
  printRelocHeaderFields<ELFT>(OS, Type, this->Obj.getHeader());
3881
}
3882

3883
template <class ELFT>
3884
static bool isRelocationSec(const typename ELFT::Shdr &Sec,
3885
                            const typename ELFT::Ehdr &EHeader) {
3886
  return Sec.sh_type == ELF::SHT_REL || Sec.sh_type == ELF::SHT_RELA ||
3887
         Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_CREL ||
3888
         Sec.sh_type == ELF::SHT_ANDROID_REL ||
3889
         Sec.sh_type == ELF::SHT_ANDROID_RELA ||
3890
         Sec.sh_type == ELF::SHT_ANDROID_RELR ||
3891
         (EHeader.e_machine == EM_AARCH64 &&
3892
          Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR);
3893
}
3894

3895
template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
3896
  auto PrintAsRelr = [&](const Elf_Shdr &Sec) {
3897
    return Sec.sh_type == ELF::SHT_RELR ||
3898
           Sec.sh_type == ELF::SHT_ANDROID_RELR ||
3899
           (this->Obj.getHeader().e_machine == EM_AARCH64 &&
3900
            Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR);
3901
  };
3902
  auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected<size_t> {
3903
    // Android's packed relocation section needs to be unpacked first
3904
    // to get the actual number of entries.
3905
    if (Sec.sh_type == ELF::SHT_ANDROID_REL ||
3906
        Sec.sh_type == ELF::SHT_ANDROID_RELA) {
3907
      Expected<std::vector<typename ELFT::Rela>> RelasOrErr =
3908
          this->Obj.android_relas(Sec);
3909
      if (!RelasOrErr)
3910
        return RelasOrErr.takeError();
3911
      return RelasOrErr->size();
3912
    }
3913

3914
    if (Sec.sh_type == ELF::SHT_CREL) {
3915
      Expected<ArrayRef<uint8_t>> ContentsOrErr =
3916
          this->Obj.getSectionContents(Sec);
3917
      if (!ContentsOrErr)
3918
        return ContentsOrErr.takeError();
3919
      auto NumOrErr = this->Obj.getCrelHeader(*ContentsOrErr);
3920
      if (!NumOrErr)
3921
        return NumOrErr.takeError();
3922
      return *NumOrErr / 8;
3923
    }
3924

3925
    if (PrintAsRelr(Sec)) {
3926
      Expected<Elf_Relr_Range> RelrsOrErr = this->Obj.relrs(Sec);
3927
      if (!RelrsOrErr)
3928
        return RelrsOrErr.takeError();
3929
      return this->Obj.decode_relrs(*RelrsOrErr).size();
3930
    }
3931

3932
    return Sec.getEntityCount();
3933
  };
3934

3935
  bool HasRelocSections = false;
3936
  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
3937
    if (!isRelocationSec<ELFT>(Sec, this->Obj.getHeader()))
3938
      continue;
3939
    HasRelocSections = true;
3940

3941
    std::string EntriesNum = "<?>";
3942
    if (Expected<size_t> NumOrErr = GetEntriesNum(Sec))
3943
      EntriesNum = std::to_string(*NumOrErr);
3944
    else
3945
      this->reportUniqueWarning("unable to get the number of relocations in " +
3946
                                this->describe(Sec) + ": " +
3947
                                toString(NumOrErr.takeError()));
3948

3949
    uintX_t Offset = Sec.sh_offset;
3950
    StringRef Name = this->getPrintableSectionName(Sec);
3951
    OS << "\nRelocation section '" << Name << "' at offset 0x"
3952
       << utohexstr(Offset, /*LowerCase=*/true) << " contains " << EntriesNum
3953
       << " entries:\n";
3954

3955
    if (PrintAsRelr(Sec)) {
3956
      printRelr(Sec);
3957
    } else {
3958
      uint64_t CrelHdr = 0;
3959
      // For CREL, read the header and call printRelocationsHelper only if
3960
      // GetEntriesNum(Sec) succeeded.
3961
      if (Sec.sh_type == ELF::SHT_CREL && EntriesNum != "<?>") {
3962
        CrelHdr = cantFail(this->Obj.getCrelHeader(
3963
            cantFail(this->Obj.getSectionContents(Sec))));
3964
      }
3965
      printRelocHeaderFields<ELFT>(OS, Sec.sh_type, this->Obj.getHeader(),
3966
                                   CrelHdr);
3967
      if (Sec.sh_type != ELF::SHT_CREL || EntriesNum != "<?>")
3968
        this->printRelocationsHelper(Sec);
3969
    }
3970
  }
3971
  if (!HasRelocSections)
3972
    OS << "\nThere are no relocations in this file.\n";
3973
}
3974

3975
template <class ELFT> void GNUELFDumper<ELFT>::printRelr(const Elf_Shdr &Sec) {
3976
  Expected<Elf_Relr_Range> RangeOrErr = this->Obj.relrs(Sec);
3977
  if (!RangeOrErr) {
3978
    this->reportUniqueWarning("unable to read relocations from " +
3979
                              this->describe(Sec) + ": " +
3980
                              toString(RangeOrErr.takeError()));
3981
    return;
3982
  }
3983
  if (ELFT::Is64Bits)
3984
    OS << "Index: Entry            Address           Symbolic Address\n";
3985
  else
3986
    OS << "Index: Entry    Address   Symbolic Address\n";
3987

3988
  // If .symtab is available, collect its defined symbols and sort them by
3989
  // st_value.
3990
  SmallVector<std::pair<uint64_t, std::string>, 0> Syms;
3991
  if (this->DotSymtabSec) {
3992
    Elf_Sym_Range Symtab;
3993
    std::optional<StringRef> Strtab;
3994
    std::tie(Symtab, Strtab) = this->getSymtabAndStrtab();
3995
    if (Symtab.size() && Strtab) {
3996
      for (auto [I, Sym] : enumerate(Symtab)) {
3997
        if (!Sym.st_shndx)
3998
          continue;
3999
        Syms.emplace_back(Sym.st_value,
4000
                          this->getFullSymbolName(Sym, I, ArrayRef<Elf_Word>(),
4001
                                                  *Strtab, false));
4002
      }
4003
    }
4004
  }
4005
  llvm::stable_sort(Syms);
4006

4007
  typename ELFT::uint Base = 0;
4008
  size_t I = 0;
4009
  auto Print = [&](uint64_t Where) {
4010
    OS << format_hex_no_prefix(Where, ELFT::Is64Bits ? 16 : 8);
4011
    for (; I < Syms.size() && Syms[I].first <= Where; ++I)
4012
      ;
4013
    // Try symbolizing the address. Find the nearest symbol before or at the
4014
    // address and print the symbol and the address difference.
4015
    if (I) {
4016
      OS << "  " << Syms[I - 1].second;
4017
      if (Syms[I - 1].first < Where)
4018
        OS << " + 0x" << Twine::utohexstr(Where - Syms[I - 1].first);
4019
    }
4020
    OS << '\n';
4021
  };
4022
  for (auto [Index, R] : enumerate(*RangeOrErr)) {
4023
    typename ELFT::uint Entry = R;
4024
    OS << formatv("{0:4}:  ", Index)
4025
       << format_hex_no_prefix(Entry, ELFT::Is64Bits ? 16 : 8) << ' ';
4026
    if ((Entry & 1) == 0) {
4027
      Print(Entry);
4028
      Base = Entry + sizeof(typename ELFT::uint);
4029
    } else {
4030
      bool First = true;
4031
      for (auto Where = Base; Entry >>= 1;
4032
           Where += sizeof(typename ELFT::uint)) {
4033
        if (Entry & 1) {
4034
          if (First)
4035
            First = false;
4036
          else
4037
            OS.indent(ELFT::Is64Bits ? 24 : 16);
4038
          Print(Where);
4039
        }
4040
      }
4041
      Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(typename ELFT::uint);
4042
    }
4043
  }
4044
}
4045

4046
// Print the offset of a particular section from anyone of the ranges:
4047
// [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].
4048
// If 'Type' does not fall within any of those ranges, then a string is
4049
// returned as '<unknown>' followed by the type value.
4050
static std::string getSectionTypeOffsetString(unsigned Type) {
4051
  if (Type >= SHT_LOOS && Type <= SHT_HIOS)
4052
    return "LOOS+0x" + utohexstr(Type - SHT_LOOS);
4053
  else if (Type >= SHT_LOPROC && Type <= SHT_HIPROC)
4054
    return "LOPROC+0x" + utohexstr(Type - SHT_LOPROC);
4055
  else if (Type >= SHT_LOUSER && Type <= SHT_HIUSER)
4056
    return "LOUSER+0x" + utohexstr(Type - SHT_LOUSER);
4057
  return "0x" + utohexstr(Type) + ": <unknown>";
4058
}
4059

4060
static std::string getSectionTypeString(unsigned Machine, unsigned Type) {
4061
  StringRef Name = getELFSectionTypeName(Machine, Type);
4062

4063
  // Handle SHT_GNU_* type names.
4064
  if (Name.consume_front("SHT_GNU_")) {
4065
    if (Name == "HASH")
4066
      return "GNU_HASH";
4067
    // E.g. SHT_GNU_verneed -> VERNEED.
4068
    return Name.upper();
4069
  }
4070

4071
  if (Name == "SHT_SYMTAB_SHNDX")
4072
    return "SYMTAB SECTION INDICES";
4073

4074
  if (Name.consume_front("SHT_"))
4075
    return Name.str();
4076
  return getSectionTypeOffsetString(Type);
4077
}
4078

4079
static void printSectionDescription(formatted_raw_ostream &OS,
4080
                                    unsigned EMachine) {
4081
  OS << "Key to Flags:\n";
4082
  OS << "  W (write), A (alloc), X (execute), M (merge), S (strings), I "
4083
        "(info),\n";
4084
  OS << "  L (link order), O (extra OS processing required), G (group), T "
4085
        "(TLS),\n";
4086
  OS << "  C (compressed), x (unknown), o (OS specific), E (exclude),\n";
4087
  OS << "  R (retain)";
4088

4089
  if (EMachine == EM_X86_64)
4090
    OS << ", l (large)";
4091
  else if (EMachine == EM_ARM)
4092
    OS << ", y (purecode)";
4093

4094
  OS << ", p (processor specific)\n";
4095
}
4096

4097
template <class ELFT> void GNUELFDumper<ELFT>::printSectionHeaders() {
4098
  ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections());
4099
  if (Sections.empty()) {
4100
    OS << "\nThere are no sections in this file.\n";
4101
    Expected<StringRef> SecStrTableOrErr =
4102
        this->Obj.getSectionStringTable(Sections, this->WarningHandler);
4103
    if (!SecStrTableOrErr)
4104
      this->reportUniqueWarning(SecStrTableOrErr.takeError());
4105
    return;
4106
  }
4107
  unsigned Bias = ELFT::Is64Bits ? 0 : 8;
4108
  OS << "There are " << to_string(Sections.size())
4109
     << " section headers, starting at offset "
4110
     << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n";
4111
  OS << "Section Headers:\n";
4112
  Field Fields[11] = {
4113
      {"[Nr]", 2},        {"Name", 7},        {"Type", 25},
4114
      {"Address", 41},    {"Off", 58 - Bias}, {"Size", 65 - Bias},
4115
      {"ES", 72 - Bias},  {"Flg", 75 - Bias}, {"Lk", 79 - Bias},
4116
      {"Inf", 82 - Bias}, {"Al", 86 - Bias}};
4117
  for (const Field &F : Fields)
4118
    printField(F);
4119
  OS << "\n";
4120

4121
  StringRef SecStrTable;
4122
  if (Expected<StringRef> SecStrTableOrErr =
4123
          this->Obj.getSectionStringTable(Sections, this->WarningHandler))
4124
    SecStrTable = *SecStrTableOrErr;
4125
  else
4126
    this->reportUniqueWarning(SecStrTableOrErr.takeError());
4127

4128
  size_t SectionIndex = 0;
4129
  for (const Elf_Shdr &Sec : Sections) {
4130
    Fields[0].Str = to_string(SectionIndex);
4131
    if (SecStrTable.empty())
4132
      Fields[1].Str = "<no-strings>";
4133
    else
4134
      Fields[1].Str = std::string(unwrapOrError<StringRef>(
4135
          this->FileName, this->Obj.getSectionName(Sec, SecStrTable)));
4136
    Fields[2].Str =
4137
        getSectionTypeString(this->Obj.getHeader().e_machine, Sec.sh_type);
4138
    Fields[3].Str =
4139
        to_string(format_hex_no_prefix(Sec.sh_addr, ELFT::Is64Bits ? 16 : 8));
4140
    Fields[4].Str = to_string(format_hex_no_prefix(Sec.sh_offset, 6));
4141
    Fields[5].Str = to_string(format_hex_no_prefix(Sec.sh_size, 6));
4142
    Fields[6].Str = to_string(format_hex_no_prefix(Sec.sh_entsize, 2));
4143
    Fields[7].Str = getGNUFlags(this->Obj.getHeader().e_ident[ELF::EI_OSABI],
4144
                                this->Obj.getHeader().e_machine, Sec.sh_flags);
4145
    Fields[8].Str = to_string(Sec.sh_link);
4146
    Fields[9].Str = to_string(Sec.sh_info);
4147
    Fields[10].Str = to_string(Sec.sh_addralign);
4148

4149
    OS.PadToColumn(Fields[0].Column);
4150
    OS << "[" << right_justify(Fields[0].Str, 2) << "]";
4151
    for (int i = 1; i < 7; i++)
4152
      printField(Fields[i]);
4153
    OS.PadToColumn(Fields[7].Column);
4154
    OS << right_justify(Fields[7].Str, 3);
4155
    OS.PadToColumn(Fields[8].Column);
4156
    OS << right_justify(Fields[8].Str, 2);
4157
    OS.PadToColumn(Fields[9].Column);
4158
    OS << right_justify(Fields[9].Str, 3);
4159
    OS.PadToColumn(Fields[10].Column);
4160
    OS << right_justify(Fields[10].Str, 2);
4161
    OS << "\n";
4162
    ++SectionIndex;
4163
  }
4164
  printSectionDescription(OS, this->Obj.getHeader().e_machine);
4165
}
4166

4167
template <class ELFT>
4168
void GNUELFDumper<ELFT>::printSymtabMessage(const Elf_Shdr *Symtab,
4169
                                            size_t Entries,
4170
                                            bool NonVisibilityBitsUsed,
4171
                                            bool ExtraSymInfo) const {
4172
  StringRef Name;
4173
  if (Symtab)
4174
    Name = this->getPrintableSectionName(*Symtab);
4175
  if (!Name.empty())
4176
    OS << "\nSymbol table '" << Name << "'";
4177
  else
4178
    OS << "\nSymbol table for image";
4179
  OS << " contains " << Entries << " entries:\n";
4180

4181
  if (ELFT::Is64Bits) {
4182
    OS << "   Num:    Value          Size Type    Bind   Vis";
4183
    if (ExtraSymInfo)
4184
      OS << "+Other";
4185
  } else {
4186
    OS << "   Num:    Value  Size Type    Bind   Vis";
4187
    if (ExtraSymInfo)
4188
      OS << "+Other";
4189
  }
4190

4191
  OS.PadToColumn((ELFT::Is64Bits ? 56 : 48) + (NonVisibilityBitsUsed ? 13 : 0));
4192
  if (ExtraSymInfo)
4193
    OS << "Ndx(SecName) Name [+ Version Info]\n";
4194
  else
4195
    OS << "Ndx Name\n";
4196
}
4197

4198
template <class ELFT>
4199
std::string GNUELFDumper<ELFT>::getSymbolSectionNdx(
4200
    const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable,
4201
    bool ExtraSymInfo) const {
4202
  unsigned SectionIndex = Symbol.st_shndx;
4203
  switch (SectionIndex) {
4204
  case ELF::SHN_UNDEF:
4205
    return "UND";
4206
  case ELF::SHN_ABS:
4207
    return "ABS";
4208
  case ELF::SHN_COMMON:
4209
    return "COM";
4210
  case ELF::SHN_XINDEX: {
4211
    Expected<uint32_t> IndexOrErr =
4212
        object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex, ShndxTable);
4213
    if (!IndexOrErr) {
4214
      assert(Symbol.st_shndx == SHN_XINDEX &&
4215
             "getExtendedSymbolTableIndex should only fail due to an invalid "
4216
             "SHT_SYMTAB_SHNDX table/reference");
4217
      this->reportUniqueWarning(IndexOrErr.takeError());
4218
      return "RSV[0xffff]";
4219
    }
4220
    SectionIndex = *IndexOrErr;
4221
    break;
4222
  }
4223
  default:
4224
    // Find if:
4225
    // Processor specific
4226
    if (SectionIndex >= ELF::SHN_LOPROC && SectionIndex <= ELF::SHN_HIPROC)
4227
      return std::string("PRC[0x") +
4228
             to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
4229
    // OS specific
4230
    if (SectionIndex >= ELF::SHN_LOOS && SectionIndex <= ELF::SHN_HIOS)
4231
      return std::string("OS[0x") +
4232
             to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
4233
    // Architecture reserved:
4234
    if (SectionIndex >= ELF::SHN_LORESERVE &&
4235
        SectionIndex <= ELF::SHN_HIRESERVE)
4236
      return std::string("RSV[0x") +
4237
             to_string(format_hex_no_prefix(SectionIndex, 4)) + "]";
4238
    break;
4239
  }
4240

4241
  std::string Extra;
4242
  if (ExtraSymInfo) {
4243
    auto Sec = this->Obj.getSection(SectionIndex);
4244
    if (!Sec) {
4245
      this->reportUniqueWarning(Sec.takeError());
4246
    } else {
4247
      auto SecName = this->Obj.getSectionName(**Sec);
4248
      if (!SecName)
4249
        this->reportUniqueWarning(SecName.takeError());
4250
      else
4251
        Extra = Twine(" (" + *SecName + ")").str();
4252
    }
4253
  }
4254
  return to_string(format_decimal(SectionIndex, 3)) + Extra;
4255
}
4256

4257
template <class ELFT>
4258
void GNUELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
4259
                                     DataRegion<Elf_Word> ShndxTable,
4260
                                     std::optional<StringRef> StrTable,
4261
                                     bool IsDynamic, bool NonVisibilityBitsUsed,
4262
                                     bool ExtraSymInfo) const {
4263
  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
4264
  Field Fields[8] = {0,         8,         17 + Bias, 23 + Bias,
4265
                     31 + Bias, 38 + Bias, 48 + Bias, 51 + Bias};
4266
  Fields[0].Str = to_string(format_decimal(SymIndex, 6)) + ":";
4267
  Fields[1].Str =
4268
      to_string(format_hex_no_prefix(Symbol.st_value, ELFT::Is64Bits ? 16 : 8));
4269
  Fields[2].Str = to_string(format_decimal(Symbol.st_size, 5));
4270

4271
  unsigned char SymbolType = Symbol.getType();
4272
  if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&
4273
      SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
4274
    Fields[3].Str = enumToString(SymbolType, ArrayRef(AMDGPUSymbolTypes));
4275
  else
4276
    Fields[3].Str = enumToString(SymbolType, ArrayRef(ElfSymbolTypes));
4277

4278
  Fields[4].Str =
4279
      enumToString(Symbol.getBinding(), ArrayRef(ElfSymbolBindings));
4280
  Fields[5].Str =
4281
      enumToString(Symbol.getVisibility(), ArrayRef(ElfSymbolVisibilities));
4282

4283
  if (Symbol.st_other & ~0x3) {
4284
    if (this->Obj.getHeader().e_machine == ELF::EM_AARCH64) {
4285
      uint8_t Other = Symbol.st_other & ~0x3;
4286
      if (Other & STO_AARCH64_VARIANT_PCS) {
4287
        Other &= ~STO_AARCH64_VARIANT_PCS;
4288
        Fields[5].Str += " [VARIANT_PCS";
4289
        if (Other != 0)
4290
          Fields[5].Str.append(" | " + utohexstr(Other, /*LowerCase=*/true));
4291
        Fields[5].Str.append("]");
4292
      }
4293
    } else if (this->Obj.getHeader().e_machine == ELF::EM_RISCV) {
4294
      uint8_t Other = Symbol.st_other & ~0x3;
4295
      if (Other & STO_RISCV_VARIANT_CC) {
4296
        Other &= ~STO_RISCV_VARIANT_CC;
4297
        Fields[5].Str += " [VARIANT_CC";
4298
        if (Other != 0)
4299
          Fields[5].Str.append(" | " + utohexstr(Other, /*LowerCase=*/true));
4300
        Fields[5].Str.append("]");
4301
      }
4302
    } else {
4303
      Fields[5].Str +=
4304
          " [<other: " + to_string(format_hex(Symbol.st_other, 2)) + ">]";
4305
    }
4306
  }
4307

4308
  Fields[6].Column += NonVisibilityBitsUsed ? 13 : 0;
4309
  Fields[6].Str =
4310
      getSymbolSectionNdx(Symbol, SymIndex, ShndxTable, ExtraSymInfo);
4311

4312
  Fields[7].Column += ExtraSymInfo ? 10 : 0;
4313
  Fields[7].Str = this->getFullSymbolName(Symbol, SymIndex, ShndxTable,
4314
                                          StrTable, IsDynamic);
4315
  for (const Field &Entry : Fields)
4316
    printField(Entry);
4317
  OS << "\n";
4318
}
4319

4320
template <class ELFT>
4321
void GNUELFDumper<ELFT>::printHashedSymbol(const Elf_Sym *Symbol,
4322
                                           unsigned SymIndex,
4323
                                           DataRegion<Elf_Word> ShndxTable,
4324
                                           StringRef StrTable,
4325
                                           uint32_t Bucket) {
4326
  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
4327
  Field Fields[9] = {0,         6,         11,        20 + Bias, 25 + Bias,
4328
                     34 + Bias, 41 + Bias, 49 + Bias, 53 + Bias};
4329
  Fields[0].Str = to_string(format_decimal(SymIndex, 5));
4330
  Fields[1].Str = to_string(format_decimal(Bucket, 3)) + ":";
4331

4332
  Fields[2].Str = to_string(
4333
      format_hex_no_prefix(Symbol->st_value, ELFT::Is64Bits ? 16 : 8));
4334
  Fields[3].Str = to_string(format_decimal(Symbol->st_size, 5));
4335

4336
  unsigned char SymbolType = Symbol->getType();
4337
  if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&
4338
      SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
4339
    Fields[4].Str = enumToString(SymbolType, ArrayRef(AMDGPUSymbolTypes));
4340
  else
4341
    Fields[4].Str = enumToString(SymbolType, ArrayRef(ElfSymbolTypes));
4342

4343
  Fields[5].Str =
4344
      enumToString(Symbol->getBinding(), ArrayRef(ElfSymbolBindings));
4345
  Fields[6].Str =
4346
      enumToString(Symbol->getVisibility(), ArrayRef(ElfSymbolVisibilities));
4347
  Fields[7].Str = getSymbolSectionNdx(*Symbol, SymIndex, ShndxTable);
4348
  Fields[8].Str =
4349
      this->getFullSymbolName(*Symbol, SymIndex, ShndxTable, StrTable, true);
4350

4351
  for (const Field &Entry : Fields)
4352
    printField(Entry);
4353
  OS << "\n";
4354
}
4355

4356
template <class ELFT>
4357
void GNUELFDumper<ELFT>::printSymbols(bool PrintSymbols,
4358
                                      bool PrintDynamicSymbols,
4359
                                      bool ExtraSymInfo) {
4360
  if (!PrintSymbols && !PrintDynamicSymbols)
4361
    return;
4362
  // GNU readelf prints both the .dynsym and .symtab with --symbols.
4363
  this->printSymbolsHelper(true, ExtraSymInfo);
4364
  if (PrintSymbols)
4365
    this->printSymbolsHelper(false, ExtraSymInfo);
4366
}
4367

4368
template <class ELFT>
4369
void GNUELFDumper<ELFT>::printHashTableSymbols(const Elf_Hash &SysVHash) {
4370
  if (this->DynamicStringTable.empty())
4371
    return;
4372

4373
  if (ELFT::Is64Bits)
4374
    OS << "  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name";
4375
  else
4376
    OS << "  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name";
4377
  OS << "\n";
4378

4379
  Elf_Sym_Range DynSyms = this->dynamic_symbols();
4380
  const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];
4381
  if (!FirstSym) {
4382
    this->reportUniqueWarning(
4383
        Twine("unable to print symbols for the .hash table: the "
4384
              "dynamic symbol table ") +
4385
        (this->DynSymRegion ? "is empty" : "was not found"));
4386
    return;
4387
  }
4388

4389
  DataRegion<Elf_Word> ShndxTable(
4390
      (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
4391
  auto Buckets = SysVHash.buckets();
4392
  auto Chains = SysVHash.chains();
4393
  for (uint32_t Buc = 0; Buc < SysVHash.nbucket; Buc++) {
4394
    if (Buckets[Buc] == ELF::STN_UNDEF)
4395
      continue;
4396
    BitVector Visited(SysVHash.nchain);
4397
    for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash.nchain; Ch = Chains[Ch]) {
4398
      if (Ch == ELF::STN_UNDEF)
4399
        break;
4400

4401
      if (Visited[Ch]) {
4402
        this->reportUniqueWarning(".hash section is invalid: bucket " +
4403
                                  Twine(Ch) +
4404
                                  ": a cycle was detected in the linked chain");
4405
        break;
4406
      }
4407

4408
      printHashedSymbol(FirstSym + Ch, Ch, ShndxTable, this->DynamicStringTable,
4409
                        Buc);
4410
      Visited[Ch] = true;
4411
    }
4412
  }
4413
}
4414

4415
template <class ELFT>
4416
void GNUELFDumper<ELFT>::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) {
4417
  if (this->DynamicStringTable.empty())
4418
    return;
4419

4420
  Elf_Sym_Range DynSyms = this->dynamic_symbols();
4421
  const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];
4422
  if (!FirstSym) {
4423
    this->reportUniqueWarning(
4424
        Twine("unable to print symbols for the .gnu.hash table: the "
4425
              "dynamic symbol table ") +
4426
        (this->DynSymRegion ? "is empty" : "was not found"));
4427
    return;
4428
  }
4429

4430
  auto GetSymbol = [&](uint64_t SymIndex,
4431
                       uint64_t SymsTotal) -> const Elf_Sym * {
4432
    if (SymIndex >= SymsTotal) {
4433
      this->reportUniqueWarning(
4434
          "unable to print hashed symbol with index " + Twine(SymIndex) +
4435
          ", which is greater than or equal to the number of dynamic symbols "
4436
          "(" +
4437
          Twine::utohexstr(SymsTotal) + ")");
4438
      return nullptr;
4439
    }
4440
    return FirstSym + SymIndex;
4441
  };
4442

4443
  Expected<ArrayRef<Elf_Word>> ValuesOrErr =
4444
      getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHash);
4445
  ArrayRef<Elf_Word> Values;
4446
  if (!ValuesOrErr)
4447
    this->reportUniqueWarning("unable to get hash values for the SHT_GNU_HASH "
4448
                              "section: " +
4449
                              toString(ValuesOrErr.takeError()));
4450
  else
4451
    Values = *ValuesOrErr;
4452

4453
  DataRegion<Elf_Word> ShndxTable(
4454
      (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
4455
  ArrayRef<Elf_Word> Buckets = GnuHash.buckets();
4456
  for (uint32_t Buc = 0; Buc < GnuHash.nbuckets; Buc++) {
4457
    if (Buckets[Buc] == ELF::STN_UNDEF)
4458
      continue;
4459
    uint32_t Index = Buckets[Buc];
4460
    // Print whole chain.
4461
    while (true) {
4462
      uint32_t SymIndex = Index++;
4463
      if (const Elf_Sym *Sym = GetSymbol(SymIndex, DynSyms.size()))
4464
        printHashedSymbol(Sym, SymIndex, ShndxTable, this->DynamicStringTable,
4465
                          Buc);
4466
      else
4467
        break;
4468

4469
      if (SymIndex < GnuHash.symndx) {
4470
        this->reportUniqueWarning(
4471
            "unable to read the hash value for symbol with index " +
4472
            Twine(SymIndex) +
4473
            ", which is less than the index of the first hashed symbol (" +
4474
            Twine(GnuHash.symndx) + ")");
4475
        break;
4476
      }
4477

4478
       // Chain ends at symbol with stopper bit.
4479
      if ((Values[SymIndex - GnuHash.symndx] & 1) == 1)
4480
        break;
4481
    }
4482
  }
4483
}
4484

4485
template <class ELFT> void GNUELFDumper<ELFT>::printHashSymbols() {
4486
  if (this->HashTable) {
4487
    OS << "\n Symbol table of .hash for image:\n";
4488
    if (Error E = checkHashTable<ELFT>(*this, this->HashTable))
4489
      this->reportUniqueWarning(std::move(E));
4490
    else
4491
      printHashTableSymbols(*this->HashTable);
4492
  }
4493

4494
  // Try printing the .gnu.hash table.
4495
  if (this->GnuHashTable) {
4496
    OS << "\n Symbol table of .gnu.hash for image:\n";
4497
    if (ELFT::Is64Bits)
4498
      OS << "  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name";
4499
    else
4500
      OS << "  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name";
4501
    OS << "\n";
4502

4503
    if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable))
4504
      this->reportUniqueWarning(std::move(E));
4505
    else
4506
      printGnuHashTableSymbols(*this->GnuHashTable);
4507
  }
4508
}
4509

4510
template <class ELFT> void GNUELFDumper<ELFT>::printSectionDetails() {
4511
  ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections());
4512
  if (Sections.empty()) {
4513
    OS << "\nThere are no sections in this file.\n";
4514
    Expected<StringRef> SecStrTableOrErr =
4515
        this->Obj.getSectionStringTable(Sections, this->WarningHandler);
4516
    if (!SecStrTableOrErr)
4517
      this->reportUniqueWarning(SecStrTableOrErr.takeError());
4518
    return;
4519
  }
4520
  OS << "There are " << to_string(Sections.size())
4521
     << " section headers, starting at offset "
4522
     << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n";
4523

4524
  OS << "Section Headers:\n";
4525

4526
  auto PrintFields = [&](ArrayRef<Field> V) {
4527
    for (const Field &F : V)
4528
      printField(F);
4529
    OS << "\n";
4530
  };
4531

4532
  PrintFields({{"[Nr]", 2}, {"Name", 7}});
4533

4534
  constexpr bool Is64 = ELFT::Is64Bits;
4535
  PrintFields({{"Type", 7},
4536
               {Is64 ? "Address" : "Addr", 23},
4537
               {"Off", Is64 ? 40 : 32},
4538
               {"Size", Is64 ? 47 : 39},
4539
               {"ES", Is64 ? 54 : 46},
4540
               {"Lk", Is64 ? 59 : 51},
4541
               {"Inf", Is64 ? 62 : 54},
4542
               {"Al", Is64 ? 66 : 57}});
4543
  PrintFields({{"Flags", 7}});
4544

4545
  StringRef SecStrTable;
4546
  if (Expected<StringRef> SecStrTableOrErr =
4547
          this->Obj.getSectionStringTable(Sections, this->WarningHandler))
4548
    SecStrTable = *SecStrTableOrErr;
4549
  else
4550
    this->reportUniqueWarning(SecStrTableOrErr.takeError());
4551

4552
  size_t SectionIndex = 0;
4553
  const unsigned AddrSize = Is64 ? 16 : 8;
4554
  for (const Elf_Shdr &S : Sections) {
4555
    StringRef Name = "<?>";
4556
    if (Expected<StringRef> NameOrErr =
4557
            this->Obj.getSectionName(S, SecStrTable))
4558
      Name = *NameOrErr;
4559
    else
4560
      this->reportUniqueWarning(NameOrErr.takeError());
4561

4562
    OS.PadToColumn(2);
4563
    OS << "[" << right_justify(to_string(SectionIndex), 2) << "]";
4564
    PrintFields({{Name, 7}});
4565
    PrintFields(
4566
        {{getSectionTypeString(this->Obj.getHeader().e_machine, S.sh_type), 7},
4567
         {to_string(format_hex_no_prefix(S.sh_addr, AddrSize)), 23},
4568
         {to_string(format_hex_no_prefix(S.sh_offset, 6)), Is64 ? 39 : 32},
4569
         {to_string(format_hex_no_prefix(S.sh_size, 6)), Is64 ? 47 : 39},
4570
         {to_string(format_hex_no_prefix(S.sh_entsize, 2)), Is64 ? 54 : 46},
4571
         {to_string(S.sh_link), Is64 ? 59 : 51},
4572
         {to_string(S.sh_info), Is64 ? 63 : 55},
4573
         {to_string(S.sh_addralign), Is64 ? 66 : 58}});
4574

4575
    OS.PadToColumn(7);
4576
    OS << "[" << to_string(format_hex_no_prefix(S.sh_flags, AddrSize)) << "]: ";
4577

4578
    DenseMap<unsigned, StringRef> FlagToName = {
4579
        {SHF_WRITE, "WRITE"},           {SHF_ALLOC, "ALLOC"},
4580
        {SHF_EXECINSTR, "EXEC"},        {SHF_MERGE, "MERGE"},
4581
        {SHF_STRINGS, "STRINGS"},       {SHF_INFO_LINK, "INFO LINK"},
4582
        {SHF_LINK_ORDER, "LINK ORDER"}, {SHF_OS_NONCONFORMING, "OS NONCONF"},
4583
        {SHF_GROUP, "GROUP"},           {SHF_TLS, "TLS"},
4584
        {SHF_COMPRESSED, "COMPRESSED"}, {SHF_EXCLUDE, "EXCLUDE"}};
4585

4586
    uint64_t Flags = S.sh_flags;
4587
    uint64_t UnknownFlags = 0;
4588
    ListSeparator LS;
4589
    while (Flags) {
4590
      // Take the least significant bit as a flag.
4591
      uint64_t Flag = Flags & -Flags;
4592
      Flags -= Flag;
4593

4594
      auto It = FlagToName.find(Flag);
4595
      if (It != FlagToName.end())
4596
        OS << LS << It->second;
4597
      else
4598
        UnknownFlags |= Flag;
4599
    }
4600

4601
    auto PrintUnknownFlags = [&](uint64_t Mask, StringRef Name) {
4602
      uint64_t FlagsToPrint = UnknownFlags & Mask;
4603
      if (!FlagsToPrint)
4604
        return;
4605

4606
      OS << LS << Name << " ("
4607
         << to_string(format_hex_no_prefix(FlagsToPrint, AddrSize)) << ")";
4608
      UnknownFlags &= ~Mask;
4609
    };
4610

4611
    PrintUnknownFlags(SHF_MASKOS, "OS");
4612
    PrintUnknownFlags(SHF_MASKPROC, "PROC");
4613
    PrintUnknownFlags(uint64_t(-1), "UNKNOWN");
4614

4615
    OS << "\n";
4616
    ++SectionIndex;
4617

4618
    if (!(S.sh_flags & SHF_COMPRESSED))
4619
      continue;
4620
    Expected<ArrayRef<uint8_t>> Data = this->Obj.getSectionContents(S);
4621
    if (!Data || Data->size() < sizeof(Elf_Chdr)) {
4622
      consumeError(Data.takeError());
4623
      reportWarning(createError("SHF_COMPRESSED section '" + Name +
4624
                                "' does not have an Elf_Chdr header"),
4625
                    this->FileName);
4626
      OS.indent(7);
4627
      OS << "[<corrupt>]";
4628
    } else {
4629
      OS.indent(7);
4630
      auto *Chdr = reinterpret_cast<const Elf_Chdr *>(Data->data());
4631
      if (Chdr->ch_type == ELFCOMPRESS_ZLIB)
4632
        OS << "ZLIB";
4633
      else if (Chdr->ch_type == ELFCOMPRESS_ZSTD)
4634
        OS << "ZSTD";
4635
      else
4636
        OS << format("[<unknown>: 0x%x]", unsigned(Chdr->ch_type));
4637
      OS << ", " << format_hex_no_prefix(Chdr->ch_size, ELFT::Is64Bits ? 16 : 8)
4638
         << ", " << Chdr->ch_addralign;
4639
    }
4640
    OS << '\n';
4641
  }
4642
}
4643

4644
static inline std::string printPhdrFlags(unsigned Flag) {
4645
  std::string Str;
4646
  Str = (Flag & PF_R) ? "R" : " ";
4647
  Str += (Flag & PF_W) ? "W" : " ";
4648
  Str += (Flag & PF_X) ? "E" : " ";
4649
  return Str;
4650
}
4651

4652
template <class ELFT>
4653
static bool checkTLSSections(const typename ELFT::Phdr &Phdr,
4654
                             const typename ELFT::Shdr &Sec) {
4655
  if (Sec.sh_flags & ELF::SHF_TLS) {
4656
    // .tbss must only be shown in the PT_TLS segment.
4657
    if (Sec.sh_type == ELF::SHT_NOBITS)
4658
      return Phdr.p_type == ELF::PT_TLS;
4659

4660
    // SHF_TLS sections are only shown in PT_TLS, PT_LOAD or PT_GNU_RELRO
4661
    // segments.
4662
    return (Phdr.p_type == ELF::PT_TLS) || (Phdr.p_type == ELF::PT_LOAD) ||
4663
           (Phdr.p_type == ELF::PT_GNU_RELRO);
4664
  }
4665

4666
  // PT_TLS must only have SHF_TLS sections.
4667
  return Phdr.p_type != ELF::PT_TLS;
4668
}
4669

4670
template <class ELFT>
4671
static bool checkPTDynamic(const typename ELFT::Phdr &Phdr,
4672
                           const typename ELFT::Shdr &Sec) {
4673
  if (Phdr.p_type != ELF::PT_DYNAMIC || Phdr.p_memsz == 0 || Sec.sh_size != 0)
4674
    return true;
4675

4676
  // We get here when we have an empty section. Only non-empty sections can be
4677
  // at the start or at the end of PT_DYNAMIC.
4678
  // Is section within the phdr both based on offset and VMA?
4679
  bool CheckOffset = (Sec.sh_type == ELF::SHT_NOBITS) ||
4680
                     (Sec.sh_offset > Phdr.p_offset &&
4681
                      Sec.sh_offset < Phdr.p_offset + Phdr.p_filesz);
4682
  bool CheckVA = !(Sec.sh_flags & ELF::SHF_ALLOC) ||
4683
                 (Sec.sh_addr > Phdr.p_vaddr && Sec.sh_addr < Phdr.p_memsz);
4684
  return CheckOffset && CheckVA;
4685
}
4686

4687
template <class ELFT>
4688
void GNUELFDumper<ELFT>::printProgramHeaders(
4689
    bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {
4690
  const bool ShouldPrintSectionMapping = (PrintSectionMapping != cl::BOU_FALSE);
4691
  // Exit early if no program header or section mapping details were requested.
4692
  if (!PrintProgramHeaders && !ShouldPrintSectionMapping)
4693
    return;
4694

4695
  if (PrintProgramHeaders) {
4696
    const Elf_Ehdr &Header = this->Obj.getHeader();
4697
    if (Header.e_phnum == 0) {
4698
      OS << "\nThere are no program headers in this file.\n";
4699
    } else {
4700
      printProgramHeaders();
4701
    }
4702
  }
4703

4704
  if (ShouldPrintSectionMapping)
4705
    printSectionMapping();
4706
}
4707

4708
template <class ELFT> void GNUELFDumper<ELFT>::printProgramHeaders() {
4709
  unsigned Bias = ELFT::Is64Bits ? 8 : 0;
4710
  const Elf_Ehdr &Header = this->Obj.getHeader();
4711
  Field Fields[8] = {2,         17,        26,        37 + Bias,
4712
                     48 + Bias, 56 + Bias, 64 + Bias, 68 + Bias};
4713
  OS << "\nElf file type is "
4714
     << enumToString(Header.e_type, ArrayRef(ElfObjectFileType)) << "\n"
4715
     << "Entry point " << format_hex(Header.e_entry, 3) << "\n"
4716
     << "There are " << Header.e_phnum << " program headers,"
4717
     << " starting at offset " << Header.e_phoff << "\n\n"
4718
     << "Program Headers:\n";
4719
  if (ELFT::Is64Bits)
4720
    OS << "  Type           Offset   VirtAddr           PhysAddr         "
4721
       << "  FileSiz  MemSiz   Flg Align\n";
4722
  else
4723
    OS << "  Type           Offset   VirtAddr   PhysAddr   FileSiz "
4724
       << "MemSiz  Flg Align\n";
4725

4726
  unsigned Width = ELFT::Is64Bits ? 18 : 10;
4727
  unsigned SizeWidth = ELFT::Is64Bits ? 8 : 7;
4728

4729
  Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
4730
  if (!PhdrsOrErr) {
4731
    this->reportUniqueWarning("unable to dump program headers: " +
4732
                              toString(PhdrsOrErr.takeError()));
4733
    return;
4734
  }
4735

4736
  for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
4737
    Fields[0].Str = getGNUPtType(Header.e_machine, Phdr.p_type);
4738
    Fields[1].Str = to_string(format_hex(Phdr.p_offset, 8));
4739
    Fields[2].Str = to_string(format_hex(Phdr.p_vaddr, Width));
4740
    Fields[3].Str = to_string(format_hex(Phdr.p_paddr, Width));
4741
    Fields[4].Str = to_string(format_hex(Phdr.p_filesz, SizeWidth));
4742
    Fields[5].Str = to_string(format_hex(Phdr.p_memsz, SizeWidth));
4743
    Fields[6].Str = printPhdrFlags(Phdr.p_flags);
4744
    Fields[7].Str = to_string(format_hex(Phdr.p_align, 1));
4745
    for (const Field &F : Fields)
4746
      printField(F);
4747
    if (Phdr.p_type == ELF::PT_INTERP) {
4748
      OS << "\n";
4749
      auto ReportBadInterp = [&](const Twine &Msg) {
4750
        this->reportUniqueWarning(
4751
            "unable to read program interpreter name at offset 0x" +
4752
            Twine::utohexstr(Phdr.p_offset) + ": " + Msg);
4753
      };
4754

4755
      if (Phdr.p_offset >= this->Obj.getBufSize()) {
4756
        ReportBadInterp("it goes past the end of the file (0x" +
4757
                        Twine::utohexstr(this->Obj.getBufSize()) + ")");
4758
        continue;
4759
      }
4760

4761
      const char *Data =
4762
          reinterpret_cast<const char *>(this->Obj.base()) + Phdr.p_offset;
4763
      size_t MaxSize = this->Obj.getBufSize() - Phdr.p_offset;
4764
      size_t Len = strnlen(Data, MaxSize);
4765
      if (Len == MaxSize) {
4766
        ReportBadInterp("it is not null-terminated");
4767
        continue;
4768
      }
4769

4770
      OS << "      [Requesting program interpreter: ";
4771
      OS << StringRef(Data, Len) << "]";
4772
    }
4773
    OS << "\n";
4774
  }
4775
}
4776

4777
template <class ELFT> void GNUELFDumper<ELFT>::printSectionMapping() {
4778
  OS << "\n Section to Segment mapping:\n  Segment Sections...\n";
4779
  DenseSet<const Elf_Shdr *> BelongsToSegment;
4780
  int Phnum = 0;
4781

4782
  Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
4783
  if (!PhdrsOrErr) {
4784
    this->reportUniqueWarning(
4785
        "can't read program headers to build section to segment mapping: " +
4786
        toString(PhdrsOrErr.takeError()));
4787
    return;
4788
  }
4789

4790
  for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
4791
    std::string Sections;
4792
    OS << format("   %2.2d     ", Phnum++);
4793
    // Check if each section is in a segment and then print mapping.
4794
    for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
4795
      if (Sec.sh_type == ELF::SHT_NULL)
4796
        continue;
4797

4798
      // readelf additionally makes sure it does not print zero sized sections
4799
      // at end of segments and for PT_DYNAMIC both start and end of section
4800
      // .tbss must only be shown in PT_TLS section.
4801
      if (isSectionInSegment<ELFT>(Phdr, Sec) &&
4802
          checkTLSSections<ELFT>(Phdr, Sec) &&
4803
          checkPTDynamic<ELFT>(Phdr, Sec)) {
4804
        Sections +=
4805
            unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() +
4806
            " ";
4807
        BelongsToSegment.insert(&Sec);
4808
      }
4809
    }
4810
    OS << Sections << "\n";
4811
    OS.flush();
4812
  }
4813

4814
  // Display sections that do not belong to a segment.
4815
  std::string Sections;
4816
  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
4817
    if (BelongsToSegment.find(&Sec) == BelongsToSegment.end())
4818
      Sections +=
4819
          unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() +
4820
          ' ';
4821
  }
4822
  if (!Sections.empty()) {
4823
    OS << "   None  " << Sections << '\n';
4824
    OS.flush();
4825
  }
4826
}
4827

4828
namespace {
4829

4830
template <class ELFT>
4831
RelSymbol<ELFT> getSymbolForReloc(const ELFDumper<ELFT> &Dumper,
4832
                                  const Relocation<ELFT> &Reloc) {
4833
  using Elf_Sym = typename ELFT::Sym;
4834
  auto WarnAndReturn = [&](const Elf_Sym *Sym,
4835
                           const Twine &Reason) -> RelSymbol<ELFT> {
4836
    Dumper.reportUniqueWarning(
4837
        "unable to get name of the dynamic symbol with index " +
4838
        Twine(Reloc.Symbol) + ": " + Reason);
4839
    return {Sym, "<corrupt>"};
4840
  };
4841

4842
  ArrayRef<Elf_Sym> Symbols = Dumper.dynamic_symbols();
4843
  const Elf_Sym *FirstSym = Symbols.begin();
4844
  if (!FirstSym)
4845
    return WarnAndReturn(nullptr, "no dynamic symbol table found");
4846

4847
  // We might have an object without a section header. In this case the size of
4848
  // Symbols is zero, because there is no way to know the size of the dynamic
4849
  // table. We should allow this case and not print a warning.
4850
  if (!Symbols.empty() && Reloc.Symbol >= Symbols.size())
4851
    return WarnAndReturn(
4852
        nullptr,
4853
        "index is greater than or equal to the number of dynamic symbols (" +
4854
            Twine(Symbols.size()) + ")");
4855

4856
  const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
4857
  const uint64_t FileSize = Obj.getBufSize();
4858
  const uint64_t SymOffset = ((const uint8_t *)FirstSym - Obj.base()) +
4859
                             (uint64_t)Reloc.Symbol * sizeof(Elf_Sym);
4860
  if (SymOffset + sizeof(Elf_Sym) > FileSize)
4861
    return WarnAndReturn(nullptr, "symbol at 0x" + Twine::utohexstr(SymOffset) +
4862
                                      " goes past the end of the file (0x" +
4863
                                      Twine::utohexstr(FileSize) + ")");
4864

4865
  const Elf_Sym *Sym = FirstSym + Reloc.Symbol;
4866
  Expected<StringRef> ErrOrName = Sym->getName(Dumper.getDynamicStringTable());
4867
  if (!ErrOrName)
4868
    return WarnAndReturn(Sym, toString(ErrOrName.takeError()));
4869

4870
  return {Sym == FirstSym ? nullptr : Sym, maybeDemangle(*ErrOrName)};
4871
}
4872
} // namespace
4873

4874
template <class ELFT>
4875
static size_t getMaxDynamicTagSize(const ELFFile<ELFT> &Obj,
4876
                                   typename ELFT::DynRange Tags) {
4877
  size_t Max = 0;
4878
  for (const typename ELFT::Dyn &Dyn : Tags)
4879
    Max = std::max(Max, Obj.getDynamicTagAsString(Dyn.d_tag).size());
4880
  return Max;
4881
}
4882

4883
template <class ELFT> void GNUELFDumper<ELFT>::printDynamicTable() {
4884
  Elf_Dyn_Range Table = this->dynamic_table();
4885
  if (Table.empty())
4886
    return;
4887

4888
  OS << "Dynamic section at offset "
4889
     << format_hex(reinterpret_cast<const uint8_t *>(this->DynamicTable.Addr) -
4890
                       this->Obj.base(),
4891
                   1)
4892
     << " contains " << Table.size() << " entries:\n";
4893

4894
  // The type name is surrounded with round brackets, hence add 2.
4895
  size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table) + 2;
4896
  // The "Name/Value" column should be indented from the "Type" column by N
4897
  // spaces, where N = MaxTagSize - length of "Type" (4) + trailing
4898
  // space (1) = 3.
4899
  OS << "  Tag" + std::string(ELFT::Is64Bits ? 16 : 8, ' ') + "Type"
4900
     << std::string(MaxTagSize - 3, ' ') << "Name/Value\n";
4901

4902
  std::string ValueFmt = " %-" + std::to_string(MaxTagSize) + "s ";
4903
  for (auto Entry : Table) {
4904
    uintX_t Tag = Entry.getTag();
4905
    std::string Type =
4906
        std::string("(") + this->Obj.getDynamicTagAsString(Tag) + ")";
4907
    std::string Value = this->getDynamicEntry(Tag, Entry.getVal());
4908
    OS << "  " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10)
4909
       << format(ValueFmt.c_str(), Type.c_str()) << Value << "\n";
4910
  }
4911
}
4912

4913
template <class ELFT> void GNUELFDumper<ELFT>::printDynamicRelocations() {
4914
  this->printDynamicRelocationsHelper();
4915
}
4916

4917
template <class ELFT>
4918
void ELFDumper<ELFT>::printDynamicReloc(const Relocation<ELFT> &R) {
4919
  printRelRelaReloc(R, getSymbolForReloc(*this, R));
4920
}
4921

4922
template <class ELFT>
4923
void ELFDumper<ELFT>::printRelocationsHelper(const Elf_Shdr &Sec) {
4924
  this->forEachRelocationDo(
4925
      Sec, [&](const Relocation<ELFT> &R, unsigned Ndx, const Elf_Shdr &Sec,
4926
               const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); });
4927
}
4928

4929
template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocationsHelper() {
4930
  const bool IsMips64EL = this->Obj.isMips64EL();
4931
  auto DumpCrelRegion = [&](DynRegionInfo &Region) {
4932
    // While the size is unknown, a valid CREL has at least one byte. We can
4933
    // check whether Addr is in bounds, and then decode CREL until the file
4934
    // end.
4935
    Region.Size = Region.EntSize = 1;
4936
    if (!Region.template getAsArrayRef<uint8_t>().empty()) {
4937
      const uint64_t Offset =
4938
          Region.Addr - reinterpret_cast<const uint8_t *>(
4939
                            ObjF.getMemoryBufferRef().getBufferStart());
4940
      const uint64_t ObjSize = ObjF.getMemoryBufferRef().getBufferSize();
4941
      auto RelsOrRelas =
4942
          Obj.decodeCrel(ArrayRef<uint8_t>(Region.Addr, ObjSize - Offset));
4943
      if (!RelsOrRelas) {
4944
        reportUniqueWarning(toString(RelsOrRelas.takeError()));
4945
      } else {
4946
        for (const Elf_Rel &R : RelsOrRelas->first)
4947
          printDynamicReloc(Relocation<ELFT>(R, false));
4948
        for (const Elf_Rela &R : RelsOrRelas->second)
4949
          printDynamicReloc(Relocation<ELFT>(R, false));
4950
      }
4951
    }
4952
  };
4953

4954
  if (this->DynCrelRegion.Addr) {
4955
    printDynamicRelocHeader(ELF::SHT_CREL, "CREL", this->DynCrelRegion);
4956
    DumpCrelRegion(this->DynCrelRegion);
4957
  }
4958

4959
  if (this->DynRelaRegion.Size > 0) {
4960
    printDynamicRelocHeader(ELF::SHT_RELA, "RELA", this->DynRelaRegion);
4961
    for (const Elf_Rela &Rela :
4962
         this->DynRelaRegion.template getAsArrayRef<Elf_Rela>())
4963
      printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL));
4964
  }
4965

4966
  if (this->DynRelRegion.Size > 0) {
4967
    printDynamicRelocHeader(ELF::SHT_REL, "REL", this->DynRelRegion);
4968
    for (const Elf_Rel &Rel :
4969
         this->DynRelRegion.template getAsArrayRef<Elf_Rel>())
4970
      printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));
4971
  }
4972

4973
  if (this->DynRelrRegion.Size > 0) {
4974
    printDynamicRelocHeader(ELF::SHT_REL, "RELR", this->DynRelrRegion);
4975
    Elf_Relr_Range Relrs =
4976
        this->DynRelrRegion.template getAsArrayRef<Elf_Relr>();
4977
    for (const Elf_Rel &Rel : Obj.decode_relrs(Relrs))
4978
      printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));
4979
  }
4980

4981
  if (this->DynPLTRelRegion.Size) {
4982
    if (this->DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) {
4983
      printDynamicRelocHeader(ELF::SHT_RELA, "PLT", this->DynPLTRelRegion);
4984
      for (const Elf_Rela &Rela :
4985
           this->DynPLTRelRegion.template getAsArrayRef<Elf_Rela>())
4986
        printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL));
4987
    } else if (this->DynPLTRelRegion.EntSize == 1) {
4988
      DumpCrelRegion(this->DynPLTRelRegion);
4989
    } else {
4990
      printDynamicRelocHeader(ELF::SHT_REL, "PLT", this->DynPLTRelRegion);
4991
      for (const Elf_Rel &Rel :
4992
           this->DynPLTRelRegion.template getAsArrayRef<Elf_Rel>())
4993
        printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL));
4994
    }
4995
  }
4996
}
4997

4998
template <class ELFT>
4999
void GNUELFDumper<ELFT>::printGNUVersionSectionProlog(
5000
    const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum) {
5001
  // Don't inline the SecName, because it might report a warning to stderr and
5002
  // corrupt the output.
5003
  StringRef SecName = this->getPrintableSectionName(Sec);
5004
  OS << Label << " section '" << SecName << "' "
5005
     << "contains " << EntriesNum << " entries:\n";
5006

5007
  StringRef LinkedSecName = "<corrupt>";
5008
  if (Expected<const typename ELFT::Shdr *> LinkedSecOrErr =
5009
          this->Obj.getSection(Sec.sh_link))
5010
    LinkedSecName = this->getPrintableSectionName(**LinkedSecOrErr);
5011
  else
5012
    this->reportUniqueWarning("invalid section linked to " +
5013
                              this->describe(Sec) + ": " +
5014
                              toString(LinkedSecOrErr.takeError()));
5015

5016
  OS << " Addr: " << format_hex_no_prefix(Sec.sh_addr, 16)
5017
     << "  Offset: " << format_hex(Sec.sh_offset, 8)
5018
     << "  Link: " << Sec.sh_link << " (" << LinkedSecName << ")\n";
5019
}
5020

5021
template <class ELFT>
5022
void GNUELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) {
5023
  if (!Sec)
5024
    return;
5025

5026
  printGNUVersionSectionProlog(*Sec, "Version symbols",
5027
                               Sec->sh_size / sizeof(Elf_Versym));
5028
  Expected<ArrayRef<Elf_Versym>> VerTableOrErr =
5029
      this->getVersionTable(*Sec, /*SymTab=*/nullptr,
5030
                            /*StrTab=*/nullptr, /*SymTabSec=*/nullptr);
5031
  if (!VerTableOrErr) {
5032
    this->reportUniqueWarning(VerTableOrErr.takeError());
5033
    return;
5034
  }
5035

5036
  SmallVector<std::optional<VersionEntry>, 0> *VersionMap = nullptr;
5037
  if (Expected<SmallVector<std::optional<VersionEntry>, 0> *> MapOrErr =
5038
          this->getVersionMap())
5039
    VersionMap = *MapOrErr;
5040
  else
5041
    this->reportUniqueWarning(MapOrErr.takeError());
5042

5043
  ArrayRef<Elf_Versym> VerTable = *VerTableOrErr;
5044
  std::vector<StringRef> Versions;
5045
  for (size_t I = 0, E = VerTable.size(); I < E; ++I) {
5046
    unsigned Ndx = VerTable[I].vs_index;
5047
    if (Ndx == VER_NDX_LOCAL || Ndx == VER_NDX_GLOBAL) {
5048
      Versions.emplace_back(Ndx == VER_NDX_LOCAL ? "*local*" : "*global*");
5049
      continue;
5050
    }
5051

5052
    if (!VersionMap) {
5053
      Versions.emplace_back("<corrupt>");
5054
      continue;
5055
    }
5056

5057
    bool IsDefault;
5058
    Expected<StringRef> NameOrErr = this->Obj.getSymbolVersionByIndex(
5059
        Ndx, IsDefault, *VersionMap, /*IsSymHidden=*/std::nullopt);
5060
    if (!NameOrErr) {
5061
      this->reportUniqueWarning("unable to get a version for entry " +
5062
                                Twine(I) + " of " + this->describe(*Sec) +
5063
                                ": " + toString(NameOrErr.takeError()));
5064
      Versions.emplace_back("<corrupt>");
5065
      continue;
5066
    }
5067
    Versions.emplace_back(*NameOrErr);
5068
  }
5069

5070
  // readelf prints 4 entries per line.
5071
  uint64_t Entries = VerTable.size();
5072
  for (uint64_t VersymRow = 0; VersymRow < Entries; VersymRow += 4) {
5073
    OS << "  " << format_hex_no_prefix(VersymRow, 3) << ":";
5074
    for (uint64_t I = 0; (I < 4) && (I + VersymRow) < Entries; ++I) {
5075
      unsigned Ndx = VerTable[VersymRow + I].vs_index;
5076
      OS << format("%4x%c", Ndx & VERSYM_VERSION,
5077
                   Ndx & VERSYM_HIDDEN ? 'h' : ' ');
5078
      OS << left_justify("(" + std::string(Versions[VersymRow + I]) + ")", 13);
5079
    }
5080
    OS << '\n';
5081
  }
5082
  OS << '\n';
5083
}
5084

5085
static std::string versionFlagToString(unsigned Flags) {
5086
  if (Flags == 0)
5087
    return "none";
5088

5089
  std::string Ret;
5090
  auto AddFlag = [&Ret, &Flags](unsigned Flag, StringRef Name) {
5091
    if (!(Flags & Flag))
5092
      return;
5093
    if (!Ret.empty())
5094
      Ret += " | ";
5095
    Ret += Name;
5096
    Flags &= ~Flag;
5097
  };
5098

5099
  AddFlag(VER_FLG_BASE, "BASE");
5100
  AddFlag(VER_FLG_WEAK, "WEAK");
5101
  AddFlag(VER_FLG_INFO, "INFO");
5102
  AddFlag(~0, "<unknown>");
5103
  return Ret;
5104
}
5105

5106
template <class ELFT>
5107
void GNUELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) {
5108
  if (!Sec)
5109
    return;
5110

5111
  printGNUVersionSectionProlog(*Sec, "Version definition", Sec->sh_info);
5112

5113
  Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec);
5114
  if (!V) {
5115
    this->reportUniqueWarning(V.takeError());
5116
    return;
5117
  }
5118

5119
  for (const VerDef &Def : *V) {
5120
    OS << format("  0x%04x: Rev: %u  Flags: %s  Index: %u  Cnt: %u  Name: %s\n",
5121
                 Def.Offset, Def.Version,
5122
                 versionFlagToString(Def.Flags).c_str(), Def.Ndx, Def.Cnt,
5123
                 Def.Name.data());
5124
    unsigned I = 0;
5125
    for (const VerdAux &Aux : Def.AuxV)
5126
      OS << format("  0x%04x: Parent %u: %s\n", Aux.Offset, ++I,
5127
                   Aux.Name.data());
5128
  }
5129

5130
  OS << '\n';
5131
}
5132

5133
template <class ELFT>
5134
void GNUELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) {
5135
  if (!Sec)
5136
    return;
5137

5138
  unsigned VerneedNum = Sec->sh_info;
5139
  printGNUVersionSectionProlog(*Sec, "Version needs", VerneedNum);
5140

5141
  Expected<std::vector<VerNeed>> V =
5142
      this->Obj.getVersionDependencies(*Sec, this->WarningHandler);
5143
  if (!V) {
5144
    this->reportUniqueWarning(V.takeError());
5145
    return;
5146
  }
5147

5148
  for (const VerNeed &VN : *V) {
5149
    OS << format("  0x%04x: Version: %u  File: %s  Cnt: %u\n", VN.Offset,
5150
                 VN.Version, VN.File.data(), VN.Cnt);
5151
    for (const VernAux &Aux : VN.AuxV)
5152
      OS << format("  0x%04x:   Name: %s  Flags: %s  Version: %u\n", Aux.Offset,
5153
                   Aux.Name.data(), versionFlagToString(Aux.Flags).c_str(),
5154
                   Aux.Other);
5155
  }
5156
  OS << '\n';
5157
}
5158

5159
template <class ELFT>
5160
void GNUELFDumper<ELFT>::printHashHistogramStats(size_t NBucket,
5161
                                                 size_t MaxChain,
5162
                                                 size_t TotalSyms,
5163
                                                 ArrayRef<size_t> Count,
5164
                                                 bool IsGnu) const {
5165
  size_t CumulativeNonZero = 0;
5166
  OS << "Histogram for" << (IsGnu ? " `.gnu.hash'" : "")
5167
     << " bucket list length (total of " << NBucket << " buckets)\n"
5168
     << " Length  Number     % of total  Coverage\n";
5169
  for (size_t I = 0; I < MaxChain; ++I) {
5170
    CumulativeNonZero += Count[I] * I;
5171
    OS << format("%7lu  %-10lu (%5.1f%%)     %5.1f%%\n", I, Count[I],
5172
                 (Count[I] * 100.0) / NBucket,
5173
                 (CumulativeNonZero * 100.0) / TotalSyms);
5174
  }
5175
}
5176

5177
template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() {
5178
  OS << "GNUStyle::printCGProfile not implemented\n";
5179
}
5180

5181
template <class ELFT>
5182
void GNUELFDumper<ELFT>::printBBAddrMaps(bool /*PrettyPGOAnalysis*/) {
5183
  OS << "GNUStyle::printBBAddrMaps not implemented\n";
5184
}
5185

5186
static Expected<std::vector<uint64_t>> toULEB128Array(ArrayRef<uint8_t> Data) {
5187
  std::vector<uint64_t> Ret;
5188
  const uint8_t *Cur = Data.begin();
5189
  const uint8_t *End = Data.end();
5190
  while (Cur != End) {
5191
    unsigned Size;
5192
    const char *Err = nullptr;
5193
    Ret.push_back(decodeULEB128(Cur, &Size, End, &Err));
5194
    if (Err)
5195
      return createError(Err);
5196
    Cur += Size;
5197
  }
5198
  return Ret;
5199
}
5200

5201
template <class ELFT>
5202
static Expected<std::vector<uint64_t>>
5203
decodeAddrsigSection(const ELFFile<ELFT> &Obj, const typename ELFT::Shdr &Sec) {
5204
  Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Sec);
5205
  if (!ContentsOrErr)
5206
    return ContentsOrErr.takeError();
5207

5208
  if (Expected<std::vector<uint64_t>> SymsOrErr =
5209
          toULEB128Array(*ContentsOrErr))
5210
    return *SymsOrErr;
5211
  else
5212
    return createError("unable to decode " + describe(Obj, Sec) + ": " +
5213
                       toString(SymsOrErr.takeError()));
5214
}
5215

5216
template <class ELFT> void GNUELFDumper<ELFT>::printAddrsig() {
5217
  if (!this->DotAddrsigSec)
5218
    return;
5219

5220
  Expected<std::vector<uint64_t>> SymsOrErr =
5221
      decodeAddrsigSection(this->Obj, *this->DotAddrsigSec);
5222
  if (!SymsOrErr) {
5223
    this->reportUniqueWarning(SymsOrErr.takeError());
5224
    return;
5225
  }
5226

5227
  StringRef Name = this->getPrintableSectionName(*this->DotAddrsigSec);
5228
  OS << "\nAddress-significant symbols section '" << Name << "'"
5229
     << " contains " << SymsOrErr->size() << " entries:\n";
5230
  OS << "   Num: Name\n";
5231

5232
  Field Fields[2] = {0, 8};
5233
  size_t SymIndex = 0;
5234
  for (uint64_t Sym : *SymsOrErr) {
5235
    Fields[0].Str = to_string(format_decimal(++SymIndex, 6)) + ":";
5236
    Fields[1].Str = this->getStaticSymbolName(Sym);
5237
    for (const Field &Entry : Fields)
5238
      printField(Entry);
5239
    OS << "\n";
5240
  }
5241
}
5242

5243
template <class ELFT>
5244
static bool printAArch64PAuthABICoreInfo(raw_ostream &OS, uint32_t DataSize,
5245
                                         ArrayRef<uint8_t> Desc) {
5246
  OS << "    AArch64 PAuth ABI core info: ";
5247
  // DataSize - size without padding, Desc.size() - size with padding
5248
  if (DataSize != 16) {
5249
    OS << format("<corrupted size: expected 16, got %d>", DataSize);
5250
    return false;
5251
  }
5252

5253
  uint64_t Platform =
5254
      support::endian::read64<ELFT::Endianness>(Desc.data() + 0);
5255
  uint64_t Version = support::endian::read64<ELFT::Endianness>(Desc.data() + 8);
5256

5257
  const char *PlatformDesc = [Platform]() {
5258
    switch (Platform) {
5259
    case AARCH64_PAUTH_PLATFORM_INVALID:
5260
      return "invalid";
5261
    case AARCH64_PAUTH_PLATFORM_BAREMETAL:
5262
      return "baremetal";
5263
    case AARCH64_PAUTH_PLATFORM_LLVM_LINUX:
5264
      return "llvm_linux";
5265
    default:
5266
      return "unknown";
5267
    }
5268
  }();
5269

5270
  std::string VersionDesc = [Platform, Version]() -> std::string {
5271
    if (Platform != AARCH64_PAUTH_PLATFORM_LLVM_LINUX)
5272
      return "";
5273
    if (Version >= (1 << (AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST + 1)))
5274
      return "unknown";
5275

5276
    std::array<StringRef, AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST + 1>
5277
        Flags;
5278
    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS] = "Intrinsics";
5279
    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS] = "Calls";
5280
    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS] = "Returns";
5281
    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS] = "AuthTraps";
5282
    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR] =
5283
        "VTPtrAddressDiscrimination";
5284
    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR] =
5285
        "VTPtrTypeDiscrimination";
5286
    Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI] = "InitFini";
5287

5288
    static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI ==
5289
                      AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST,
5290
                  "Update when new enum items are defined");
5291

5292
    std::string Desc;
5293
    for (uint32_t I = 0, End = Flags.size(); I < End; ++I) {
5294
      if (!(Version & (1ULL << I)))
5295
        Desc += '!';
5296
      Desc +=
5297
          Twine("PointerAuth" + Flags[I] + (I == End - 1 ? "" : ", ")).str();
5298
    }
5299
    return Desc;
5300
  }();
5301

5302
  OS << format("platform 0x%" PRIx64 " (%s), version 0x%" PRIx64, Platform,
5303
               PlatformDesc, Version);
5304
  if (!VersionDesc.empty())
5305
    OS << format(" (%s)", VersionDesc.c_str());
5306

5307
  return true;
5308
}
5309

5310
template <typename ELFT>
5311
static std::string getGNUProperty(uint32_t Type, uint32_t DataSize,
5312
                                  ArrayRef<uint8_t> Data) {
5313
  std::string str;
5314
  raw_string_ostream OS(str);
5315
  uint32_t PrData;
5316
  auto DumpBit = [&](uint32_t Flag, StringRef Name) {
5317
    if (PrData & Flag) {
5318
      PrData &= ~Flag;
5319
      OS << Name;
5320
      if (PrData)
5321
        OS << ", ";
5322
    }
5323
  };
5324

5325
  switch (Type) {
5326
  default:
5327
    OS << format("<application-specific type 0x%x>", Type);
5328
    return OS.str();
5329
  case GNU_PROPERTY_STACK_SIZE: {
5330
    OS << "stack size: ";
5331
    if (DataSize == sizeof(typename ELFT::uint))
5332
      OS << formatv("{0:x}",
5333
                    (uint64_t)(*(const typename ELFT::Addr *)Data.data()));
5334
    else
5335
      OS << format("<corrupt length: 0x%x>", DataSize);
5336
    return OS.str();
5337
  }
5338
  case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
5339
    OS << "no copy on protected";
5340
    if (DataSize)
5341
      OS << format(" <corrupt length: 0x%x>", DataSize);
5342
    return OS.str();
5343
  case GNU_PROPERTY_AARCH64_FEATURE_1_AND:
5344
  case GNU_PROPERTY_X86_FEATURE_1_AND:
5345
    OS << ((Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) ? "aarch64 feature: "
5346
                                                        : "x86 feature: ");
5347
    if (DataSize != 4) {
5348
      OS << format("<corrupt length: 0x%x>", DataSize);
5349
      return OS.str();
5350
    }
5351
    PrData = endian::read32<ELFT::Endianness>(Data.data());
5352
    if (PrData == 0) {
5353
      OS << "<None>";
5354
      return OS.str();
5355
    }
5356
    if (Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
5357
      DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI");
5358
      DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC");
5359
      DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_GCS, "GCS");
5360
    } else {
5361
      DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT");
5362
      DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK");
5363
    }
5364
    if (PrData)
5365
      OS << format("<unknown flags: 0x%x>", PrData);
5366
    return OS.str();
5367
  case GNU_PROPERTY_AARCH64_FEATURE_PAUTH:
5368
    printAArch64PAuthABICoreInfo<ELFT>(OS, DataSize, Data);
5369
    return OS.str();
5370
  case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
5371
  case GNU_PROPERTY_X86_FEATURE_2_USED:
5372
    OS << "x86 feature "
5373
       << (Type == GNU_PROPERTY_X86_FEATURE_2_NEEDED ? "needed: " : "used: ");
5374
    if (DataSize != 4) {
5375
      OS << format("<corrupt length: 0x%x>", DataSize);
5376
      return OS.str();
5377
    }
5378
    PrData = endian::read32<ELFT::Endianness>(Data.data());
5379
    if (PrData == 0) {
5380
      OS << "<None>";
5381
      return OS.str();
5382
    }
5383
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_X86, "x86");
5384
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_X87, "x87");
5385
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_MMX, "MMX");
5386
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XMM, "XMM");
5387
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_YMM, "YMM");
5388
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_ZMM, "ZMM");
5389
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_FXSR, "FXSR");
5390
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVE, "XSAVE");
5391
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT, "XSAVEOPT");
5392
    DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEC, "XSAVEC");
5393
    if (PrData)
5394
      OS << format("<unknown flags: 0x%x>", PrData);
5395
    return OS.str();
5396
  case GNU_PROPERTY_X86_ISA_1_NEEDED:
5397
  case GNU_PROPERTY_X86_ISA_1_USED:
5398
    OS << "x86 ISA "
5399
       << (Type == GNU_PROPERTY_X86_ISA_1_NEEDED ? "needed: " : "used: ");
5400
    if (DataSize != 4) {
5401
      OS << format("<corrupt length: 0x%x>", DataSize);
5402
      return OS.str();
5403
    }
5404
    PrData = endian::read32<ELFT::Endianness>(Data.data());
5405
    if (PrData == 0) {
5406
      OS << "<None>";
5407
      return OS.str();
5408
    }
5409
    DumpBit(GNU_PROPERTY_X86_ISA_1_BASELINE, "x86-64-baseline");
5410
    DumpBit(GNU_PROPERTY_X86_ISA_1_V2, "x86-64-v2");
5411
    DumpBit(GNU_PROPERTY_X86_ISA_1_V3, "x86-64-v3");
5412
    DumpBit(GNU_PROPERTY_X86_ISA_1_V4, "x86-64-v4");
5413
    if (PrData)
5414
      OS << format("<unknown flags: 0x%x>", PrData);
5415
    return OS.str();
5416
  }
5417
}
5418

5419
template <typename ELFT>
5420
static SmallVector<std::string, 4> getGNUPropertyList(ArrayRef<uint8_t> Arr) {
5421
  using Elf_Word = typename ELFT::Word;
5422

5423
  SmallVector<std::string, 4> Properties;
5424
  while (Arr.size() >= 8) {
5425
    uint32_t Type = *reinterpret_cast<const Elf_Word *>(Arr.data());
5426
    uint32_t DataSize = *reinterpret_cast<const Elf_Word *>(Arr.data() + 4);
5427
    Arr = Arr.drop_front(8);
5428

5429
    // Take padding size into account if present.
5430
    uint64_t PaddedSize = alignTo(DataSize, sizeof(typename ELFT::uint));
5431
    std::string str;
5432
    raw_string_ostream OS(str);
5433
    if (Arr.size() < PaddedSize) {
5434
      OS << format("<corrupt type (0x%x) datasz: 0x%x>", Type, DataSize);
5435
      Properties.push_back(OS.str());
5436
      break;
5437
    }
5438
    Properties.push_back(
5439
        getGNUProperty<ELFT>(Type, DataSize, Arr.take_front(PaddedSize)));
5440
    Arr = Arr.drop_front(PaddedSize);
5441
  }
5442

5443
  if (!Arr.empty())
5444
    Properties.push_back("<corrupted GNU_PROPERTY_TYPE_0>");
5445

5446
  return Properties;
5447
}
5448

5449
struct GNUAbiTag {
5450
  std::string OSName;
5451
  std::string ABI;
5452
  bool IsValid;
5453
};
5454

5455
template <typename ELFT> static GNUAbiTag getGNUAbiTag(ArrayRef<uint8_t> Desc) {
5456
  typedef typename ELFT::Word Elf_Word;
5457

5458
  ArrayRef<Elf_Word> Words(reinterpret_cast<const Elf_Word *>(Desc.begin()),
5459
                           reinterpret_cast<const Elf_Word *>(Desc.end()));
5460

5461
  if (Words.size() < 4)
5462
    return {"", "", /*IsValid=*/false};
5463

5464
  static const char *OSNames[] = {
5465
      "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable", "NaCl",
5466
  };
5467
  StringRef OSName = "Unknown";
5468
  if (Words[0] < std::size(OSNames))
5469
    OSName = OSNames[Words[0]];
5470
  uint32_t Major = Words[1], Minor = Words[2], Patch = Words[3];
5471
  std::string str;
5472
  raw_string_ostream ABI(str);
5473
  ABI << Major << "." << Minor << "." << Patch;
5474
  return {std::string(OSName), ABI.str(), /*IsValid=*/true};
5475
}
5476

5477
static std::string getGNUBuildId(ArrayRef<uint8_t> Desc) {
5478
  std::string str;
5479
  raw_string_ostream OS(str);
5480
  for (uint8_t B : Desc)
5481
    OS << format_hex_no_prefix(B, 2);
5482
  return OS.str();
5483
}
5484

5485
static StringRef getDescAsStringRef(ArrayRef<uint8_t> Desc) {
5486
  return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
5487
}
5488

5489
template <typename ELFT>
5490
static bool printGNUNote(raw_ostream &OS, uint32_t NoteType,
5491
                         ArrayRef<uint8_t> Desc) {
5492
  // Return true if we were able to pretty-print the note, false otherwise.
5493
  switch (NoteType) {
5494
  default:
5495
    return false;
5496
  case ELF::NT_GNU_ABI_TAG: {
5497
    const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
5498
    if (!AbiTag.IsValid)
5499
      OS << "    <corrupt GNU_ABI_TAG>";
5500
    else
5501
      OS << "    OS: " << AbiTag.OSName << ", ABI: " << AbiTag.ABI;
5502
    break;
5503
  }
5504
  case ELF::NT_GNU_BUILD_ID: {
5505
    OS << "    Build ID: " << getGNUBuildId(Desc);
5506
    break;
5507
  }
5508
  case ELF::NT_GNU_GOLD_VERSION:
5509
    OS << "    Version: " << getDescAsStringRef(Desc);
5510
    break;
5511
  case ELF::NT_GNU_PROPERTY_TYPE_0:
5512
    OS << "    Properties:";
5513
    for (const std::string &Property : getGNUPropertyList<ELFT>(Desc))
5514
      OS << "    " << Property << "\n";
5515
    break;
5516
  }
5517
  OS << '\n';
5518
  return true;
5519
}
5520

5521
using AndroidNoteProperties = std::vector<std::pair<StringRef, std::string>>;
5522
static AndroidNoteProperties getAndroidNoteProperties(uint32_t NoteType,
5523
                                                      ArrayRef<uint8_t> Desc) {
5524
  AndroidNoteProperties Props;
5525
  switch (NoteType) {
5526
  case ELF::NT_ANDROID_TYPE_MEMTAG:
5527
    if (Desc.empty()) {
5528
      Props.emplace_back("Invalid .note.android.memtag", "");
5529
      return Props;
5530
    }
5531

5532
    switch (Desc[0] & NT_MEMTAG_LEVEL_MASK) {
5533
    case NT_MEMTAG_LEVEL_NONE:
5534
      Props.emplace_back("Tagging Mode", "NONE");
5535
      break;
5536
    case NT_MEMTAG_LEVEL_ASYNC:
5537
      Props.emplace_back("Tagging Mode", "ASYNC");
5538
      break;
5539
    case NT_MEMTAG_LEVEL_SYNC:
5540
      Props.emplace_back("Tagging Mode", "SYNC");
5541
      break;
5542
    default:
5543
      Props.emplace_back(
5544
          "Tagging Mode",
5545
          ("Unknown (" + Twine::utohexstr(Desc[0] & NT_MEMTAG_LEVEL_MASK) + ")")
5546
              .str());
5547
      break;
5548
    }
5549
    Props.emplace_back("Heap",
5550
                       (Desc[0] & NT_MEMTAG_HEAP) ? "Enabled" : "Disabled");
5551
    Props.emplace_back("Stack",
5552
                       (Desc[0] & NT_MEMTAG_STACK) ? "Enabled" : "Disabled");
5553
    break;
5554
  default:
5555
    return Props;
5556
  }
5557
  return Props;
5558
}
5559

5560
static bool printAndroidNote(raw_ostream &OS, uint32_t NoteType,
5561
                             ArrayRef<uint8_t> Desc) {
5562
  // Return true if we were able to pretty-print the note, false otherwise.
5563
  AndroidNoteProperties Props = getAndroidNoteProperties(NoteType, Desc);
5564
  if (Props.empty())
5565
    return false;
5566
  for (const auto &KV : Props)
5567
    OS << "    " << KV.first << ": " << KV.second << '\n';
5568
  return true;
5569
}
5570

5571
template <class ELFT>
5572
void GNUELFDumper<ELFT>::printMemtag(
5573
    const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,
5574
    const ArrayRef<uint8_t> AndroidNoteDesc,
5575
    const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) {
5576
  OS << "Memtag Dynamic Entries:\n";
5577
  if (DynamicEntries.empty())
5578
    OS << "    < none found >\n";
5579
  for (const auto &DynamicEntryKV : DynamicEntries)
5580
    OS << "    " << DynamicEntryKV.first << ": " << DynamicEntryKV.second
5581
       << "\n";
5582

5583
  if (!AndroidNoteDesc.empty()) {
5584
    OS << "Memtag Android Note:\n";
5585
    printAndroidNote(OS, ELF::NT_ANDROID_TYPE_MEMTAG, AndroidNoteDesc);
5586
  }
5587

5588
  if (Descriptors.empty())
5589
    return;
5590

5591
  OS << "Memtag Global Descriptors:\n";
5592
  for (const auto &[Addr, BytesToTag] : Descriptors) {
5593
    OS << "    0x" << utohexstr(Addr, /*LowerCase=*/true) << ": 0x"
5594
       << utohexstr(BytesToTag, /*LowerCase=*/true) << "\n";
5595
  }
5596
}
5597

5598
template <typename ELFT>
5599
static bool printLLVMOMPOFFLOADNote(raw_ostream &OS, uint32_t NoteType,
5600
                                    ArrayRef<uint8_t> Desc) {
5601
  switch (NoteType) {
5602
  default:
5603
    return false;
5604
  case ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION:
5605
    OS << "    Version: " << getDescAsStringRef(Desc);
5606
    break;
5607
  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER:
5608
    OS << "    Producer: " << getDescAsStringRef(Desc);
5609
    break;
5610
  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION:
5611
    OS << "    Producer version: " << getDescAsStringRef(Desc);
5612
    break;
5613
  }
5614
  OS << '\n';
5615
  return true;
5616
}
5617

5618
const EnumEntry<unsigned> FreeBSDFeatureCtlFlags[] = {
5619
    {"ASLR_DISABLE", NT_FREEBSD_FCTL_ASLR_DISABLE},
5620
    {"PROTMAX_DISABLE", NT_FREEBSD_FCTL_PROTMAX_DISABLE},
5621
    {"STKGAP_DISABLE", NT_FREEBSD_FCTL_STKGAP_DISABLE},
5622
    {"WXNEEDED", NT_FREEBSD_FCTL_WXNEEDED},
5623
    {"LA48", NT_FREEBSD_FCTL_LA48},
5624
    {"ASG_DISABLE", NT_FREEBSD_FCTL_ASG_DISABLE},
5625
};
5626

5627
struct FreeBSDNote {
5628
  std::string Type;
5629
  std::string Value;
5630
};
5631

5632
template <typename ELFT>
5633
static std::optional<FreeBSDNote>
5634
getFreeBSDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc, bool IsCore) {
5635
  if (IsCore)
5636
    return std::nullopt; // No pretty-printing yet.
5637
  switch (NoteType) {
5638
  case ELF::NT_FREEBSD_ABI_TAG:
5639
    if (Desc.size() != 4)
5640
      return std::nullopt;
5641
    return FreeBSDNote{"ABI tag",
5642
                       utostr(endian::read32<ELFT::Endianness>(Desc.data()))};
5643
  case ELF::NT_FREEBSD_ARCH_TAG:
5644
    return FreeBSDNote{"Arch tag", toStringRef(Desc).str()};
5645
  case ELF::NT_FREEBSD_FEATURE_CTL: {
5646
    if (Desc.size() != 4)
5647
      return std::nullopt;
5648
    unsigned Value = endian::read32<ELFT::Endianness>(Desc.data());
5649
    std::string FlagsStr;
5650
    raw_string_ostream OS(FlagsStr);
5651
    printFlags(Value, ArrayRef(FreeBSDFeatureCtlFlags), OS);
5652
    if (OS.str().empty())
5653
      OS << "0x" << utohexstr(Value);
5654
    else
5655
      OS << "(0x" << utohexstr(Value) << ")";
5656
    return FreeBSDNote{"Feature flags", OS.str()};
5657
  }
5658
  default:
5659
    return std::nullopt;
5660
  }
5661
}
5662

5663
struct AMDNote {
5664
  std::string Type;
5665
  std::string Value;
5666
};
5667

5668
template <typename ELFT>
5669
static AMDNote getAMDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
5670
  switch (NoteType) {
5671
  default:
5672
    return {"", ""};
5673
  case ELF::NT_AMD_HSA_CODE_OBJECT_VERSION: {
5674
    struct CodeObjectVersion {
5675
      support::aligned_ulittle32_t MajorVersion;
5676
      support::aligned_ulittle32_t MinorVersion;
5677
    };
5678
    if (Desc.size() != sizeof(CodeObjectVersion))
5679
      return {"AMD HSA Code Object Version",
5680
              "Invalid AMD HSA Code Object Version"};
5681
    std::string VersionString;
5682
    raw_string_ostream StrOS(VersionString);
5683
    auto Version = reinterpret_cast<const CodeObjectVersion *>(Desc.data());
5684
    StrOS << "[Major: " << Version->MajorVersion
5685
          << ", Minor: " << Version->MinorVersion << "]";
5686
    return {"AMD HSA Code Object Version", VersionString};
5687
  }
5688
  case ELF::NT_AMD_HSA_HSAIL: {
5689
    struct HSAILProperties {
5690
      support::aligned_ulittle32_t HSAILMajorVersion;
5691
      support::aligned_ulittle32_t HSAILMinorVersion;
5692
      uint8_t Profile;
5693
      uint8_t MachineModel;
5694
      uint8_t DefaultFloatRound;
5695
    };
5696
    if (Desc.size() != sizeof(HSAILProperties))
5697
      return {"AMD HSA HSAIL Properties", "Invalid AMD HSA HSAIL Properties"};
5698
    auto Properties = reinterpret_cast<const HSAILProperties *>(Desc.data());
5699
    std::string HSAILPropetiesString;
5700
    raw_string_ostream StrOS(HSAILPropetiesString);
5701
    StrOS << "[HSAIL Major: " << Properties->HSAILMajorVersion
5702
          << ", HSAIL Minor: " << Properties->HSAILMinorVersion
5703
          << ", Profile: " << uint32_t(Properties->Profile)
5704
          << ", Machine Model: " << uint32_t(Properties->MachineModel)
5705
          << ", Default Float Round: "
5706
          << uint32_t(Properties->DefaultFloatRound) << "]";
5707
    return {"AMD HSA HSAIL Properties", HSAILPropetiesString};
5708
  }
5709
  case ELF::NT_AMD_HSA_ISA_VERSION: {
5710
    struct IsaVersion {
5711
      support::aligned_ulittle16_t VendorNameSize;
5712
      support::aligned_ulittle16_t ArchitectureNameSize;
5713
      support::aligned_ulittle32_t Major;
5714
      support::aligned_ulittle32_t Minor;
5715
      support::aligned_ulittle32_t Stepping;
5716
    };
5717
    if (Desc.size() < sizeof(IsaVersion))
5718
      return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"};
5719
    auto Isa = reinterpret_cast<const IsaVersion *>(Desc.data());
5720
    if (Desc.size() < sizeof(IsaVersion) +
5721
                          Isa->VendorNameSize + Isa->ArchitectureNameSize ||
5722
        Isa->VendorNameSize == 0 || Isa->ArchitectureNameSize == 0)
5723
      return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"};
5724
    std::string IsaString;
5725
    raw_string_ostream StrOS(IsaString);
5726
    StrOS << "[Vendor: "
5727
          << StringRef((const char*)Desc.data() + sizeof(IsaVersion), Isa->VendorNameSize - 1)
5728
          << ", Architecture: "
5729
          << StringRef((const char*)Desc.data() + sizeof(IsaVersion) + Isa->VendorNameSize,
5730
                       Isa->ArchitectureNameSize - 1)
5731
          << ", Major: " << Isa->Major << ", Minor: " << Isa->Minor
5732
          << ", Stepping: " << Isa->Stepping << "]";
5733
    return {"AMD HSA ISA Version", IsaString};
5734
  }
5735
  case ELF::NT_AMD_HSA_METADATA: {
5736
    if (Desc.size() == 0)
5737
      return {"AMD HSA Metadata", ""};
5738
    return {
5739
        "AMD HSA Metadata",
5740
        std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size() - 1)};
5741
  }
5742
  case ELF::NT_AMD_HSA_ISA_NAME: {
5743
    if (Desc.size() == 0)
5744
      return {"AMD HSA ISA Name", ""};
5745
    return {
5746
        "AMD HSA ISA Name",
5747
        std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size())};
5748
  }
5749
  case ELF::NT_AMD_PAL_METADATA: {
5750
    struct PALMetadata {
5751
      support::aligned_ulittle32_t Key;
5752
      support::aligned_ulittle32_t Value;
5753
    };
5754
    if (Desc.size() % sizeof(PALMetadata) != 0)
5755
      return {"AMD PAL Metadata", "Invalid AMD PAL Metadata"};
5756
    auto Isa = reinterpret_cast<const PALMetadata *>(Desc.data());
5757
    std::string MetadataString;
5758
    raw_string_ostream StrOS(MetadataString);
5759
    for (size_t I = 0, E = Desc.size() / sizeof(PALMetadata); I < E; ++I) {
5760
      StrOS << "[" << Isa[I].Key << ": " << Isa[I].Value << "]";
5761
    }
5762
    return {"AMD PAL Metadata", MetadataString};
5763
  }
5764
  }
5765
}
5766

5767
struct AMDGPUNote {
5768
  std::string Type;
5769
  std::string Value;
5770
};
5771

5772
template <typename ELFT>
5773
static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) {
5774
  switch (NoteType) {
5775
  default:
5776
    return {"", ""};
5777
  case ELF::NT_AMDGPU_METADATA: {
5778
    StringRef MsgPackString =
5779
        StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
5780
    msgpack::Document MsgPackDoc;
5781
    if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false))
5782
      return {"", ""};
5783

5784
    std::string MetadataString;
5785

5786
    // FIXME: Metadata Verifier only works with AMDHSA.
5787
    //  This is an ugly workaround to avoid the verifier for other MD
5788
    //  formats (e.g. amdpal)
5789
    if (MsgPackString.contains("amdhsa.")) {
5790
      AMDGPU::HSAMD::V3::MetadataVerifier Verifier(true);
5791
      if (!Verifier.verify(MsgPackDoc.getRoot()))
5792
        MetadataString = "Invalid AMDGPU Metadata\n";
5793
    }
5794

5795
    raw_string_ostream StrOS(MetadataString);
5796
    if (MsgPackDoc.getRoot().isScalar()) {
5797
      // TODO: passing a scalar root to toYAML() asserts:
5798
      // (PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar &&
5799
      //    "plain scalar documents are not supported")
5800
      // To avoid this crash we print the raw data instead.
5801
      return {"", ""};
5802
    }
5803
    MsgPackDoc.toYAML(StrOS);
5804
    return {"AMDGPU Metadata", StrOS.str()};
5805
  }
5806
  }
5807
}
5808

5809
struct CoreFileMapping {
5810
  uint64_t Start, End, Offset;
5811
  StringRef Filename;
5812
};
5813

5814
struct CoreNote {
5815
  uint64_t PageSize;
5816
  std::vector<CoreFileMapping> Mappings;
5817
};
5818

5819
static Expected<CoreNote> readCoreNote(DataExtractor Desc) {
5820
  // Expected format of the NT_FILE note description:
5821
  // 1. # of file mappings (call it N)
5822
  // 2. Page size
5823
  // 3. N (start, end, offset) triples
5824
  // 4. N packed filenames (null delimited)
5825
  // Each field is an Elf_Addr, except for filenames which are char* strings.
5826

5827
  CoreNote Ret;
5828
  const int Bytes = Desc.getAddressSize();
5829

5830
  if (!Desc.isValidOffsetForAddress(2))
5831
    return createError("the note of size 0x" + Twine::utohexstr(Desc.size()) +
5832
                       " is too short, expected at least 0x" +
5833
                       Twine::utohexstr(Bytes * 2));
5834
  if (Desc.getData().back() != 0)
5835
    return createError("the note is not NUL terminated");
5836

5837
  uint64_t DescOffset = 0;
5838
  uint64_t FileCount = Desc.getAddress(&DescOffset);
5839
  Ret.PageSize = Desc.getAddress(&DescOffset);
5840

5841
  if (!Desc.isValidOffsetForAddress(3 * FileCount * Bytes))
5842
    return createError("unable to read file mappings (found " +
5843
                       Twine(FileCount) + "): the note of size 0x" +
5844
                       Twine::utohexstr(Desc.size()) + " is too short");
5845

5846
  uint64_t FilenamesOffset = 0;
5847
  DataExtractor Filenames(
5848
      Desc.getData().drop_front(DescOffset + 3 * FileCount * Bytes),
5849
      Desc.isLittleEndian(), Desc.getAddressSize());
5850

5851
  Ret.Mappings.resize(FileCount);
5852
  size_t I = 0;
5853
  for (CoreFileMapping &Mapping : Ret.Mappings) {
5854
    ++I;
5855
    if (!Filenames.isValidOffsetForDataOfSize(FilenamesOffset, 1))
5856
      return createError(
5857
          "unable to read the file name for the mapping with index " +
5858
          Twine(I) + ": the note of size 0x" + Twine::utohexstr(Desc.size()) +
5859
          " is truncated");
5860
    Mapping.Start = Desc.getAddress(&DescOffset);
5861
    Mapping.End = Desc.getAddress(&DescOffset);
5862
    Mapping.Offset = Desc.getAddress(&DescOffset);
5863
    Mapping.Filename = Filenames.getCStrRef(&FilenamesOffset);
5864
  }
5865

5866
  return Ret;
5867
}
5868

5869
template <typename ELFT>
5870
static void printCoreNote(raw_ostream &OS, const CoreNote &Note) {
5871
  // Length of "0x<address>" string.
5872
  const int FieldWidth = ELFT::Is64Bits ? 18 : 10;
5873

5874
  OS << "    Page size: " << format_decimal(Note.PageSize, 0) << '\n';
5875
  OS << "    " << right_justify("Start", FieldWidth) << "  "
5876
     << right_justify("End", FieldWidth) << "  "
5877
     << right_justify("Page Offset", FieldWidth) << '\n';
5878
  for (const CoreFileMapping &Mapping : Note.Mappings) {
5879
    OS << "    " << format_hex(Mapping.Start, FieldWidth) << "  "
5880
       << format_hex(Mapping.End, FieldWidth) << "  "
5881
       << format_hex(Mapping.Offset, FieldWidth) << "\n        "
5882
       << Mapping.Filename << '\n';
5883
  }
5884
}
5885

5886
const NoteType GenericNoteTypes[] = {
5887
    {ELF::NT_VERSION, "NT_VERSION (version)"},
5888
    {ELF::NT_ARCH, "NT_ARCH (architecture)"},
5889
    {ELF::NT_GNU_BUILD_ATTRIBUTE_OPEN, "OPEN"},
5890
    {ELF::NT_GNU_BUILD_ATTRIBUTE_FUNC, "func"},
5891
};
5892

5893
const NoteType GNUNoteTypes[] = {
5894
    {ELF::NT_GNU_ABI_TAG, "NT_GNU_ABI_TAG (ABI version tag)"},
5895
    {ELF::NT_GNU_HWCAP, "NT_GNU_HWCAP (DSO-supplied software HWCAP info)"},
5896
    {ELF::NT_GNU_BUILD_ID, "NT_GNU_BUILD_ID (unique build ID bitstring)"},
5897
    {ELF::NT_GNU_GOLD_VERSION, "NT_GNU_GOLD_VERSION (gold version)"},
5898
    {ELF::NT_GNU_PROPERTY_TYPE_0, "NT_GNU_PROPERTY_TYPE_0 (property note)"},
5899
};
5900

5901
const NoteType FreeBSDCoreNoteTypes[] = {
5902
    {ELF::NT_FREEBSD_THRMISC, "NT_THRMISC (thrmisc structure)"},
5903
    {ELF::NT_FREEBSD_PROCSTAT_PROC, "NT_PROCSTAT_PROC (proc data)"},
5904
    {ELF::NT_FREEBSD_PROCSTAT_FILES, "NT_PROCSTAT_FILES (files data)"},
5905
    {ELF::NT_FREEBSD_PROCSTAT_VMMAP, "NT_PROCSTAT_VMMAP (vmmap data)"},
5906
    {ELF::NT_FREEBSD_PROCSTAT_GROUPS, "NT_PROCSTAT_GROUPS (groups data)"},
5907
    {ELF::NT_FREEBSD_PROCSTAT_UMASK, "NT_PROCSTAT_UMASK (umask data)"},
5908
    {ELF::NT_FREEBSD_PROCSTAT_RLIMIT, "NT_PROCSTAT_RLIMIT (rlimit data)"},
5909
    {ELF::NT_FREEBSD_PROCSTAT_OSREL, "NT_PROCSTAT_OSREL (osreldate data)"},
5910
    {ELF::NT_FREEBSD_PROCSTAT_PSSTRINGS,
5911
     "NT_PROCSTAT_PSSTRINGS (ps_strings data)"},
5912
    {ELF::NT_FREEBSD_PROCSTAT_AUXV, "NT_PROCSTAT_AUXV (auxv data)"},
5913
};
5914

5915
const NoteType FreeBSDNoteTypes[] = {
5916
    {ELF::NT_FREEBSD_ABI_TAG, "NT_FREEBSD_ABI_TAG (ABI version tag)"},
5917
    {ELF::NT_FREEBSD_NOINIT_TAG, "NT_FREEBSD_NOINIT_TAG (no .init tag)"},
5918
    {ELF::NT_FREEBSD_ARCH_TAG, "NT_FREEBSD_ARCH_TAG (architecture tag)"},
5919
    {ELF::NT_FREEBSD_FEATURE_CTL,
5920
     "NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)"},
5921
};
5922

5923
const NoteType NetBSDCoreNoteTypes[] = {
5924
    {ELF::NT_NETBSDCORE_PROCINFO,
5925
     "NT_NETBSDCORE_PROCINFO (procinfo structure)"},
5926
    {ELF::NT_NETBSDCORE_AUXV, "NT_NETBSDCORE_AUXV (ELF auxiliary vector data)"},
5927
    {ELF::NT_NETBSDCORE_LWPSTATUS, "PT_LWPSTATUS (ptrace_lwpstatus structure)"},
5928
};
5929

5930
const NoteType OpenBSDCoreNoteTypes[] = {
5931
    {ELF::NT_OPENBSD_PROCINFO, "NT_OPENBSD_PROCINFO (procinfo structure)"},
5932
    {ELF::NT_OPENBSD_AUXV, "NT_OPENBSD_AUXV (ELF auxiliary vector data)"},
5933
    {ELF::NT_OPENBSD_REGS, "NT_OPENBSD_REGS (regular registers)"},
5934
    {ELF::NT_OPENBSD_FPREGS, "NT_OPENBSD_FPREGS (floating point registers)"},
5935
    {ELF::NT_OPENBSD_WCOOKIE, "NT_OPENBSD_WCOOKIE (window cookie)"},
5936
};
5937

5938
const NoteType AMDNoteTypes[] = {
5939
    {ELF::NT_AMD_HSA_CODE_OBJECT_VERSION,
5940
     "NT_AMD_HSA_CODE_OBJECT_VERSION (AMD HSA Code Object Version)"},
5941
    {ELF::NT_AMD_HSA_HSAIL, "NT_AMD_HSA_HSAIL (AMD HSA HSAIL Properties)"},
5942
    {ELF::NT_AMD_HSA_ISA_VERSION, "NT_AMD_HSA_ISA_VERSION (AMD HSA ISA Version)"},
5943
    {ELF::NT_AMD_HSA_METADATA, "NT_AMD_HSA_METADATA (AMD HSA Metadata)"},
5944
    {ELF::NT_AMD_HSA_ISA_NAME, "NT_AMD_HSA_ISA_NAME (AMD HSA ISA Name)"},
5945
    {ELF::NT_AMD_PAL_METADATA, "NT_AMD_PAL_METADATA (AMD PAL Metadata)"},
5946
};
5947

5948
const NoteType AMDGPUNoteTypes[] = {
5949
    {ELF::NT_AMDGPU_METADATA, "NT_AMDGPU_METADATA (AMDGPU Metadata)"},
5950
};
5951

5952
const NoteType LLVMOMPOFFLOADNoteTypes[] = {
5953
    {ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION,
5954
     "NT_LLVM_OPENMP_OFFLOAD_VERSION (image format version)"},
5955
    {ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER,
5956
     "NT_LLVM_OPENMP_OFFLOAD_PRODUCER (producing toolchain)"},
5957
    {ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION,
5958
     "NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION (producing toolchain version)"},
5959
};
5960

5961
const NoteType AndroidNoteTypes[] = {
5962
    {ELF::NT_ANDROID_TYPE_IDENT, "NT_ANDROID_TYPE_IDENT"},
5963
    {ELF::NT_ANDROID_TYPE_KUSER, "NT_ANDROID_TYPE_KUSER"},
5964
    {ELF::NT_ANDROID_TYPE_MEMTAG,
5965
     "NT_ANDROID_TYPE_MEMTAG (Android memory tagging information)"},
5966
};
5967

5968
const NoteType CoreNoteTypes[] = {
5969
    {ELF::NT_PRSTATUS, "NT_PRSTATUS (prstatus structure)"},
5970
    {ELF::NT_FPREGSET, "NT_FPREGSET (floating point registers)"},
5971
    {ELF::NT_PRPSINFO, "NT_PRPSINFO (prpsinfo structure)"},
5972
    {ELF::NT_TASKSTRUCT, "NT_TASKSTRUCT (task structure)"},
5973
    {ELF::NT_AUXV, "NT_AUXV (auxiliary vector)"},
5974
    {ELF::NT_PSTATUS, "NT_PSTATUS (pstatus structure)"},
5975
    {ELF::NT_FPREGS, "NT_FPREGS (floating point registers)"},
5976
    {ELF::NT_PSINFO, "NT_PSINFO (psinfo structure)"},
5977
    {ELF::NT_LWPSTATUS, "NT_LWPSTATUS (lwpstatus_t structure)"},
5978
    {ELF::NT_LWPSINFO, "NT_LWPSINFO (lwpsinfo_t structure)"},
5979
    {ELF::NT_WIN32PSTATUS, "NT_WIN32PSTATUS (win32_pstatus structure)"},
5980

5981
    {ELF::NT_PPC_VMX, "NT_PPC_VMX (ppc Altivec registers)"},
5982
    {ELF::NT_PPC_VSX, "NT_PPC_VSX (ppc VSX registers)"},
5983
    {ELF::NT_PPC_TAR, "NT_PPC_TAR (ppc TAR register)"},
5984
    {ELF::NT_PPC_PPR, "NT_PPC_PPR (ppc PPR register)"},
5985
    {ELF::NT_PPC_DSCR, "NT_PPC_DSCR (ppc DSCR register)"},
5986
    {ELF::NT_PPC_EBB, "NT_PPC_EBB (ppc EBB registers)"},
5987
    {ELF::NT_PPC_PMU, "NT_PPC_PMU (ppc PMU registers)"},
5988
    {ELF::NT_PPC_TM_CGPR, "NT_PPC_TM_CGPR (ppc checkpointed GPR registers)"},
5989
    {ELF::NT_PPC_TM_CFPR,
5990
     "NT_PPC_TM_CFPR (ppc checkpointed floating point registers)"},
5991
    {ELF::NT_PPC_TM_CVMX,
5992
     "NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)"},
5993
    {ELF::NT_PPC_TM_CVSX, "NT_PPC_TM_CVSX (ppc checkpointed VSX registers)"},
5994
    {ELF::NT_PPC_TM_SPR, "NT_PPC_TM_SPR (ppc TM special purpose registers)"},
5995
    {ELF::NT_PPC_TM_CTAR, "NT_PPC_TM_CTAR (ppc checkpointed TAR register)"},
5996
    {ELF::NT_PPC_TM_CPPR, "NT_PPC_TM_CPPR (ppc checkpointed PPR register)"},
5997
    {ELF::NT_PPC_TM_CDSCR, "NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)"},
5998

5999
    {ELF::NT_386_TLS, "NT_386_TLS (x86 TLS information)"},
6000
    {ELF::NT_386_IOPERM, "NT_386_IOPERM (x86 I/O permissions)"},
6001
    {ELF::NT_X86_XSTATE, "NT_X86_XSTATE (x86 XSAVE extended state)"},
6002

6003
    {ELF::NT_S390_HIGH_GPRS, "NT_S390_HIGH_GPRS (s390 upper register halves)"},
6004
    {ELF::NT_S390_TIMER, "NT_S390_TIMER (s390 timer register)"},
6005
    {ELF::NT_S390_TODCMP, "NT_S390_TODCMP (s390 TOD comparator register)"},
6006
    {ELF::NT_S390_TODPREG, "NT_S390_TODPREG (s390 TOD programmable register)"},
6007
    {ELF::NT_S390_CTRS, "NT_S390_CTRS (s390 control registers)"},
6008
    {ELF::NT_S390_PREFIX, "NT_S390_PREFIX (s390 prefix register)"},
6009
    {ELF::NT_S390_LAST_BREAK,
6010
     "NT_S390_LAST_BREAK (s390 last breaking event address)"},
6011
    {ELF::NT_S390_SYSTEM_CALL,
6012
     "NT_S390_SYSTEM_CALL (s390 system call restart data)"},
6013
    {ELF::NT_S390_TDB, "NT_S390_TDB (s390 transaction diagnostic block)"},
6014
    {ELF::NT_S390_VXRS_LOW,
6015
     "NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)"},
6016
    {ELF::NT_S390_VXRS_HIGH, "NT_S390_VXRS_HIGH (s390 vector registers 16-31)"},
6017
    {ELF::NT_S390_GS_CB, "NT_S390_GS_CB (s390 guarded-storage registers)"},
6018
    {ELF::NT_S390_GS_BC,
6019
     "NT_S390_GS_BC (s390 guarded-storage broadcast control)"},
6020

6021
    {ELF::NT_ARM_VFP, "NT_ARM_VFP (arm VFP registers)"},
6022
    {ELF::NT_ARM_TLS, "NT_ARM_TLS (AArch TLS registers)"},
6023
    {ELF::NT_ARM_HW_BREAK,
6024
     "NT_ARM_HW_BREAK (AArch hardware breakpoint registers)"},
6025
    {ELF::NT_ARM_HW_WATCH,
6026
     "NT_ARM_HW_WATCH (AArch hardware watchpoint registers)"},
6027
    {ELF::NT_ARM_SVE, "NT_ARM_SVE (AArch64 SVE registers)"},
6028
    {ELF::NT_ARM_PAC_MASK,
6029
     "NT_ARM_PAC_MASK (AArch64 Pointer Authentication code masks)"},
6030
    {ELF::NT_ARM_TAGGED_ADDR_CTRL,
6031
     "NT_ARM_TAGGED_ADDR_CTRL (AArch64 Tagged Address Control)"},
6032
    {ELF::NT_ARM_SSVE, "NT_ARM_SSVE (AArch64 Streaming SVE registers)"},
6033
    {ELF::NT_ARM_ZA, "NT_ARM_ZA (AArch64 SME ZA registers)"},
6034
    {ELF::NT_ARM_ZT, "NT_ARM_ZT (AArch64 SME ZT registers)"},
6035

6036
    {ELF::NT_FILE, "NT_FILE (mapped files)"},
6037
    {ELF::NT_PRXFPREG, "NT_PRXFPREG (user_xfpregs structure)"},
6038
    {ELF::NT_SIGINFO, "NT_SIGINFO (siginfo_t data)"},
6039
};
6040

6041
template <class ELFT>
6042
StringRef getNoteTypeName(const typename ELFT::Note &Note, unsigned ELFType) {
6043
  uint32_t Type = Note.getType();
6044
  auto FindNote = [&](ArrayRef<NoteType> V) -> StringRef {
6045
    for (const NoteType &N : V)
6046
      if (N.ID == Type)
6047
        return N.Name;
6048
    return "";
6049
  };
6050

6051
  StringRef Name = Note.getName();
6052
  if (Name == "GNU")
6053
    return FindNote(GNUNoteTypes);
6054
  if (Name == "FreeBSD") {
6055
    if (ELFType == ELF::ET_CORE) {
6056
      // FreeBSD also places the generic core notes in the FreeBSD namespace.
6057
      StringRef Result = FindNote(FreeBSDCoreNoteTypes);
6058
      if (!Result.empty())
6059
        return Result;
6060
      return FindNote(CoreNoteTypes);
6061
    } else {
6062
      return FindNote(FreeBSDNoteTypes);
6063
    }
6064
  }
6065
  if (ELFType == ELF::ET_CORE && Name.starts_with("NetBSD-CORE")) {
6066
    StringRef Result = FindNote(NetBSDCoreNoteTypes);
6067
    if (!Result.empty())
6068
      return Result;
6069
    return FindNote(CoreNoteTypes);
6070
  }
6071
  if (ELFType == ELF::ET_CORE && Name.starts_with("OpenBSD")) {
6072
    // OpenBSD also places the generic core notes in the OpenBSD namespace.
6073
    StringRef Result = FindNote(OpenBSDCoreNoteTypes);
6074
    if (!Result.empty())
6075
      return Result;
6076
    return FindNote(CoreNoteTypes);
6077
  }
6078
  if (Name == "AMD")
6079
    return FindNote(AMDNoteTypes);
6080
  if (Name == "AMDGPU")
6081
    return FindNote(AMDGPUNoteTypes);
6082
  if (Name == "LLVMOMPOFFLOAD")
6083
    return FindNote(LLVMOMPOFFLOADNoteTypes);
6084
  if (Name == "Android")
6085
    return FindNote(AndroidNoteTypes);
6086

6087
  if (ELFType == ELF::ET_CORE)
6088
    return FindNote(CoreNoteTypes);
6089
  return FindNote(GenericNoteTypes);
6090
}
6091

6092
template <class ELFT>
6093
static void processNotesHelper(
6094
    const ELFDumper<ELFT> &Dumper,
6095
    llvm::function_ref<void(std::optional<StringRef>, typename ELFT::Off,
6096
                            typename ELFT::Addr, size_t)>
6097
        StartNotesFn,
6098
    llvm::function_ref<Error(const typename ELFT::Note &, bool)> ProcessNoteFn,
6099
    llvm::function_ref<void()> FinishNotesFn) {
6100
  const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
6101
  bool IsCoreFile = Obj.getHeader().e_type == ELF::ET_CORE;
6102

6103
  ArrayRef<typename ELFT::Shdr> Sections = cantFail(Obj.sections());
6104
  if (!IsCoreFile && !Sections.empty()) {
6105
    for (const typename ELFT::Shdr &S : Sections) {
6106
      if (S.sh_type != SHT_NOTE)
6107
        continue;
6108
      StartNotesFn(expectedToStdOptional(Obj.getSectionName(S)), S.sh_offset,
6109
                   S.sh_size, S.sh_addralign);
6110
      Error Err = Error::success();
6111
      size_t I = 0;
6112
      for (const typename ELFT::Note Note : Obj.notes(S, Err)) {
6113
        if (Error E = ProcessNoteFn(Note, IsCoreFile))
6114
          Dumper.reportUniqueWarning(
6115
              "unable to read note with index " + Twine(I) + " from the " +
6116
              describe(Obj, S) + ": " + toString(std::move(E)));
6117
        ++I;
6118
      }
6119
      if (Err)
6120
        Dumper.reportUniqueWarning("unable to read notes from the " +
6121
                                   describe(Obj, S) + ": " +
6122
                                   toString(std::move(Err)));
6123
      FinishNotesFn();
6124
    }
6125
    return;
6126
  }
6127

6128
  Expected<ArrayRef<typename ELFT::Phdr>> PhdrsOrErr = Obj.program_headers();
6129
  if (!PhdrsOrErr) {
6130
    Dumper.reportUniqueWarning(
6131
        "unable to read program headers to locate the PT_NOTE segment: " +
6132
        toString(PhdrsOrErr.takeError()));
6133
    return;
6134
  }
6135

6136
  for (size_t I = 0, E = (*PhdrsOrErr).size(); I != E; ++I) {
6137
    const typename ELFT::Phdr &P = (*PhdrsOrErr)[I];
6138
    if (P.p_type != PT_NOTE)
6139
      continue;
6140
    StartNotesFn(/*SecName=*/std::nullopt, P.p_offset, P.p_filesz, P.p_align);
6141
    Error Err = Error::success();
6142
    size_t Index = 0;
6143
    for (const typename ELFT::Note Note : Obj.notes(P, Err)) {
6144
      if (Error E = ProcessNoteFn(Note, IsCoreFile))
6145
        Dumper.reportUniqueWarning("unable to read note with index " +
6146
                                   Twine(Index) +
6147
                                   " from the PT_NOTE segment with index " +
6148
                                   Twine(I) + ": " + toString(std::move(E)));
6149
      ++Index;
6150
    }
6151
    if (Err)
6152
      Dumper.reportUniqueWarning(
6153
          "unable to read notes from the PT_NOTE segment with index " +
6154
          Twine(I) + ": " + toString(std::move(Err)));
6155
    FinishNotesFn();
6156
  }
6157
}
6158

6159
template <class ELFT> void GNUELFDumper<ELFT>::printNotes() {
6160
  size_t Align = 0;
6161
  bool IsFirstHeader = true;
6162
  auto PrintHeader = [&](std::optional<StringRef> SecName,
6163
                         const typename ELFT::Off Offset,
6164
                         const typename ELFT::Addr Size, size_t Al) {
6165
    Align = std::max<size_t>(Al, 4);
6166
    // Print a newline between notes sections to match GNU readelf.
6167
    if (!IsFirstHeader) {
6168
      OS << '\n';
6169
    } else {
6170
      IsFirstHeader = false;
6171
    }
6172

6173
    OS << "Displaying notes found ";
6174

6175
    if (SecName)
6176
      OS << "in: " << *SecName << "\n";
6177
    else
6178
      OS << "at file offset " << format_hex(Offset, 10) << " with length "
6179
         << format_hex(Size, 10) << ":\n";
6180

6181
    OS << "  Owner                Data size \tDescription\n";
6182
  };
6183

6184
  auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {
6185
    StringRef Name = Note.getName();
6186
    ArrayRef<uint8_t> Descriptor = Note.getDesc(Align);
6187
    Elf_Word Type = Note.getType();
6188

6189
    // Print the note owner/type.
6190
    OS << "  " << left_justify(Name, 20) << ' '
6191
       << format_hex(Descriptor.size(), 10) << '\t';
6192

6193
    StringRef NoteType =
6194
        getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type);
6195
    if (!NoteType.empty())
6196
      OS << NoteType << '\n';
6197
    else
6198
      OS << "Unknown note type: (" << format_hex(Type, 10) << ")\n";
6199

6200
    // Print the description, or fallback to printing raw bytes for unknown
6201
    // owners/if we fail to pretty-print the contents.
6202
    if (Name == "GNU") {
6203
      if (printGNUNote<ELFT>(OS, Type, Descriptor))
6204
        return Error::success();
6205
    } else if (Name == "FreeBSD") {
6206
      if (std::optional<FreeBSDNote> N =
6207
              getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {
6208
        OS << "    " << N->Type << ": " << N->Value << '\n';
6209
        return Error::success();
6210
      }
6211
    } else if (Name == "AMD") {
6212
      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
6213
      if (!N.Type.empty()) {
6214
        OS << "    " << N.Type << ":\n        " << N.Value << '\n';
6215
        return Error::success();
6216
      }
6217
    } else if (Name == "AMDGPU") {
6218
      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
6219
      if (!N.Type.empty()) {
6220
        OS << "    " << N.Type << ":\n        " << N.Value << '\n';
6221
        return Error::success();
6222
      }
6223
    } else if (Name == "LLVMOMPOFFLOAD") {
6224
      if (printLLVMOMPOFFLOADNote<ELFT>(OS, Type, Descriptor))
6225
        return Error::success();
6226
    } else if (Name == "CORE") {
6227
      if (Type == ELF::NT_FILE) {
6228
        DataExtractor DescExtractor(
6229
            Descriptor, ELFT::Endianness == llvm::endianness::little,
6230
            sizeof(Elf_Addr));
6231
        if (Expected<CoreNote> NoteOrErr = readCoreNote(DescExtractor)) {
6232
          printCoreNote<ELFT>(OS, *NoteOrErr);
6233
          return Error::success();
6234
        } else {
6235
          return NoteOrErr.takeError();
6236
        }
6237
      }
6238
    } else if (Name == "Android") {
6239
      if (printAndroidNote(OS, Type, Descriptor))
6240
        return Error::success();
6241
    }
6242
    if (!Descriptor.empty()) {
6243
      OS << "   description data:";
6244
      for (uint8_t B : Descriptor)
6245
        OS << " " << format("%02x", B);
6246
      OS << '\n';
6247
    }
6248
    return Error::success();
6249
  };
6250

6251
  processNotesHelper(*this, /*StartNotesFn=*/PrintHeader,
6252
                     /*ProcessNoteFn=*/ProcessNote, /*FinishNotesFn=*/[]() {});
6253
}
6254

6255
template <class ELFT>
6256
ArrayRef<uint8_t>
6257
ELFDumper<ELFT>::getMemtagGlobalsSectionContents(uint64_t ExpectedAddr) {
6258
  for (const typename ELFT::Shdr &Sec : cantFail(Obj.sections())) {
6259
    if (Sec.sh_type != SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC)
6260
      continue;
6261
    if (Sec.sh_addr != ExpectedAddr) {
6262
      reportUniqueWarning(
6263
          "SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section was unexpectedly at 0x" +
6264
          Twine::utohexstr(Sec.sh_addr) +
6265
          ", when DT_AARCH64_MEMTAG_GLOBALS says it should be at 0x" +
6266
          Twine::utohexstr(ExpectedAddr));
6267
      return ArrayRef<uint8_t>();
6268
    }
6269
    Expected<ArrayRef<uint8_t>> Contents = Obj.getSectionContents(Sec);
6270
    if (auto E = Contents.takeError()) {
6271
      reportUniqueWarning(
6272
          "couldn't get SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section contents: " +
6273
          toString(std::move(E)));
6274
      return ArrayRef<uint8_t>();
6275
    }
6276
    return Contents.get();
6277
  }
6278
  return ArrayRef<uint8_t>();
6279
}
6280

6281
// Reserve the lower three bits of the first byte of the step distance when
6282
// encoding the memtag descriptors. Found to be the best overall size tradeoff
6283
// when compiling Android T with full MTE globals enabled.
6284
constexpr uint64_t MemtagStepVarintReservedBits = 3;
6285
constexpr uint64_t MemtagGranuleSize = 16;
6286

6287
template <typename ELFT> void ELFDumper<ELFT>::printMemtag() {
6288
  if (Obj.getHeader().e_machine != EM_AARCH64) return;
6289
  std::vector<std::pair<std::string, std::string>> DynamicEntries;
6290
  uint64_t MemtagGlobalsSz = 0;
6291
  uint64_t MemtagGlobals = 0;
6292
  for (const typename ELFT::Dyn &Entry : dynamic_table()) {
6293
    uintX_t Tag = Entry.getTag();
6294
    switch (Tag) {
6295
    case DT_AARCH64_MEMTAG_GLOBALSSZ:
6296
      MemtagGlobalsSz = Entry.getVal();
6297
      DynamicEntries.emplace_back(Obj.getDynamicTagAsString(Tag),
6298
                                  getDynamicEntry(Tag, Entry.getVal()));
6299
      break;
6300
    case DT_AARCH64_MEMTAG_GLOBALS:
6301
      MemtagGlobals = Entry.getVal();
6302
      DynamicEntries.emplace_back(Obj.getDynamicTagAsString(Tag),
6303
                                  getDynamicEntry(Tag, Entry.getVal()));
6304
      break;
6305
    case DT_AARCH64_MEMTAG_MODE:
6306
    case DT_AARCH64_MEMTAG_HEAP:
6307
    case DT_AARCH64_MEMTAG_STACK:
6308
      DynamicEntries.emplace_back(Obj.getDynamicTagAsString(Tag),
6309
                                  getDynamicEntry(Tag, Entry.getVal()));
6310
      break;
6311
    }
6312
  }
6313

6314
  ArrayRef<uint8_t> AndroidNoteDesc;
6315
  auto FindAndroidNote = [&](const Elf_Note &Note, bool IsCore) -> Error {
6316
    if (Note.getName() == "Android" &&
6317
        Note.getType() == ELF::NT_ANDROID_TYPE_MEMTAG)
6318
      AndroidNoteDesc = Note.getDesc(4);
6319
    return Error::success();
6320
  };
6321

6322
  processNotesHelper(
6323
      *this,
6324
      /*StartNotesFn=*/
6325
      [](std::optional<StringRef>, const typename ELFT::Off,
6326
         const typename ELFT::Addr, size_t) {},
6327
      /*ProcessNoteFn=*/FindAndroidNote, /*FinishNotesFn=*/[]() {});
6328

6329
  ArrayRef<uint8_t> Contents = getMemtagGlobalsSectionContents(MemtagGlobals);
6330
  if (Contents.size() != MemtagGlobalsSz) {
6331
    reportUniqueWarning(
6332
        "mismatch between DT_AARCH64_MEMTAG_GLOBALSSZ (0x" +
6333
        Twine::utohexstr(MemtagGlobalsSz) +
6334
        ") and SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section size (0x" +
6335
        Twine::utohexstr(Contents.size()) + ")");
6336
    Contents = ArrayRef<uint8_t>();
6337
  }
6338

6339
  std::vector<std::pair<uint64_t, uint64_t>> GlobalDescriptors;
6340
  uint64_t Address = 0;
6341
  // See the AArch64 MemtagABI document for a description of encoding scheme:
6342
  // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#83encoding-of-sht_aarch64_memtag_globals_dynamic
6343
  for (size_t I = 0; I < Contents.size();) {
6344
    const char *Error = nullptr;
6345
    unsigned DecodedBytes = 0;
6346
    uint64_t Value = decodeULEB128(Contents.data() + I, &DecodedBytes,
6347
                                   Contents.end(), &Error);
6348
    I += DecodedBytes;
6349
    if (Error) {
6350
      reportUniqueWarning(
6351
          "error decoding distance uleb, " + Twine(DecodedBytes) +
6352
          " byte(s) into SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC: " + Twine(Error));
6353
      GlobalDescriptors.clear();
6354
      break;
6355
    }
6356
    uint64_t Distance = Value >> MemtagStepVarintReservedBits;
6357
    uint64_t GranulesToTag = Value & ((1 << MemtagStepVarintReservedBits) - 1);
6358
    if (GranulesToTag == 0) {
6359
      GranulesToTag = decodeULEB128(Contents.data() + I, &DecodedBytes,
6360
                                    Contents.end(), &Error) +
6361
                      1;
6362
      I += DecodedBytes;
6363
      if (Error) {
6364
        reportUniqueWarning(
6365
            "error decoding size-only uleb, " + Twine(DecodedBytes) +
6366
            " byte(s) into SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC: " + Twine(Error));
6367
        GlobalDescriptors.clear();
6368
        break;
6369
      }
6370
    }
6371
    Address += Distance * MemtagGranuleSize;
6372
    GlobalDescriptors.emplace_back(Address, GranulesToTag * MemtagGranuleSize);
6373
    Address += GranulesToTag * MemtagGranuleSize;
6374
  }
6375

6376
  printMemtag(DynamicEntries, AndroidNoteDesc, GlobalDescriptors);
6377
}
6378

6379
template <class ELFT> void GNUELFDumper<ELFT>::printELFLinkerOptions() {
6380
  OS << "printELFLinkerOptions not implemented!\n";
6381
}
6382

6383
template <class ELFT>
6384
void ELFDumper<ELFT>::printDependentLibsHelper(
6385
    function_ref<void(const Elf_Shdr &)> OnSectionStart,
6386
    function_ref<void(StringRef, uint64_t)> OnLibEntry) {
6387
  auto Warn = [this](unsigned SecNdx, StringRef Msg) {
6388
    this->reportUniqueWarning("SHT_LLVM_DEPENDENT_LIBRARIES section at index " +
6389
                              Twine(SecNdx) + " is broken: " + Msg);
6390
  };
6391

6392
  unsigned I = -1;
6393
  for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) {
6394
    ++I;
6395
    if (Shdr.sh_type != ELF::SHT_LLVM_DEPENDENT_LIBRARIES)
6396
      continue;
6397

6398
    OnSectionStart(Shdr);
6399

6400
    Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Shdr);
6401
    if (!ContentsOrErr) {
6402
      Warn(I, toString(ContentsOrErr.takeError()));
6403
      continue;
6404
    }
6405

6406
    ArrayRef<uint8_t> Contents = *ContentsOrErr;
6407
    if (!Contents.empty() && Contents.back() != 0) {
6408
      Warn(I, "the content is not null-terminated");
6409
      continue;
6410
    }
6411

6412
    for (const uint8_t *I = Contents.begin(), *E = Contents.end(); I < E;) {
6413
      StringRef Lib((const char *)I);
6414
      OnLibEntry(Lib, I - Contents.begin());
6415
      I += Lib.size() + 1;
6416
    }
6417
  }
6418
}
6419

6420
template <class ELFT>
6421
void ELFDumper<ELFT>::forEachRelocationDo(
6422
    const Elf_Shdr &Sec,
6423
    llvm::function_ref<void(const Relocation<ELFT> &, unsigned,
6424
                            const Elf_Shdr &, const Elf_Shdr *)>
6425
        RelRelaFn) {
6426
  auto Warn = [&](Error &&E,
6427
                  const Twine &Prefix = "unable to read relocations from") {
6428
    this->reportUniqueWarning(Prefix + " " + describe(Sec) + ": " +
6429
                              toString(std::move(E)));
6430
  };
6431

6432
  // SHT_RELR/SHT_ANDROID_RELR/SHT_AARCH64_AUTH_RELR sections do not have an
6433
  // associated symbol table. For them we should not treat the value of the
6434
  // sh_link field as an index of a symbol table.
6435
  const Elf_Shdr *SymTab;
6436
  if (Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_RELR &&
6437
      !(Obj.getHeader().e_machine == EM_AARCH64 &&
6438
        Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR)) {
6439
    Expected<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Sec.sh_link);
6440
    if (!SymTabOrErr) {
6441
      Warn(SymTabOrErr.takeError(), "unable to locate a symbol table for");
6442
      return;
6443
    }
6444
    SymTab = *SymTabOrErr;
6445
  }
6446

6447
  unsigned RelNdx = 0;
6448
  const bool IsMips64EL = this->Obj.isMips64EL();
6449
  switch (Sec.sh_type) {
6450
  case ELF::SHT_REL:
6451
    if (Expected<Elf_Rel_Range> RangeOrErr = Obj.rels(Sec)) {
6452
      for (const Elf_Rel &R : *RangeOrErr)
6453
        RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);
6454
    } else {
6455
      Warn(RangeOrErr.takeError());
6456
    }
6457
    break;
6458
  case ELF::SHT_RELA:
6459
    if (Expected<Elf_Rela_Range> RangeOrErr = Obj.relas(Sec)) {
6460
      for (const Elf_Rela &R : *RangeOrErr)
6461
        RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);
6462
    } else {
6463
      Warn(RangeOrErr.takeError());
6464
    }
6465
    break;
6466
  case ELF::SHT_AARCH64_AUTH_RELR:
6467
    if (Obj.getHeader().e_machine != EM_AARCH64)
6468
      break;
6469
    [[fallthrough]];
6470
  case ELF::SHT_RELR:
6471
  case ELF::SHT_ANDROID_RELR: {
6472
    Expected<Elf_Relr_Range> RangeOrErr = Obj.relrs(Sec);
6473
    if (!RangeOrErr) {
6474
      Warn(RangeOrErr.takeError());
6475
      break;
6476
    }
6477

6478
    for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr))
6479
      RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec,
6480
                /*SymTab=*/nullptr);
6481
    break;
6482
  }
6483
  case ELF::SHT_CREL: {
6484
    if (auto RelsOrRelas = Obj.crels(Sec)) {
6485
      for (const Elf_Rel &R : RelsOrRelas->first)
6486
        RelRelaFn(Relocation<ELFT>(R, false), RelNdx++, Sec, SymTab);
6487
      for (const Elf_Rela &R : RelsOrRelas->second)
6488
        RelRelaFn(Relocation<ELFT>(R, false), RelNdx++, Sec, SymTab);
6489
    } else {
6490
      Warn(RelsOrRelas.takeError());
6491
    }
6492
    break;
6493
  }
6494
  case ELF::SHT_ANDROID_REL:
6495
  case ELF::SHT_ANDROID_RELA:
6496
    if (Expected<std::vector<Elf_Rela>> RelasOrErr = Obj.android_relas(Sec)) {
6497
      for (const Elf_Rela &R : *RelasOrErr)
6498
        RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab);
6499
    } else {
6500
      Warn(RelasOrErr.takeError());
6501
    }
6502
    break;
6503
  }
6504
}
6505

6506
template <class ELFT>
6507
StringRef ELFDumper<ELFT>::getPrintableSectionName(const Elf_Shdr &Sec) const {
6508
  StringRef Name = "<?>";
6509
  if (Expected<StringRef> SecNameOrErr =
6510
          Obj.getSectionName(Sec, this->WarningHandler))
6511
    Name = *SecNameOrErr;
6512
  else
6513
    this->reportUniqueWarning("unable to get the name of " + describe(Sec) +
6514
                              ": " + toString(SecNameOrErr.takeError()));
6515
  return Name;
6516
}
6517

6518
template <class ELFT> void GNUELFDumper<ELFT>::printDependentLibs() {
6519
  bool SectionStarted = false;
6520
  struct NameOffset {
6521
    StringRef Name;
6522
    uint64_t Offset;
6523
  };
6524
  std::vector<NameOffset> SecEntries;
6525
  NameOffset Current;
6526
  auto PrintSection = [&]() {
6527
    OS << "Dependent libraries section " << Current.Name << " at offset "
6528
       << format_hex(Current.Offset, 1) << " contains " << SecEntries.size()
6529
       << " entries:\n";
6530
    for (NameOffset Entry : SecEntries)
6531
      OS << "  [" << format("%6" PRIx64, Entry.Offset) << "]  " << Entry.Name
6532
         << "\n";
6533
    OS << "\n";
6534
    SecEntries.clear();
6535
  };
6536

6537
  auto OnSectionStart = [&](const Elf_Shdr &Shdr) {
6538
    if (SectionStarted)
6539
      PrintSection();
6540
    SectionStarted = true;
6541
    Current.Offset = Shdr.sh_offset;
6542
    Current.Name = this->getPrintableSectionName(Shdr);
6543
  };
6544
  auto OnLibEntry = [&](StringRef Lib, uint64_t Offset) {
6545
    SecEntries.push_back(NameOffset{Lib, Offset});
6546
  };
6547

6548
  this->printDependentLibsHelper(OnSectionStart, OnLibEntry);
6549
  if (SectionStarted)
6550
    PrintSection();
6551
}
6552

6553
template <class ELFT>
6554
SmallVector<uint32_t> ELFDumper<ELFT>::getSymbolIndexesForFunctionAddress(
6555
    uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec) {
6556
  SmallVector<uint32_t> SymbolIndexes;
6557
  if (!this->AddressToIndexMap) {
6558
    // Populate the address to index map upon the first invocation of this
6559
    // function.
6560
    this->AddressToIndexMap.emplace();
6561
    if (this->DotSymtabSec) {
6562
      if (Expected<Elf_Sym_Range> SymsOrError =
6563
              Obj.symbols(this->DotSymtabSec)) {
6564
        uint32_t Index = (uint32_t)-1;
6565
        for (const Elf_Sym &Sym : *SymsOrError) {
6566
          ++Index;
6567

6568
          if (Sym.st_shndx == ELF::SHN_UNDEF || Sym.getType() != ELF::STT_FUNC)
6569
            continue;
6570

6571
          Expected<uint64_t> SymAddrOrErr =
6572
              ObjF.toSymbolRef(this->DotSymtabSec, Index).getAddress();
6573
          if (!SymAddrOrErr) {
6574
            std::string Name = this->getStaticSymbolName(Index);
6575
            reportUniqueWarning("unable to get address of symbol '" + Name +
6576
                                "': " + toString(SymAddrOrErr.takeError()));
6577
            return SymbolIndexes;
6578
          }
6579

6580
          (*this->AddressToIndexMap)[*SymAddrOrErr].push_back(Index);
6581
        }
6582
      } else {
6583
        reportUniqueWarning("unable to read the symbol table: " +
6584
                            toString(SymsOrError.takeError()));
6585
      }
6586
    }
6587
  }
6588

6589
  auto Symbols = this->AddressToIndexMap->find(SymValue);
6590
  if (Symbols == this->AddressToIndexMap->end())
6591
    return SymbolIndexes;
6592

6593
  for (uint32_t Index : Symbols->second) {
6594
    // Check if the symbol is in the right section. FunctionSec == None
6595
    // means "any section".
6596
    if (FunctionSec) {
6597
      const Elf_Sym &Sym = *cantFail(Obj.getSymbol(this->DotSymtabSec, Index));
6598
      if (Expected<const Elf_Shdr *> SecOrErr =
6599
              Obj.getSection(Sym, this->DotSymtabSec,
6600
                             this->getShndxTable(this->DotSymtabSec))) {
6601
        if (*FunctionSec != *SecOrErr)
6602
          continue;
6603
      } else {
6604
        std::string Name = this->getStaticSymbolName(Index);
6605
        // Note: it is impossible to trigger this error currently, it is
6606
        // untested.
6607
        reportUniqueWarning("unable to get section of symbol '" + Name +
6608
                            "': " + toString(SecOrErr.takeError()));
6609
        return SymbolIndexes;
6610
      }
6611
    }
6612

6613
    SymbolIndexes.push_back(Index);
6614
  }
6615

6616
  return SymbolIndexes;
6617
}
6618

6619
template <class ELFT>
6620
bool ELFDumper<ELFT>::printFunctionStackSize(
6621
    uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec,
6622
    const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) {
6623
  SmallVector<uint32_t> FuncSymIndexes =
6624
      this->getSymbolIndexesForFunctionAddress(SymValue, FunctionSec);
6625
  if (FuncSymIndexes.empty())
6626
    reportUniqueWarning(
6627
        "could not identify function symbol for stack size entry in " +
6628
        describe(StackSizeSec));
6629

6630
  // Extract the size. The expectation is that Offset is pointing to the right
6631
  // place, i.e. past the function address.
6632
  Error Err = Error::success();
6633
  uint64_t StackSize = Data.getULEB128(Offset, &Err);
6634
  if (Err) {
6635
    reportUniqueWarning("could not extract a valid stack size from " +
6636
                        describe(StackSizeSec) + ": " +
6637
                        toString(std::move(Err)));
6638
    return false;
6639
  }
6640

6641
  if (FuncSymIndexes.empty()) {
6642
    printStackSizeEntry(StackSize, {"?"});
6643
  } else {
6644
    SmallVector<std::string> FuncSymNames;
6645
    for (uint32_t Index : FuncSymIndexes)
6646
      FuncSymNames.push_back(this->getStaticSymbolName(Index));
6647
    printStackSizeEntry(StackSize, FuncSymNames);
6648
  }
6649

6650
  return true;
6651
}
6652

6653
template <class ELFT>
6654
void GNUELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,
6655
                                             ArrayRef<std::string> FuncNames) {
6656
  OS.PadToColumn(2);
6657
  OS << format_decimal(Size, 11);
6658
  OS.PadToColumn(18);
6659

6660
  OS << join(FuncNames.begin(), FuncNames.end(), ", ") << "\n";
6661
}
6662

6663
template <class ELFT>
6664
void ELFDumper<ELFT>::printStackSize(const Relocation<ELFT> &R,
6665
                                     const Elf_Shdr &RelocSec, unsigned Ndx,
6666
                                     const Elf_Shdr *SymTab,
6667
                                     const Elf_Shdr *FunctionSec,
6668
                                     const Elf_Shdr &StackSizeSec,
6669
                                     const RelocationResolver &Resolver,
6670
                                     DataExtractor Data) {
6671
  // This function ignores potentially erroneous input, unless it is directly
6672
  // related to stack size reporting.
6673
  const Elf_Sym *Sym = nullptr;
6674
  Expected<RelSymbol<ELFT>> TargetOrErr = this->getRelocationTarget(R, SymTab);
6675
  if (!TargetOrErr)
6676
    reportUniqueWarning("unable to get the target of relocation with index " +
6677
                        Twine(Ndx) + " in " + describe(RelocSec) + ": " +
6678
                        toString(TargetOrErr.takeError()));
6679
  else
6680
    Sym = TargetOrErr->Sym;
6681

6682
  uint64_t RelocSymValue = 0;
6683
  if (Sym) {
6684
    Expected<const Elf_Shdr *> SectionOrErr =
6685
        this->Obj.getSection(*Sym, SymTab, this->getShndxTable(SymTab));
6686
    if (!SectionOrErr) {
6687
      reportUniqueWarning(
6688
          "cannot identify the section for relocation symbol '" +
6689
          (*TargetOrErr).Name + "': " + toString(SectionOrErr.takeError()));
6690
    } else if (*SectionOrErr != FunctionSec) {
6691
      reportUniqueWarning("relocation symbol '" + (*TargetOrErr).Name +
6692
                          "' is not in the expected section");
6693
      // Pretend that the symbol is in the correct section and report its
6694
      // stack size anyway.
6695
      FunctionSec = *SectionOrErr;
6696
    }
6697

6698
    RelocSymValue = Sym->st_value;
6699
  }
6700

6701
  uint64_t Offset = R.Offset;
6702
  if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {
6703
    reportUniqueWarning("found invalid relocation offset (0x" +
6704
                        Twine::utohexstr(Offset) + ") into " +
6705
                        describe(StackSizeSec) +
6706
                        " while trying to extract a stack size entry");
6707
    return;
6708
  }
6709

6710
  uint64_t SymValue = Resolver(R.Type, Offset, RelocSymValue,
6711
                               Data.getAddress(&Offset), R.Addend.value_or(0));
6712
  this->printFunctionStackSize(SymValue, FunctionSec, StackSizeSec, Data,
6713
                               &Offset);
6714
}
6715

6716
template <class ELFT>
6717
void ELFDumper<ELFT>::printNonRelocatableStackSizes(
6718
    std::function<void()> PrintHeader) {
6719
  // This function ignores potentially erroneous input, unless it is directly
6720
  // related to stack size reporting.
6721
  for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
6722
    if (this->getPrintableSectionName(Sec) != ".stack_sizes")
6723
      continue;
6724
    PrintHeader();
6725
    ArrayRef<uint8_t> Contents =
6726
        unwrapOrError(this->FileName, Obj.getSectionContents(Sec));
6727
    DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr));
6728
    uint64_t Offset = 0;
6729
    while (Offset < Contents.size()) {
6730
      // The function address is followed by a ULEB representing the stack
6731
      // size. Check for an extra byte before we try to process the entry.
6732
      if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {
6733
        reportUniqueWarning(
6734
            describe(Sec) +
6735
            " ended while trying to extract a stack size entry");
6736
        break;
6737
      }
6738
      uint64_t SymValue = Data.getAddress(&Offset);
6739
      if (!printFunctionStackSize(SymValue, /*FunctionSec=*/std::nullopt, Sec,
6740
                                  Data, &Offset))
6741
        break;
6742
    }
6743
  }
6744
}
6745

6746
template <class ELFT>
6747
void ELFDumper<ELFT>::printRelocatableStackSizes(
6748
    std::function<void()> PrintHeader) {
6749
  // Build a map between stack size sections and their corresponding relocation
6750
  // sections.
6751
  auto IsMatch = [&](const Elf_Shdr &Sec) -> bool {
6752
    StringRef SectionName;
6753
    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Sec))
6754
      SectionName = *NameOrErr;
6755
    else
6756
      consumeError(NameOrErr.takeError());
6757

6758
    return SectionName == ".stack_sizes";
6759
  };
6760

6761
  Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>>
6762
      StackSizeRelocMapOrErr = Obj.getSectionAndRelocations(IsMatch);
6763
  if (!StackSizeRelocMapOrErr) {
6764
    reportUniqueWarning("unable to get stack size map section(s): " +
6765
                        toString(StackSizeRelocMapOrErr.takeError()));
6766
    return;
6767
  }
6768

6769
  for (const auto &StackSizeMapEntry : *StackSizeRelocMapOrErr) {
6770
    PrintHeader();
6771
    const Elf_Shdr *StackSizesELFSec = StackSizeMapEntry.first;
6772
    const Elf_Shdr *RelocSec = StackSizeMapEntry.second;
6773

6774
    // Warn about stack size sections without a relocation section.
6775
    if (!RelocSec) {
6776
      reportWarning(createError(".stack_sizes (" + describe(*StackSizesELFSec) +
6777
                                ") does not have a corresponding "
6778
                                "relocation section"),
6779
                    FileName);
6780
      continue;
6781
    }
6782

6783
    // A .stack_sizes section header's sh_link field is supposed to point
6784
    // to the section that contains the functions whose stack sizes are
6785
    // described in it.
6786
    const Elf_Shdr *FunctionSec = unwrapOrError(
6787
        this->FileName, Obj.getSection(StackSizesELFSec->sh_link));
6788

6789
    SupportsRelocation IsSupportedFn;
6790
    RelocationResolver Resolver;
6791
    std::tie(IsSupportedFn, Resolver) = getRelocationResolver(this->ObjF);
6792
    ArrayRef<uint8_t> Contents =
6793
        unwrapOrError(this->FileName, Obj.getSectionContents(*StackSizesELFSec));
6794
    DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr));
6795

6796
    forEachRelocationDo(
6797
        *RelocSec, [&](const Relocation<ELFT> &R, unsigned Ndx,
6798
                       const Elf_Shdr &Sec, const Elf_Shdr *SymTab) {
6799
          if (!IsSupportedFn || !IsSupportedFn(R.Type)) {
6800
            reportUniqueWarning(
6801
                describe(*RelocSec) +
6802
                " contains an unsupported relocation with index " + Twine(Ndx) +
6803
                ": " + Obj.getRelocationTypeName(R.Type));
6804
            return;
6805
          }
6806

6807
          this->printStackSize(R, *RelocSec, Ndx, SymTab, FunctionSec,
6808
                               *StackSizesELFSec, Resolver, Data);
6809
        });
6810
  }
6811
}
6812

6813
template <class ELFT>
6814
void GNUELFDumper<ELFT>::printStackSizes() {
6815
  bool HeaderHasBeenPrinted = false;
6816
  auto PrintHeader = [&]() {
6817
    if (HeaderHasBeenPrinted)
6818
      return;
6819
    OS << "\nStack Sizes:\n";
6820
    OS.PadToColumn(9);
6821
    OS << "Size";
6822
    OS.PadToColumn(18);
6823
    OS << "Functions\n";
6824
    HeaderHasBeenPrinted = true;
6825
  };
6826

6827
  // For non-relocatable objects, look directly for sections whose name starts
6828
  // with .stack_sizes and process the contents.
6829
  if (this->Obj.getHeader().e_type == ELF::ET_REL)
6830
    this->printRelocatableStackSizes(PrintHeader);
6831
  else
6832
    this->printNonRelocatableStackSizes(PrintHeader);
6833
}
6834

6835
template <class ELFT>
6836
void GNUELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
6837
  size_t Bias = ELFT::Is64Bits ? 8 : 0;
6838
  auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {
6839
    OS.PadToColumn(2);
6840
    OS << format_hex_no_prefix(Parser.getGotAddress(E), 8 + Bias);
6841
    OS.PadToColumn(11 + Bias);
6842
    OS << format_decimal(Parser.getGotOffset(E), 6) << "(gp)";
6843
    OS.PadToColumn(22 + Bias);
6844
    OS << format_hex_no_prefix(*E, 8 + Bias);
6845
    OS.PadToColumn(31 + 2 * Bias);
6846
    OS << Purpose << "\n";
6847
  };
6848

6849
  OS << (Parser.IsStatic ? "Static GOT:\n" : "Primary GOT:\n");
6850
  OS << " Canonical gp value: "
6851
     << format_hex_no_prefix(Parser.getGp(), 8 + Bias) << "\n\n";
6852

6853
  OS << " Reserved entries:\n";
6854
  if (ELFT::Is64Bits)
6855
    OS << "           Address     Access          Initial Purpose\n";
6856
  else
6857
    OS << "   Address     Access  Initial Purpose\n";
6858
  PrintEntry(Parser.getGotLazyResolver(), "Lazy resolver");
6859
  if (Parser.getGotModulePointer())
6860
    PrintEntry(Parser.getGotModulePointer(), "Module pointer (GNU extension)");
6861

6862
  if (!Parser.getLocalEntries().empty()) {
6863
    OS << "\n";
6864
    OS << " Local entries:\n";
6865
    if (ELFT::Is64Bits)
6866
      OS << "           Address     Access          Initial\n";
6867
    else
6868
      OS << "   Address     Access  Initial\n";
6869
    for (auto &E : Parser.getLocalEntries())
6870
      PrintEntry(&E, "");
6871
  }
6872

6873
  if (Parser.IsStatic)
6874
    return;
6875

6876
  if (!Parser.getGlobalEntries().empty()) {
6877
    OS << "\n";
6878
    OS << " Global entries:\n";
6879
    if (ELFT::Is64Bits)
6880
      OS << "           Address     Access          Initial         Sym.Val."
6881
         << " Type    Ndx Name\n";
6882
    else
6883
      OS << "   Address     Access  Initial Sym.Val. Type    Ndx Name\n";
6884

6885
    DataRegion<Elf_Word> ShndxTable(
6886
        (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
6887
    for (auto &E : Parser.getGlobalEntries()) {
6888
      const Elf_Sym &Sym = *Parser.getGotSym(&E);
6889
      const Elf_Sym &FirstSym = this->dynamic_symbols()[0];
6890
      std::string SymName = this->getFullSymbolName(
6891
          Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false);
6892

6893
      OS.PadToColumn(2);
6894
      OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias));
6895
      OS.PadToColumn(11 + Bias);
6896
      OS << to_string(format_decimal(Parser.getGotOffset(&E), 6)) + "(gp)";
6897
      OS.PadToColumn(22 + Bias);
6898
      OS << to_string(format_hex_no_prefix(E, 8 + Bias));
6899
      OS.PadToColumn(31 + 2 * Bias);
6900
      OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias));
6901
      OS.PadToColumn(40 + 3 * Bias);
6902
      OS << enumToString(Sym.getType(), ArrayRef(ElfSymbolTypes));
6903
      OS.PadToColumn(48 + 3 * Bias);
6904
      OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(),
6905
                                ShndxTable);
6906
      OS.PadToColumn(52 + 3 * Bias);
6907
      OS << SymName << "\n";
6908
    }
6909
  }
6910

6911
  if (!Parser.getOtherEntries().empty())
6912
    OS << "\n Number of TLS and multi-GOT entries "
6913
       << Parser.getOtherEntries().size() << "\n";
6914
}
6915

6916
template <class ELFT>
6917
void GNUELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
6918
  size_t Bias = ELFT::Is64Bits ? 8 : 0;
6919
  auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {
6920
    OS.PadToColumn(2);
6921
    OS << format_hex_no_prefix(Parser.getPltAddress(E), 8 + Bias);
6922
    OS.PadToColumn(11 + Bias);
6923
    OS << format_hex_no_prefix(*E, 8 + Bias);
6924
    OS.PadToColumn(20 + 2 * Bias);
6925
    OS << Purpose << "\n";
6926
  };
6927

6928
  OS << "PLT GOT:\n\n";
6929

6930
  OS << " Reserved entries:\n";
6931
  OS << "   Address  Initial Purpose\n";
6932
  PrintEntry(Parser.getPltLazyResolver(), "PLT lazy resolver");
6933
  if (Parser.getPltModulePointer())
6934
    PrintEntry(Parser.getPltModulePointer(), "Module pointer");
6935

6936
  if (!Parser.getPltEntries().empty()) {
6937
    OS << "\n";
6938
    OS << " Entries:\n";
6939
    OS << "   Address  Initial Sym.Val. Type    Ndx Name\n";
6940
    DataRegion<Elf_Word> ShndxTable(
6941
        (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
6942
    for (auto &E : Parser.getPltEntries()) {
6943
      const Elf_Sym &Sym = *Parser.getPltSym(&E);
6944
      const Elf_Sym &FirstSym = *cantFail(
6945
          this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));
6946
      std::string SymName = this->getFullSymbolName(
6947
          Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false);
6948

6949
      OS.PadToColumn(2);
6950
      OS << to_string(format_hex_no_prefix(Parser.getPltAddress(&E), 8 + Bias));
6951
      OS.PadToColumn(11 + Bias);
6952
      OS << to_string(format_hex_no_prefix(E, 8 + Bias));
6953
      OS.PadToColumn(20 + 2 * Bias);
6954
      OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias));
6955
      OS.PadToColumn(29 + 3 * Bias);
6956
      OS << enumToString(Sym.getType(), ArrayRef(ElfSymbolTypes));
6957
      OS.PadToColumn(37 + 3 * Bias);
6958
      OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(),
6959
                                ShndxTable);
6960
      OS.PadToColumn(41 + 3 * Bias);
6961
      OS << SymName << "\n";
6962
    }
6963
  }
6964
}
6965

6966
template <class ELFT>
6967
Expected<const Elf_Mips_ABIFlags<ELFT> *>
6968
getMipsAbiFlagsSection(const ELFDumper<ELFT> &Dumper) {
6969
  const typename ELFT::Shdr *Sec = Dumper.findSectionByName(".MIPS.abiflags");
6970
  if (Sec == nullptr)
6971
    return nullptr;
6972

6973
  constexpr StringRef ErrPrefix = "unable to read the .MIPS.abiflags section: ";
6974
  Expected<ArrayRef<uint8_t>> DataOrErr =
6975
      Dumper.getElfObject().getELFFile().getSectionContents(*Sec);
6976
  if (!DataOrErr)
6977
    return createError(ErrPrefix + toString(DataOrErr.takeError()));
6978

6979
  if (DataOrErr->size() != sizeof(Elf_Mips_ABIFlags<ELFT>))
6980
    return createError(ErrPrefix + "it has a wrong size (" +
6981
        Twine(DataOrErr->size()) + ")");
6982
  return reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(DataOrErr->data());
6983
}
6984

6985
template <class ELFT> void GNUELFDumper<ELFT>::printMipsABIFlags() {
6986
  const Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
6987
  if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =
6988
          getMipsAbiFlagsSection(*this))
6989
    Flags = *SecOrErr;
6990
  else
6991
    this->reportUniqueWarning(SecOrErr.takeError());
6992
  if (!Flags)
6993
    return;
6994

6995
  OS << "MIPS ABI Flags Version: " << Flags->version << "\n\n";
6996
  OS << "ISA: MIPS" << int(Flags->isa_level);
6997
  if (Flags->isa_rev > 1)
6998
    OS << "r" << int(Flags->isa_rev);
6999
  OS << "\n";
7000
  OS << "GPR size: " << getMipsRegisterSize(Flags->gpr_size) << "\n";
7001
  OS << "CPR1 size: " << getMipsRegisterSize(Flags->cpr1_size) << "\n";
7002
  OS << "CPR2 size: " << getMipsRegisterSize(Flags->cpr2_size) << "\n";
7003
  OS << "FP ABI: " << enumToString(Flags->fp_abi, ArrayRef(ElfMipsFpABIType))
7004
     << "\n";
7005
  OS << "ISA Extension: "
7006
     << enumToString(Flags->isa_ext, ArrayRef(ElfMipsISAExtType)) << "\n";
7007
  if (Flags->ases == 0)
7008
    OS << "ASEs: None\n";
7009
  else
7010
    // FIXME: Print each flag on a separate line.
7011
    OS << "ASEs: " << printFlags(Flags->ases, ArrayRef(ElfMipsASEFlags))
7012
       << "\n";
7013
  OS << "FLAGS 1: " << format_hex_no_prefix(Flags->flags1, 8, false) << "\n";
7014
  OS << "FLAGS 2: " << format_hex_no_prefix(Flags->flags2, 8, false) << "\n";
7015
  OS << "\n";
7016
}
7017

7018
template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() {
7019
  const Elf_Ehdr &E = this->Obj.getHeader();
7020
  {
7021
    DictScope D(W, "ElfHeader");
7022
    {
7023
      DictScope D(W, "Ident");
7024
      W.printBinary("Magic",
7025
                    ArrayRef<unsigned char>(E.e_ident).slice(ELF::EI_MAG0, 4));
7026
      W.printEnum("Class", E.e_ident[ELF::EI_CLASS], ArrayRef(ElfClass));
7027
      W.printEnum("DataEncoding", E.e_ident[ELF::EI_DATA],
7028
                  ArrayRef(ElfDataEncoding));
7029
      W.printNumber("FileVersion", E.e_ident[ELF::EI_VERSION]);
7030

7031
      auto OSABI = ArrayRef(ElfOSABI);
7032
      if (E.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH &&
7033
          E.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) {
7034
        switch (E.e_machine) {
7035
        case ELF::EM_AMDGPU:
7036
          OSABI = ArrayRef(AMDGPUElfOSABI);
7037
          break;
7038
        case ELF::EM_ARM:
7039
          OSABI = ArrayRef(ARMElfOSABI);
7040
          break;
7041
        case ELF::EM_TI_C6000:
7042
          OSABI = ArrayRef(C6000ElfOSABI);
7043
          break;
7044
        }
7045
      }
7046
      W.printEnum("OS/ABI", E.e_ident[ELF::EI_OSABI], OSABI);
7047
      W.printNumber("ABIVersion", E.e_ident[ELF::EI_ABIVERSION]);
7048
      W.printBinary("Unused",
7049
                    ArrayRef<unsigned char>(E.e_ident).slice(ELF::EI_PAD));
7050
    }
7051

7052
    std::string TypeStr;
7053
    if (const EnumEntry<unsigned> *Ent = getObjectFileEnumEntry(E.e_type)) {
7054
      TypeStr = Ent->Name.str();
7055
    } else {
7056
      if (E.e_type >= ET_LOPROC)
7057
        TypeStr = "Processor Specific";
7058
      else if (E.e_type >= ET_LOOS)
7059
        TypeStr = "OS Specific";
7060
      else
7061
        TypeStr = "Unknown";
7062
    }
7063
    W.printString("Type", TypeStr + " (0x" + utohexstr(E.e_type) + ")");
7064

7065
    W.printEnum("Machine", E.e_machine, ArrayRef(ElfMachineType));
7066
    W.printNumber("Version", E.e_version);
7067
    W.printHex("Entry", E.e_entry);
7068
    W.printHex("ProgramHeaderOffset", E.e_phoff);
7069
    W.printHex("SectionHeaderOffset", E.e_shoff);
7070
    if (E.e_machine == EM_MIPS)
7071
      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderMipsFlags),
7072
                   unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
7073
                   unsigned(ELF::EF_MIPS_MACH));
7074
    else if (E.e_machine == EM_AMDGPU) {
7075
      switch (E.e_ident[ELF::EI_ABIVERSION]) {
7076
      default:
7077
        W.printHex("Flags", E.e_flags);
7078
        break;
7079
      case 0:
7080
        // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags.
7081
        [[fallthrough]];
7082
      case ELF::ELFABIVERSION_AMDGPU_HSA_V3:
7083
        W.printFlags("Flags", E.e_flags,
7084
                     ArrayRef(ElfHeaderAMDGPUFlagsABIVersion3),
7085
                     unsigned(ELF::EF_AMDGPU_MACH));
7086
        break;
7087
      case ELF::ELFABIVERSION_AMDGPU_HSA_V4:
7088
      case ELF::ELFABIVERSION_AMDGPU_HSA_V5:
7089
        W.printFlags("Flags", E.e_flags,
7090
                     ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),
7091
                     unsigned(ELF::EF_AMDGPU_MACH),
7092
                     unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),
7093
                     unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4));
7094
        break;
7095
      case ELF::ELFABIVERSION_AMDGPU_HSA_V6: {
7096
        std::optional<FlagEntry> VerFlagEntry;
7097
        // The string needs to remain alive from the moment we create a
7098
        // FlagEntry until printFlags is done.
7099
        std::string FlagStr;
7100
        if (auto VersionFlag = E.e_flags & ELF::EF_AMDGPU_GENERIC_VERSION) {
7101
          unsigned Version =
7102
              VersionFlag >> ELF::EF_AMDGPU_GENERIC_VERSION_OFFSET;
7103
          FlagStr = "EF_AMDGPU_GENERIC_VERSION_V" + std::to_string(Version);
7104
          VerFlagEntry = FlagEntry(FlagStr, VersionFlag);
7105
        }
7106
        W.printFlags(
7107
            "Flags", E.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4),
7108
            unsigned(ELF::EF_AMDGPU_MACH),
7109
            unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4),
7110
            unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4),
7111
            VerFlagEntry ? ArrayRef(*VerFlagEntry) : ArrayRef<FlagEntry>());
7112
        break;
7113
      }
7114
      }
7115
    } else if (E.e_machine == EM_RISCV)
7116
      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderRISCVFlags));
7117
    else if (E.e_machine == EM_AVR)
7118
      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderAVRFlags),
7119
                   unsigned(ELF::EF_AVR_ARCH_MASK));
7120
    else if (E.e_machine == EM_LOONGARCH)
7121
      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderLoongArchFlags),
7122
                   unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK),
7123
                   unsigned(ELF::EF_LOONGARCH_OBJABI_MASK));
7124
    else if (E.e_machine == EM_XTENSA)
7125
      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderXtensaFlags),
7126
                   unsigned(ELF::EF_XTENSA_MACH));
7127
    else if (E.e_machine == EM_CUDA)
7128
      W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderNVPTXFlags),
7129
                   unsigned(ELF::EF_CUDA_SM));
7130
    else
7131
      W.printFlags("Flags", E.e_flags);
7132
    W.printNumber("HeaderSize", E.e_ehsize);
7133
    W.printNumber("ProgramHeaderEntrySize", E.e_phentsize);
7134
    W.printNumber("ProgramHeaderCount", E.e_phnum);
7135
    W.printNumber("SectionHeaderEntrySize", E.e_shentsize);
7136
    W.printString("SectionHeaderCount",
7137
                  getSectionHeadersNumString(this->Obj, this->FileName));
7138
    W.printString("StringTableSectionIndex",
7139
                  getSectionHeaderTableIndexString(this->Obj, this->FileName));
7140
  }
7141
}
7142

7143
template <class ELFT> void LLVMELFDumper<ELFT>::printGroupSections() {
7144
  DictScope Lists(W, "Groups");
7145
  std::vector<GroupSection> V = this->getGroups();
7146
  DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
7147
  for (const GroupSection &G : V) {
7148
    DictScope D(W, "Group");
7149
    W.printNumber("Name", G.Name, G.ShName);
7150
    W.printNumber("Index", G.Index);
7151
    W.printNumber("Link", G.Link);
7152
    W.printNumber("Info", G.Info);
7153
    W.printHex("Type", getGroupType(G.Type), G.Type);
7154
    W.printString("Signature", G.Signature);
7155

7156
    ListScope L(W, getGroupSectionHeaderName());
7157
    for (const GroupMember &GM : G.Members) {
7158
      const GroupSection *MainGroup = Map[GM.Index];
7159
      if (MainGroup != &G)
7160
        this->reportUniqueWarning(
7161
            "section with index " + Twine(GM.Index) +
7162
            ", included in the group section with index " +
7163
            Twine(MainGroup->Index) +
7164
            ", was also found in the group section with index " +
7165
            Twine(G.Index));
7166
      printSectionGroupMembers(GM.Name, GM.Index);
7167
    }
7168
  }
7169

7170
  if (V.empty())
7171
    printEmptyGroupMessage();
7172
}
7173

7174
template <class ELFT>
7175
std::string LLVMELFDumper<ELFT>::getGroupSectionHeaderName() const {
7176
  return "Section(s) in group";
7177
}
7178

7179
template <class ELFT>
7180
void LLVMELFDumper<ELFT>::printSectionGroupMembers(StringRef Name,
7181
                                                   uint64_t Idx) const {
7182
  W.startLine() << Name << " (" << Idx << ")\n";
7183
}
7184

7185
template <class ELFT> void LLVMELFDumper<ELFT>::printRelocations() {
7186
  ListScope D(W, "Relocations");
7187

7188
  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
7189
    if (!isRelocationSec<ELFT>(Sec, this->Obj.getHeader()))
7190
      continue;
7191

7192
    StringRef Name = this->getPrintableSectionName(Sec);
7193
    unsigned SecNdx = &Sec - &cantFail(this->Obj.sections()).front();
7194
    printRelocationSectionInfo(Sec, Name, SecNdx);
7195
  }
7196
}
7197

7198
template <class ELFT>
7199
void LLVMELFDumper<ELFT>::printExpandedRelRelaReloc(const Relocation<ELFT> &R,
7200
                                                    StringRef SymbolName,
7201
                                                    StringRef RelocName) {
7202
  DictScope Group(W, "Relocation");
7203
  W.printHex("Offset", R.Offset);
7204
  W.printNumber("Type", RelocName, R.Type);
7205
  W.printNumber("Symbol", !SymbolName.empty() ? SymbolName : "-", R.Symbol);
7206
  if (R.Addend)
7207
    W.printHex("Addend", (uintX_t)*R.Addend);
7208
}
7209

7210
template <class ELFT>
7211
void LLVMELFDumper<ELFT>::printDefaultRelRelaReloc(const Relocation<ELFT> &R,
7212
                                                   StringRef SymbolName,
7213
                                                   StringRef RelocName) {
7214
  raw_ostream &OS = W.startLine();
7215
  OS << W.hex(R.Offset) << " " << RelocName << " "
7216
     << (!SymbolName.empty() ? SymbolName : "-");
7217
  if (R.Addend)
7218
    OS << " " << W.hex((uintX_t)*R.Addend);
7219
  OS << "\n";
7220
}
7221

7222
template <class ELFT>
7223
void LLVMELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec,
7224
                                                     StringRef Name,
7225
                                                     const unsigned SecNdx) {
7226
  DictScope D(W, (Twine("Section (") + Twine(SecNdx) + ") " + Name).str());
7227
  this->printRelocationsHelper(Sec);
7228
}
7229

7230
template <class ELFT> void LLVMELFDumper<ELFT>::printEmptyGroupMessage() const {
7231
  W.startLine() << "There are no group sections in the file.\n";
7232
}
7233

7234
template <class ELFT>
7235
void LLVMELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R,
7236
                                            const RelSymbol<ELFT> &RelSym) {
7237
  StringRef SymbolName = RelSym.Name;
7238
  if (RelSym.Sym && RelSym.Name.empty())
7239
    SymbolName = "<null>";
7240
  SmallString<32> RelocName;
7241
  this->Obj.getRelocationTypeName(R.Type, RelocName);
7242

7243
  if (opts::ExpandRelocs) {
7244
    printExpandedRelRelaReloc(R, SymbolName, RelocName);
7245
  } else {
7246
    printDefaultRelRelaReloc(R, SymbolName, RelocName);
7247
  }
7248
}
7249

7250
template <class ELFT> void LLVMELFDumper<ELFT>::printSectionHeaders() {
7251
  ListScope SectionsD(W, "Sections");
7252

7253
  int SectionIndex = -1;
7254
  std::vector<EnumEntry<unsigned>> FlagsList =
7255
      getSectionFlagsForTarget(this->Obj.getHeader().e_ident[ELF::EI_OSABI],
7256
                               this->Obj.getHeader().e_machine);
7257
  for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) {
7258
    DictScope SectionD(W, "Section");
7259
    W.printNumber("Index", ++SectionIndex);
7260
    W.printNumber("Name", this->getPrintableSectionName(Sec), Sec.sh_name);
7261
    W.printHex("Type",
7262
               object::getELFSectionTypeName(this->Obj.getHeader().e_machine,
7263
                                             Sec.sh_type),
7264
               Sec.sh_type);
7265
    W.printFlags("Flags", Sec.sh_flags, ArrayRef(FlagsList));
7266
    W.printHex("Address", Sec.sh_addr);
7267
    W.printHex("Offset", Sec.sh_offset);
7268
    W.printNumber("Size", Sec.sh_size);
7269
    W.printNumber("Link", Sec.sh_link);
7270
    W.printNumber("Info", Sec.sh_info);
7271
    W.printNumber("AddressAlignment", Sec.sh_addralign);
7272
    W.printNumber("EntrySize", Sec.sh_entsize);
7273

7274
    if (opts::SectionRelocations) {
7275
      ListScope D(W, "Relocations");
7276
      this->printRelocationsHelper(Sec);
7277
    }
7278

7279
    if (opts::SectionSymbols) {
7280
      ListScope D(W, "Symbols");
7281
      if (this->DotSymtabSec) {
7282
        StringRef StrTable = unwrapOrError(
7283
            this->FileName,
7284
            this->Obj.getStringTableForSymtab(*this->DotSymtabSec));
7285
        ArrayRef<Elf_Word> ShndxTable = this->getShndxTable(this->DotSymtabSec);
7286

7287
        typename ELFT::SymRange Symbols = unwrapOrError(
7288
            this->FileName, this->Obj.symbols(this->DotSymtabSec));
7289
        for (const Elf_Sym &Sym : Symbols) {
7290
          const Elf_Shdr *SymSec = unwrapOrError(
7291
              this->FileName,
7292
              this->Obj.getSection(Sym, this->DotSymtabSec, ShndxTable));
7293
          if (SymSec == &Sec)
7294
            printSymbol(Sym, &Sym - &Symbols[0], ShndxTable, StrTable, false,
7295
                        /*NonVisibilityBitsUsed=*/false,
7296
                        /*ExtraSymInfo=*/false);
7297
        }
7298
      }
7299
    }
7300

7301
    if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
7302
      ArrayRef<uint8_t> Data =
7303
          unwrapOrError(this->FileName, this->Obj.getSectionContents(Sec));
7304
      W.printBinaryBlock(
7305
          "SectionData",
7306
          StringRef(reinterpret_cast<const char *>(Data.data()), Data.size()));
7307
    }
7308
  }
7309
}
7310

7311
template <class ELFT>
7312
void LLVMELFDumper<ELFT>::printSymbolSection(
7313
    const Elf_Sym &Symbol, unsigned SymIndex,
7314
    DataRegion<Elf_Word> ShndxTable) const {
7315
  auto GetSectionSpecialType = [&]() -> std::optional<StringRef> {
7316
    if (Symbol.isUndefined())
7317
      return StringRef("Undefined");
7318
    if (Symbol.isProcessorSpecific())
7319
      return StringRef("Processor Specific");
7320
    if (Symbol.isOSSpecific())
7321
      return StringRef("Operating System Specific");
7322
    if (Symbol.isAbsolute())
7323
      return StringRef("Absolute");
7324
    if (Symbol.isCommon())
7325
      return StringRef("Common");
7326
    if (Symbol.isReserved() && Symbol.st_shndx != SHN_XINDEX)
7327
      return StringRef("Reserved");
7328
    return std::nullopt;
7329
  };
7330

7331
  if (std::optional<StringRef> Type = GetSectionSpecialType()) {
7332
    W.printHex("Section", *Type, Symbol.st_shndx);
7333
    return;
7334
  }
7335

7336
  Expected<unsigned> SectionIndex =
7337
      this->getSymbolSectionIndex(Symbol, SymIndex, ShndxTable);
7338
  if (!SectionIndex) {
7339
    assert(Symbol.st_shndx == SHN_XINDEX &&
7340
           "getSymbolSectionIndex should only fail due to an invalid "
7341
           "SHT_SYMTAB_SHNDX table/reference");
7342
    this->reportUniqueWarning(SectionIndex.takeError());
7343
    W.printHex("Section", "Reserved", SHN_XINDEX);
7344
    return;
7345
  }
7346

7347
  Expected<StringRef> SectionName =
7348
      this->getSymbolSectionName(Symbol, *SectionIndex);
7349
  if (!SectionName) {
7350
    // Don't report an invalid section name if the section headers are missing.
7351
    // In such situations, all sections will be "invalid".
7352
    if (!this->ObjF.sections().empty())
7353
      this->reportUniqueWarning(SectionName.takeError());
7354
    else
7355
      consumeError(SectionName.takeError());
7356
    W.printHex("Section", "<?>", *SectionIndex);
7357
  } else {
7358
    W.printHex("Section", *SectionName, *SectionIndex);
7359
  }
7360
}
7361

7362
template <class ELFT>
7363
void LLVMELFDumper<ELFT>::printSymbolOtherField(const Elf_Sym &Symbol) const {
7364
  std::vector<EnumEntry<unsigned>> SymOtherFlags =
7365
      this->getOtherFlagsFromSymbol(this->Obj.getHeader(), Symbol);
7366
  W.printFlags("Other", Symbol.st_other, ArrayRef(SymOtherFlags), 0x3u);
7367
}
7368

7369
template <class ELFT>
7370
void LLVMELFDumper<ELFT>::printZeroSymbolOtherField(
7371
    const Elf_Sym &Symbol) const {
7372
  assert(Symbol.st_other == 0 && "non-zero Other Field");
7373
  // Usually st_other flag is zero. Do not pollute the output
7374
  // by flags enumeration in that case.
7375
  W.printNumber("Other", 0);
7376
}
7377

7378
template <class ELFT>
7379
void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
7380
                                      DataRegion<Elf_Word> ShndxTable,
7381
                                      std::optional<StringRef> StrTable,
7382
                                      bool IsDynamic,
7383
                                      bool /*NonVisibilityBitsUsed*/,
7384
                                      bool /*ExtraSymInfo*/) const {
7385
  std::string FullSymbolName = this->getFullSymbolName(
7386
      Symbol, SymIndex, ShndxTable, StrTable, IsDynamic);
7387
  unsigned char SymbolType = Symbol.getType();
7388

7389
  DictScope D(W, "Symbol");
7390
  W.printNumber("Name", FullSymbolName, Symbol.st_name);
7391
  W.printHex("Value", Symbol.st_value);
7392
  W.printNumber("Size", Symbol.st_size);
7393
  W.printEnum("Binding", Symbol.getBinding(), ArrayRef(ElfSymbolBindings));
7394
  if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU &&
7395
      SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
7396
    W.printEnum("Type", SymbolType, ArrayRef(AMDGPUSymbolTypes));
7397
  else
7398
    W.printEnum("Type", SymbolType, ArrayRef(ElfSymbolTypes));
7399
  if (Symbol.st_other == 0)
7400
    printZeroSymbolOtherField(Symbol);
7401
  else
7402
    printSymbolOtherField(Symbol);
7403
  printSymbolSection(Symbol, SymIndex, ShndxTable);
7404
}
7405

7406
template <class ELFT>
7407
void LLVMELFDumper<ELFT>::printSymbols(bool PrintSymbols,
7408
                                       bool PrintDynamicSymbols,
7409
                                       bool ExtraSymInfo) {
7410
  if (PrintSymbols) {
7411
    ListScope Group(W, "Symbols");
7412
    this->printSymbolsHelper(false, ExtraSymInfo);
7413
  }
7414
  if (PrintDynamicSymbols) {
7415
    ListScope Group(W, "DynamicSymbols");
7416
    this->printSymbolsHelper(true, ExtraSymInfo);
7417
  }
7418
}
7419

7420
template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicTable() {
7421
  Elf_Dyn_Range Table = this->dynamic_table();
7422
  if (Table.empty())
7423
    return;
7424

7425
  W.startLine() << "DynamicSection [ (" << Table.size() << " entries)\n";
7426

7427
  size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table);
7428
  // The "Name/Value" column should be indented from the "Type" column by N
7429
  // spaces, where N = MaxTagSize - length of "Type" (4) + trailing
7430
  // space (1) = -3.
7431
  W.startLine() << "  Tag" << std::string(ELFT::Is64Bits ? 16 : 8, ' ')
7432
                << "Type" << std::string(MaxTagSize - 3, ' ') << "Name/Value\n";
7433

7434
  std::string ValueFmt = "%-" + std::to_string(MaxTagSize) + "s ";
7435
  for (auto Entry : Table) {
7436
    uintX_t Tag = Entry.getTag();
7437
    std::string Value = this->getDynamicEntry(Tag, Entry.getVal());
7438
    W.startLine() << "  " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10, true)
7439
                  << " "
7440
                  << format(ValueFmt.c_str(),
7441
                            this->Obj.getDynamicTagAsString(Tag).c_str())
7442
                  << Value << "\n";
7443
  }
7444
  W.startLine() << "]\n";
7445
}
7446

7447
template <class ELFT>
7448
void JSONELFDumper<ELFT>::printAuxillaryDynamicTableEntryInfo(
7449
    const Elf_Dyn &Entry) {
7450
  auto FormatFlags = [this, Value = Entry.getVal()](auto Flags) {
7451
    ListScope L(this->W, "Flags");
7452
    for (const auto &Flag : Flags) {
7453
      if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value)
7454
        this->W.printString(Flag.Name);
7455
    }
7456
  };
7457
  switch (Entry.getTag()) {
7458
  case DT_SONAME:
7459
    this->W.printString("Name", this->getDynamicString(Entry.getVal()));
7460
    break;
7461
  case DT_AUXILIARY:
7462
  case DT_FILTER:
7463
  case DT_NEEDED:
7464
    this->W.printString("Library", this->getDynamicString(Entry.getVal()));
7465
    break;
7466
  case DT_USED:
7467
    this->W.printString("Object", this->getDynamicString(Entry.getVal()));
7468
    break;
7469
  case DT_RPATH:
7470
  case DT_RUNPATH: {
7471
    StringRef Value = this->getDynamicString(Entry.getVal());
7472
    ListScope L(this->W, "Path");
7473
    while (!Value.empty()) {
7474
      auto [Front, Back] = Value.split(':');
7475
      this->W.printString(Front);
7476
      Value = Back;
7477
    }
7478
    break;
7479
  }
7480
  case DT_FLAGS:
7481
    FormatFlags(ArrayRef(ElfDynamicDTFlags));
7482
    break;
7483
  case DT_FLAGS_1:
7484
    FormatFlags(ArrayRef(ElfDynamicDTFlags1));
7485
    break;
7486
  default:
7487
    return;
7488
  }
7489
}
7490

7491
template <class ELFT> void JSONELFDumper<ELFT>::printDynamicTable() {
7492
  Elf_Dyn_Range Table = this->dynamic_table();
7493
  ListScope L(this->W, "DynamicSection");
7494
  for (const auto &Entry : Table) {
7495
    DictScope D(this->W);
7496
    uintX_t Tag = Entry.getTag();
7497
    this->W.printHex("Tag", Tag);
7498
    this->W.printString("Type", this->Obj.getDynamicTagAsString(Tag));
7499
    this->W.printHex("Value", Entry.getVal());
7500
    this->printAuxillaryDynamicTableEntryInfo(Entry);
7501
  }
7502
}
7503

7504
template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicRelocations() {
7505
  W.startLine() << "Dynamic Relocations {\n";
7506
  W.indent();
7507
  this->printDynamicRelocationsHelper();
7508
  W.unindent();
7509
  W.startLine() << "}\n";
7510
}
7511

7512
template <class ELFT>
7513
void LLVMELFDumper<ELFT>::printProgramHeaders(
7514
    bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {
7515
  if (PrintProgramHeaders)
7516
    printProgramHeaders();
7517
  if (PrintSectionMapping == cl::BOU_TRUE)
7518
    printSectionMapping();
7519
}
7520

7521
template <class ELFT> void LLVMELFDumper<ELFT>::printProgramHeaders() {
7522
  ListScope L(W, "ProgramHeaders");
7523

7524
  Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
7525
  if (!PhdrsOrErr) {
7526
    this->reportUniqueWarning("unable to dump program headers: " +
7527
                              toString(PhdrsOrErr.takeError()));
7528
    return;
7529
  }
7530

7531
  for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
7532
    DictScope P(W, "ProgramHeader");
7533
    StringRef Type =
7534
        segmentTypeToString(this->Obj.getHeader().e_machine, Phdr.p_type);
7535

7536
    W.printHex("Type", Type.empty() ? "Unknown" : Type, Phdr.p_type);
7537
    W.printHex("Offset", Phdr.p_offset);
7538
    W.printHex("VirtualAddress", Phdr.p_vaddr);
7539
    W.printHex("PhysicalAddress", Phdr.p_paddr);
7540
    W.printNumber("FileSize", Phdr.p_filesz);
7541
    W.printNumber("MemSize", Phdr.p_memsz);
7542
    W.printFlags("Flags", Phdr.p_flags, ArrayRef(ElfSegmentFlags));
7543
    W.printNumber("Alignment", Phdr.p_align);
7544
  }
7545
}
7546

7547
template <class ELFT>
7548
void LLVMELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) {
7549
  ListScope SS(W, "VersionSymbols");
7550
  if (!Sec)
7551
    return;
7552

7553
  StringRef StrTable;
7554
  ArrayRef<Elf_Sym> Syms;
7555
  const Elf_Shdr *SymTabSec;
7556
  Expected<ArrayRef<Elf_Versym>> VerTableOrErr =
7557
      this->getVersionTable(*Sec, &Syms, &StrTable, &SymTabSec);
7558
  if (!VerTableOrErr) {
7559
    this->reportUniqueWarning(VerTableOrErr.takeError());
7560
    return;
7561
  }
7562

7563
  if (StrTable.empty() || Syms.empty() || Syms.size() != VerTableOrErr->size())
7564
    return;
7565

7566
  ArrayRef<Elf_Word> ShNdxTable = this->getShndxTable(SymTabSec);
7567
  for (size_t I = 0, E = Syms.size(); I < E; ++I) {
7568
    DictScope S(W, "Symbol");
7569
    W.printNumber("Version", (*VerTableOrErr)[I].vs_index & VERSYM_VERSION);
7570
    W.printString("Name",
7571
                  this->getFullSymbolName(Syms[I], I, ShNdxTable, StrTable,
7572
                                          /*IsDynamic=*/true));
7573
  }
7574
}
7575

7576
const EnumEntry<unsigned> SymVersionFlags[] = {
7577
    {"Base", "BASE", VER_FLG_BASE},
7578
    {"Weak", "WEAK", VER_FLG_WEAK},
7579
    {"Info", "INFO", VER_FLG_INFO}};
7580

7581
template <class ELFT>
7582
void LLVMELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) {
7583
  ListScope SD(W, "VersionDefinitions");
7584
  if (!Sec)
7585
    return;
7586

7587
  Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec);
7588
  if (!V) {
7589
    this->reportUniqueWarning(V.takeError());
7590
    return;
7591
  }
7592

7593
  for (const VerDef &D : *V) {
7594
    DictScope Def(W, "Definition");
7595
    W.printNumber("Version", D.Version);
7596
    W.printFlags("Flags", D.Flags, ArrayRef(SymVersionFlags));
7597
    W.printNumber("Index", D.Ndx);
7598
    W.printNumber("Hash", D.Hash);
7599
    W.printString("Name", D.Name.c_str());
7600
    W.printList(
7601
        "Predecessors", D.AuxV,
7602
        [](raw_ostream &OS, const VerdAux &Aux) { OS << Aux.Name.c_str(); });
7603
  }
7604
}
7605

7606
template <class ELFT>
7607
void LLVMELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) {
7608
  ListScope SD(W, "VersionRequirements");
7609
  if (!Sec)
7610
    return;
7611

7612
  Expected<std::vector<VerNeed>> V =
7613
      this->Obj.getVersionDependencies(*Sec, this->WarningHandler);
7614
  if (!V) {
7615
    this->reportUniqueWarning(V.takeError());
7616
    return;
7617
  }
7618

7619
  for (const VerNeed &VN : *V) {
7620
    DictScope Entry(W, "Dependency");
7621
    W.printNumber("Version", VN.Version);
7622
    W.printNumber("Count", VN.Cnt);
7623
    W.printString("FileName", VN.File.c_str());
7624

7625
    ListScope L(W, "Entries");
7626
    for (const VernAux &Aux : VN.AuxV) {
7627
      DictScope Entry(W, "Entry");
7628
      W.printNumber("Hash", Aux.Hash);
7629
      W.printFlags("Flags", Aux.Flags, ArrayRef(SymVersionFlags));
7630
      W.printNumber("Index", Aux.Other);
7631
      W.printString("Name", Aux.Name.c_str());
7632
    }
7633
  }
7634
}
7635

7636
template <class ELFT>
7637
void LLVMELFDumper<ELFT>::printHashHistogramStats(size_t NBucket,
7638
                                                  size_t MaxChain,
7639
                                                  size_t TotalSyms,
7640
                                                  ArrayRef<size_t> Count,
7641
                                                  bool IsGnu) const {
7642
  StringRef HistName = IsGnu ? "GnuHashHistogram" : "HashHistogram";
7643
  StringRef BucketName = IsGnu ? "Bucket" : "Chain";
7644
  StringRef ListName = IsGnu ? "Buckets" : "Chains";
7645
  DictScope Outer(W, HistName);
7646
  W.printNumber("TotalBuckets", NBucket);
7647
  ListScope Buckets(W, ListName);
7648
  size_t CumulativeNonZero = 0;
7649
  for (size_t I = 0; I < MaxChain; ++I) {
7650
    CumulativeNonZero += Count[I] * I;
7651
    DictScope Bucket(W, BucketName);
7652
    W.printNumber("Length", I);
7653
    W.printNumber("Count", Count[I]);
7654
    W.printNumber("Percentage", (float)(Count[I] * 100.0) / NBucket);
7655
    W.printNumber("Coverage", (float)(CumulativeNonZero * 100.0) / TotalSyms);
7656
  }
7657
}
7658

7659
// Returns true if rel/rela section exists, and populates SymbolIndices.
7660
// Otherwise returns false.
7661
template <class ELFT>
7662
static bool getSymbolIndices(const typename ELFT::Shdr *CGRelSection,
7663
                             const ELFFile<ELFT> &Obj,
7664
                             const LLVMELFDumper<ELFT> *Dumper,
7665
                             SmallVector<uint32_t, 128> &SymbolIndices) {
7666
  if (!CGRelSection) {
7667
    Dumper->reportUniqueWarning(
7668
        "relocation section for a call graph section doesn't exist");
7669
    return false;
7670
  }
7671

7672
  if (CGRelSection->sh_type == SHT_REL) {
7673
    typename ELFT::RelRange CGProfileRel;
7674
    Expected<typename ELFT::RelRange> CGProfileRelOrError =
7675
        Obj.rels(*CGRelSection);
7676
    if (!CGProfileRelOrError) {
7677
      Dumper->reportUniqueWarning("unable to load relocations for "
7678
                                  "SHT_LLVM_CALL_GRAPH_PROFILE section: " +
7679
                                  toString(CGProfileRelOrError.takeError()));
7680
      return false;
7681
    }
7682

7683
    CGProfileRel = *CGProfileRelOrError;
7684
    for (const typename ELFT::Rel &Rel : CGProfileRel)
7685
      SymbolIndices.push_back(Rel.getSymbol(Obj.isMips64EL()));
7686
  } else {
7687
    // MC unconditionally produces SHT_REL, but GNU strip/objcopy may convert
7688
    // the format to SHT_RELA
7689
    // (https://sourceware.org/bugzilla/show_bug.cgi?id=28035)
7690
    typename ELFT::RelaRange CGProfileRela;
7691
    Expected<typename ELFT::RelaRange> CGProfileRelaOrError =
7692
        Obj.relas(*CGRelSection);
7693
    if (!CGProfileRelaOrError) {
7694
      Dumper->reportUniqueWarning("unable to load relocations for "
7695
                                  "SHT_LLVM_CALL_GRAPH_PROFILE section: " +
7696
                                  toString(CGProfileRelaOrError.takeError()));
7697
      return false;
7698
    }
7699

7700
    CGProfileRela = *CGProfileRelaOrError;
7701
    for (const typename ELFT::Rela &Rela : CGProfileRela)
7702
      SymbolIndices.push_back(Rela.getSymbol(Obj.isMips64EL()));
7703
  }
7704

7705
  return true;
7706
}
7707

7708
template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
7709
  auto IsMatch = [](const Elf_Shdr &Sec) -> bool {
7710
    return Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
7711
  };
7712

7713
  Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecToRelocMapOrErr =
7714
      this->Obj.getSectionAndRelocations(IsMatch);
7715
  if (!SecToRelocMapOrErr) {
7716
    this->reportUniqueWarning("unable to get CG Profile section(s): " +
7717
                              toString(SecToRelocMapOrErr.takeError()));
7718
    return;
7719
  }
7720

7721
  for (const auto &CGMapEntry : *SecToRelocMapOrErr) {
7722
    const Elf_Shdr *CGSection = CGMapEntry.first;
7723
    const Elf_Shdr *CGRelSection = CGMapEntry.second;
7724

7725
    Expected<ArrayRef<Elf_CGProfile>> CGProfileOrErr =
7726
        this->Obj.template getSectionContentsAsArray<Elf_CGProfile>(*CGSection);
7727
    if (!CGProfileOrErr) {
7728
      this->reportUniqueWarning(
7729
          "unable to load the SHT_LLVM_CALL_GRAPH_PROFILE section: " +
7730
          toString(CGProfileOrErr.takeError()));
7731
      return;
7732
    }
7733

7734
    SmallVector<uint32_t, 128> SymbolIndices;
7735
    bool UseReloc =
7736
        getSymbolIndices<ELFT>(CGRelSection, this->Obj, this, SymbolIndices);
7737
    if (UseReloc && SymbolIndices.size() != CGProfileOrErr->size() * 2) {
7738
      this->reportUniqueWarning(
7739
          "number of from/to pairs does not match number of frequencies");
7740
      UseReloc = false;
7741
    }
7742

7743
    ListScope L(W, "CGProfile");
7744
    for (uint32_t I = 0, Size = CGProfileOrErr->size(); I != Size; ++I) {
7745
      const Elf_CGProfile &CGPE = (*CGProfileOrErr)[I];
7746
      DictScope D(W, "CGProfileEntry");
7747
      if (UseReloc) {
7748
        uint32_t From = SymbolIndices[I * 2];
7749
        uint32_t To = SymbolIndices[I * 2 + 1];
7750
        W.printNumber("From", this->getStaticSymbolName(From), From);
7751
        W.printNumber("To", this->getStaticSymbolName(To), To);
7752
      }
7753
      W.printNumber("Weight", CGPE.cgp_weight);
7754
    }
7755
  }
7756
}
7757

7758
template <class ELFT>
7759
void LLVMELFDumper<ELFT>::printBBAddrMaps(bool PrettyPGOAnalysis) {
7760
  bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL;
7761
  using Elf_Shdr = typename ELFT::Shdr;
7762
  auto IsMatch = [](const Elf_Shdr &Sec) -> bool {
7763
    return Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP;
7764
  };
7765
  Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecRelocMapOrErr =
7766
      this->Obj.getSectionAndRelocations(IsMatch);
7767
  if (!SecRelocMapOrErr) {
7768
    this->reportUniqueWarning(
7769
        "failed to get SHT_LLVM_BB_ADDR_MAP section(s): " +
7770
        toString(SecRelocMapOrErr.takeError()));
7771
    return;
7772
  }
7773
  for (auto const &[Sec, RelocSec] : *SecRelocMapOrErr) {
7774
    std::optional<const Elf_Shdr *> FunctionSec;
7775
    if (IsRelocatable)
7776
      FunctionSec =
7777
          unwrapOrError(this->FileName, this->Obj.getSection(Sec->sh_link));
7778
    ListScope L(W, "BBAddrMap");
7779
    if (IsRelocatable && !RelocSec) {
7780
      this->reportUniqueWarning("unable to get relocation section for " +
7781
                                this->describe(*Sec));
7782
      continue;
7783
    }
7784
    std::vector<PGOAnalysisMap> PGOAnalyses;
7785
    Expected<std::vector<BBAddrMap>> BBAddrMapOrErr =
7786
        this->Obj.decodeBBAddrMap(*Sec, RelocSec, &PGOAnalyses);
7787
    if (!BBAddrMapOrErr) {
7788
      this->reportUniqueWarning("unable to dump " + this->describe(*Sec) +
7789
                                ": " + toString(BBAddrMapOrErr.takeError()));
7790
      continue;
7791
    }
7792
    for (const auto &[AM, PAM] : zip_equal(*BBAddrMapOrErr, PGOAnalyses)) {
7793
      DictScope D(W, "Function");
7794
      W.printHex("At", AM.getFunctionAddress());
7795
      SmallVector<uint32_t> FuncSymIndex =
7796
          this->getSymbolIndexesForFunctionAddress(AM.getFunctionAddress(),
7797
                                                   FunctionSec);
7798
      std::string FuncName = "<?>";
7799
      if (FuncSymIndex.empty())
7800
        this->reportUniqueWarning(
7801
            "could not identify function symbol for address (0x" +
7802
            Twine::utohexstr(AM.getFunctionAddress()) + ") in " +
7803
            this->describe(*Sec));
7804
      else
7805
        FuncName = this->getStaticSymbolName(FuncSymIndex.front());
7806
      W.printString("Name", FuncName);
7807
      {
7808
        ListScope BBRL(W, "BB Ranges");
7809
        for (const BBAddrMap::BBRangeEntry &BBR : AM.BBRanges) {
7810
          DictScope BBRD(W);
7811
          W.printHex("Base Address", BBR.BaseAddress);
7812
          ListScope BBEL(W, "BB Entries");
7813
          for (const BBAddrMap::BBEntry &BBE : BBR.BBEntries) {
7814
            DictScope BBED(W);
7815
            W.printNumber("ID", BBE.ID);
7816
            W.printHex("Offset", BBE.Offset);
7817
            W.printHex("Size", BBE.Size);
7818
            W.printBoolean("HasReturn", BBE.hasReturn());
7819
            W.printBoolean("HasTailCall", BBE.hasTailCall());
7820
            W.printBoolean("IsEHPad", BBE.isEHPad());
7821
            W.printBoolean("CanFallThrough", BBE.canFallThrough());
7822
            W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch());
7823
          }
7824
        }
7825
      }
7826

7827
      if (PAM.FeatEnable.hasPGOAnalysis()) {
7828
        DictScope PD(W, "PGO analyses");
7829

7830
        if (PAM.FeatEnable.FuncEntryCount)
7831
          W.printNumber("FuncEntryCount", PAM.FuncEntryCount);
7832

7833
        if (PAM.FeatEnable.hasPGOAnalysisBBData()) {
7834
          ListScope L(W, "PGO BB entries");
7835
          for (const PGOAnalysisMap::PGOBBEntry &PBBE : PAM.BBEntries) {
7836
            DictScope L(W);
7837

7838
            if (PAM.FeatEnable.BBFreq) {
7839
              if (PrettyPGOAnalysis) {
7840
                std::string BlockFreqStr;
7841
                raw_string_ostream SS(BlockFreqStr);
7842
                printRelativeBlockFreq(SS, PAM.BBEntries.front().BlockFreq,
7843
                                       PBBE.BlockFreq);
7844
                W.printString("Frequency", BlockFreqStr);
7845
              } else {
7846
                W.printNumber("Frequency", PBBE.BlockFreq.getFrequency());
7847
              }
7848
            }
7849

7850
            if (PAM.FeatEnable.BrProb) {
7851
              ListScope L(W, "Successors");
7852
              for (const auto &Succ : PBBE.Successors) {
7853
                DictScope L(W);
7854
                W.printNumber("ID", Succ.ID);
7855
                if (PrettyPGOAnalysis) {
7856
                  W.printObject("Probability", Succ.Prob);
7857
                } else {
7858
                  W.printHex("Probability", Succ.Prob.getNumerator());
7859
                }
7860
              }
7861
            }
7862
          }
7863
        }
7864
      }
7865
    }
7866
  }
7867
}
7868

7869
template <class ELFT> void LLVMELFDumper<ELFT>::printAddrsig() {
7870
  ListScope L(W, "Addrsig");
7871
  if (!this->DotAddrsigSec)
7872
    return;
7873

7874
  Expected<std::vector<uint64_t>> SymsOrErr =
7875
      decodeAddrsigSection(this->Obj, *this->DotAddrsigSec);
7876
  if (!SymsOrErr) {
7877
    this->reportUniqueWarning(SymsOrErr.takeError());
7878
    return;
7879
  }
7880

7881
  for (uint64_t Sym : *SymsOrErr)
7882
    W.printNumber("Sym", this->getStaticSymbolName(Sym), Sym);
7883
}
7884

7885
template <typename ELFT>
7886
static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
7887
                                  ScopedPrinter &W) {
7888
  // Return true if we were able to pretty-print the note, false otherwise.
7889
  switch (NoteType) {
7890
  default:
7891
    return false;
7892
  case ELF::NT_GNU_ABI_TAG: {
7893
    const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc);
7894
    if (!AbiTag.IsValid) {
7895
      W.printString("ABI", "<corrupt GNU_ABI_TAG>");
7896
      return false;
7897
    } else {
7898
      W.printString("OS", AbiTag.OSName);
7899
      W.printString("ABI", AbiTag.ABI);
7900
    }
7901
    break;
7902
  }
7903
  case ELF::NT_GNU_BUILD_ID: {
7904
    W.printString("Build ID", getGNUBuildId(Desc));
7905
    break;
7906
  }
7907
  case ELF::NT_GNU_GOLD_VERSION:
7908
    W.printString("Version", getDescAsStringRef(Desc));
7909
    break;
7910
  case ELF::NT_GNU_PROPERTY_TYPE_0:
7911
    ListScope D(W, "Property");
7912
    for (const std::string &Property : getGNUPropertyList<ELFT>(Desc))
7913
      W.printString(Property);
7914
    break;
7915
  }
7916
  return true;
7917
}
7918

7919
static bool printAndroidNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc,
7920
                                      ScopedPrinter &W) {
7921
  // Return true if we were able to pretty-print the note, false otherwise.
7922
  AndroidNoteProperties Props = getAndroidNoteProperties(NoteType, Desc);
7923
  if (Props.empty())
7924
    return false;
7925
  for (const auto &KV : Props)
7926
    W.printString(KV.first, KV.second);
7927
  return true;
7928
}
7929

7930
template <class ELFT>
7931
void LLVMELFDumper<ELFT>::printMemtag(
7932
    const ArrayRef<std::pair<std::string, std::string>> DynamicEntries,
7933
    const ArrayRef<uint8_t> AndroidNoteDesc,
7934
    const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) {
7935
  {
7936
    ListScope L(W, "Memtag Dynamic Entries:");
7937
    if (DynamicEntries.empty())
7938
      W.printString("< none found >");
7939
    for (const auto &DynamicEntryKV : DynamicEntries)
7940
      W.printString(DynamicEntryKV.first, DynamicEntryKV.second);
7941
  }
7942

7943
  if (!AndroidNoteDesc.empty()) {
7944
    ListScope L(W, "Memtag Android Note:");
7945
    printAndroidNoteLLVMStyle(ELF::NT_ANDROID_TYPE_MEMTAG, AndroidNoteDesc, W);
7946
  }
7947

7948
  if (Descriptors.empty())
7949
    return;
7950

7951
  {
7952
    ListScope L(W, "Memtag Global Descriptors:");
7953
    for (const auto &[Addr, BytesToTag] : Descriptors) {
7954
      W.printHex("0x" + utohexstr(Addr), BytesToTag);
7955
    }
7956
  }
7957
}
7958

7959
template <typename ELFT>
7960
static bool printLLVMOMPOFFLOADNoteLLVMStyle(uint32_t NoteType,
7961
                                             ArrayRef<uint8_t> Desc,
7962
                                             ScopedPrinter &W) {
7963
  switch (NoteType) {
7964
  default:
7965
    return false;
7966
  case ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION:
7967
    W.printString("Version", getDescAsStringRef(Desc));
7968
    break;
7969
  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER:
7970
    W.printString("Producer", getDescAsStringRef(Desc));
7971
    break;
7972
  case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION:
7973
    W.printString("Producer version", getDescAsStringRef(Desc));
7974
    break;
7975
  }
7976
  return true;
7977
}
7978

7979
static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {
7980
  W.printNumber("Page Size", Note.PageSize);
7981
  ListScope D(W, "Mappings");
7982
  for (const CoreFileMapping &Mapping : Note.Mappings) {
7983
    DictScope D(W);
7984
    W.printHex("Start", Mapping.Start);
7985
    W.printHex("End", Mapping.End);
7986
    W.printHex("Offset", Mapping.Offset);
7987
    W.printString("Filename", Mapping.Filename);
7988
  }
7989
}
7990

7991
template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() {
7992
  ListScope L(W, "NoteSections");
7993

7994
  std::unique_ptr<DictScope> NoteSectionScope;
7995
  std::unique_ptr<ListScope> NotesScope;
7996
  size_t Align = 0;
7997
  auto StartNotes = [&](std::optional<StringRef> SecName,
7998
                        const typename ELFT::Off Offset,
7999
                        const typename ELFT::Addr Size, size_t Al) {
8000
    Align = std::max<size_t>(Al, 4);
8001
    NoteSectionScope = std::make_unique<DictScope>(W, "NoteSection");
8002
    W.printString("Name", SecName ? *SecName : "<?>");
8003
    W.printHex("Offset", Offset);
8004
    W.printHex("Size", Size);
8005
    NotesScope = std::make_unique<ListScope>(W, "Notes");
8006
  };
8007

8008
  auto EndNotes = [&] {
8009
    NotesScope.reset();
8010
    NoteSectionScope.reset();
8011
  };
8012

8013
  auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error {
8014
    DictScope D2(W);
8015
    StringRef Name = Note.getName();
8016
    ArrayRef<uint8_t> Descriptor = Note.getDesc(Align);
8017
    Elf_Word Type = Note.getType();
8018

8019
    // Print the note owner/type.
8020
    W.printString("Owner", Name);
8021
    W.printHex("Data size", Descriptor.size());
8022

8023
    StringRef NoteType =
8024
        getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type);
8025
    if (!NoteType.empty())
8026
      W.printString("Type", NoteType);
8027
    else
8028
      W.printString("Type",
8029
                    "Unknown (" + to_string(format_hex(Type, 10)) + ")");
8030

8031
    // Print the description, or fallback to printing raw bytes for unknown
8032
    // owners/if we fail to pretty-print the contents.
8033
    if (Name == "GNU") {
8034
      if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W))
8035
        return Error::success();
8036
    } else if (Name == "FreeBSD") {
8037
      if (std::optional<FreeBSDNote> N =
8038
              getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) {
8039
        W.printString(N->Type, N->Value);
8040
        return Error::success();
8041
      }
8042
    } else if (Name == "AMD") {
8043
      const AMDNote N = getAMDNote<ELFT>(Type, Descriptor);
8044
      if (!N.Type.empty()) {
8045
        W.printString(N.Type, N.Value);
8046
        return Error::success();
8047
      }
8048
    } else if (Name == "AMDGPU") {
8049
      const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor);
8050
      if (!N.Type.empty()) {
8051
        W.printString(N.Type, N.Value);
8052
        return Error::success();
8053
      }
8054
    } else if (Name == "LLVMOMPOFFLOAD") {
8055
      if (printLLVMOMPOFFLOADNoteLLVMStyle<ELFT>(Type, Descriptor, W))
8056
        return Error::success();
8057
    } else if (Name == "CORE") {
8058
      if (Type == ELF::NT_FILE) {
8059
        DataExtractor DescExtractor(
8060
            Descriptor, ELFT::Endianness == llvm::endianness::little,
8061
            sizeof(Elf_Addr));
8062
        if (Expected<CoreNote> N = readCoreNote(DescExtractor)) {
8063
          printCoreNoteLLVMStyle(*N, W);
8064
          return Error::success();
8065
        } else {
8066
          return N.takeError();
8067
        }
8068
      }
8069
    } else if (Name == "Android") {
8070
      if (printAndroidNoteLLVMStyle(Type, Descriptor, W))
8071
        return Error::success();
8072
    }
8073
    if (!Descriptor.empty()) {
8074
      W.printBinaryBlock("Description data", Descriptor);
8075
    }
8076
    return Error::success();
8077
  };
8078

8079
  processNotesHelper(*this, /*StartNotesFn=*/StartNotes,
8080
                     /*ProcessNoteFn=*/ProcessNote, /*FinishNotesFn=*/EndNotes);
8081
}
8082

8083
template <class ELFT> void LLVMELFDumper<ELFT>::printELFLinkerOptions() {
8084
  ListScope L(W, "LinkerOptions");
8085

8086
  unsigned I = -1;
8087
  for (const Elf_Shdr &Shdr : cantFail(this->Obj.sections())) {
8088
    ++I;
8089
    if (Shdr.sh_type != ELF::SHT_LLVM_LINKER_OPTIONS)
8090
      continue;
8091

8092
    Expected<ArrayRef<uint8_t>> ContentsOrErr =
8093
        this->Obj.getSectionContents(Shdr);
8094
    if (!ContentsOrErr) {
8095
      this->reportUniqueWarning("unable to read the content of the "
8096
                                "SHT_LLVM_LINKER_OPTIONS section: " +
8097
                                toString(ContentsOrErr.takeError()));
8098
      continue;
8099
    }
8100
    if (ContentsOrErr->empty())
8101
      continue;
8102

8103
    if (ContentsOrErr->back() != 0) {
8104
      this->reportUniqueWarning("SHT_LLVM_LINKER_OPTIONS section at index " +
8105
                                Twine(I) +
8106
                                " is broken: the "
8107
                                "content is not null-terminated");
8108
      continue;
8109
    }
8110

8111
    SmallVector<StringRef, 16> Strings;
8112
    toStringRef(ContentsOrErr->drop_back()).split(Strings, '\0');
8113
    if (Strings.size() % 2 != 0) {
8114
      this->reportUniqueWarning(
8115
          "SHT_LLVM_LINKER_OPTIONS section at index " + Twine(I) +
8116
          " is broken: an incomplete "
8117
          "key-value pair was found. The last possible key was: \"" +
8118
          Strings.back() + "\"");
8119
      continue;
8120
    }
8121

8122
    for (size_t I = 0; I < Strings.size(); I += 2)
8123
      W.printString(Strings[I], Strings[I + 1]);
8124
  }
8125
}
8126

8127
template <class ELFT> void LLVMELFDumper<ELFT>::printDependentLibs() {
8128
  ListScope L(W, "DependentLibs");
8129
  this->printDependentLibsHelper(
8130
      [](const Elf_Shdr &) {},
8131
      [this](StringRef Lib, uint64_t) { W.printString(Lib); });
8132
}
8133

8134
template <class ELFT> void LLVMELFDumper<ELFT>::printStackSizes() {
8135
  ListScope L(W, "StackSizes");
8136
  if (this->Obj.getHeader().e_type == ELF::ET_REL)
8137
    this->printRelocatableStackSizes([]() {});
8138
  else
8139
    this->printNonRelocatableStackSizes([]() {});
8140
}
8141

8142
template <class ELFT>
8143
void LLVMELFDumper<ELFT>::printStackSizeEntry(uint64_t Size,
8144
                                              ArrayRef<std::string> FuncNames) {
8145
  DictScope D(W, "Entry");
8146
  W.printList("Functions", FuncNames);
8147
  W.printHex("Size", Size);
8148
}
8149

8150
template <class ELFT>
8151
void LLVMELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
8152
  auto PrintEntry = [&](const Elf_Addr *E) {
8153
    W.printHex("Address", Parser.getGotAddress(E));
8154
    W.printNumber("Access", Parser.getGotOffset(E));
8155
    W.printHex("Initial", *E);
8156
  };
8157

8158
  DictScope GS(W, Parser.IsStatic ? "Static GOT" : "Primary GOT");
8159

8160
  W.printHex("Canonical gp value", Parser.getGp());
8161
  {
8162
    ListScope RS(W, "Reserved entries");
8163
    {
8164
      DictScope D(W, "Entry");
8165
      PrintEntry(Parser.getGotLazyResolver());
8166
      W.printString("Purpose", StringRef("Lazy resolver"));
8167
    }
8168

8169
    if (Parser.getGotModulePointer()) {
8170
      DictScope D(W, "Entry");
8171
      PrintEntry(Parser.getGotModulePointer());
8172
      W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
8173
    }
8174
  }
8175
  {
8176
    ListScope LS(W, "Local entries");
8177
    for (auto &E : Parser.getLocalEntries()) {
8178
      DictScope D(W, "Entry");
8179
      PrintEntry(&E);
8180
    }
8181
  }
8182

8183
  if (Parser.IsStatic)
8184
    return;
8185

8186
  {
8187
    ListScope GS(W, "Global entries");
8188
    for (auto &E : Parser.getGlobalEntries()) {
8189
      DictScope D(W, "Entry");
8190

8191
      PrintEntry(&E);
8192

8193
      const Elf_Sym &Sym = *Parser.getGotSym(&E);
8194
      W.printHex("Value", Sym.st_value);
8195
      W.printEnum("Type", Sym.getType(), ArrayRef(ElfSymbolTypes));
8196

8197
      const unsigned SymIndex = &Sym - this->dynamic_symbols().begin();
8198
      DataRegion<Elf_Word> ShndxTable(
8199
          (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
8200
      printSymbolSection(Sym, SymIndex, ShndxTable);
8201

8202
      std::string SymName = this->getFullSymbolName(
8203
          Sym, SymIndex, ShndxTable, this->DynamicStringTable, true);
8204
      W.printNumber("Name", SymName, Sym.st_name);
8205
    }
8206
  }
8207

8208
  W.printNumber("Number of TLS and multi-GOT entries",
8209
                uint64_t(Parser.getOtherEntries().size()));
8210
}
8211

8212
template <class ELFT>
8213
void LLVMELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
8214
  auto PrintEntry = [&](const Elf_Addr *E) {
8215
    W.printHex("Address", Parser.getPltAddress(E));
8216
    W.printHex("Initial", *E);
8217
  };
8218

8219
  DictScope GS(W, "PLT GOT");
8220

8221
  {
8222
    ListScope RS(W, "Reserved entries");
8223
    {
8224
      DictScope D(W, "Entry");
8225
      PrintEntry(Parser.getPltLazyResolver());
8226
      W.printString("Purpose", StringRef("PLT lazy resolver"));
8227
    }
8228

8229
    if (auto E = Parser.getPltModulePointer()) {
8230
      DictScope D(W, "Entry");
8231
      PrintEntry(E);
8232
      W.printString("Purpose", StringRef("Module pointer"));
8233
    }
8234
  }
8235
  {
8236
    ListScope LS(W, "Entries");
8237
    DataRegion<Elf_Word> ShndxTable(
8238
        (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end());
8239
    for (auto &E : Parser.getPltEntries()) {
8240
      DictScope D(W, "Entry");
8241
      PrintEntry(&E);
8242

8243
      const Elf_Sym &Sym = *Parser.getPltSym(&E);
8244
      W.printHex("Value", Sym.st_value);
8245
      W.printEnum("Type", Sym.getType(), ArrayRef(ElfSymbolTypes));
8246
      printSymbolSection(Sym, &Sym - this->dynamic_symbols().begin(),
8247
                         ShndxTable);
8248

8249
      const Elf_Sym *FirstSym = cantFail(
8250
          this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));
8251
      std::string SymName = this->getFullSymbolName(
8252
          Sym, &Sym - FirstSym, ShndxTable, Parser.getPltStrTable(), true);
8253
      W.printNumber("Name", SymName, Sym.st_name);
8254
    }
8255
  }
8256
}
8257

8258
template <class ELFT> void LLVMELFDumper<ELFT>::printMipsABIFlags() {
8259
  const Elf_Mips_ABIFlags<ELFT> *Flags;
8260
  if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =
8261
          getMipsAbiFlagsSection(*this)) {
8262
    Flags = *SecOrErr;
8263
    if (!Flags) {
8264
      W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
8265
      return;
8266
    }
8267
  } else {
8268
    this->reportUniqueWarning(SecOrErr.takeError());
8269
    return;
8270
  }
8271

8272
  raw_ostream &OS = W.getOStream();
8273
  DictScope GS(W, "MIPS ABI Flags");
8274

8275
  W.printNumber("Version", Flags->version);
8276
  W.startLine() << "ISA: ";
8277
  if (Flags->isa_rev <= 1)
8278
    OS << format("MIPS%u", Flags->isa_level);
8279
  else
8280
    OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev);
8281
  OS << "\n";
8282
  W.printEnum("ISA Extension", Flags->isa_ext, ArrayRef(ElfMipsISAExtType));
8283
  W.printFlags("ASEs", Flags->ases, ArrayRef(ElfMipsASEFlags));
8284
  W.printEnum("FP ABI", Flags->fp_abi, ArrayRef(ElfMipsFpABIType));
8285
  W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size));
8286
  W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size));
8287
  W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size));
8288
  W.printFlags("Flags 1", Flags->flags1, ArrayRef(ElfMipsFlags1));
8289
  W.printHex("Flags 2", Flags->flags2);
8290
}
8291

8292
template <class ELFT>
8293
void JSONELFDumper<ELFT>::printFileSummary(StringRef FileStr, ObjectFile &Obj,
8294
                                           ArrayRef<std::string> InputFilenames,
8295
                                           const Archive *A) {
8296
  FileScope = std::make_unique<DictScope>(this->W);
8297
  DictScope D(this->W, "FileSummary");
8298
  this->W.printString("File", FileStr);
8299
  this->W.printString("Format", Obj.getFileFormatName());
8300
  this->W.printString("Arch", Triple::getArchTypeName(Obj.getArch()));
8301
  this->W.printString(
8302
      "AddressSize",
8303
      std::string(formatv("{0}bit", 8 * Obj.getBytesInAddress())));
8304
  this->printLoadName();
8305
}
8306

8307
template <class ELFT>
8308
void JSONELFDumper<ELFT>::printZeroSymbolOtherField(
8309
    const Elf_Sym &Symbol) const {
8310
  // We want the JSON format to be uniform, since it is machine readable, so
8311
  // always print the `Other` field the same way.
8312
  this->printSymbolOtherField(Symbol);
8313
}
8314

8315
template <class ELFT>
8316
void JSONELFDumper<ELFT>::printDefaultRelRelaReloc(const Relocation<ELFT> &R,
8317
                                                   StringRef SymbolName,
8318
                                                   StringRef RelocName) {
8319
  this->printExpandedRelRelaReloc(R, SymbolName, RelocName);
8320
}
8321

8322
template <class ELFT>
8323
void JSONELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec,
8324
                                                     StringRef Name,
8325
                                                     const unsigned SecNdx) {
8326
  DictScope Group(this->W);
8327
  this->W.printNumber("SectionIndex", SecNdx);
8328
  ListScope D(this->W, "Relocs");
8329
  this->printRelocationsHelper(Sec);
8330
}
8331

8332
template <class ELFT>
8333
std::string JSONELFDumper<ELFT>::getGroupSectionHeaderName() const {
8334
  return "GroupSections";
8335
}
8336

8337
template <class ELFT>
8338
void JSONELFDumper<ELFT>::printSectionGroupMembers(StringRef Name,
8339
                                                   uint64_t Idx) const {
8340
  DictScope Grp(this->W);
8341
  this->W.printString("Name", Name);
8342
  this->W.printNumber("Index", Idx);
8343
}
8344

8345
template <class ELFT> void JSONELFDumper<ELFT>::printEmptyGroupMessage() const {
8346
  // JSON output does not need to print anything for empty groups
8347
}
8348

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.