ELFDumper.cpp revision 6948897e478cbd66626159776a8017b3c18579b9
1//===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file implements the ELF-specific dumper for llvm-readobj.
12///
13//===----------------------------------------------------------------------===//
14
15#include "llvm-readobj.h"
16#include "ARMAttributeParser.h"
17#include "ARMEHABIPrinter.h"
18#include "Error.h"
19#include "ObjDumper.h"
20#include "StreamWriter.h"
21#include "llvm/ADT/Optional.h"
22#include "llvm/ADT/SmallString.h"
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/Object/ELFObjectFile.h"
25#include "llvm/Support/ARMBuildAttributes.h"
26#include "llvm/Support/Compiler.h"
27#include "llvm/Support/Format.h"
28#include "llvm/Support/MathExtras.h"
29#include "llvm/Support/MipsABIFlags.h"
30#include "llvm/Support/raw_ostream.h"
31
32using namespace llvm;
33using namespace llvm::object;
34using namespace ELF;
35
36#define LLVM_READOBJ_ENUM_CASE(ns, enum) \
37  case ns::enum: return #enum;
38
39namespace {
40
41template<typename ELFT>
42class ELFDumper : public ObjDumper {
43public:
44  ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer)
45      : ObjDumper(Writer), Obj(Obj) {}
46
47  void printFileHeaders() override;
48  void printSections() override;
49  void printRelocations() override;
50  void printSymbols() override;
51  void printDynamicSymbols() override;
52  void printUnwindInfo() override;
53
54  void printDynamicTable() override;
55  void printNeededLibraries() override;
56  void printProgramHeaders() override;
57
58  void printAttributes() override;
59  void printMipsPLTGOT() override;
60  void printMipsABIFlags() override;
61
62private:
63  typedef ELFFile<ELFT> ELFO;
64  typedef typename ELFO::Elf_Shdr Elf_Shdr;
65  typedef typename ELFO::Elf_Sym Elf_Sym;
66
67  void printSymbol(typename ELFO::Elf_Sym_Iter Symbol);
68
69  void printRelocations(const Elf_Shdr *Sec);
70  void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel);
71
72  const ELFO *Obj;
73};
74
75template <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) {
76  if (!Val) {
77    error(Val.getError());
78    return Default;
79  }
80
81  return *Val;
82}
83} // namespace
84
85namespace llvm {
86
87template <class ELFT>
88static std::error_code createELFDumper(const ELFFile<ELFT> *Obj,
89                                       StreamWriter &Writer,
90                                       std::unique_ptr<ObjDumper> &Result) {
91  Result.reset(new ELFDumper<ELFT>(Obj, Writer));
92  return readobj_error::success;
93}
94
95std::error_code createELFDumper(const object::ObjectFile *Obj,
96                                StreamWriter &Writer,
97                                std::unique_ptr<ObjDumper> &Result) {
98  // Little-endian 32-bit
99  if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
100    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
101
102  // Big-endian 32-bit
103  if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
104    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
105
106  // Little-endian 64-bit
107  if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
108    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
109
110  // Big-endian 64-bit
111  if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
112    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
113
114  return readobj_error::unsupported_obj_file_format;
115}
116
117} // namespace llvm
118
119template <typename ELFO>
120static std::string getFullSymbolName(const ELFO &Obj,
121                                     typename ELFO::Elf_Sym_Iter Symbol) {
122  StringRef SymbolName = errorOrDefault(Obj.getSymbolName(Symbol));
123  if (!Symbol.isDynamic())
124    return SymbolName;
125
126  std::string FullSymbolName(SymbolName);
127
128  bool IsDefault;
129  ErrorOr<StringRef> Version =
130      Obj.getSymbolVersion(nullptr, &*Symbol, IsDefault);
131  if (Version) {
132    FullSymbolName += (IsDefault ? "@@" : "@");
133    FullSymbolName += *Version;
134  } else
135    error(Version.getError());
136  return FullSymbolName;
137}
138
139template <typename ELFO>
140static void
141getSectionNameIndex(const ELFO &Obj, typename ELFO::Elf_Sym_Iter Symbol,
142                    StringRef &SectionName, unsigned &SectionIndex) {
143  SectionIndex = Symbol->st_shndx;
144  if (Symbol->isUndefined())
145    SectionName = "Undefined";
146  else if (Symbol->isProcessorSpecific())
147    SectionName = "Processor Specific";
148  else if (Symbol->isOSSpecific())
149    SectionName = "Operating System Specific";
150  else if (Symbol->isAbsolute())
151    SectionName = "Absolute";
152  else if (Symbol->isCommon())
153    SectionName = "Common";
154  else if (Symbol->isReserved() && SectionIndex != SHN_XINDEX)
155    SectionName = "Reserved";
156  else {
157    if (SectionIndex == SHN_XINDEX)
158      SectionIndex = Obj.getSymbolTableIndex(&*Symbol);
159    assert(SectionIndex != SHN_XINDEX &&
160           "getSymbolTableIndex should handle this");
161    const typename ELFO::Elf_Shdr *Sec = Obj.getSection(SectionIndex);
162    SectionName = errorOrDefault(Obj.getSectionName(Sec));
163  }
164}
165
166template <class ELFT>
167static const typename ELFFile<ELFT>::Elf_Shdr *
168findSectionByAddress(const ELFFile<ELFT> *Obj, uint64_t Addr) {
169  for (const auto &Shdr : Obj->sections())
170    if (Shdr.sh_addr == Addr)
171      return &Shdr;
172  return nullptr;
173}
174
175template <class ELFT>
176static const typename ELFFile<ELFT>::Elf_Shdr *
177findSectionByName(const ELFFile<ELFT> &Obj, StringRef Name) {
178  for (const auto &Shdr : Obj.sections()) {
179    if (Name == errorOrDefault(Obj.getSectionName(&Shdr)))
180      return &Shdr;
181  }
182  return nullptr;
183}
184
185static const EnumEntry<unsigned> ElfClass[] = {
186  { "None",   ELF::ELFCLASSNONE },
187  { "32-bit", ELF::ELFCLASS32   },
188  { "64-bit", ELF::ELFCLASS64   },
189};
190
191static const EnumEntry<unsigned> ElfDataEncoding[] = {
192  { "None",         ELF::ELFDATANONE },
193  { "LittleEndian", ELF::ELFDATA2LSB },
194  { "BigEndian",    ELF::ELFDATA2MSB },
195};
196
197static const EnumEntry<unsigned> ElfObjectFileType[] = {
198  { "None",         ELF::ET_NONE },
199  { "Relocatable",  ELF::ET_REL  },
200  { "Executable",   ELF::ET_EXEC },
201  { "SharedObject", ELF::ET_DYN  },
202  { "Core",         ELF::ET_CORE },
203};
204
205static const EnumEntry<unsigned> ElfOSABI[] = {
206  { "SystemV",      ELF::ELFOSABI_NONE         },
207  { "HPUX",         ELF::ELFOSABI_HPUX         },
208  { "NetBSD",       ELF::ELFOSABI_NETBSD       },
209  { "GNU/Linux",    ELF::ELFOSABI_LINUX        },
210  { "GNU/Hurd",     ELF::ELFOSABI_HURD         },
211  { "Solaris",      ELF::ELFOSABI_SOLARIS      },
212  { "AIX",          ELF::ELFOSABI_AIX          },
213  { "IRIX",         ELF::ELFOSABI_IRIX         },
214  { "FreeBSD",      ELF::ELFOSABI_FREEBSD      },
215  { "TRU64",        ELF::ELFOSABI_TRU64        },
216  { "Modesto",      ELF::ELFOSABI_MODESTO      },
217  { "OpenBSD",      ELF::ELFOSABI_OPENBSD      },
218  { "OpenVMS",      ELF::ELFOSABI_OPENVMS      },
219  { "NSK",          ELF::ELFOSABI_NSK          },
220  { "AROS",         ELF::ELFOSABI_AROS         },
221  { "FenixOS",      ELF::ELFOSABI_FENIXOS      },
222  { "CloudABI",     ELF::ELFOSABI_CLOUDABI     },
223  { "C6000_ELFABI", ELF::ELFOSABI_C6000_ELFABI },
224  { "C6000_LINUX" , ELF::ELFOSABI_C6000_LINUX  },
225  { "ARM",          ELF::ELFOSABI_ARM          },
226  { "Standalone"  , ELF::ELFOSABI_STANDALONE   }
227};
228
229static const EnumEntry<unsigned> ElfMachineType[] = {
230  LLVM_READOBJ_ENUM_ENT(ELF, EM_NONE         ),
231  LLVM_READOBJ_ENUM_ENT(ELF, EM_M32          ),
232  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC        ),
233  LLVM_READOBJ_ENUM_ENT(ELF, EM_386          ),
234  LLVM_READOBJ_ENUM_ENT(ELF, EM_68K          ),
235  LLVM_READOBJ_ENUM_ENT(ELF, EM_88K          ),
236  LLVM_READOBJ_ENUM_ENT(ELF, EM_486          ),
237  LLVM_READOBJ_ENUM_ENT(ELF, EM_860          ),
238  LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS         ),
239  LLVM_READOBJ_ENUM_ENT(ELF, EM_S370         ),
240  LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_RS3_LE  ),
241  LLVM_READOBJ_ENUM_ENT(ELF, EM_PARISC       ),
242  LLVM_READOBJ_ENUM_ENT(ELF, EM_VPP500       ),
243  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC32PLUS  ),
244  LLVM_READOBJ_ENUM_ENT(ELF, EM_960          ),
245  LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC          ),
246  LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC64        ),
247  LLVM_READOBJ_ENUM_ENT(ELF, EM_S390         ),
248  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPU          ),
249  LLVM_READOBJ_ENUM_ENT(ELF, EM_V800         ),
250  LLVM_READOBJ_ENUM_ENT(ELF, EM_FR20         ),
251  LLVM_READOBJ_ENUM_ENT(ELF, EM_RH32         ),
252  LLVM_READOBJ_ENUM_ENT(ELF, EM_RCE          ),
253  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARM          ),
254  LLVM_READOBJ_ENUM_ENT(ELF, EM_ALPHA        ),
255  LLVM_READOBJ_ENUM_ENT(ELF, EM_SH           ),
256  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARCV9      ),
257  LLVM_READOBJ_ENUM_ENT(ELF, EM_TRICORE      ),
258  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC          ),
259  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300       ),
260  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300H      ),
261  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8S          ),
262  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_500       ),
263  LLVM_READOBJ_ENUM_ENT(ELF, EM_IA_64        ),
264  LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_X       ),
265  LLVM_READOBJ_ENUM_ENT(ELF, EM_COLDFIRE     ),
266  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC12       ),
267  LLVM_READOBJ_ENUM_ENT(ELF, EM_MMA          ),
268  LLVM_READOBJ_ENUM_ENT(ELF, EM_PCP          ),
269  LLVM_READOBJ_ENUM_ENT(ELF, EM_NCPU         ),
270  LLVM_READOBJ_ENUM_ENT(ELF, EM_NDR1         ),
271  LLVM_READOBJ_ENUM_ENT(ELF, EM_STARCORE     ),
272  LLVM_READOBJ_ENUM_ENT(ELF, EM_ME16         ),
273  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST100        ),
274  LLVM_READOBJ_ENUM_ENT(ELF, EM_TINYJ        ),
275  LLVM_READOBJ_ENUM_ENT(ELF, EM_X86_64       ),
276  LLVM_READOBJ_ENUM_ENT(ELF, EM_PDSP         ),
277  LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP10        ),
278  LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP11        ),
279  LLVM_READOBJ_ENUM_ENT(ELF, EM_FX66         ),
280  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST9PLUS      ),
281  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST7          ),
282  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC16       ),
283  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC11       ),
284  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC08       ),
285  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC05       ),
286  LLVM_READOBJ_ENUM_ENT(ELF, EM_SVX          ),
287  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST19         ),
288  LLVM_READOBJ_ENUM_ENT(ELF, EM_VAX          ),
289  LLVM_READOBJ_ENUM_ENT(ELF, EM_CRIS         ),
290  LLVM_READOBJ_ENUM_ENT(ELF, EM_JAVELIN      ),
291  LLVM_READOBJ_ENUM_ENT(ELF, EM_FIREPATH     ),
292  LLVM_READOBJ_ENUM_ENT(ELF, EM_ZSP          ),
293  LLVM_READOBJ_ENUM_ENT(ELF, EM_MMIX         ),
294  LLVM_READOBJ_ENUM_ENT(ELF, EM_HUANY        ),
295  LLVM_READOBJ_ENUM_ENT(ELF, EM_PRISM        ),
296  LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR          ),
297  LLVM_READOBJ_ENUM_ENT(ELF, EM_FR30         ),
298  LLVM_READOBJ_ENUM_ENT(ELF, EM_D10V         ),
299  LLVM_READOBJ_ENUM_ENT(ELF, EM_D30V         ),
300  LLVM_READOBJ_ENUM_ENT(ELF, EM_V850         ),
301  LLVM_READOBJ_ENUM_ENT(ELF, EM_M32R         ),
302  LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10300      ),
303  LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10200      ),
304  LLVM_READOBJ_ENUM_ENT(ELF, EM_PJ           ),
305  LLVM_READOBJ_ENUM_ENT(ELF, EM_OPENRISC     ),
306  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT  ),
307  LLVM_READOBJ_ENUM_ENT(ELF, EM_XTENSA       ),
308  LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE    ),
309  LLVM_READOBJ_ENUM_ENT(ELF, EM_TMM_GPP      ),
310  LLVM_READOBJ_ENUM_ENT(ELF, EM_NS32K        ),
311  LLVM_READOBJ_ENUM_ENT(ELF, EM_TPC          ),
312  LLVM_READOBJ_ENUM_ENT(ELF, EM_SNP1K        ),
313  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST200        ),
314  LLVM_READOBJ_ENUM_ENT(ELF, EM_IP2K         ),
315  LLVM_READOBJ_ENUM_ENT(ELF, EM_MAX          ),
316  LLVM_READOBJ_ENUM_ENT(ELF, EM_CR           ),
317  LLVM_READOBJ_ENUM_ENT(ELF, EM_F2MC16       ),
318  LLVM_READOBJ_ENUM_ENT(ELF, EM_MSP430       ),
319  LLVM_READOBJ_ENUM_ENT(ELF, EM_BLACKFIN     ),
320  LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C33       ),
321  LLVM_READOBJ_ENUM_ENT(ELF, EM_SEP          ),
322  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARCA         ),
323  LLVM_READOBJ_ENUM_ENT(ELF, EM_UNICORE      ),
324  LLVM_READOBJ_ENUM_ENT(ELF, EM_EXCESS       ),
325  LLVM_READOBJ_ENUM_ENT(ELF, EM_DXP          ),
326  LLVM_READOBJ_ENUM_ENT(ELF, EM_ALTERA_NIOS2 ),
327  LLVM_READOBJ_ENUM_ENT(ELF, EM_CRX          ),
328  LLVM_READOBJ_ENUM_ENT(ELF, EM_XGATE        ),
329  LLVM_READOBJ_ENUM_ENT(ELF, EM_C166         ),
330  LLVM_READOBJ_ENUM_ENT(ELF, EM_M16C         ),
331  LLVM_READOBJ_ENUM_ENT(ELF, EM_DSPIC30F     ),
332  LLVM_READOBJ_ENUM_ENT(ELF, EM_CE           ),
333  LLVM_READOBJ_ENUM_ENT(ELF, EM_M32C         ),
334  LLVM_READOBJ_ENUM_ENT(ELF, EM_TSK3000      ),
335  LLVM_READOBJ_ENUM_ENT(ELF, EM_RS08         ),
336  LLVM_READOBJ_ENUM_ENT(ELF, EM_SHARC        ),
337  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG2        ),
338  LLVM_READOBJ_ENUM_ENT(ELF, EM_SCORE7       ),
339  LLVM_READOBJ_ENUM_ENT(ELF, EM_DSP24        ),
340  LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE3   ),
341  LLVM_READOBJ_ENUM_ENT(ELF, EM_LATTICEMICO32),
342  LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C17       ),
343  LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C6000     ),
344  LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C2000     ),
345  LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C5500     ),
346  LLVM_READOBJ_ENUM_ENT(ELF, EM_MMDSP_PLUS   ),
347  LLVM_READOBJ_ENUM_ENT(ELF, EM_CYPRESS_M8C  ),
348  LLVM_READOBJ_ENUM_ENT(ELF, EM_R32C         ),
349  LLVM_READOBJ_ENUM_ENT(ELF, EM_TRIMEDIA     ),
350  LLVM_READOBJ_ENUM_ENT(ELF, EM_HEXAGON      ),
351  LLVM_READOBJ_ENUM_ENT(ELF, EM_8051         ),
352  LLVM_READOBJ_ENUM_ENT(ELF, EM_STXP7X       ),
353  LLVM_READOBJ_ENUM_ENT(ELF, EM_NDS32        ),
354  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1        ),
355  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1X       ),
356  LLVM_READOBJ_ENUM_ENT(ELF, EM_MAXQ30       ),
357  LLVM_READOBJ_ENUM_ENT(ELF, EM_XIMO16       ),
358  LLVM_READOBJ_ENUM_ENT(ELF, EM_MANIK        ),
359  LLVM_READOBJ_ENUM_ENT(ELF, EM_CRAYNV2      ),
360  LLVM_READOBJ_ENUM_ENT(ELF, EM_RX           ),
361  LLVM_READOBJ_ENUM_ENT(ELF, EM_METAG        ),
362  LLVM_READOBJ_ENUM_ENT(ELF, EM_MCST_ELBRUS  ),
363  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG16       ),
364  LLVM_READOBJ_ENUM_ENT(ELF, EM_CR16         ),
365  LLVM_READOBJ_ENUM_ENT(ELF, EM_ETPU         ),
366  LLVM_READOBJ_ENUM_ENT(ELF, EM_SLE9X        ),
367  LLVM_READOBJ_ENUM_ENT(ELF, EM_L10M         ),
368  LLVM_READOBJ_ENUM_ENT(ELF, EM_K10M         ),
369  LLVM_READOBJ_ENUM_ENT(ELF, EM_AARCH64      ),
370  LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR32        ),
371  LLVM_READOBJ_ENUM_ENT(ELF, EM_STM8         ),
372  LLVM_READOBJ_ENUM_ENT(ELF, EM_TILE64       ),
373  LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEPRO      ),
374  LLVM_READOBJ_ENUM_ENT(ELF, EM_CUDA         ),
375  LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEGX       ),
376  LLVM_READOBJ_ENUM_ENT(ELF, EM_CLOUDSHIELD  ),
377  LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_1ST    ),
378  LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_2ND    ),
379  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT2 ),
380  LLVM_READOBJ_ENUM_ENT(ELF, EM_OPEN8        ),
381  LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78         ),
382  LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5   ),
383  LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR        ),
384  LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX      )
385};
386
387static const EnumEntry<unsigned> ElfSymbolBindings[] = {
388  { "Local",  ELF::STB_LOCAL        },
389  { "Global", ELF::STB_GLOBAL       },
390  { "Weak",   ELF::STB_WEAK         },
391  { "Unique", ELF::STB_GNU_UNIQUE   }
392};
393
394static const EnumEntry<unsigned> ElfSymbolTypes[] = {
395  { "None",      ELF::STT_NOTYPE    },
396  { "Object",    ELF::STT_OBJECT    },
397  { "Function",  ELF::STT_FUNC      },
398  { "Section",   ELF::STT_SECTION   },
399  { "File",      ELF::STT_FILE      },
400  { "Common",    ELF::STT_COMMON    },
401  { "TLS",       ELF::STT_TLS       },
402  { "GNU_IFunc", ELF::STT_GNU_IFUNC }
403};
404
405static const char *getElfSectionType(unsigned Arch, unsigned Type) {
406  switch (Arch) {
407  case ELF::EM_ARM:
408    switch (Type) {
409    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX);
410    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
411    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
412    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
413    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
414    }
415  case ELF::EM_HEXAGON:
416    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
417  case ELF::EM_X86_64:
418    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
419  case ELF::EM_MIPS:
420  case ELF::EM_MIPS_RS3_LE:
421    switch (Type) {
422    LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
423    LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
424    LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
425    }
426  }
427
428  switch (Type) {
429  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL              );
430  LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS          );
431  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB            );
432  LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB            );
433  LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA              );
434  LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH              );
435  LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC           );
436  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE              );
437  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS            );
438  LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL               );
439  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB             );
440  LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM            );
441  LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY        );
442  LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY        );
443  LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY     );
444  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP             );
445  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX      );
446  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES    );
447  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH          );
448  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef        );
449  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed       );
450  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym        );
451  default: return "";
452  }
453}
454
455static const EnumEntry<unsigned> ElfSectionFlags[] = {
456  LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE           ),
457  LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC           ),
458  LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXCLUDE         ),
459  LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR       ),
460  LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE           ),
461  LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS         ),
462  LLVM_READOBJ_ENUM_ENT(ELF, SHF_INFO_LINK       ),
463  LLVM_READOBJ_ENUM_ENT(ELF, SHF_LINK_ORDER      ),
464  LLVM_READOBJ_ENUM_ENT(ELF, SHF_OS_NONCONFORMING),
465  LLVM_READOBJ_ENUM_ENT(ELF, SHF_GROUP           ),
466  LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS             ),
467  LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION),
468  LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION),
469  LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP    )
470};
471
472static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
473  // Check potentially overlapped processor-specific
474  // program header type.
475  switch (Arch) {
476  case ELF::EM_ARM:
477    switch (Type) {
478    LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX);
479    }
480  case ELF::EM_MIPS:
481  case ELF::EM_MIPS_RS3_LE:
482    switch (Type) {
483    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
484    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
485    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
486    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);
487    }
488  }
489
490  switch (Type) {
491  LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL   );
492  LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD   );
493  LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
494  LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP );
495  LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE   );
496  LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB  );
497  LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR   );
498  LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS    );
499
500  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
501  LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
502
503  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
504  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
505  default: return "";
506  }
507}
508
509static const EnumEntry<unsigned> ElfSegmentFlags[] = {
510  LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
511  LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
512  LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
513};
514
515static const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
516  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NOREORDER),
517  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_PIC),
518  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_CPIC),
519  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI2),
520  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_32BITMODE),
521  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_FP64),
522  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NAN2008),
523  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O32),
524  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O64),
525  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI32),
526  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI64),
527  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_3900),
528  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4010),
529  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4100),
530  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4650),
531  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4120),
532  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4111),
533  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_SB1),
534  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON),
535  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_XLR),
536  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON2),
537  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON3),
538  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5400),
539  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5900),
540  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5500),
541  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_9000),
542  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2E),
543  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2F),
544  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS3A),
545  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MICROMIPS),
546  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_M16),
547  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_MDMX),
548  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_1),
549  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_2),
550  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_3),
551  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_4),
552  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_5),
553  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32),
554  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64),
555  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R2),
556  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R2),
557  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R6),
558  LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6)
559};
560
561template<class ELFT>
562void ELFDumper<ELFT>::printFileHeaders() {
563  const typename ELFO::Elf_Ehdr *Header = Obj->getHeader();
564
565  {
566    DictScope D(W, "ElfHeader");
567    {
568      DictScope D(W, "Ident");
569      W.printBinary("Magic", makeArrayRef(Header->e_ident).slice(ELF::EI_MAG0,
570                                                                 4));
571      W.printEnum  ("Class", Header->e_ident[ELF::EI_CLASS],
572                      makeArrayRef(ElfClass));
573      W.printEnum  ("DataEncoding", Header->e_ident[ELF::EI_DATA],
574                      makeArrayRef(ElfDataEncoding));
575      W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]);
576      W.printEnum  ("OS/ABI", Header->e_ident[ELF::EI_OSABI],
577                      makeArrayRef(ElfOSABI));
578      W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]);
579      W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD));
580    }
581
582    W.printEnum  ("Type", Header->e_type, makeArrayRef(ElfObjectFileType));
583    W.printEnum  ("Machine", Header->e_machine, makeArrayRef(ElfMachineType));
584    W.printNumber("Version", Header->e_version);
585    W.printHex   ("Entry", Header->e_entry);
586    W.printHex   ("ProgramHeaderOffset", Header->e_phoff);
587    W.printHex   ("SectionHeaderOffset", Header->e_shoff);
588    if (Header->e_machine == EM_MIPS)
589      W.printFlags("Flags", Header->e_flags, makeArrayRef(ElfHeaderMipsFlags),
590                   unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
591                   unsigned(ELF::EF_MIPS_MACH));
592    else
593      W.printFlags("Flags", Header->e_flags);
594    W.printNumber("HeaderSize", Header->e_ehsize);
595    W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize);
596    W.printNumber("ProgramHeaderCount", Header->e_phnum);
597    W.printNumber("SectionHeaderEntrySize", Header->e_shentsize);
598    W.printNumber("SectionHeaderCount", Header->e_shnum);
599    W.printNumber("StringTableSectionIndex", Header->e_shstrndx);
600  }
601}
602
603template<class ELFT>
604void ELFDumper<ELFT>::printSections() {
605  ListScope SectionsD(W, "Sections");
606
607  int SectionIndex = -1;
608  for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(),
609                                    SecE = Obj->end_sections();
610       SecI != SecE; ++SecI) {
611    ++SectionIndex;
612
613    const Elf_Shdr *Section = &*SecI;
614    StringRef Name = errorOrDefault(Obj->getSectionName(Section));
615
616    DictScope SectionD(W, "Section");
617    W.printNumber("Index", SectionIndex);
618    W.printNumber("Name", Name, Section->sh_name);
619    W.printHex("Type",
620               getElfSectionType(Obj->getHeader()->e_machine, Section->sh_type),
621               Section->sh_type);
622    W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags));
623    W.printHex   ("Address", Section->sh_addr);
624    W.printHex   ("Offset", Section->sh_offset);
625    W.printNumber("Size", Section->sh_size);
626    W.printNumber("Link", Section->sh_link);
627    W.printNumber("Info", Section->sh_info);
628    W.printNumber("AddressAlignment", Section->sh_addralign);
629    W.printNumber("EntrySize", Section->sh_entsize);
630
631    if (opts::SectionRelocations) {
632      ListScope D(W, "Relocations");
633      printRelocations(Section);
634    }
635
636    if (opts::SectionSymbols) {
637      ListScope D(W, "Symbols");
638      for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(),
639                                       SymE = Obj->end_symbols();
640           SymI != SymE; ++SymI) {
641        if (Obj->getSection(&*SymI) == Section)
642          printSymbol(SymI);
643      }
644    }
645
646    if (opts::SectionData && Section->sh_type != ELF::SHT_NOBITS) {
647      ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(Section));
648      W.printBinaryBlock("SectionData",
649                         StringRef((const char *)Data.data(), Data.size()));
650    }
651  }
652}
653
654template<class ELFT>
655void ELFDumper<ELFT>::printRelocations() {
656  ListScope D(W, "Relocations");
657
658  int SectionNumber = -1;
659  for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(),
660                                    SecE = Obj->end_sections();
661       SecI != SecE; ++SecI) {
662    ++SectionNumber;
663
664    if (SecI->sh_type != ELF::SHT_REL && SecI->sh_type != ELF::SHT_RELA)
665      continue;
666
667    StringRef Name = errorOrDefault(Obj->getSectionName(&*SecI));
668
669    W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
670    W.indent();
671
672    printRelocations(&*SecI);
673
674    W.unindent();
675    W.startLine() << "}\n";
676  }
677}
678
679template <class ELFT>
680void ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) {
681  switch (Sec->sh_type) {
682  case ELF::SHT_REL:
683    for (typename ELFO::Elf_Rel_Iter RI = Obj->begin_rel(Sec),
684                                     RE = Obj->end_rel(Sec);
685         RI != RE; ++RI) {
686      typename ELFO::Elf_Rela Rela;
687      Rela.r_offset = RI->r_offset;
688      Rela.r_info = RI->r_info;
689      Rela.r_addend = 0;
690      printRelocation(Sec, Rela);
691    }
692    break;
693  case ELF::SHT_RELA:
694    for (typename ELFO::Elf_Rela_Iter RI = Obj->begin_rela(Sec),
695                                      RE = Obj->end_rela(Sec);
696         RI != RE; ++RI) {
697      printRelocation(Sec, *RI);
698    }
699    break;
700  }
701}
702
703template <class ELFT>
704void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec,
705                                      typename ELFO::Elf_Rela Rel) {
706  SmallString<32> RelocName;
707  Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
708  StringRef TargetName;
709  std::pair<const Elf_Shdr *, const Elf_Sym *> Sym =
710      Obj->getRelocationSymbol(Sec, &Rel);
711  if (Sym.second && Sym.second->getType() == ELF::STT_SECTION) {
712    const Elf_Shdr *Sec = Obj->getSection(Sym.second);
713    ErrorOr<StringRef> SecName = Obj->getSectionName(Sec);
714    if (SecName)
715      TargetName = SecName.get();
716  } else if (Sym.first) {
717    TargetName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second));
718  }
719
720  if (opts::ExpandRelocs) {
721    DictScope Group(W, "Relocation");
722    W.printHex("Offset", Rel.r_offset);
723    W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
724    W.printNumber("Symbol", TargetName.size() > 0 ? TargetName : "-",
725                  Rel.getSymbol(Obj->isMips64EL()));
726    W.printHex("Addend", Rel.r_addend);
727  } else {
728    raw_ostream& OS = W.startLine();
729    OS << W.hex(Rel.r_offset) << " " << RelocName << " "
730       << (TargetName.size() > 0 ? TargetName : "-") << " "
731       << W.hex(Rel.r_addend) << "\n";
732  }
733}
734
735template<class ELFT>
736void ELFDumper<ELFT>::printSymbols() {
737  ListScope Group(W, "Symbols");
738  for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(),
739                                   SymE = Obj->end_symbols();
740       SymI != SymE; ++SymI) {
741    printSymbol(SymI);
742  }
743}
744
745template<class ELFT>
746void ELFDumper<ELFT>::printDynamicSymbols() {
747  ListScope Group(W, "DynamicSymbols");
748
749  for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(),
750                                   SymE = Obj->end_dynamic_symbols();
751       SymI != SymE; ++SymI) {
752    printSymbol(SymI);
753  }
754}
755
756template <class ELFT>
757void ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) {
758  unsigned SectionIndex = 0;
759  StringRef SectionName;
760  getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex);
761  std::string FullSymbolName = getFullSymbolName(*Obj, Symbol);
762
763  DictScope D(W, "Symbol");
764  W.printNumber("Name", FullSymbolName, Symbol->st_name);
765  W.printHex   ("Value", Symbol->st_value);
766  W.printNumber("Size", Symbol->st_size);
767  W.printEnum  ("Binding", Symbol->getBinding(),
768                  makeArrayRef(ElfSymbolBindings));
769  W.printEnum  ("Type", Symbol->getType(), makeArrayRef(ElfSymbolTypes));
770  W.printNumber("Other", Symbol->st_other);
771  W.printHex("Section", SectionName, SectionIndex);
772}
773
774#define LLVM_READOBJ_TYPE_CASE(name) \
775  case DT_##name: return #name
776
777static const char *getTypeString(uint64_t Type) {
778  switch (Type) {
779  LLVM_READOBJ_TYPE_CASE(BIND_NOW);
780  LLVM_READOBJ_TYPE_CASE(DEBUG);
781  LLVM_READOBJ_TYPE_CASE(FINI);
782  LLVM_READOBJ_TYPE_CASE(FINI_ARRAY);
783  LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ);
784  LLVM_READOBJ_TYPE_CASE(FLAGS);
785  LLVM_READOBJ_TYPE_CASE(FLAGS_1);
786  LLVM_READOBJ_TYPE_CASE(HASH);
787  LLVM_READOBJ_TYPE_CASE(INIT);
788  LLVM_READOBJ_TYPE_CASE(INIT_ARRAY);
789  LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ);
790  LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY);
791  LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ);
792  LLVM_READOBJ_TYPE_CASE(JMPREL);
793  LLVM_READOBJ_TYPE_CASE(NEEDED);
794  LLVM_READOBJ_TYPE_CASE(NULL);
795  LLVM_READOBJ_TYPE_CASE(PLTGOT);
796  LLVM_READOBJ_TYPE_CASE(PLTREL);
797  LLVM_READOBJ_TYPE_CASE(PLTRELSZ);
798  LLVM_READOBJ_TYPE_CASE(REL);
799  LLVM_READOBJ_TYPE_CASE(RELA);
800  LLVM_READOBJ_TYPE_CASE(RELENT);
801  LLVM_READOBJ_TYPE_CASE(RELSZ);
802  LLVM_READOBJ_TYPE_CASE(RELAENT);
803  LLVM_READOBJ_TYPE_CASE(RELASZ);
804  LLVM_READOBJ_TYPE_CASE(RPATH);
805  LLVM_READOBJ_TYPE_CASE(RUNPATH);
806  LLVM_READOBJ_TYPE_CASE(SONAME);
807  LLVM_READOBJ_TYPE_CASE(STRSZ);
808  LLVM_READOBJ_TYPE_CASE(STRTAB);
809  LLVM_READOBJ_TYPE_CASE(SYMBOLIC);
810  LLVM_READOBJ_TYPE_CASE(SYMENT);
811  LLVM_READOBJ_TYPE_CASE(SYMTAB);
812  LLVM_READOBJ_TYPE_CASE(TEXTREL);
813  LLVM_READOBJ_TYPE_CASE(VERNEED);
814  LLVM_READOBJ_TYPE_CASE(VERNEEDNUM);
815  LLVM_READOBJ_TYPE_CASE(VERSYM);
816  LLVM_READOBJ_TYPE_CASE(RELCOUNT);
817  LLVM_READOBJ_TYPE_CASE(GNU_HASH);
818  LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION);
819  LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS);
820  LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS);
821  LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO);
822  LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO);
823  LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO);
824  LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM);
825  LLVM_READOBJ_TYPE_CASE(MIPS_RLD_MAP);
826  LLVM_READOBJ_TYPE_CASE(MIPS_PLTGOT);
827  LLVM_READOBJ_TYPE_CASE(MIPS_OPTIONS);
828  default: return "unknown";
829  }
830}
831
832#undef LLVM_READOBJ_TYPE_CASE
833
834#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \
835  { #enum, prefix##_##enum }
836
837static const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
838  LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
839  LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
840  LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
841  LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
842  LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
843};
844
845static const EnumEntry<unsigned> ElfDynamicDTFlags1[] = {
846  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW),
847  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL),
848  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP),
849  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE),
850  LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR),
851  LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST),
852  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN),
853  LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN),
854  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT),
855  LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS),
856  LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE),
857  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB),
858  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP),
859  LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT),
860  LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE),
861  LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE),
862  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT),
863  LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF),
864  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS),
865  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR),
866  LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED),
867  LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC),
868  LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE),
869  LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT),
870  LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON)
871};
872
873static const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
874  LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
875  LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
876  LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
877  LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
878  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
879  LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
880  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
881  LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
882  LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
883  LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
884  LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
885  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
886  LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
887  LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
888  LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
889  LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
890};
891
892#undef LLVM_READOBJ_DT_FLAG_ENT
893
894template <typename T, typename TFlag>
895void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
896  typedef EnumEntry<TFlag> FlagEntry;
897  typedef SmallVector<FlagEntry, 10> FlagVector;
898  FlagVector SetFlags;
899
900  for (const auto &Flag : Flags) {
901    if (Flag.Value == 0)
902      continue;
903
904    if ((Value & Flag.Value) == Flag.Value)
905      SetFlags.push_back(Flag);
906  }
907
908  for (const auto &Flag : SetFlags) {
909    OS << Flag.Name << " ";
910  }
911}
912
913template <class ELFT>
914static void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value,
915                       bool Is64, raw_ostream &OS) {
916  switch (Type) {
917  case DT_PLTREL:
918    if (Value == DT_REL) {
919      OS << "REL";
920      break;
921    } else if (Value == DT_RELA) {
922      OS << "RELA";
923      break;
924    }
925  // Fallthrough.
926  case DT_PLTGOT:
927  case DT_HASH:
928  case DT_STRTAB:
929  case DT_SYMTAB:
930  case DT_RELA:
931  case DT_INIT:
932  case DT_FINI:
933  case DT_REL:
934  case DT_JMPREL:
935  case DT_INIT_ARRAY:
936  case DT_FINI_ARRAY:
937  case DT_PREINIT_ARRAY:
938  case DT_DEBUG:
939  case DT_VERNEED:
940  case DT_VERSYM:
941  case DT_GNU_HASH:
942  case DT_NULL:
943  case DT_MIPS_BASE_ADDRESS:
944  case DT_MIPS_GOTSYM:
945  case DT_MIPS_RLD_MAP:
946  case DT_MIPS_PLTGOT:
947  case DT_MIPS_OPTIONS:
948    OS << format("0x%" PRIX64, Value);
949    break;
950  case DT_RELCOUNT:
951  case DT_VERNEEDNUM:
952  case DT_MIPS_RLD_VERSION:
953  case DT_MIPS_LOCAL_GOTNO:
954  case DT_MIPS_SYMTABNO:
955  case DT_MIPS_UNREFEXTNO:
956    OS << Value;
957    break;
958  case DT_PLTRELSZ:
959  case DT_RELASZ:
960  case DT_RELAENT:
961  case DT_STRSZ:
962  case DT_SYMENT:
963  case DT_RELSZ:
964  case DT_RELENT:
965  case DT_INIT_ARRAYSZ:
966  case DT_FINI_ARRAYSZ:
967  case DT_PREINIT_ARRAYSZ:
968    OS << Value << " (bytes)";
969    break;
970  case DT_NEEDED:
971    OS << "SharedLibrary (" << O->getDynamicString(Value) << ")";
972    break;
973  case DT_SONAME:
974    OS << "LibrarySoname (" << O->getDynamicString(Value) << ")";
975    break;
976  case DT_RPATH:
977  case DT_RUNPATH:
978    OS << O->getDynamicString(Value);
979    break;
980  case DT_MIPS_FLAGS:
981    printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS);
982    break;
983  case DT_FLAGS:
984    printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
985    break;
986  case DT_FLAGS_1:
987    printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS);
988    break;
989  }
990}
991
992template<class ELFT>
993void ELFDumper<ELFT>::printUnwindInfo() {
994  W.startLine() << "UnwindInfo not implemented.\n";
995}
996
997namespace {
998template <> void ELFDumper<ELFType<support::little, false>>::printUnwindInfo() {
999  const unsigned Machine = Obj->getHeader()->e_machine;
1000  if (Machine == EM_ARM) {
1001    ARM::EHABI::PrinterContext<ELFType<support::little, false>> Ctx(W, Obj);
1002    return Ctx.PrintUnwindInformation();
1003  }
1004  W.startLine() << "UnwindInfo not implemented.\n";
1005}
1006}
1007
1008template<class ELFT>
1009void ELFDumper<ELFT>::printDynamicTable() {
1010  auto DynTable = Obj->dynamic_table(true);
1011
1012  ptrdiff_t Total = std::distance(DynTable.begin(), DynTable.end());
1013  if (Total == 0)
1014    return;
1015
1016  raw_ostream &OS = W.getOStream();
1017  W.startLine() << "DynamicSection [ (" << Total << " entries)\n";
1018
1019  bool Is64 = ELFT::Is64Bits;
1020
1021  W.startLine()
1022     << "  Tag" << (Is64 ? "                " : "        ") << "Type"
1023     << "                 " << "Name/Value\n";
1024  for (const auto &Entry : DynTable) {
1025    W.startLine()
1026       << "  "
1027       << format(Is64 ? "0x%016" PRIX64 : "0x%08" PRIX64, Entry.getTag())
1028       << " " << format("%-21s", getTypeString(Entry.getTag()));
1029    printValue(Obj, Entry.getTag(), Entry.getVal(), Is64, OS);
1030    OS << "\n";
1031  }
1032
1033  W.startLine() << "]\n";
1034}
1035
1036template<class ELFT>
1037void ELFDumper<ELFT>::printNeededLibraries() {
1038  ListScope D(W, "NeededLibraries");
1039
1040  typedef std::vector<StringRef> LibsTy;
1041  LibsTy Libs;
1042
1043  for (const auto &Entry : Obj->dynamic_table())
1044    if (Entry.d_tag == ELF::DT_NEEDED)
1045      Libs.push_back(Obj->getDynamicString(Entry.d_un.d_val));
1046
1047  std::stable_sort(Libs.begin(), Libs.end());
1048
1049  for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); I != E; ++I) {
1050    outs() << "  " << *I << "\n";
1051  }
1052}
1053
1054template<class ELFT>
1055void ELFDumper<ELFT>::printProgramHeaders() {
1056  ListScope L(W, "ProgramHeaders");
1057
1058  for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(),
1059                                    PE = Obj->end_program_headers();
1060                                    PI != PE; ++PI) {
1061    DictScope P(W, "ProgramHeader");
1062    W.printHex   ("Type",
1063                  getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type),
1064                  PI->p_type);
1065    W.printHex   ("Offset", PI->p_offset);
1066    W.printHex   ("VirtualAddress", PI->p_vaddr);
1067    W.printHex   ("PhysicalAddress", PI->p_paddr);
1068    W.printNumber("FileSize", PI->p_filesz);
1069    W.printNumber("MemSize", PI->p_memsz);
1070    W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags));
1071    W.printNumber("Alignment", PI->p_align);
1072  }
1073}
1074
1075template <class ELFT>
1076void ELFDumper<ELFT>::printAttributes() {
1077  W.startLine() << "Attributes not implemented.\n";
1078}
1079
1080namespace {
1081template <> void ELFDumper<ELFType<support::little, false>>::printAttributes() {
1082  if (Obj->getHeader()->e_machine != EM_ARM) {
1083    W.startLine() << "Attributes not implemented.\n";
1084    return;
1085  }
1086
1087  DictScope BA(W, "BuildAttributes");
1088  for (ELFO::Elf_Shdr_Iter SI = Obj->begin_sections(), SE = Obj->end_sections();
1089       SI != SE; ++SI) {
1090    if (SI->sh_type != ELF::SHT_ARM_ATTRIBUTES)
1091      continue;
1092
1093    ErrorOr<ArrayRef<uint8_t> > Contents = Obj->getSectionContents(&(*SI));
1094    if (!Contents)
1095      continue;
1096
1097    if ((*Contents)[0] != ARMBuildAttrs::Format_Version) {
1098      errs() << "unrecognised FormatVersion: 0x" << utohexstr((*Contents)[0])
1099             << '\n';
1100      continue;
1101    }
1102
1103    W.printHex("FormatVersion", (*Contents)[0]);
1104    if (Contents->size() == 1)
1105      continue;
1106
1107    ARMAttributeParser(W).Parse(*Contents);
1108  }
1109}
1110}
1111
1112namespace {
1113template <class ELFT> class MipsGOTParser {
1114public:
1115  typedef object::ELFFile<ELFT> ObjectFile;
1116  typedef typename ObjectFile::Elf_Shdr Elf_Shdr;
1117
1118  MipsGOTParser(const ObjectFile *Obj, StreamWriter &W) : Obj(Obj), W(W) {}
1119
1120  void parseGOT(const Elf_Shdr &GOTShdr);
1121
1122private:
1123  typedef typename ObjectFile::Elf_Sym_Iter Elf_Sym_Iter;
1124  typedef typename ObjectFile::Elf_Addr GOTEntry;
1125  typedef typename ObjectFile::template ELFEntityIterator<const GOTEntry>
1126  GOTIter;
1127
1128  const ObjectFile *Obj;
1129  StreamWriter &W;
1130
1131  std::size_t getGOTTotal(ArrayRef<uint8_t> GOT) const;
1132  GOTIter makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum);
1133
1134  bool getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym);
1135  void printGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It);
1136  void printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It,
1137                           Elf_Sym_Iter Sym);
1138};
1139}
1140
1141template <class ELFT>
1142void MipsGOTParser<ELFT>::parseGOT(const Elf_Shdr &GOTShdr) {
1143  // See "Global Offset Table" in Chapter 5 in the following document
1144  // for detailed GOT description.
1145  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1146
1147  ErrorOr<ArrayRef<uint8_t>> GOT = Obj->getSectionContents(&GOTShdr);
1148  if (!GOT) {
1149    W.startLine() << "The .got section is empty.\n";
1150    return;
1151  }
1152
1153  uint64_t DtLocalGotNum;
1154  uint64_t DtGotSym;
1155  if (!getGOTTags(DtLocalGotNum, DtGotSym))
1156    return;
1157
1158  if (DtLocalGotNum > getGOTTotal(*GOT)) {
1159    W.startLine() << "MIPS_LOCAL_GOTNO exceeds a number of GOT entries.\n";
1160    return;
1161  }
1162
1163  Elf_Sym_Iter DynSymBegin = Obj->begin_dynamic_symbols();
1164  Elf_Sym_Iter DynSymEnd = Obj->end_dynamic_symbols();
1165  std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
1166
1167  if (DtGotSym > DynSymTotal) {
1168    W.startLine() << "MIPS_GOTSYM exceeds a number of dynamic symbols.\n";
1169    return;
1170  }
1171
1172  std::size_t GlobalGotNum = DynSymTotal - DtGotSym;
1173
1174  if (DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT)) {
1175    W.startLine() << "Number of global GOT entries exceeds the size of GOT.\n";
1176    return;
1177  }
1178
1179  GOTIter GotBegin = makeGOTIter(*GOT, 0);
1180  GOTIter GotLocalEnd = makeGOTIter(*GOT, DtLocalGotNum);
1181  GOTIter It = GotBegin;
1182
1183  DictScope GS(W, "Primary GOT");
1184
1185  W.printHex("Canonical gp value", GOTShdr.sh_addr + 0x7ff0);
1186  {
1187    ListScope RS(W, "Reserved entries");
1188
1189    {
1190      DictScope D(W, "Entry");
1191      printGotEntry(GOTShdr.sh_addr, GotBegin, It++);
1192      W.printString("Purpose", StringRef("Lazy resolver"));
1193    }
1194
1195    if (It != GotLocalEnd && (*It >> (sizeof(GOTEntry) * 8 - 1)) != 0) {
1196      DictScope D(W, "Entry");
1197      printGotEntry(GOTShdr.sh_addr, GotBegin, It++);
1198      W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
1199    }
1200  }
1201  {
1202    ListScope LS(W, "Local entries");
1203    for (; It != GotLocalEnd; ++It) {
1204      DictScope D(W, "Entry");
1205      printGotEntry(GOTShdr.sh_addr, GotBegin, It);
1206    }
1207  }
1208  {
1209    ListScope GS(W, "Global entries");
1210
1211    GOTIter GotGlobalEnd = makeGOTIter(*GOT, DtLocalGotNum + GlobalGotNum);
1212    Elf_Sym_Iter GotDynSym = DynSymBegin + DtGotSym;
1213    for (; It != GotGlobalEnd; ++It) {
1214      DictScope D(W, "Entry");
1215      printGlobalGotEntry(GOTShdr.sh_addr, GotBegin, It, GotDynSym++);
1216    }
1217  }
1218
1219  std::size_t SpecGotNum = getGOTTotal(*GOT) - DtLocalGotNum - GlobalGotNum;
1220  W.printNumber("Number of TLS and multi-GOT entries", uint64_t(SpecGotNum));
1221}
1222
1223template <class ELFT>
1224std::size_t MipsGOTParser<ELFT>::getGOTTotal(ArrayRef<uint8_t> GOT) const {
1225  return GOT.size() / sizeof(GOTEntry);
1226}
1227
1228template <class ELFT>
1229typename MipsGOTParser<ELFT>::GOTIter
1230MipsGOTParser<ELFT>::makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum) {
1231  const char *Data = reinterpret_cast<const char *>(GOT.data());
1232  return GOTIter(sizeof(GOTEntry), Data + EntryNum * sizeof(GOTEntry));
1233}
1234
1235template <class ELFT>
1236bool MipsGOTParser<ELFT>::getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym) {
1237  bool FoundLocalGotNum = false;
1238  bool FoundGotSym = false;
1239  for (const auto &Entry : Obj->dynamic_table()) {
1240    switch (Entry.getTag()) {
1241    case ELF::DT_MIPS_LOCAL_GOTNO:
1242      LocalGotNum = Entry.getVal();
1243      FoundLocalGotNum = true;
1244      break;
1245    case ELF::DT_MIPS_GOTSYM:
1246      GotSym = Entry.getVal();
1247      FoundGotSym = true;
1248      break;
1249    }
1250  }
1251
1252  if (!FoundLocalGotNum) {
1253    W.startLine() << "Cannot find MIPS_LOCAL_GOTNO dynamic table tag.\n";
1254    return false;
1255  }
1256
1257  if (!FoundGotSym) {
1258    W.startLine() << "Cannot find MIPS_GOTSYM dynamic table tag.\n";
1259    return false;
1260  }
1261
1262  return true;
1263}
1264
1265template <class ELFT>
1266void MipsGOTParser<ELFT>::printGotEntry(uint64_t GotAddr, GOTIter BeginIt,
1267                                        GOTIter It) {
1268  int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry);
1269  W.printHex("Address", GotAddr + Offset);
1270  W.printNumber("Access", Offset - 0x7ff0);
1271  W.printHex("Initial", *It);
1272}
1273
1274template <class ELFT>
1275void MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt,
1276                                              GOTIter It, Elf_Sym_Iter Sym) {
1277  printGotEntry(GotAddr, BeginIt, It);
1278
1279  W.printHex("Value", Sym->st_value);
1280  W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes));
1281
1282  unsigned SectionIndex = 0;
1283  StringRef SectionName;
1284  getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex);
1285  W.printHex("Section", SectionName, SectionIndex);
1286
1287  std::string FullSymbolName = getFullSymbolName(*Obj, Sym);
1288  W.printNumber("Name", FullSymbolName, Sym->st_name);
1289}
1290
1291template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
1292  if (Obj->getHeader()->e_machine != EM_MIPS) {
1293    W.startLine() << "MIPS PLT GOT is available for MIPS targets only.\n";
1294    return;
1295  }
1296
1297  llvm::Optional<uint64_t> DtPltGot;
1298  for (const auto &Entry : Obj->dynamic_table()) {
1299    if (Entry.getTag() == ELF::DT_PLTGOT) {
1300      DtPltGot = Entry.getVal();
1301      break;
1302    }
1303  }
1304
1305  if (!DtPltGot) {
1306    W.startLine() << "Cannot find PLTGOT dynamic table tag.\n";
1307    return;
1308  }
1309
1310  const Elf_Shdr *GotShdr = findSectionByAddress(Obj, *DtPltGot);
1311  if (!GotShdr) {
1312    W.startLine() << "There is no .got section in the file.\n";
1313    return;
1314  }
1315
1316  MipsGOTParser<ELFT>(Obj, W).parseGOT(*GotShdr);
1317}
1318
1319static const EnumEntry<unsigned> ElfMipsISAExtType[] = {
1320  {"None",                    Mips::AFL_EXT_NONE},
1321  {"Broadcom SB-1",           Mips::AFL_EXT_SB1},
1322  {"Cavium Networks Octeon",  Mips::AFL_EXT_OCTEON},
1323  {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2},
1324  {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP},
1325  {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3},
1326  {"LSI R4010",               Mips::AFL_EXT_4010},
1327  {"Loongson 2E",             Mips::AFL_EXT_LOONGSON_2E},
1328  {"Loongson 2F",             Mips::AFL_EXT_LOONGSON_2F},
1329  {"Loongson 3A",             Mips::AFL_EXT_LOONGSON_3A},
1330  {"MIPS R4650",              Mips::AFL_EXT_4650},
1331  {"MIPS R5900",              Mips::AFL_EXT_5900},
1332  {"MIPS R10000",             Mips::AFL_EXT_10000},
1333  {"NEC VR4100",              Mips::AFL_EXT_4100},
1334  {"NEC VR4111/VR4181",       Mips::AFL_EXT_4111},
1335  {"NEC VR4120",              Mips::AFL_EXT_4120},
1336  {"NEC VR5400",              Mips::AFL_EXT_5400},
1337  {"NEC VR5500",              Mips::AFL_EXT_5500},
1338  {"RMI Xlr",                 Mips::AFL_EXT_XLR},
1339  {"Toshiba R3900",           Mips::AFL_EXT_3900}
1340};
1341
1342static const EnumEntry<unsigned> ElfMipsASEFlags[] = {
1343  {"DSP",                Mips::AFL_ASE_DSP},
1344  {"DSPR2",              Mips::AFL_ASE_DSPR2},
1345  {"Enhanced VA Scheme", Mips::AFL_ASE_EVA},
1346  {"MCU",                Mips::AFL_ASE_MCU},
1347  {"MDMX",               Mips::AFL_ASE_MDMX},
1348  {"MIPS-3D",            Mips::AFL_ASE_MIPS3D},
1349  {"MT",                 Mips::AFL_ASE_MT},
1350  {"SmartMIPS",          Mips::AFL_ASE_SMARTMIPS},
1351  {"VZ",                 Mips::AFL_ASE_VIRT},
1352  {"MSA",                Mips::AFL_ASE_MSA},
1353  {"MIPS16",             Mips::AFL_ASE_MIPS16},
1354  {"microMIPS",          Mips::AFL_ASE_MICROMIPS},
1355  {"XPA",                Mips::AFL_ASE_XPA}
1356};
1357
1358static const EnumEntry<unsigned> ElfMipsFpABIType[] = {
1359  {"Hard or soft float",                  Mips::Val_GNU_MIPS_ABI_FP_ANY},
1360  {"Hard float (double precision)",       Mips::Val_GNU_MIPS_ABI_FP_DOUBLE},
1361  {"Hard float (single precision)",       Mips::Val_GNU_MIPS_ABI_FP_SINGLE},
1362  {"Soft float",                          Mips::Val_GNU_MIPS_ABI_FP_SOFT},
1363  {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)",
1364   Mips::Val_GNU_MIPS_ABI_FP_OLD_64},
1365  {"Hard float (32-bit CPU, Any FPU)",    Mips::Val_GNU_MIPS_ABI_FP_XX},
1366  {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64},
1367  {"Hard float compat (32-bit CPU, 64-bit FPU)",
1368   Mips::Val_GNU_MIPS_ABI_FP_64A}
1369};
1370
1371static const EnumEntry<unsigned> ElfMipsFlags1[] {
1372  {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG},
1373};
1374
1375static int getMipsRegisterSize(uint8_t Flag) {
1376  switch (Flag) {
1377  case Mips::AFL_REG_NONE:
1378    return 0;
1379  case Mips::AFL_REG_32:
1380    return 32;
1381  case Mips::AFL_REG_64:
1382    return 64;
1383  case Mips::AFL_REG_128:
1384    return 128;
1385  default:
1386    return -1;
1387  }
1388}
1389
1390template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() {
1391  const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.abiflags");
1392  if (!Shdr) {
1393    W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
1394    return;
1395  }
1396  ErrorOr<ArrayRef<uint8_t>> Sec = Obj->getSectionContents(Shdr);
1397  if (!Sec) {
1398    W.startLine() << "The .MIPS.abiflags section is empty.\n";
1399    return;
1400  }
1401  if (Sec->size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) {
1402    W.startLine() << "The .MIPS.abiflags section has a wrong size.\n";
1403    return;
1404  }
1405
1406  auto *Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(Sec->data());
1407
1408  raw_ostream &OS = W.getOStream();
1409  DictScope GS(W, "MIPS ABI Flags");
1410
1411  W.printNumber("Version", Flags->version);
1412  W.startLine() << "ISA: ";
1413  if (Flags->isa_rev <= 1)
1414    OS << format("MIPS%u", Flags->isa_level);
1415  else
1416    OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev);
1417  OS << "\n";
1418  W.printEnum("ISA Extension", Flags->isa_ext, makeArrayRef(ElfMipsISAExtType));
1419  W.printFlags("ASEs", Flags->ases, makeArrayRef(ElfMipsASEFlags));
1420  W.printEnum("FP ABI", Flags->fp_abi, makeArrayRef(ElfMipsFpABIType));
1421  W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size));
1422  W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size));
1423  W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size));
1424  W.printFlags("Flags 1", Flags->flags1, makeArrayRef(ElfMipsFlags1));
1425  W.printHex("Flags 2", Flags->flags2);
1426}
1427