ELFDumper.cpp revision 37ed9c199ca639565f6ce88105f9e39e898d82d0
176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===//
276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//
376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//                     The LLVM Compiler Infrastructure
476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//
576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher// This file is distributed under the University of Illinois Open Source
676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher// License. See LICENSE.TXT for details.
776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//
876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//===----------------------------------------------------------------------===//
976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher///
1076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher/// \file
1176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher/// \brief This file implements the ELF-specific dumper for llvm-readobj.
1276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher///
1376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//===----------------------------------------------------------------------===//
1476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
1576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm-readobj.h"
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "ARMAttributeParser.h"
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "ARMEHABIPrinter.h"
1876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "Error.h"
1976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "ObjDumper.h"
2076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "StreamWriter.h"
21c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/ADT/Optional.h"
2276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/ADT/SmallString.h"
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringExtras.h"
24081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer#include "llvm/Object/ELFObjectFile.h"
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ARMBuildAttributes.h"
2676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/Compiler.h"
2776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/Format.h"
2876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/MathExtras.h"
2976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/raw_ostream.h"
3076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
3176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherusing namespace llvm;
3276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherusing namespace llvm::object;
3376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherusing namespace ELF;
3476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
3576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#define LLVM_READOBJ_ENUM_CASE(ns, enum) \
3676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case ns::enum: return #enum;
3776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
3876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophernamespace {
3976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
4076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<typename ELFT>
4176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherclass ELFDumper : public ObjDumper {
4276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherpublic:
43081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer)
44081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      : ObjDumper(Writer), Obj(Obj) {}
4576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printFileHeaders() override;
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printSections() override;
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printRelocations() override;
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printSymbols() override;
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printDynamicSymbols() override;
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printUnwindInfo() override;
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printDynamicTable() override;
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printNeededLibraries() override;
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printProgramHeaders() override;
5676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printAttributes() override;
58c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void printMipsPLTGOT() override;
5976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
6076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherprivate:
61081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  typedef ELFFile<ELFT> ELFO;
62cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  typedef typename ELFO::Elf_Shdr Elf_Shdr;
63cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  typedef typename ELFO::Elf_Sym Elf_Sym;
6476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
65081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  void printSymbol(typename ELFO::Elf_Sym_Iter Symbol);
6676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
67081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  void printRelocations(const Elf_Shdr *Sec);
68081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel);
6976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
70cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  const ELFO *Obj;
7176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
7276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
73081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) {
74081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  if (!Val) {
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    error(Val.getError());
76081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    return Default;
77081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  }
7876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
79081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  return *Val;
80081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer}
81081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer} // namespace
8276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
8376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophernamespace llvm {
8476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
85bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindolatemplate <class ELFT>
86c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic std::error_code createELFDumper(const ELFFile<ELFT> *Obj,
87c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                       StreamWriter &Writer,
88c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                       std::unique_ptr<ObjDumper> &Result) {
89bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  Result.reset(new ELFDumper<ELFT>(Obj, Writer));
90bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  return readobj_error::success;
91bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola}
92bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola
93c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::error_code createELFDumper(const object::ObjectFile *Obj,
94c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                StreamWriter &Writer,
95c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                std::unique_ptr<ObjDumper> &Result) {
9676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // Little-endian 32-bit
97bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
98081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
9976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
10076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // Big-endian 32-bit
101bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
102081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
10376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
10476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // Little-endian 64-bit
105bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
106081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
10776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
10876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // Big-endian 64-bit
109bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
110081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
11176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
11276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  return readobj_error::unsupported_obj_file_format;
11376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
11476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
11576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher} // namespace llvm
11676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
117c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <typename ELFO>
118c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic std::string getFullSymbolName(const ELFO &Obj,
119c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                     typename ELFO::Elf_Sym_Iter Symbol) {
120c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  StringRef SymbolName = errorOrDefault(Obj.getSymbolName(Symbol));
121c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!Symbol.isDynamic())
122c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return SymbolName;
123c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
124c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::string FullSymbolName(SymbolName);
125c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
126c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool IsDefault;
127c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  ErrorOr<StringRef> Version =
128c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      Obj.getSymbolVersion(nullptr, &*Symbol, IsDefault);
129c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (Version) {
130c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    FullSymbolName += (IsDefault ? "@@" : "@");
131c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    FullSymbolName += *Version;
132c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else
133c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    error(Version.getError());
134c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return FullSymbolName;
135c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
136c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
137c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <typename ELFO>
138c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic void
139c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesgetSectionNameIndex(const ELFO &Obj, typename ELFO::Elf_Sym_Iter Symbol,
140c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                    StringRef &SectionName, unsigned &SectionIndex) {
141c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  SectionIndex = Symbol->st_shndx;
142c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (SectionIndex == SHN_UNDEF) {
143c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    SectionName = "Undefined";
144c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else if (SectionIndex >= SHN_LOPROC && SectionIndex <= SHN_HIPROC) {
145c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    SectionName = "Processor Specific";
146c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else if (SectionIndex >= SHN_LOOS && SectionIndex <= SHN_HIOS) {
147c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    SectionName = "Operating System Specific";
148c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else if (SectionIndex > SHN_HIOS && SectionIndex < SHN_ABS) {
149c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    SectionName = "Reserved";
150c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else if (SectionIndex == SHN_ABS) {
151c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    SectionName = "Absolute";
152c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else if (SectionIndex == SHN_COMMON) {
153c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    SectionName = "Common";
154c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else {
155c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (SectionIndex == SHN_XINDEX)
156c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      SectionIndex = Obj.getSymbolTableIndex(&*Symbol);
157c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    assert(SectionIndex != SHN_XINDEX &&
158c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines           "getSymbolTableIndex should handle this");
159c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    const typename ELFO::Elf_Shdr *Sec = Obj.getSection(SectionIndex);
160c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    SectionName = errorOrDefault(Obj.getSectionName(Sec));
161c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
162c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
163c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
164c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <class ELFT>
165c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic const typename ELFFile<ELFT>::Elf_Shdr *
166c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesfindSectionByAddress(const ELFFile<ELFT> *Obj, uint64_t Addr) {
167c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  for (const auto &Shdr : Obj->sections())
168c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (Shdr.sh_addr == Addr)
169c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return &Shdr;
170c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return nullptr;
171c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
172c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
17376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const EnumEntry<unsigned> ElfClass[] = {
17476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "None",   ELF::ELFCLASSNONE },
17576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "32-bit", ELF::ELFCLASS32   },
17676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "64-bit", ELF::ELFCLASS64   },
17776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
17876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
17976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const EnumEntry<unsigned> ElfDataEncoding[] = {
18076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "None",         ELF::ELFDATANONE },
18176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "LittleEndian", ELF::ELFDATA2LSB },
18276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "BigEndian",    ELF::ELFDATA2MSB },
18376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
18476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
18576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const EnumEntry<unsigned> ElfObjectFileType[] = {
18676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "None",         ELF::ET_NONE },
18776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Relocatable",  ELF::ET_REL  },
18876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Executable",   ELF::ET_EXEC },
18976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "SharedObject", ELF::ET_DYN  },
19076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Core",         ELF::ET_CORE },
19176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
19276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
19376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const EnumEntry<unsigned> ElfOSABI[] = {
19476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "SystemV",      ELF::ELFOSABI_NONE         },
19576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "HPUX",         ELF::ELFOSABI_HPUX         },
19676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "NetBSD",       ELF::ELFOSABI_NETBSD       },
19776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "GNU/Linux",    ELF::ELFOSABI_LINUX        },
19876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "GNU/Hurd",     ELF::ELFOSABI_HURD         },
19976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Solaris",      ELF::ELFOSABI_SOLARIS      },
20076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "AIX",          ELF::ELFOSABI_AIX          },
20176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "IRIX",         ELF::ELFOSABI_IRIX         },
20276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "FreeBSD",      ELF::ELFOSABI_FREEBSD      },
20376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "TRU64",        ELF::ELFOSABI_TRU64        },
20476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Modesto",      ELF::ELFOSABI_MODESTO      },
20576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "OpenBSD",      ELF::ELFOSABI_OPENBSD      },
20676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "OpenVMS",      ELF::ELFOSABI_OPENVMS      },
20776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "NSK",          ELF::ELFOSABI_NSK          },
20876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "AROS",         ELF::ELFOSABI_AROS         },
20976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "FenixOS",      ELF::ELFOSABI_FENIXOS      },
21076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "C6000_ELFABI", ELF::ELFOSABI_C6000_ELFABI },
21176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "C6000_LINUX" , ELF::ELFOSABI_C6000_LINUX  },
21276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "ARM",          ELF::ELFOSABI_ARM          },
21376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Standalone"  , ELF::ELFOSABI_STANDALONE   }
21476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
21576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
21676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const EnumEntry<unsigned> ElfMachineType[] = {
21776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_NONE         ),
21876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_M32          ),
21976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC        ),
22076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_386          ),
22176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_68K          ),
22276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_88K          ),
22376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_486          ),
22476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_860          ),
22576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS         ),
22676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_S370         ),
22776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_RS3_LE  ),
22876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_PARISC       ),
22976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_VPP500       ),
23076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC32PLUS  ),
23176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_960          ),
23276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC          ),
23376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC64        ),
23476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_S390         ),
23576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPU          ),
23676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_V800         ),
23776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_FR20         ),
23876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_RH32         ),
23976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_RCE          ),
24076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARM          ),
24176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ALPHA        ),
24276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SH           ),
24376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARCV9      ),
24476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TRICORE      ),
24576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC          ),
24676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300       ),
24776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300H      ),
24876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8S          ),
24976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_500       ),
25076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_IA_64        ),
25176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_X       ),
25276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_COLDFIRE     ),
25376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC12       ),
25476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MMA          ),
25576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_PCP          ),
25676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_NCPU         ),
25776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_NDR1         ),
25876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_STARCORE     ),
25976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ME16         ),
26076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST100        ),
26176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TINYJ        ),
26276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_X86_64       ),
26376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_PDSP         ),
26476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP10        ),
26576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP11        ),
26676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_FX66         ),
26776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST9PLUS      ),
26876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST7          ),
26976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC16       ),
27076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC11       ),
27176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC08       ),
27276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC05       ),
27376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SVX          ),
27476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST19         ),
27576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_VAX          ),
27676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_CRIS         ),
27776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_JAVELIN      ),
27876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_FIREPATH     ),
27976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ZSP          ),
28076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MMIX         ),
28176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_HUANY        ),
28276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_PRISM        ),
28376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR          ),
28476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_FR30         ),
28576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_D10V         ),
28676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_D30V         ),
28776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_V850         ),
28876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_M32R         ),
28976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10300      ),
29076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10200      ),
29176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_PJ           ),
29276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_OPENRISC     ),
29376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT  ),
29476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_XTENSA       ),
29576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE    ),
29676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TMM_GPP      ),
29776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_NS32K        ),
29876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TPC          ),
29976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SNP1K        ),
30076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST200        ),
30176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_IP2K         ),
30276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MAX          ),
30376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_CR           ),
30476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_F2MC16       ),
30576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MSP430       ),
30676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_BLACKFIN     ),
30776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C33       ),
30876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SEP          ),
30976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARCA         ),
31076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_UNICORE      ),
31176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_EXCESS       ),
31276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_DXP          ),
31376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ALTERA_NIOS2 ),
31476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_CRX          ),
31576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_XGATE        ),
31676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_C166         ),
31776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_M16C         ),
31876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_DSPIC30F     ),
31976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_CE           ),
32076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_M32C         ),
32176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TSK3000      ),
32276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_RS08         ),
32376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SHARC        ),
32476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG2        ),
32576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SCORE7       ),
32676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_DSP24        ),
32776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE3   ),
32876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_LATTICEMICO32),
32976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C17       ),
33076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C6000     ),
33176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C2000     ),
33276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C5500     ),
33376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MMDSP_PLUS   ),
33476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_CYPRESS_M8C  ),
33576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_R32C         ),
33676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TRIMEDIA     ),
33776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_HEXAGON      ),
33876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_8051         ),
33976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_STXP7X       ),
34076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_NDS32        ),
34176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1        ),
34276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1X       ),
34376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MAXQ30       ),
34476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_XIMO16       ),
34576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MANIK        ),
34676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_CRAYNV2      ),
34776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_RX           ),
34876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_METAG        ),
34976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_MCST_ELBRUS  ),
35076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG16       ),
35176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_CR16         ),
35276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ETPU         ),
35376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_SLE9X        ),
35476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_L10M         ),
35576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_K10M         ),
35676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_AARCH64      ),
35776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR32        ),
35876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_STM8         ),
35976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TILE64       ),
36076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEPRO      ),
36176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_CUDA         ),
36276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEGX       ),
36376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_CLOUDSHIELD  ),
36476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_1ST    ),
36576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_2ND    ),
36676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT2 ),
36776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_OPEN8        ),
36876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78         ),
36976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5   ),
37076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR        ),
3716fccaafd8be0eb7619b5a210387b0d1254ef4174Rafael Espindola  LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX      )
37276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
37376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
37476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const EnumEntry<unsigned> ElfSymbolBindings[] = {
37576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Local",  ELF::STB_LOCAL  },
37676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Global", ELF::STB_GLOBAL },
37776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Weak",   ELF::STB_WEAK   }
37876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
37976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
38076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const EnumEntry<unsigned> ElfSymbolTypes[] = {
38176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "None",      ELF::STT_NOTYPE    },
38276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Object",    ELF::STT_OBJECT    },
38376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Function",  ELF::STT_FUNC      },
38476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Section",   ELF::STT_SECTION   },
38576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "File",      ELF::STT_FILE      },
38676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "Common",    ELF::STT_COMMON    },
38776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "TLS",       ELF::STT_TLS       },
38876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  { "GNU_IFunc", ELF::STT_GNU_IFUNC }
38976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
39076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
39176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const char *getElfSectionType(unsigned Arch, unsigned Type) {
39276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  switch (Arch) {
393081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  case ELF::EM_ARM:
39476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    switch (Type) {
39576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX);
39676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
39776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
39876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
39976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
40076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
401081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  case ELF::EM_HEXAGON:
402081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
403081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  case ELF::EM_X86_64:
404081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
405081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  case ELF::EM_MIPS:
406081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  case ELF::EM_MIPS_RS3_LE:
40776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    switch (Type) {
40876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
40976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
41037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
41176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
41276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
41376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
41476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  switch (Type) {
41576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL              );
41676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS          );
41776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB            );
41876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB            );
41976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA              );
42076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH              );
42176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC           );
42276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE              );
42376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS            );
42476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL               );
42576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB             );
42676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM            );
42776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY        );
42876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY        );
42976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY     );
43076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP             );
43176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX      );
43276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES    );
43376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH          );
43476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef        );
43576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed       );
43676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym        );
43776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  default: return "";
43876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
43976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
44076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
44176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const EnumEntry<unsigned> ElfSectionFlags[] = {
44276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE           ),
44376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC           ),
444766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer  LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXCLUDE         ),
44576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR       ),
44676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE           ),
44776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS         ),
44876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_INFO_LINK       ),
44976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_LINK_ORDER      ),
45076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_OS_NONCONFORMING),
45176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_GROUP           ),
45276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS             ),
45376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION),
45476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION),
45576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP    )
45676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
45776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
458c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyanstatic const char *getElfSegmentType(unsigned Arch, unsigned Type) {
459c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  // Check potentially overlapped processor-specific
460c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  // program header type.
461c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  switch (Arch) {
462c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  case ELF::EM_ARM:
463c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    switch (Type) {
464c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX);
465c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    }
466c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  case ELF::EM_MIPS:
467c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  case ELF::EM_MIPS_RS3_LE:
468c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    switch (Type) {
469c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
470c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
471c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
472c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    }
473c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  }
474c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan
475c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  switch (Type) {
476c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL   );
477c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD   );
478c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
479c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP );
480c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE   );
481c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB  );
482c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR   );
483c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS    );
484c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan
485c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
486c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
487c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan
488c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
489c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
490c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  default: return "";
491c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  }
492c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan}
493cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck
494cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieckstatic const EnumEntry<unsigned> ElfSegmentFlags[] = {
495cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
496cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
497cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
498cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck};
499cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck
500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NOREORDER),
502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_PIC),
503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_CPIC),
504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI2),
505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_32BITMODE),
506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NAN2008),
507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O32),
508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MICROMIPS),
509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_M16),
510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_1),
511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_2),
512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_3),
513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_4),
514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_5),
515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32),
516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64),
517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R2),
518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R2),
519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R6),
520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6)
521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
52376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
52476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printFileHeaders() {
525081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  const typename ELFO::Elf_Ehdr *Header = Obj->getHeader();
52676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
52776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  {
52876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    DictScope D(W, "ElfHeader");
52976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    {
53076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      DictScope D(W, "Ident");
53176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printBinary("Magic", makeArrayRef(Header->e_ident).slice(ELF::EI_MAG0,
53276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                                                                 4));
53376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printEnum  ("Class", Header->e_ident[ELF::EI_CLASS],
53476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                      makeArrayRef(ElfClass));
53576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printEnum  ("DataEncoding", Header->e_ident[ELF::EI_DATA],
53676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                      makeArrayRef(ElfDataEncoding));
53776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]);
53876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printEnum  ("OS/ABI", Header->e_ident[ELF::EI_OSABI],
53976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                      makeArrayRef(ElfOSABI));
54076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]);
54176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD));
54276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
54376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
54476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printEnum  ("Type", Header->e_type, makeArrayRef(ElfObjectFileType));
54576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printEnum  ("Machine", Header->e_machine, makeArrayRef(ElfMachineType));
54676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Version", Header->e_version);
54776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("Entry", Header->e_entry);
54876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("ProgramHeaderOffset", Header->e_phoff);
54976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("SectionHeaderOffset", Header->e_shoff);
550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Header->e_machine == EM_MIPS)
551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      W.printFlags("Flags", Header->e_flags, makeArrayRef(ElfHeaderMipsFlags),
552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                   unsigned(ELF::EF_MIPS_ARCH));
553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      W.printFlags("Flags", Header->e_flags);
55576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("HeaderSize", Header->e_ehsize);
55676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize);
55776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("ProgramHeaderCount", Header->e_phnum);
55876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("SectionHeaderEntrySize", Header->e_shentsize);
55976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("SectionHeaderCount", Header->e_shnum);
56076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("StringTableSectionIndex", Header->e_shstrndx);
56176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
56276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
56376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
56476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
56576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printSections() {
56676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope SectionsD(W, "Sections");
56776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
56876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  int SectionIndex = -1;
569081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(),
570081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                    SecE = Obj->end_sections();
571081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       SecI != SecE; ++SecI) {
57276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    ++SectionIndex;
57376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
574081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    const Elf_Shdr *Section = &*SecI;
575081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    StringRef Name = errorOrDefault(Obj->getSectionName(Section));
57676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
57776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    DictScope SectionD(W, "Section");
57876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Index", SectionIndex);
57976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Name", Name, Section->sh_name);
580081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.printHex("Type",
581081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer               getElfSectionType(Obj->getHeader()->e_machine, Section->sh_type),
582081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer               Section->sh_type);
58376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags));
58476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("Address", Section->sh_addr);
58576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("Offset", Section->sh_offset);
58676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Size", Section->sh_size);
58776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Link", Section->sh_link);
58876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Info", Section->sh_info);
58976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("AddressAlignment", Section->sh_addralign);
59076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("EntrySize", Section->sh_entsize);
59176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
59276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    if (opts::SectionRelocations) {
59376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      ListScope D(W, "Relocations");
594081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      printRelocations(Section);
59576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
59676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
59776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    if (opts::SectionSymbols) {
59876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      ListScope D(W, "Symbols");
599081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(),
600081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                       SymE = Obj->end_symbols();
601081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer           SymI != SymE; ++SymI) {
602081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer        if (Obj->getSection(&*SymI) == Section)
603081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer          printSymbol(SymI);
60476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      }
60576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
60676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
60737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (opts::SectionData && Section->sh_type != ELF::SHT_NOBITS) {
608081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(Section));
609081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      W.printBinaryBlock("SectionData",
610081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                         StringRef((const char *)Data.data(), Data.size()));
61176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
61276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
61376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
61476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
61576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
61676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printRelocations() {
61776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope D(W, "Relocations");
61876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
61976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  int SectionNumber = -1;
620081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(),
621081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                    SecE = Obj->end_sections();
622081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       SecI != SecE; ++SecI) {
62376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    ++SectionNumber;
624081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer
625081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    if (SecI->sh_type != ELF::SHT_REL && SecI->sh_type != ELF::SHT_RELA)
62676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      continue;
62776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
628081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    StringRef Name = errorOrDefault(Obj->getSectionName(&*SecI));
62976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
630081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
631081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.indent();
63276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
633081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    printRelocations(&*SecI);
634081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer
635081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.unindent();
636081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.startLine() << "}\n";
637081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  }
638081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer}
63976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
640081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class ELFT>
641081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencervoid ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) {
642081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  switch (Sec->sh_type) {
643081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  case ELF::SHT_REL:
644081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    for (typename ELFO::Elf_Rel_Iter RI = Obj->begin_rel(Sec),
645081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                     RE = Obj->end_rel(Sec);
646081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer         RI != RE; ++RI) {
647081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      typename ELFO::Elf_Rela Rela;
648081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      Rela.r_offset = RI->r_offset;
649081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      Rela.r_info = RI->r_info;
650081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      Rela.r_addend = 0;
651081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      printRelocation(Sec, Rela);
652081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    }
653081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    break;
654081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  case ELF::SHT_RELA:
655081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    for (typename ELFO::Elf_Rela_Iter RI = Obj->begin_rela(Sec),
656081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                      RE = Obj->end_rela(Sec);
657081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer         RI != RE; ++RI) {
658081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      printRelocation(Sec, *RI);
65976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
660081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    break;
66176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
66276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
66376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
664081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class ELFT>
665081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencervoid ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec,
666081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                      typename ELFO::Elf_Rela Rel) {
66776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  SmallString<32> RelocName;
668081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
66976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  StringRef SymbolName;
670081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  std::pair<const Elf_Shdr *, const Elf_Sym *> Sym =
671081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      Obj->getRelocationSymbol(Sec, &Rel);
672081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  if (Sym.first)
673081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    SymbolName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second));
67476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
6751c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck  if (opts::ExpandRelocs) {
6761c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck    DictScope Group(W, "Relocation");
677081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.printHex("Offset", Rel.r_offset);
678081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
67937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    W.printNumber("Symbol", SymbolName.size() > 0 ? SymbolName : "-",
68037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                  Rel.getSymbol(Obj->isMips64EL()));
681081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.printHex("Addend", Rel.r_addend);
6821c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck  } else {
6831c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck    raw_ostream& OS = W.startLine();
684081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    OS << W.hex(Rel.r_offset)
6851c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck       << " " << RelocName
6861c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck       << " " << (SymbolName.size() > 0 ? SymbolName : "-")
687081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       << " " << W.hex(Rel.r_addend)
6881c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck       << "\n";
6891c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck  }
69076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
69176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
69276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
69376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printSymbols() {
69476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope Group(W, "Symbols");
695081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(),
696081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                   SymE = Obj->end_symbols();
697081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       SymI != SymE; ++SymI) {
69876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    printSymbol(SymI);
69976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
70076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
70176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
70276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
70376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printDynamicSymbols() {
70476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope Group(W, "DynamicSymbols");
70576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
706081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(),
707081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                   SymE = Obj->end_dynamic_symbols();
708081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       SymI != SymE; ++SymI) {
709081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    printSymbol(SymI);
71076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
71176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
71276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
713081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class ELFT>
714081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencervoid ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) {
715c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  unsigned SectionIndex = 0;
71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef SectionName;
717c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex);
718c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::string FullSymbolName = getFullSymbolName(*Obj, Symbol);
71976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
72076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  DictScope D(W, "Symbol");
72176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printNumber("Name", FullSymbolName, Symbol->st_name);
72276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printHex   ("Value", Symbol->st_value);
72376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printNumber("Size", Symbol->st_size);
72476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printEnum  ("Binding", Symbol->getBinding(),
72576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                  makeArrayRef(ElfSymbolBindings));
72676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printEnum  ("Type", Symbol->getType(), makeArrayRef(ElfSymbolTypes));
72776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printNumber("Other", Symbol->st_other);
72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  W.printHex("Section", SectionName, SectionIndex);
72976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
73076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
73176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#define LLVM_READOBJ_TYPE_CASE(name) \
73276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_##name: return #name
73376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
73476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const char *getTypeString(uint64_t Type) {
73576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  switch (Type) {
73676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(BIND_NOW);
73776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(DEBUG);
73876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(FINI);
73976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(FINI_ARRAY);
74076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ);
74176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(FLAGS);
74276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(HASH);
74376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(INIT);
74476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(INIT_ARRAY);
74576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ);
74676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY);
74776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ);
74876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(JMPREL);
74976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(NEEDED);
75076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(NULL);
75176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PLTGOT);
75276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PLTREL);
75376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PLTRELSZ);
75476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(REL);
75576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELA);
75676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELENT);
75776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELSZ);
75876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELAENT);
75976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELASZ);
76076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RPATH);
76176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RUNPATH);
76276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(SONAME);
76376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(STRSZ);
76476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(STRTAB);
76576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(SYMBOLIC);
76676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(SYMENT);
76776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(SYMTAB);
76876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(TEXTREL);
769fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(VERNEED);
770fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(VERNEEDNUM);
771fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(VERSYM);
772dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_TYPE_CASE(RELCOUNT);
773dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_TYPE_CASE(GNU_HASH);
774fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION);
775fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS);
776fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS);
777fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO);
778fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO);
779fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO);
780fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM);
78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LLVM_READOBJ_TYPE_CASE(MIPS_RLD_MAP);
78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LLVM_READOBJ_TYPE_CASE(MIPS_PLTGOT);
78376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  default: return "unknown";
78476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
78576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
78676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
78776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#undef LLVM_READOBJ_TYPE_CASE
78876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \
790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  { #enum, prefix##_##enum }
791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
807dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
812dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
815dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
816dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
817dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
818dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#undef LLVM_READOBJ_DT_FLAG_ENT
820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestemplate <typename T, typename TFlag>
822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
823dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  typedef EnumEntry<TFlag> FlagEntry;
824dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  typedef SmallVector<FlagEntry, 10> FlagVector;
825dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  FlagVector SetFlags;
826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const auto &Flag : Flags) {
828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Flag.Value == 0)
829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      continue;
830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if ((Value & Flag.Value) == Flag.Value)
832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SetFlags.push_back(Flag);
833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const auto &Flag : SetFlags) {
836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << Flag.Name << " ";
837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
839dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
840081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class ELFT>
841081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencerstatic void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value,
842081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                       bool Is64, raw_ostream &OS) {
84376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  switch (Type) {
84476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PLTREL:
84576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    if (Value == DT_REL) {
84676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      OS << "REL";
84776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      break;
84876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    } else if (Value == DT_RELA) {
84976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      OS << "RELA";
85076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      break;
85176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
85276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // Fallthrough.
85376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PLTGOT:
85476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_HASH:
85576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_STRTAB:
85676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_SYMTAB:
85776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELA:
85876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_INIT:
85976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_FINI:
86076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_REL:
86176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_JMPREL:
86276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_INIT_ARRAY:
86376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_FINI_ARRAY:
86476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PREINIT_ARRAY:
86576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_DEBUG:
866fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_VERNEED:
867fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_VERSYM:
868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case DT_GNU_HASH:
86976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_NULL:
870fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_BASE_ADDRESS:
871fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_GOTSYM:
87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case DT_MIPS_RLD_MAP:
87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case DT_MIPS_PLTGOT:
87476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    OS << format("0x%" PRIX64, Value);
87576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    break;
876dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case DT_RELCOUNT:
877fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_VERNEEDNUM:
878fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_RLD_VERSION:
879fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_LOCAL_GOTNO:
880fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_SYMTABNO:
881fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_UNREFEXTNO:
882fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan    OS << Value;
883fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan    break;
88476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PLTRELSZ:
88576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELASZ:
88676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELAENT:
88776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_STRSZ:
88876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_SYMENT:
88976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELSZ:
89076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELENT:
89176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_INIT_ARRAYSZ:
89276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_FINI_ARRAYSZ:
89376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PREINIT_ARRAYSZ:
89476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    OS << Value << " (bytes)";
89576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    break;
89676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_NEEDED:
897081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    OS << "SharedLibrary (" << O->getDynamicString(Value) << ")";
89876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    break;
89976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_SONAME:
900081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    OS << "LibrarySoname (" << O->getDynamicString(Value) << ")";
90176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    break;
9026217187ff202cb919257abc32782faa35c29f5d9Joerg Sonnenberger  case DT_RPATH:
9036217187ff202cb919257abc32782faa35c29f5d9Joerg Sonnenberger  case DT_RUNPATH:
9046217187ff202cb919257abc32782faa35c29f5d9Joerg Sonnenberger    OS << O->getDynamicString(Value);
9056217187ff202cb919257abc32782faa35c29f5d9Joerg Sonnenberger    break;
906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case DT_MIPS_FLAGS:
907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS);
908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case DT_FLAGS:
910dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
91276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
91376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
91476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
91576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
91676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printUnwindInfo() {
91776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.startLine() << "UnwindInfo not implemented.\n";
91876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
91976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
92036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace {
92136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <>
92236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ELFDumper<ELFType<support::little, 2, false> >::printUnwindInfo() {
92336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const unsigned Machine = Obj->getHeader()->e_machine;
92436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Machine == EM_ARM) {
92536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ARM::EHABI::PrinterContext<ELFType<support::little, 2, false> > Ctx(W, Obj);
92636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Ctx.PrintUnwindInformation();
92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  W.startLine() << "UnwindInfo not implemented.\n";
92936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
93036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
93136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
93276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
93376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printDynamicTable() {
934c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  auto DynTable = Obj->dynamic_table(true);
93576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
936c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  ptrdiff_t Total = std::distance(DynTable.begin(), DynTable.end());
937c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (Total == 0)
93876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    return;
93976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
94076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  raw_ostream &OS = W.getOStream();
94176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.startLine() << "DynamicSection [ (" << Total << " entries)\n";
94276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
943081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  bool Is64 = ELFT::Is64Bits;
94476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
94576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.startLine()
94676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher     << "  Tag" << (Is64 ? "                " : "        ") << "Type"
94776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher     << "                 " << "Name/Value\n";
948c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  for (const auto &Entry : DynTable) {
94976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.startLine()
95076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher       << "  "
951c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines       << format(Is64 ? "0x%016" PRIX64 : "0x%08" PRIX64, Entry.getTag())
952c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines       << " " << format("%-21s", getTypeString(Entry.getTag()));
953c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    printValue(Obj, Entry.getTag(), Entry.getVal(), Is64, OS);
95476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    OS << "\n";
95576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
95676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
95776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.startLine() << "]\n";
95876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
95976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
96076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
96176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printNeededLibraries() {
96276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope D(W, "NeededLibraries");
96376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
964081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  typedef std::vector<StringRef> LibsTy;
96576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LibsTy Libs;
96676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
967c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  for (const auto &Entry : Obj->dynamic_table())
968c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (Entry.d_tag == ELF::DT_NEEDED)
969c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      Libs.push_back(Obj->getDynamicString(Entry.d_un.d_val));
97076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
971081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  std::stable_sort(Libs.begin(), Libs.end());
97276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
973081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); I != E; ++I) {
974081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    outs() << "  " << *I << "\n";
97576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
97676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
977cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck
978cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Riecktemplate<class ELFT>
979cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieckvoid ELFDumper<ELFT>::printProgramHeaders() {
980cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  ListScope L(W, "ProgramHeaders");
981cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck
982cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(),
983cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck                                    PE = Obj->end_program_headers();
984cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck                                    PI != PE; ++PI) {
985cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    DictScope P(W, "ProgramHeader");
986c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    W.printHex   ("Type",
987c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan                  getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type),
988c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan                  PI->p_type);
989cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printHex   ("Offset", PI->p_offset);
990cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printHex   ("VirtualAddress", PI->p_vaddr);
991cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printHex   ("PhysicalAddress", PI->p_paddr);
992cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printNumber("FileSize", PI->p_filesz);
993cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printNumber("MemSize", PI->p_memsz);
994cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags));
995cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printNumber("Alignment", PI->p_align);
996cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  }
997cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck}
99836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
99936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT>
100036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ELFDumper<ELFT>::printAttributes() {
100136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  W.startLine() << "Attributes not implemented.\n";
100236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
100336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
100436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace {
100536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <>
100636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ELFDumper<ELFType<support::little, 2, false> >::printAttributes() {
100736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Obj->getHeader()->e_machine != EM_ARM) {
100836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    W.startLine() << "Attributes not implemented.\n";
100936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
101036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
101236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DictScope BA(W, "BuildAttributes");
101336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (ELFO::Elf_Shdr_Iter SI = Obj->begin_sections(), SE = Obj->end_sections();
101436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       SI != SE; ++SI) {
101536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SI->sh_type != ELF::SHT_ARM_ATTRIBUTES)
101636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
101736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
101836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ErrorOr<ArrayRef<uint8_t> > Contents = Obj->getSectionContents(&(*SI));
101936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!Contents)
102036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
102136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
102236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if ((*Contents)[0] != ARMBuildAttrs::Format_Version) {
102336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      errs() << "unrecognised FormatVersion: 0x" << utohexstr((*Contents)[0])
102436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             << '\n';
102536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
102636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
102736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
102836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    W.printHex("FormatVersion", (*Contents)[0]);
102936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Contents->size() == 1)
103036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
103136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
103236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ARMAttributeParser(W).Parse(*Contents);
103336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
103436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
103636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1037c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesnamespace {
1038c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <class ELFT> class MipsGOTParser {
1039c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinespublic:
1040c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  typedef object::ELFFile<ELFT> ObjectFile;
1041c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  typedef typename ObjectFile::Elf_Shdr Elf_Shdr;
1042c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1043c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MipsGOTParser(const ObjectFile *Obj, StreamWriter &W) : Obj(Obj), W(W) {}
1044c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1045c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void parseGOT(const Elf_Shdr &GOTShdr);
1046c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1047c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesprivate:
1048c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  typedef typename ObjectFile::Elf_Sym_Iter Elf_Sym_Iter;
1049c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  typedef typename ObjectFile::Elf_Addr GOTEntry;
1050c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  typedef typename ObjectFile::template ELFEntityIterator<const GOTEntry>
1051c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  GOTIter;
1052c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1053c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  const ObjectFile *Obj;
1054c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  StreamWriter &W;
1055c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1056c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::size_t getGOTTotal(ArrayRef<uint8_t> GOT) const;
1057c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  GOTIter makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum);
1058c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1059c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym);
1060c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void printGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It);
1061c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It,
1062c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                           Elf_Sym_Iter Sym);
1063c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines};
1064c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
1065c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1066c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <class ELFT>
1067c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid MipsGOTParser<ELFT>::parseGOT(const Elf_Shdr &GOTShdr) {
1068c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // See "Global Offset Table" in Chapter 5 in the following document
1069c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // for detailed GOT description.
1070c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1071c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1072c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  ErrorOr<ArrayRef<uint8_t>> GOT = Obj->getSectionContents(&GOTShdr);
1073c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!GOT) {
1074c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    W.startLine() << "The .got section is empty.\n";
1075c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
1076c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1077c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1078c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint64_t DtLocalGotNum;
1079c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint64_t DtGotSym;
1080c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!getGOTTags(DtLocalGotNum, DtGotSym))
1081c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
1082c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1083c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (DtLocalGotNum > getGOTTotal(*GOT)) {
1084c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    W.startLine() << "MIPS_LOCAL_GOTNO exceeds a number of GOT entries.\n";
1085c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
1086c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1087c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1088c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Elf_Sym_Iter DynSymBegin = Obj->begin_dynamic_symbols();
1089c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Elf_Sym_Iter DynSymEnd = Obj->end_dynamic_symbols();
1090c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
1091c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1092c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (DtGotSym > DynSymTotal) {
1093c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    W.startLine() << "MIPS_GOTSYM exceeds a number of dynamic symbols.\n";
1094c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
1095c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1096c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1097c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::size_t GlobalGotNum = DynSymTotal - DtGotSym;
1098c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1099c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT)) {
1100c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    W.startLine() << "Number of global GOT entries exceeds the size of GOT.\n";
1101c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
1102c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1103c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1104c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  GOTIter GotBegin = makeGOTIter(*GOT, 0);
1105c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  GOTIter GotLocalEnd = makeGOTIter(*GOT, DtLocalGotNum);
1106c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  GOTIter It = GotBegin;
1107c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1108c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  DictScope GS(W, "Primary GOT");
1109c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1110c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  W.printHex("Canonical gp value", GOTShdr.sh_addr + 0x7ff0);
1111c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  {
1112c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    ListScope RS(W, "Reserved entries");
1113c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1114c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    {
1115c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      DictScope D(W, "Entry");
1116c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      printGotEntry(GOTShdr.sh_addr, GotBegin, It++);
1117c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      W.printString("Purpose", StringRef("Lazy resolver"));
1118c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
1119c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1120c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (It != GotLocalEnd && (*It >> (sizeof(GOTEntry) * 8 - 1)) != 0) {
1121c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      DictScope D(W, "Entry");
1122c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      printGotEntry(GOTShdr.sh_addr, GotBegin, It++);
1123c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
1124c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
1125c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1126c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  {
1127c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    ListScope LS(W, "Local entries");
1128c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    for (; It != GotLocalEnd; ++It) {
1129c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      DictScope D(W, "Entry");
1130c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      printGotEntry(GOTShdr.sh_addr, GotBegin, It);
1131c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
1132c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1133c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  {
1134c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    ListScope GS(W, "Global entries");
1135c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1136c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    GOTIter GotGlobalEnd = makeGOTIter(*GOT, DtLocalGotNum + GlobalGotNum);
1137c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Elf_Sym_Iter GotDynSym = DynSymBegin + DtGotSym;
1138c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    for (; It != GotGlobalEnd; ++It) {
1139c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      DictScope D(W, "Entry");
1140c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      printGlobalGotEntry(GOTShdr.sh_addr, GotBegin, It, GotDynSym++);
1141c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
1142c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1143c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1144c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::size_t SpecGotNum = getGOTTotal(*GOT) - DtLocalGotNum - GlobalGotNum;
1145c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  W.printNumber("Number of TLS and multi-GOT entries", uint64_t(SpecGotNum));
1146c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
1147c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1148c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <class ELFT>
1149c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstd::size_t MipsGOTParser<ELFT>::getGOTTotal(ArrayRef<uint8_t> GOT) const {
1150c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return GOT.size() / sizeof(GOTEntry);
1151c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
1152c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1153c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <class ELFT>
1154c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestypename MipsGOTParser<ELFT>::GOTIter
1155c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesMipsGOTParser<ELFT>::makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum) {
1156c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  const char *Data = reinterpret_cast<const char *>(GOT.data());
1157c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return GOTIter(sizeof(GOTEntry), Data + EntryNum * sizeof(GOTEntry));
1158c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
1159c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1160c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <class ELFT>
1161c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsGOTParser<ELFT>::getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym) {
1162c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool FoundLocalGotNum = false;
1163c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool FoundGotSym = false;
1164c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  for (const auto &Entry : Obj->dynamic_table()) {
1165c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    switch (Entry.getTag()) {
1166c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    case ELF::DT_MIPS_LOCAL_GOTNO:
1167c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      LocalGotNum = Entry.getVal();
1168c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      FoundLocalGotNum = true;
1169c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      break;
1170c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    case ELF::DT_MIPS_GOTSYM:
1171c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      GotSym = Entry.getVal();
1172c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      FoundGotSym = true;
1173c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      break;
1174c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
1175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1176c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1177c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!FoundLocalGotNum) {
1178c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    W.startLine() << "Cannot find MIPS_LOCAL_GOTNO dynamic table tag.\n";
1179c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
1180c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1181c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1182c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!FoundGotSym) {
1183c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    W.startLine() << "Cannot find MIPS_GOTSYM dynamic table tag.\n";
1184c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
1185c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1186c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1187c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return true;
1188c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
1189c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1190c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <class ELFT>
1191c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid MipsGOTParser<ELFT>::printGotEntry(uint64_t GotAddr, GOTIter BeginIt,
1192c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                        GOTIter It) {
1193c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry);
1194c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  W.printHex("Address", GotAddr + Offset);
1195c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  W.printNumber("Access", Offset - 0x7ff0);
1196c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  W.printHex("Initial", *It);
1197c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
1198c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1199c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <class ELFT>
1200c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt,
1201c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                              GOTIter It, Elf_Sym_Iter Sym) {
1202c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  printGotEntry(GotAddr, BeginIt, It);
1203c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1204c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  W.printHex("Value", Sym->st_value);
1205c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes));
1206c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1207c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  unsigned SectionIndex = 0;
1208c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  StringRef SectionName;
1209c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex);
1210c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  W.printHex("Section", SectionName, SectionIndex);
1211c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1212c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::string FullSymbolName = getFullSymbolName(*Obj, Sym);
1213c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  W.printNumber("Name", FullSymbolName, Sym->st_name);
1214c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
1215c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1216c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinestemplate <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
1217c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (Obj->getHeader()->e_machine != EM_MIPS) {
1218c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    W.startLine() << "MIPS PLT GOT is available for MIPS targets only.\n";
1219c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
1220c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1221c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1222c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  llvm::Optional<uint64_t> DtPltGot;
1223c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  for (const auto &Entry : Obj->dynamic_table()) {
1224c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (Entry.getTag() == ELF::DT_PLTGOT) {
1225c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      DtPltGot = Entry.getVal();
1226c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      break;
1227c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
1228c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1229c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1230c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!DtPltGot) {
1231c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    W.startLine() << "Cannot find PLTGOT dynamic table tag.\n";
1232c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
1233c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1234c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1235c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  const Elf_Shdr *GotShdr = findSectionByAddress(Obj, *DtPltGot);
1236c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!GotShdr) {
1237c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    W.startLine() << "There is no .got section in the file.\n";
1238c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return;
1239c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1240c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1241c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MipsGOTParser<ELFT>(Obj, W).parseGOT(*GotShdr);
1242c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
1243