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"
21cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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;
58cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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>
86cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic std::error_code createELFDumper(const ELFFile<ELFT> *Obj,
87cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                       StreamWriter &Writer,
88cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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
93cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code createELFDumper(const object::ObjectFile *Obj,
94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                StreamWriter &Writer,
95cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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
117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <typename ELFO>
118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic std::string getFullSymbolName(const ELFO &Obj,
119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                     typename ELFO::Elf_Sym_Iter Symbol) {
120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  StringRef SymbolName = errorOrDefault(Obj.getSymbolName(Symbol));
121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!Symbol.isDynamic())
122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return SymbolName;
123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::string FullSymbolName(SymbolName);
125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool IsDefault;
127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ErrorOr<StringRef> Version =
128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Obj.getSymbolVersion(nullptr, &*Symbol, IsDefault);
129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Version) {
130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    FullSymbolName += (IsDefault ? "@@" : "@");
131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    FullSymbolName += *Version;
132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else
133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    error(Version.getError());
134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return FullSymbolName;
135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <typename ELFO>
138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic void
139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesgetSectionNameIndex(const ELFO &Obj, typename ELFO::Elf_Sym_Iter Symbol,
140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                    StringRef &SectionName, unsigned &SectionIndex) {
141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  SectionIndex = Symbol->st_shndx;
142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (SectionIndex == SHN_UNDEF) {
143cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SectionName = "Undefined";
144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else if (SectionIndex >= SHN_LOPROC && SectionIndex <= SHN_HIPROC) {
145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SectionName = "Processor Specific";
146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else if (SectionIndex >= SHN_LOOS && SectionIndex <= SHN_HIOS) {
147cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SectionName = "Operating System Specific";
148cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else if (SectionIndex > SHN_HIOS && SectionIndex < SHN_ABS) {
149cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SectionName = "Reserved";
150cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else if (SectionIndex == SHN_ABS) {
151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SectionName = "Absolute";
152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else if (SectionIndex == SHN_COMMON) {
153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SectionName = "Common";
154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else {
155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (SectionIndex == SHN_XINDEX)
156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      SectionIndex = Obj.getSymbolTableIndex(&*Symbol);
157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    assert(SectionIndex != SHN_XINDEX &&
158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines           "getSymbolTableIndex should handle this");
159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const typename ELFO::Elf_Shdr *Sec = Obj.getSection(SectionIndex);
160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SectionName = errorOrDefault(Obj.getSectionName(Sec));
161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
162cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
163cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <class ELFT>
165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic const typename ELFFile<ELFT>::Elf_Shdr *
166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesfindSectionByAddress(const ELFFile<ELFT> *Obj, uint64_t Addr) {
167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  for (const auto &Shdr : Obj->sections())
168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Shdr.sh_addr == Addr)
169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return &Shdr;
170cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return nullptr;
171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
172cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen 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);
41076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
41176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
41276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
41376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  switch (Type) {
41476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL              );
41576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS          );
41676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB            );
41776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB            );
41876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA              );
41976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH              );
42076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC           );
42176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE              );
42276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS            );
42376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL               );
42476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB             );
42576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM            );
42676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY        );
42776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY        );
42876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY     );
42976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP             );
43076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX      );
43176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES    );
43276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH          );
43376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef        );
43476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed       );
43576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym        );
43676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  default: return "";
43776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
43876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
43976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
44076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const EnumEntry<unsigned> ElfSectionFlags[] = {
44176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE           ),
44276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC           ),
443766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer  LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXCLUDE         ),
44476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR       ),
44576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE           ),
44676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS         ),
44776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_INFO_LINK       ),
44876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_LINK_ORDER      ),
44976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_OS_NONCONFORMING),
45076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_GROUP           ),
45176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS             ),
45276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION),
45376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION),
45476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP    )
45576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
45676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
457c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyanstatic const char *getElfSegmentType(unsigned Arch, unsigned Type) {
458c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  // Check potentially overlapped processor-specific
459c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  // program header type.
460c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  switch (Arch) {
461c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  case ELF::EM_ARM:
462c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    switch (Type) {
463c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX);
464c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    }
465c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  case ELF::EM_MIPS:
466c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  case ELF::EM_MIPS_RS3_LE:
467c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    switch (Type) {
468c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
469c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
470c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
471c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    }
472c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  }
473c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan
474c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  switch (Type) {
475c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL   );
476c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD   );
477c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
478c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP );
479c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE   );
480c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB  );
481c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR   );
482c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS    );
483c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan
484c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
485c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
486c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan
487c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
488c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
489c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  default: return "";
490c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan  }
491c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan}
492cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck
493cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieckstatic const EnumEntry<unsigned> ElfSegmentFlags[] = {
494cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
495cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
496cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
497cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck};
498cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck
499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NOREORDER),
501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_PIC),
502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_CPIC),
503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI2),
504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_32BITMODE),
505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NAN2008),
506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O32),
507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MICROMIPS),
508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_M16),
509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_1),
510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_2),
511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_3),
512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_4),
513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_5),
514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32),
515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64),
516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R2),
517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R2),
518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R6),
519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6)
520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
52276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
52376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printFileHeaders() {
524081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  const typename ELFO::Elf_Ehdr *Header = Obj->getHeader();
52576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
52676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  {
52776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    DictScope D(W, "ElfHeader");
52876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    {
52976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      DictScope D(W, "Ident");
53076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printBinary("Magic", makeArrayRef(Header->e_ident).slice(ELF::EI_MAG0,
53176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                                                                 4));
53276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printEnum  ("Class", Header->e_ident[ELF::EI_CLASS],
53376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                      makeArrayRef(ElfClass));
53476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printEnum  ("DataEncoding", Header->e_ident[ELF::EI_DATA],
53576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                      makeArrayRef(ElfDataEncoding));
53676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]);
53776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printEnum  ("OS/ABI", Header->e_ident[ELF::EI_OSABI],
53876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                      makeArrayRef(ElfOSABI));
53976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]);
54076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD));
54176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
54276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
54376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printEnum  ("Type", Header->e_type, makeArrayRef(ElfObjectFileType));
54476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printEnum  ("Machine", Header->e_machine, makeArrayRef(ElfMachineType));
54576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Version", Header->e_version);
54676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("Entry", Header->e_entry);
54776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("ProgramHeaderOffset", Header->e_phoff);
54876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("SectionHeaderOffset", Header->e_shoff);
549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Header->e_machine == EM_MIPS)
550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      W.printFlags("Flags", Header->e_flags, makeArrayRef(ElfHeaderMipsFlags),
551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                   unsigned(ELF::EF_MIPS_ARCH));
552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      W.printFlags("Flags", Header->e_flags);
55476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("HeaderSize", Header->e_ehsize);
55576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize);
55676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("ProgramHeaderCount", Header->e_phnum);
55776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("SectionHeaderEntrySize", Header->e_shentsize);
55876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("SectionHeaderCount", Header->e_shnum);
55976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("StringTableSectionIndex", Header->e_shstrndx);
56076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
56176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
56276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
56376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
56476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printSections() {
56576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope SectionsD(W, "Sections");
56676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
56776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  int SectionIndex = -1;
568081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(),
569081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                    SecE = Obj->end_sections();
570081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       SecI != SecE; ++SecI) {
57176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    ++SectionIndex;
57276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
573081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    const Elf_Shdr *Section = &*SecI;
574081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    StringRef Name = errorOrDefault(Obj->getSectionName(Section));
57576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
57676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    DictScope SectionD(W, "Section");
57776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Index", SectionIndex);
57876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Name", Name, Section->sh_name);
579081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.printHex("Type",
580081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer               getElfSectionType(Obj->getHeader()->e_machine, Section->sh_type),
581081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer               Section->sh_type);
58276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags));
58376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("Address", Section->sh_addr);
58476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printHex   ("Offset", Section->sh_offset);
58576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Size", Section->sh_size);
58676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Link", Section->sh_link);
58776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("Info", Section->sh_info);
58876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("AddressAlignment", Section->sh_addralign);
58976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.printNumber("EntrySize", Section->sh_entsize);
59076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
59176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    if (opts::SectionRelocations) {
59276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      ListScope D(W, "Relocations");
593081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      printRelocations(Section);
59476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
59576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
59676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    if (opts::SectionSymbols) {
59776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      ListScope D(W, "Symbols");
598081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(),
599081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                       SymE = Obj->end_symbols();
600081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer           SymI != SymE; ++SymI) {
601081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer        if (Obj->getSection(&*SymI) == Section)
602081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer          printSymbol(SymI);
60376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      }
60476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
60576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
60676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    if (opts::SectionData) {
607081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(Section));
608081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      W.printBinaryBlock("SectionData",
609081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                         StringRef((const char *)Data.data(), Data.size()));
61076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
61176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
61276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
61376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
61476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
61576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printRelocations() {
61676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope D(W, "Relocations");
61776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
61876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  int SectionNumber = -1;
619081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(),
620081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                    SecE = Obj->end_sections();
621081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       SecI != SecE; ++SecI) {
62276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    ++SectionNumber;
623081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer
624081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    if (SecI->sh_type != ELF::SHT_REL && SecI->sh_type != ELF::SHT_RELA)
62576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      continue;
62676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
627081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    StringRef Name = errorOrDefault(Obj->getSectionName(&*SecI));
62876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
629081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
630081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.indent();
63176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
632081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    printRelocations(&*SecI);
633081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer
634081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.unindent();
635081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.startLine() << "}\n";
636081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  }
637081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer}
63876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
639081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class ELFT>
640081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencervoid ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) {
641081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  switch (Sec->sh_type) {
642081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  case ELF::SHT_REL:
643081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    for (typename ELFO::Elf_Rel_Iter RI = Obj->begin_rel(Sec),
644081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                     RE = Obj->end_rel(Sec);
645081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer         RI != RE; ++RI) {
646081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      typename ELFO::Elf_Rela Rela;
647081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      Rela.r_offset = RI->r_offset;
648081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      Rela.r_info = RI->r_info;
649081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      Rela.r_addend = 0;
650081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      printRelocation(Sec, Rela);
651081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    }
652081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    break;
653081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  case ELF::SHT_RELA:
654081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    for (typename ELFO::Elf_Rela_Iter RI = Obj->begin_rela(Sec),
655081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                      RE = Obj->end_rela(Sec);
656081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer         RI != RE; ++RI) {
657081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      printRelocation(Sec, *RI);
65876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
659081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    break;
66076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
66176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
66276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
663081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class ELFT>
664081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencervoid ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec,
665081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                      typename ELFO::Elf_Rela Rel) {
66676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  SmallString<32> RelocName;
667081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
66876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  StringRef SymbolName;
669081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  std::pair<const Elf_Shdr *, const Elf_Sym *> Sym =
670081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer      Obj->getRelocationSymbol(Sec, &Rel);
671081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  if (Sym.first)
672081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    SymbolName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second));
67376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
6741c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck  if (opts::ExpandRelocs) {
6751c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck    DictScope Group(W, "Relocation");
676081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.printHex("Offset", Rel.r_offset);
677081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
6781c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck    W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
679081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    W.printHex("Addend", Rel.r_addend);
6801c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck  } else {
6811c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck    raw_ostream& OS = W.startLine();
682081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    OS << W.hex(Rel.r_offset)
6831c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck       << " " << RelocName
6841c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck       << " " << (SymbolName.size() > 0 ? SymbolName : "-")
685081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       << " " << W.hex(Rel.r_addend)
6861c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck       << "\n";
6871c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fdNico Rieck  }
68876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
68976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
69076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
69176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printSymbols() {
69276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope Group(W, "Symbols");
693081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(),
694081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                   SymE = Obj->end_symbols();
695081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       SymI != SymE; ++SymI) {
69676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    printSymbol(SymI);
69776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
69876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
69976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
70076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
70176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printDynamicSymbols() {
70276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope Group(W, "DynamicSymbols");
70376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
704081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(),
705081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                                   SymE = Obj->end_dynamic_symbols();
706081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer       SymI != SymE; ++SymI) {
707081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    printSymbol(SymI);
70876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
70976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
71076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
711081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class ELFT>
712081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencervoid ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) {
713cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned SectionIndex = 0;
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef SectionName;
715cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex);
716cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::string FullSymbolName = getFullSymbolName(*Obj, Symbol);
71776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
71876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  DictScope D(W, "Symbol");
71976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printNumber("Name", FullSymbolName, Symbol->st_name);
72076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printHex   ("Value", Symbol->st_value);
72176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printNumber("Size", Symbol->st_size);
72276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printEnum  ("Binding", Symbol->getBinding(),
72376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                  makeArrayRef(ElfSymbolBindings));
72476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printEnum  ("Type", Symbol->getType(), makeArrayRef(ElfSymbolTypes));
72576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.printNumber("Other", Symbol->st_other);
72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  W.printHex("Section", SectionName, SectionIndex);
72776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
72876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
72976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#define LLVM_READOBJ_TYPE_CASE(name) \
73076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_##name: return #name
73176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
73276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstatic const char *getTypeString(uint64_t Type) {
73376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  switch (Type) {
73476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(BIND_NOW);
73576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(DEBUG);
73676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(FINI);
73776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(FINI_ARRAY);
73876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ);
73976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(FLAGS);
74076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(HASH);
74176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(INIT);
74276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(INIT_ARRAY);
74376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ);
74476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY);
74576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ);
74676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(JMPREL);
74776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(NEEDED);
74876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(NULL);
74976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PLTGOT);
75076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PLTREL);
75176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(PLTRELSZ);
75276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(REL);
75376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELA);
75476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELENT);
75576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELSZ);
75676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELAENT);
75776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RELASZ);
75876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RPATH);
75976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(RUNPATH);
76076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(SONAME);
76176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(STRSZ);
76276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(STRTAB);
76376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(SYMBOLIC);
76476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(SYMENT);
76576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(SYMTAB);
76676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LLVM_READOBJ_TYPE_CASE(TEXTREL);
767fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(VERNEED);
768fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(VERNEEDNUM);
769fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(VERSYM);
770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_TYPE_CASE(RELCOUNT);
771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_TYPE_CASE(GNU_HASH);
772fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION);
773fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS);
774fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS);
775fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO);
776fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO);
777fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO);
778fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM);
77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LLVM_READOBJ_TYPE_CASE(MIPS_RLD_MAP);
78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LLVM_READOBJ_TYPE_CASE(MIPS_PLTGOT);
78176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  default: return "unknown";
78276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
78376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
78476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
78576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#undef LLVM_READOBJ_TYPE_CASE
78676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \
788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  { #enum, prefix##_##enum }
789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
791dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
792dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
806dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
807dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
808dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
809dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
810dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
812dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
813dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
815dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
816dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
817dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#undef LLVM_READOBJ_DT_FLAG_ENT
818dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
819dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestemplate <typename T, typename TFlag>
820dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
821dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  typedef EnumEntry<TFlag> FlagEntry;
822dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  typedef SmallVector<FlagEntry, 10> FlagVector;
823dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  FlagVector SetFlags;
824dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
825dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const auto &Flag : Flags) {
826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Flag.Value == 0)
827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      continue;
828dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
829dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if ((Value & Flag.Value) == Flag.Value)
830dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SetFlags.push_back(Flag);
831dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
832dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
833dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const auto &Flag : SetFlags) {
834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    OS << Flag.Name << " ";
835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
838081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class ELFT>
839081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencerstatic void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value,
840081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer                       bool Is64, raw_ostream &OS) {
84176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  switch (Type) {
84276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PLTREL:
84376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    if (Value == DT_REL) {
84476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      OS << "REL";
84576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      break;
84676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    } else if (Value == DT_RELA) {
84776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      OS << "RELA";
84876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      break;
84976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
85076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // Fallthrough.
85176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PLTGOT:
85276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_HASH:
85376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_STRTAB:
85476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_SYMTAB:
85576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELA:
85676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_INIT:
85776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_FINI:
85876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_REL:
85976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_JMPREL:
86076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_INIT_ARRAY:
86176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_FINI_ARRAY:
86276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PREINIT_ARRAY:
86376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_DEBUG:
864fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_VERNEED:
865fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_VERSYM:
866dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case DT_GNU_HASH:
86776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_NULL:
868fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_BASE_ADDRESS:
869fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_GOTSYM:
87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case DT_MIPS_RLD_MAP:
87136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case DT_MIPS_PLTGOT:
87276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    OS << format("0x%" PRIX64, Value);
87376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    break;
874dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case DT_RELCOUNT:
875fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_VERNEEDNUM:
876fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_RLD_VERSION:
877fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_LOCAL_GOTNO:
878fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_SYMTABNO:
879fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan  case DT_MIPS_UNREFEXTNO:
880fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan    OS << Value;
881fe9ce427d076627beed834d5c322e61323dfd1fcSimon Atanasyan    break;
88276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PLTRELSZ:
88376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELASZ:
88476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELAENT:
88576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_STRSZ:
88676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_SYMENT:
88776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELSZ:
88876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_RELENT:
88976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_INIT_ARRAYSZ:
89076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_FINI_ARRAYSZ:
89176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_PREINIT_ARRAYSZ:
89276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    OS << Value << " (bytes)";
89376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    break;
89476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_NEEDED:
895081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    OS << "SharedLibrary (" << O->getDynamicString(Value) << ")";
89676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    break;
89776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  case DT_SONAME:
898081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    OS << "LibrarySoname (" << O->getDynamicString(Value) << ")";
89976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    break;
9006217187ff202cb919257abc32782faa35c29f5d9Joerg Sonnenberger  case DT_RPATH:
9016217187ff202cb919257abc32782faa35c29f5d9Joerg Sonnenberger  case DT_RUNPATH:
9026217187ff202cb919257abc32782faa35c29f5d9Joerg Sonnenberger    OS << O->getDynamicString(Value);
9036217187ff202cb919257abc32782faa35c29f5d9Joerg Sonnenberger    break;
904dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case DT_MIPS_FLAGS:
905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS);
906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case DT_FLAGS:
908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
91076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
91176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
91276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
91376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
91476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printUnwindInfo() {
91576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.startLine() << "UnwindInfo not implemented.\n";
91676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
91776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
91836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace {
91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <>
92036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ELFDumper<ELFType<support::little, 2, false> >::printUnwindInfo() {
92136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const unsigned Machine = Obj->getHeader()->e_machine;
92236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Machine == EM_ARM) {
92336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ARM::EHABI::PrinterContext<ELFType<support::little, 2, false> > Ctx(W, Obj);
92436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Ctx.PrintUnwindInformation();
92536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
92636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  W.startLine() << "UnwindInfo not implemented.\n";
92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
92936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
93076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
93176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printDynamicTable() {
932cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  auto DynTable = Obj->dynamic_table(true);
93376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
934cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ptrdiff_t Total = std::distance(DynTable.begin(), DynTable.end());
935cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Total == 0)
93676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    return;
93776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
93876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  raw_ostream &OS = W.getOStream();
93976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.startLine() << "DynamicSection [ (" << Total << " entries)\n";
94076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
941081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  bool Is64 = ELFT::Is64Bits;
94276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
94376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.startLine()
94476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher     << "  Tag" << (Is64 ? "                " : "        ") << "Type"
94576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher     << "                 " << "Name/Value\n";
946cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  for (const auto &Entry : DynTable) {
94776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.startLine()
94876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher       << "  "
949cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines       << format(Is64 ? "0x%016" PRIX64 : "0x%08" PRIX64, Entry.getTag())
950cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines       << " " << format("%-21s", getTypeString(Entry.getTag()));
951cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    printValue(Obj, Entry.getTag(), Entry.getVal(), Is64, OS);
95276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    OS << "\n";
95376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
95476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
95576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  W.startLine() << "]\n";
95676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
95776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
95876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<class ELFT>
95976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophervoid ELFDumper<ELFT>::printNeededLibraries() {
96076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope D(W, "NeededLibraries");
96176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
962081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  typedef std::vector<StringRef> LibsTy;
96376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  LibsTy Libs;
96476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
965cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  for (const auto &Entry : Obj->dynamic_table())
966cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Entry.d_tag == ELF::DT_NEEDED)
967cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Libs.push_back(Obj->getDynamicString(Entry.d_un.d_val));
96876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
969081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  std::stable_sort(Libs.begin(), Libs.end());
97076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
971081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); I != E; ++I) {
972081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    outs() << "  " << *I << "\n";
97376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
97476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher}
975cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck
976cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Riecktemplate<class ELFT>
977cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieckvoid ELFDumper<ELFT>::printProgramHeaders() {
978cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  ListScope L(W, "ProgramHeaders");
979cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck
980cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(),
981cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck                                    PE = Obj->end_program_headers();
982cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck                                    PI != PE; ++PI) {
983cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    DictScope P(W, "ProgramHeader");
984c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan    W.printHex   ("Type",
985c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan                  getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type),
986c84c742eddc0c57c34271471f332c9857d79e672Simon Atanasyan                  PI->p_type);
987cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printHex   ("Offset", PI->p_offset);
988cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printHex   ("VirtualAddress", PI->p_vaddr);
989cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printHex   ("PhysicalAddress", PI->p_paddr);
990cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printNumber("FileSize", PI->p_filesz);
991cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printNumber("MemSize", PI->p_memsz);
992cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags));
993cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck    W.printNumber("Alignment", PI->p_align);
994cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck  }
995cf3b55ab18b6d0f5b658e746b57ec3cf193d5688Nico Rieck}
99636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
99736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT>
99836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ELFDumper<ELFT>::printAttributes() {
99936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  W.startLine() << "Attributes not implemented.\n";
100036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
100136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
100236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace {
100336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <>
100436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ELFDumper<ELFType<support::little, 2, false> >::printAttributes() {
100536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Obj->getHeader()->e_machine != EM_ARM) {
100636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    W.startLine() << "Attributes not implemented.\n";
100736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
100836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
100936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
101036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DictScope BA(W, "BuildAttributes");
101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (ELFO::Elf_Shdr_Iter SI = Obj->begin_sections(), SE = Obj->end_sections();
101236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       SI != SE; ++SI) {
101336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SI->sh_type != ELF::SHT_ARM_ATTRIBUTES)
101436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
101536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
101636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ErrorOr<ArrayRef<uint8_t> > Contents = Obj->getSectionContents(&(*SI));
101736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!Contents)
101836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
101936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
102036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if ((*Contents)[0] != ARMBuildAttrs::Format_Version) {
102136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      errs() << "unrecognised FormatVersion: 0x" << utohexstr((*Contents)[0])
102236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             << '\n';
102336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
102436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
102536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
102636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    W.printHex("FormatVersion", (*Contents)[0]);
102736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Contents->size() == 1)
102836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
102936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
103036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ARMAttributeParser(W).Parse(*Contents);
103136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
103236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
103336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
103436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1035cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesnamespace {
1036cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <class ELFT> class MipsGOTParser {
1037cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinespublic:
1038cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  typedef object::ELFFile<ELFT> ObjectFile;
1039cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  typedef typename ObjectFile::Elf_Shdr Elf_Shdr;
1040cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1041cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsGOTParser(const ObjectFile *Obj, StreamWriter &W) : Obj(Obj), W(W) {}
1042cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1043cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void parseGOT(const Elf_Shdr &GOTShdr);
1044cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1045cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprivate:
1046cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  typedef typename ObjectFile::Elf_Sym_Iter Elf_Sym_Iter;
1047cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  typedef typename ObjectFile::Elf_Addr GOTEntry;
1048cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  typedef typename ObjectFile::template ELFEntityIterator<const GOTEntry>
1049cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  GOTIter;
1050cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1051cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const ObjectFile *Obj;
1052cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  StreamWriter &W;
1053cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1054cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::size_t getGOTTotal(ArrayRef<uint8_t> GOT) const;
1055cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  GOTIter makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum);
1056cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1057cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym);
1058cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void printGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It);
1059cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It,
1060cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                           Elf_Sym_Iter Sym);
1061cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines};
1062cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1063cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1064cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <class ELFT>
1065cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsGOTParser<ELFT>::parseGOT(const Elf_Shdr &GOTShdr) {
1066cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // See "Global Offset Table" in Chapter 5 in the following document
1067cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // for detailed GOT description.
1068cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1069cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1070cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ErrorOr<ArrayRef<uint8_t>> GOT = Obj->getSectionContents(&GOTShdr);
1071cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!GOT) {
1072cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    W.startLine() << "The .got section is empty.\n";
1073cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return;
1074cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1075cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1076cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  uint64_t DtLocalGotNum;
1077cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  uint64_t DtGotSym;
1078cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!getGOTTags(DtLocalGotNum, DtGotSym))
1079cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return;
1080cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1081cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (DtLocalGotNum > getGOTTotal(*GOT)) {
1082cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    W.startLine() << "MIPS_LOCAL_GOTNO exceeds a number of GOT entries.\n";
1083cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return;
1084cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1085cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1086cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Elf_Sym_Iter DynSymBegin = Obj->begin_dynamic_symbols();
1087cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Elf_Sym_Iter DynSymEnd = Obj->end_dynamic_symbols();
1088cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
1089cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1090cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (DtGotSym > DynSymTotal) {
1091cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    W.startLine() << "MIPS_GOTSYM exceeds a number of dynamic symbols.\n";
1092cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return;
1093cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1094cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1095cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::size_t GlobalGotNum = DynSymTotal - DtGotSym;
1096cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1097cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT)) {
1098cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    W.startLine() << "Number of global GOT entries exceeds the size of GOT.\n";
1099cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return;
1100cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1102cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  GOTIter GotBegin = makeGOTIter(*GOT, 0);
1103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  GOTIter GotLocalEnd = makeGOTIter(*GOT, DtLocalGotNum);
1104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  GOTIter It = GotBegin;
1105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  DictScope GS(W, "Primary GOT");
1107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  W.printHex("Canonical gp value", GOTShdr.sh_addr + 0x7ff0);
1109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  {
1110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    ListScope RS(W, "Reserved entries");
1111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    {
1113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      DictScope D(W, "Entry");
1114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      printGotEntry(GOTShdr.sh_addr, GotBegin, It++);
1115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      W.printString("Purpose", StringRef("Lazy resolver"));
1116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (It != GotLocalEnd && (*It >> (sizeof(GOTEntry) * 8 - 1)) != 0) {
1119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      DictScope D(W, "Entry");
1120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      printGotEntry(GOTShdr.sh_addr, GotBegin, It++);
1121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
1122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  {
1125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    ListScope LS(W, "Local entries");
1126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    for (; It != GotLocalEnd; ++It) {
1127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      DictScope D(W, "Entry");
1128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      printGotEntry(GOTShdr.sh_addr, GotBegin, It);
1129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  {
1132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    ListScope GS(W, "Global entries");
1133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    GOTIter GotGlobalEnd = makeGOTIter(*GOT, DtLocalGotNum + GlobalGotNum);
1135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Elf_Sym_Iter GotDynSym = DynSymBegin + DtGotSym;
1136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    for (; It != GotGlobalEnd; ++It) {
1137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      DictScope D(W, "Entry");
1138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      printGlobalGotEntry(GOTShdr.sh_addr, GotBegin, It, GotDynSym++);
1139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::size_t SpecGotNum = getGOTTotal(*GOT) - DtLocalGotNum - GlobalGotNum;
1143cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  W.printNumber("Number of TLS and multi-GOT entries", uint64_t(SpecGotNum));
1144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <class ELFT>
1147cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::size_t MipsGOTParser<ELFT>::getGOTTotal(ArrayRef<uint8_t> GOT) const {
1148cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return GOT.size() / sizeof(GOTEntry);
1149cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1150cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <class ELFT>
1152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestypename MipsGOTParser<ELFT>::GOTIter
1153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsGOTParser<ELFT>::makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum) {
1154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const char *Data = reinterpret_cast<const char *>(GOT.data());
1155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return GOTIter(sizeof(GOTEntry), Data + EntryNum * sizeof(GOTEntry));
1156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <class ELFT>
1159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsGOTParser<ELFT>::getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym) {
1160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool FoundLocalGotNum = false;
1161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool FoundGotSym = false;
1162cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  for (const auto &Entry : Obj->dynamic_table()) {
1163cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    switch (Entry.getTag()) {
1164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case ELF::DT_MIPS_LOCAL_GOTNO:
1165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      LocalGotNum = Entry.getVal();
1166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      FoundLocalGotNum = true;
1167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
1168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case ELF::DT_MIPS_GOTSYM:
1169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      GotSym = Entry.getVal();
1170cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      FoundGotSym = true;
1171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
1172cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1173cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1174cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1175cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!FoundLocalGotNum) {
1176cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    W.startLine() << "Cannot find MIPS_LOCAL_GOTNO dynamic table tag.\n";
1177cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
1178cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1179cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1180cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!FoundGotSym) {
1181cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    W.startLine() << "Cannot find MIPS_GOTSYM dynamic table tag.\n";
1182cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
1183cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1184cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1185cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return true;
1186cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <class ELFT>
1189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsGOTParser<ELFT>::printGotEntry(uint64_t GotAddr, GOTIter BeginIt,
1190cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                        GOTIter It) {
1191cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry);
1192cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  W.printHex("Address", GotAddr + Offset);
1193cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  W.printNumber("Access", Offset - 0x7ff0);
1194cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  W.printHex("Initial", *It);
1195cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1196cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1197cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <class ELFT>
1198cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt,
1199cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                              GOTIter It, Elf_Sym_Iter Sym) {
1200cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  printGotEntry(GotAddr, BeginIt, It);
1201cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1202cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  W.printHex("Value", Sym->st_value);
1203cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes));
1204cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1205cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned SectionIndex = 0;
1206cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  StringRef SectionName;
1207cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex);
1208cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  W.printHex("Section", SectionName, SectionIndex);
1209cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1210cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::string FullSymbolName = getFullSymbolName(*Obj, Sym);
1211cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  W.printNumber("Name", FullSymbolName, Sym->st_name);
1212cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1213cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1214cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
1215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Obj->getHeader()->e_machine != EM_MIPS) {
1216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    W.startLine() << "MIPS PLT GOT is available for MIPS targets only.\n";
1217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return;
1218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  llvm::Optional<uint64_t> DtPltGot;
1221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  for (const auto &Entry : Obj->dynamic_table()) {
1222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Entry.getTag() == ELF::DT_PLTGOT) {
1223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      DtPltGot = Entry.getVal();
1224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
1225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1226cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!DtPltGot) {
1229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    W.startLine() << "Cannot find PLTGOT dynamic table tag.\n";
1230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return;
1231cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1232cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const Elf_Shdr *GotShdr = findSectionByAddress(Obj, *DtPltGot);
1234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!GotShdr) {
1235cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    W.startLine() << "There is no .got section in the file.\n";
1236cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return;
1237cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsGOTParser<ELFT>(Obj, W).parseGOT(*GotShdr);
1240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1241