1249259Sdim//===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim///
10249259Sdim/// \file
11249259Sdim/// \brief This file implements the ELF-specific dumper for llvm-readobj.
12249259Sdim///
13249259Sdim//===----------------------------------------------------------------------===//
14249259Sdim
15249259Sdim#include "llvm-readobj.h"
16249259Sdim#include "Error.h"
17249259Sdim#include "ObjDumper.h"
18249259Sdim#include "StreamWriter.h"
19249259Sdim
20249259Sdim#include "llvm/ADT/SmallString.h"
21263509Sdim#include "llvm/Object/ELFObjectFile.h"
22249259Sdim#include "llvm/Support/Compiler.h"
23249259Sdim#include "llvm/Support/Format.h"
24249259Sdim#include "llvm/Support/MathExtras.h"
25249259Sdim#include "llvm/Support/raw_ostream.h"
26249259Sdim
27249259Sdimusing namespace llvm;
28249259Sdimusing namespace llvm::object;
29249259Sdimusing namespace ELF;
30249259Sdim
31249259Sdim#define LLVM_READOBJ_ENUM_CASE(ns, enum) \
32249259Sdim  case ns::enum: return #enum;
33249259Sdim
34249259Sdimnamespace {
35249259Sdim
36249259Sdimtemplate<typename ELFT>
37249259Sdimclass ELFDumper : public ObjDumper {
38249259Sdimpublic:
39263509Sdim  ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer)
40263509Sdim      : ObjDumper(Writer), Obj(Obj) {}
41249259Sdim
42249259Sdim  virtual void printFileHeaders() LLVM_OVERRIDE;
43249259Sdim  virtual void printSections() LLVM_OVERRIDE;
44249259Sdim  virtual void printRelocations() LLVM_OVERRIDE;
45249259Sdim  virtual void printSymbols() LLVM_OVERRIDE;
46249259Sdim  virtual void printDynamicSymbols() LLVM_OVERRIDE;
47249259Sdim  virtual void printUnwindInfo() LLVM_OVERRIDE;
48249259Sdim
49249259Sdim  virtual void printDynamicTable() LLVM_OVERRIDE;
50249259Sdim  virtual void printNeededLibraries() LLVM_OVERRIDE;
51252723Sdim  virtual void printProgramHeaders() LLVM_OVERRIDE;
52249259Sdim
53249259Sdimprivate:
54263509Sdim  typedef ELFFile<ELFT> ELFO;
55252723Sdim  typedef typename ELFO::Elf_Shdr Elf_Shdr;
56252723Sdim  typedef typename ELFO::Elf_Sym Elf_Sym;
57249259Sdim
58263509Sdim  void printSymbol(typename ELFO::Elf_Sym_Iter Symbol);
59249259Sdim
60263509Sdim  void printRelocations(const Elf_Shdr *Sec);
61263509Sdim  void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel);
62249259Sdim
63252723Sdim  const ELFO *Obj;
64249259Sdim};
65249259Sdim
66263509Sdimtemplate <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) {
67263509Sdim  if (!Val) {
68263509Sdim    error(Val);
69263509Sdim    return Default;
70263509Sdim  }
71263509Sdim
72263509Sdim  return *Val;
73263509Sdim}
74249259Sdim} // namespace
75249259Sdim
76249259Sdimnamespace llvm {
77249259Sdim
78263509Sdimtemplate <class ELFT>
79263509Sdimstatic error_code createELFDumper(const ELFFile<ELFT> *Obj,
80263509Sdim                                  StreamWriter &Writer,
81263509Sdim                                  OwningPtr<ObjDumper> &Result) {
82263509Sdim  Result.reset(new ELFDumper<ELFT>(Obj, Writer));
83263509Sdim  return readobj_error::success;
84263509Sdim}
85263509Sdim
86249259Sdimerror_code createELFDumper(const object::ObjectFile *Obj,
87249259Sdim                           StreamWriter& Writer,
88249259Sdim                           OwningPtr<ObjDumper> &Result) {
89249259Sdim  // Little-endian 32-bit
90263509Sdim  if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
91263509Sdim    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
92249259Sdim
93249259Sdim  // Big-endian 32-bit
94263509Sdim  if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
95263509Sdim    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
96249259Sdim
97249259Sdim  // Little-endian 64-bit
98263509Sdim  if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
99263509Sdim    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
100249259Sdim
101249259Sdim  // Big-endian 64-bit
102263509Sdim  if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
103263509Sdim    return createELFDumper(ELFObj->getELFFile(), Writer, Result);
104249259Sdim
105249259Sdim  return readobj_error::unsupported_obj_file_format;
106249259Sdim}
107249259Sdim
108249259Sdim} // namespace llvm
109249259Sdim
110249259Sdimstatic const EnumEntry<unsigned> ElfClass[] = {
111249259Sdim  { "None",   ELF::ELFCLASSNONE },
112249259Sdim  { "32-bit", ELF::ELFCLASS32   },
113249259Sdim  { "64-bit", ELF::ELFCLASS64   },
114249259Sdim};
115249259Sdim
116249259Sdimstatic const EnumEntry<unsigned> ElfDataEncoding[] = {
117249259Sdim  { "None",         ELF::ELFDATANONE },
118249259Sdim  { "LittleEndian", ELF::ELFDATA2LSB },
119249259Sdim  { "BigEndian",    ELF::ELFDATA2MSB },
120249259Sdim};
121249259Sdim
122249259Sdimstatic const EnumEntry<unsigned> ElfObjectFileType[] = {
123249259Sdim  { "None",         ELF::ET_NONE },
124249259Sdim  { "Relocatable",  ELF::ET_REL  },
125249259Sdim  { "Executable",   ELF::ET_EXEC },
126249259Sdim  { "SharedObject", ELF::ET_DYN  },
127249259Sdim  { "Core",         ELF::ET_CORE },
128249259Sdim};
129249259Sdim
130249259Sdimstatic const EnumEntry<unsigned> ElfOSABI[] = {
131249259Sdim  { "SystemV",      ELF::ELFOSABI_NONE         },
132249259Sdim  { "HPUX",         ELF::ELFOSABI_HPUX         },
133249259Sdim  { "NetBSD",       ELF::ELFOSABI_NETBSD       },
134249259Sdim  { "GNU/Linux",    ELF::ELFOSABI_LINUX        },
135249259Sdim  { "GNU/Hurd",     ELF::ELFOSABI_HURD         },
136249259Sdim  { "Solaris",      ELF::ELFOSABI_SOLARIS      },
137249259Sdim  { "AIX",          ELF::ELFOSABI_AIX          },
138249259Sdim  { "IRIX",         ELF::ELFOSABI_IRIX         },
139249259Sdim  { "FreeBSD",      ELF::ELFOSABI_FREEBSD      },
140249259Sdim  { "TRU64",        ELF::ELFOSABI_TRU64        },
141249259Sdim  { "Modesto",      ELF::ELFOSABI_MODESTO      },
142249259Sdim  { "OpenBSD",      ELF::ELFOSABI_OPENBSD      },
143249259Sdim  { "OpenVMS",      ELF::ELFOSABI_OPENVMS      },
144249259Sdim  { "NSK",          ELF::ELFOSABI_NSK          },
145249259Sdim  { "AROS",         ELF::ELFOSABI_AROS         },
146249259Sdim  { "FenixOS",      ELF::ELFOSABI_FENIXOS      },
147249259Sdim  { "C6000_ELFABI", ELF::ELFOSABI_C6000_ELFABI },
148249259Sdim  { "C6000_LINUX" , ELF::ELFOSABI_C6000_LINUX  },
149249259Sdim  { "ARM",          ELF::ELFOSABI_ARM          },
150249259Sdim  { "Standalone"  , ELF::ELFOSABI_STANDALONE   }
151249259Sdim};
152249259Sdim
153249259Sdimstatic const EnumEntry<unsigned> ElfMachineType[] = {
154249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_NONE         ),
155249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_M32          ),
156249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC        ),
157249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_386          ),
158249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_68K          ),
159249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_88K          ),
160249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_486          ),
161249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_860          ),
162249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS         ),
163249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_S370         ),
164249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_RS3_LE  ),
165249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_PARISC       ),
166249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_VPP500       ),
167249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC32PLUS  ),
168249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_960          ),
169249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC          ),
170249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC64        ),
171249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_S390         ),
172249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPU          ),
173249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_V800         ),
174249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_FR20         ),
175249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_RH32         ),
176249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_RCE          ),
177249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARM          ),
178249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ALPHA        ),
179249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SH           ),
180249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARCV9      ),
181249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TRICORE      ),
182249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC          ),
183249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300       ),
184249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300H      ),
185249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8S          ),
186249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_500       ),
187249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_IA_64        ),
188249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_X       ),
189249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_COLDFIRE     ),
190249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC12       ),
191249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MMA          ),
192249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_PCP          ),
193249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_NCPU         ),
194249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_NDR1         ),
195249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_STARCORE     ),
196249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ME16         ),
197249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST100        ),
198249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TINYJ        ),
199249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_X86_64       ),
200249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_PDSP         ),
201249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP10        ),
202249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP11        ),
203249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_FX66         ),
204249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST9PLUS      ),
205249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST7          ),
206249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC16       ),
207249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC11       ),
208249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC08       ),
209249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC05       ),
210249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SVX          ),
211249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST19         ),
212249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_VAX          ),
213249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_CRIS         ),
214249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_JAVELIN      ),
215249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_FIREPATH     ),
216249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ZSP          ),
217249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MMIX         ),
218249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_HUANY        ),
219249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_PRISM        ),
220249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR          ),
221249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_FR30         ),
222249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_D10V         ),
223249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_D30V         ),
224249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_V850         ),
225249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_M32R         ),
226249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10300      ),
227249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10200      ),
228249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_PJ           ),
229249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_OPENRISC     ),
230249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT  ),
231249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_XTENSA       ),
232249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE    ),
233249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TMM_GPP      ),
234249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_NS32K        ),
235249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TPC          ),
236249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SNP1K        ),
237249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ST200        ),
238249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_IP2K         ),
239249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MAX          ),
240249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_CR           ),
241249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_F2MC16       ),
242249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MSP430       ),
243249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_BLACKFIN     ),
244249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C33       ),
245249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SEP          ),
246249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARCA         ),
247249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_UNICORE      ),
248249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_EXCESS       ),
249249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_DXP          ),
250249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ALTERA_NIOS2 ),
251249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_CRX          ),
252249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_XGATE        ),
253249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_C166         ),
254249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_M16C         ),
255249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_DSPIC30F     ),
256249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_CE           ),
257249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_M32C         ),
258249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TSK3000      ),
259249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_RS08         ),
260249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SHARC        ),
261249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG2        ),
262249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SCORE7       ),
263249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_DSP24        ),
264249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE3   ),
265249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_LATTICEMICO32),
266249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C17       ),
267249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C6000     ),
268249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C2000     ),
269249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C5500     ),
270249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MMDSP_PLUS   ),
271249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_CYPRESS_M8C  ),
272249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_R32C         ),
273249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TRIMEDIA     ),
274249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_HEXAGON      ),
275249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_8051         ),
276249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_STXP7X       ),
277249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_NDS32        ),
278249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1        ),
279249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1X       ),
280249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MAXQ30       ),
281249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_XIMO16       ),
282249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MANIK        ),
283249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_CRAYNV2      ),
284249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_RX           ),
285249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_METAG        ),
286249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_MCST_ELBRUS  ),
287249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG16       ),
288249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_CR16         ),
289249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ETPU         ),
290249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_SLE9X        ),
291249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_L10M         ),
292249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_K10M         ),
293249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_AARCH64      ),
294249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR32        ),
295249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_STM8         ),
296249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TILE64       ),
297249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEPRO      ),
298249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_CUDA         ),
299249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEGX       ),
300249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_CLOUDSHIELD  ),
301249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_1ST    ),
302249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_2ND    ),
303249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT2 ),
304249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_OPEN8        ),
305249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78         ),
306249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5   ),
307249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR        ),
308263509Sdim  LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX      )
309249259Sdim};
310249259Sdim
311249259Sdimstatic const EnumEntry<unsigned> ElfSymbolBindings[] = {
312249259Sdim  { "Local",  ELF::STB_LOCAL  },
313249259Sdim  { "Global", ELF::STB_GLOBAL },
314249259Sdim  { "Weak",   ELF::STB_WEAK   }
315249259Sdim};
316249259Sdim
317249259Sdimstatic const EnumEntry<unsigned> ElfSymbolTypes[] = {
318249259Sdim  { "None",      ELF::STT_NOTYPE    },
319249259Sdim  { "Object",    ELF::STT_OBJECT    },
320249259Sdim  { "Function",  ELF::STT_FUNC      },
321249259Sdim  { "Section",   ELF::STT_SECTION   },
322249259Sdim  { "File",      ELF::STT_FILE      },
323249259Sdim  { "Common",    ELF::STT_COMMON    },
324249259Sdim  { "TLS",       ELF::STT_TLS       },
325249259Sdim  { "GNU_IFunc", ELF::STT_GNU_IFUNC }
326249259Sdim};
327249259Sdim
328249259Sdimstatic const char *getElfSectionType(unsigned Arch, unsigned Type) {
329249259Sdim  switch (Arch) {
330263509Sdim  case ELF::EM_ARM:
331249259Sdim    switch (Type) {
332249259Sdim    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX);
333249259Sdim    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
334249259Sdim    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
335249259Sdim    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
336249259Sdim    LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
337249259Sdim    }
338263509Sdim  case ELF::EM_HEXAGON:
339263509Sdim    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
340263509Sdim  case ELF::EM_X86_64:
341263509Sdim    switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
342263509Sdim  case ELF::EM_MIPS:
343263509Sdim  case ELF::EM_MIPS_RS3_LE:
344249259Sdim    switch (Type) {
345249259Sdim    LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
346249259Sdim    LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
347249259Sdim    }
348249259Sdim  }
349249259Sdim
350249259Sdim  switch (Type) {
351249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL              );
352249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS          );
353249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB            );
354249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB            );
355249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA              );
356249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH              );
357249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC           );
358249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE              );
359249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS            );
360249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL               );
361249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB             );
362249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM            );
363249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY        );
364249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY        );
365249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY     );
366249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP             );
367249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX      );
368249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES    );
369249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH          );
370249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef        );
371249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed       );
372249259Sdim  LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym        );
373249259Sdim  default: return "";
374249259Sdim  }
375249259Sdim}
376249259Sdim
377249259Sdimstatic const EnumEntry<unsigned> ElfSectionFlags[] = {
378249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE           ),
379249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC           ),
380263509Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXCLUDE         ),
381249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR       ),
382249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE           ),
383249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS         ),
384249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_INFO_LINK       ),
385249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_LINK_ORDER      ),
386249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_OS_NONCONFORMING),
387249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_GROUP           ),
388249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS             ),
389249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION),
390249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION),
391249259Sdim  LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP    )
392249259Sdim};
393249259Sdim
394263509Sdimstatic const char *getElfSegmentType(unsigned Arch, unsigned Type) {
395263509Sdim  // Check potentially overlapped processor-specific
396263509Sdim  // program header type.
397263509Sdim  switch (Arch) {
398263509Sdim  case ELF::EM_ARM:
399263509Sdim    switch (Type) {
400263509Sdim    LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX);
401263509Sdim    }
402263509Sdim  case ELF::EM_MIPS:
403263509Sdim  case ELF::EM_MIPS_RS3_LE:
404263509Sdim    switch (Type) {
405263509Sdim    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
406263509Sdim    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
407263509Sdim    LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
408263509Sdim    }
409263509Sdim  }
410249259Sdim
411263509Sdim  switch (Type) {
412263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL   );
413263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD   );
414263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
415263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP );
416263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE   );
417263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB  );
418263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR   );
419263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS    );
420252723Sdim
421263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
422263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
423252723Sdim
424263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
425263509Sdim  LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
426263509Sdim  default: return "";
427263509Sdim  }
428263509Sdim}
429252723Sdim
430252723Sdimstatic const EnumEntry<unsigned> ElfSegmentFlags[] = {
431252723Sdim  LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
432252723Sdim  LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
433252723Sdim  LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
434252723Sdim};
435252723Sdim
436249259Sdimtemplate<class ELFT>
437249259Sdimvoid ELFDumper<ELFT>::printFileHeaders() {
438263509Sdim  const typename ELFO::Elf_Ehdr *Header = Obj->getHeader();
439249259Sdim
440249259Sdim  {
441249259Sdim    DictScope D(W, "ElfHeader");
442249259Sdim    {
443249259Sdim      DictScope D(W, "Ident");
444249259Sdim      W.printBinary("Magic", makeArrayRef(Header->e_ident).slice(ELF::EI_MAG0,
445249259Sdim                                                                 4));
446249259Sdim      W.printEnum  ("Class", Header->e_ident[ELF::EI_CLASS],
447249259Sdim                      makeArrayRef(ElfClass));
448249259Sdim      W.printEnum  ("DataEncoding", Header->e_ident[ELF::EI_DATA],
449249259Sdim                      makeArrayRef(ElfDataEncoding));
450249259Sdim      W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]);
451249259Sdim      W.printEnum  ("OS/ABI", Header->e_ident[ELF::EI_OSABI],
452249259Sdim                      makeArrayRef(ElfOSABI));
453249259Sdim      W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]);
454249259Sdim      W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD));
455249259Sdim    }
456249259Sdim
457249259Sdim    W.printEnum  ("Type", Header->e_type, makeArrayRef(ElfObjectFileType));
458249259Sdim    W.printEnum  ("Machine", Header->e_machine, makeArrayRef(ElfMachineType));
459249259Sdim    W.printNumber("Version", Header->e_version);
460249259Sdim    W.printHex   ("Entry", Header->e_entry);
461249259Sdim    W.printHex   ("ProgramHeaderOffset", Header->e_phoff);
462249259Sdim    W.printHex   ("SectionHeaderOffset", Header->e_shoff);
463249259Sdim    W.printFlags ("Flags", Header->e_flags);
464249259Sdim    W.printNumber("HeaderSize", Header->e_ehsize);
465249259Sdim    W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize);
466249259Sdim    W.printNumber("ProgramHeaderCount", Header->e_phnum);
467249259Sdim    W.printNumber("SectionHeaderEntrySize", Header->e_shentsize);
468249259Sdim    W.printNumber("SectionHeaderCount", Header->e_shnum);
469249259Sdim    W.printNumber("StringTableSectionIndex", Header->e_shstrndx);
470249259Sdim  }
471249259Sdim}
472249259Sdim
473249259Sdimtemplate<class ELFT>
474249259Sdimvoid ELFDumper<ELFT>::printSections() {
475249259Sdim  ListScope SectionsD(W, "Sections");
476249259Sdim
477249259Sdim  int SectionIndex = -1;
478263509Sdim  for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(),
479263509Sdim                                    SecE = Obj->end_sections();
480263509Sdim       SecI != SecE; ++SecI) {
481249259Sdim    ++SectionIndex;
482249259Sdim
483263509Sdim    const Elf_Shdr *Section = &*SecI;
484263509Sdim    StringRef Name = errorOrDefault(Obj->getSectionName(Section));
485249259Sdim
486249259Sdim    DictScope SectionD(W, "Section");
487249259Sdim    W.printNumber("Index", SectionIndex);
488249259Sdim    W.printNumber("Name", Name, Section->sh_name);
489263509Sdim    W.printHex("Type",
490263509Sdim               getElfSectionType(Obj->getHeader()->e_machine, Section->sh_type),
491263509Sdim               Section->sh_type);
492249259Sdim    W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags));
493249259Sdim    W.printHex   ("Address", Section->sh_addr);
494249259Sdim    W.printHex   ("Offset", Section->sh_offset);
495249259Sdim    W.printNumber("Size", Section->sh_size);
496249259Sdim    W.printNumber("Link", Section->sh_link);
497249259Sdim    W.printNumber("Info", Section->sh_info);
498249259Sdim    W.printNumber("AddressAlignment", Section->sh_addralign);
499249259Sdim    W.printNumber("EntrySize", Section->sh_entsize);
500249259Sdim
501249259Sdim    if (opts::SectionRelocations) {
502249259Sdim      ListScope D(W, "Relocations");
503263509Sdim      printRelocations(Section);
504249259Sdim    }
505249259Sdim
506249259Sdim    if (opts::SectionSymbols) {
507249259Sdim      ListScope D(W, "Symbols");
508263509Sdim      for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(),
509263509Sdim                                       SymE = Obj->end_symbols();
510263509Sdim           SymI != SymE; ++SymI) {
511263509Sdim        if (Obj->getSection(&*SymI) == Section)
512263509Sdim          printSymbol(SymI);
513249259Sdim      }
514249259Sdim    }
515249259Sdim
516249259Sdim    if (opts::SectionData) {
517263509Sdim      ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(Section));
518263509Sdim      W.printBinaryBlock("SectionData",
519263509Sdim                         StringRef((const char *)Data.data(), Data.size()));
520249259Sdim    }
521249259Sdim  }
522249259Sdim}
523249259Sdim
524249259Sdimtemplate<class ELFT>
525249259Sdimvoid ELFDumper<ELFT>::printRelocations() {
526249259Sdim  ListScope D(W, "Relocations");
527249259Sdim
528249259Sdim  int SectionNumber = -1;
529263509Sdim  for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(),
530263509Sdim                                    SecE = Obj->end_sections();
531263509Sdim       SecI != SecE; ++SecI) {
532263509Sdim    ++SectionNumber;
533249259Sdim
534263509Sdim    if (SecI->sh_type != ELF::SHT_REL && SecI->sh_type != ELF::SHT_RELA)
535249259Sdim      continue;
536249259Sdim
537263509Sdim    StringRef Name = errorOrDefault(Obj->getSectionName(&*SecI));
538249259Sdim
539263509Sdim    W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
540263509Sdim    W.indent();
541249259Sdim
542263509Sdim    printRelocations(&*SecI);
543249259Sdim
544263509Sdim    W.unindent();
545263509Sdim    W.startLine() << "}\n";
546263509Sdim  }
547263509Sdim}
548263509Sdim
549263509Sdimtemplate <class ELFT>
550263509Sdimvoid ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) {
551263509Sdim  switch (Sec->sh_type) {
552263509Sdim  case ELF::SHT_REL:
553263509Sdim    for (typename ELFO::Elf_Rel_Iter RI = Obj->begin_rel(Sec),
554263509Sdim                                     RE = Obj->end_rel(Sec);
555263509Sdim         RI != RE; ++RI) {
556263509Sdim      typename ELFO::Elf_Rela Rela;
557263509Sdim      Rela.r_offset = RI->r_offset;
558263509Sdim      Rela.r_info = RI->r_info;
559263509Sdim      Rela.r_addend = 0;
560263509Sdim      printRelocation(Sec, Rela);
561249259Sdim    }
562263509Sdim    break;
563263509Sdim  case ELF::SHT_RELA:
564263509Sdim    for (typename ELFO::Elf_Rela_Iter RI = Obj->begin_rela(Sec),
565263509Sdim                                      RE = Obj->end_rela(Sec);
566263509Sdim         RI != RE; ++RI) {
567263509Sdim      printRelocation(Sec, *RI);
568263509Sdim    }
569263509Sdim    break;
570249259Sdim  }
571249259Sdim}
572249259Sdim
573263509Sdimtemplate <class ELFT>
574263509Sdimvoid ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec,
575263509Sdim                                      typename ELFO::Elf_Rela Rel) {
576249259Sdim  SmallString<32> RelocName;
577263509Sdim  Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
578249259Sdim  StringRef SymbolName;
579263509Sdim  std::pair<const Elf_Shdr *, const Elf_Sym *> Sym =
580263509Sdim      Obj->getRelocationSymbol(Sec, &Rel);
581263509Sdim  if (Sym.first)
582263509Sdim    SymbolName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second));
583249259Sdim
584252723Sdim  if (opts::ExpandRelocs) {
585252723Sdim    DictScope Group(W, "Relocation");
586263509Sdim    W.printHex("Offset", Rel.r_offset);
587263509Sdim    W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
588252723Sdim    W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
589263509Sdim    W.printHex("Addend", Rel.r_addend);
590252723Sdim  } else {
591252723Sdim    raw_ostream& OS = W.startLine();
592263509Sdim    OS << W.hex(Rel.r_offset)
593252723Sdim       << " " << RelocName
594252723Sdim       << " " << (SymbolName.size() > 0 ? SymbolName : "-")
595263509Sdim       << " " << W.hex(Rel.r_addend)
596252723Sdim       << "\n";
597252723Sdim  }
598249259Sdim}
599249259Sdim
600249259Sdimtemplate<class ELFT>
601249259Sdimvoid ELFDumper<ELFT>::printSymbols() {
602249259Sdim  ListScope Group(W, "Symbols");
603263509Sdim  for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(),
604263509Sdim                                   SymE = Obj->end_symbols();
605263509Sdim       SymI != SymE; ++SymI) {
606249259Sdim    printSymbol(SymI);
607249259Sdim  }
608249259Sdim}
609249259Sdim
610249259Sdimtemplate<class ELFT>
611249259Sdimvoid ELFDumper<ELFT>::printDynamicSymbols() {
612249259Sdim  ListScope Group(W, "DynamicSymbols");
613249259Sdim
614263509Sdim  for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(),
615263509Sdim                                   SymE = Obj->end_dynamic_symbols();
616263509Sdim       SymI != SymE; ++SymI) {
617263509Sdim    printSymbol(SymI);
618249259Sdim  }
619249259Sdim}
620249259Sdim
621263509Sdimtemplate <class ELFT>
622263509Sdimvoid ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) {
623263509Sdim  StringRef SymbolName = errorOrDefault(Obj->getSymbolName(Symbol));
624263509Sdim  const Elf_Shdr *Sec = Obj->getSection(&*Symbol);
625263509Sdim  StringRef SectionName = Sec ? errorOrDefault(Obj->getSectionName(Sec)) : "";
626249259Sdim  std::string FullSymbolName(SymbolName);
627263509Sdim  if (Symbol.isDynamic()) {
628249259Sdim    bool IsDefault;
629263509Sdim    ErrorOr<StringRef> Version = Obj->getSymbolVersion(0, &*Symbol, IsDefault);
630263509Sdim    if (Version) {
631249259Sdim      FullSymbolName += (IsDefault ? "@@" : "@");
632263509Sdim      FullSymbolName += *Version;
633263509Sdim    } else
634263509Sdim      error(Version);
635249259Sdim  }
636249259Sdim
637249259Sdim  DictScope D(W, "Symbol");
638249259Sdim  W.printNumber("Name", FullSymbolName, Symbol->st_name);
639249259Sdim  W.printHex   ("Value", Symbol->st_value);
640249259Sdim  W.printNumber("Size", Symbol->st_size);
641249259Sdim  W.printEnum  ("Binding", Symbol->getBinding(),
642249259Sdim                  makeArrayRef(ElfSymbolBindings));
643249259Sdim  W.printEnum  ("Type", Symbol->getType(), makeArrayRef(ElfSymbolTypes));
644249259Sdim  W.printNumber("Other", Symbol->st_other);
645249259Sdim  W.printHex   ("Section", SectionName, Symbol->st_shndx);
646249259Sdim}
647249259Sdim
648249259Sdim#define LLVM_READOBJ_TYPE_CASE(name) \
649249259Sdim  case DT_##name: return #name
650249259Sdim
651249259Sdimstatic const char *getTypeString(uint64_t Type) {
652249259Sdim  switch (Type) {
653249259Sdim  LLVM_READOBJ_TYPE_CASE(BIND_NOW);
654249259Sdim  LLVM_READOBJ_TYPE_CASE(DEBUG);
655249259Sdim  LLVM_READOBJ_TYPE_CASE(FINI);
656249259Sdim  LLVM_READOBJ_TYPE_CASE(FINI_ARRAY);
657249259Sdim  LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ);
658249259Sdim  LLVM_READOBJ_TYPE_CASE(FLAGS);
659249259Sdim  LLVM_READOBJ_TYPE_CASE(HASH);
660249259Sdim  LLVM_READOBJ_TYPE_CASE(INIT);
661249259Sdim  LLVM_READOBJ_TYPE_CASE(INIT_ARRAY);
662249259Sdim  LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ);
663249259Sdim  LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY);
664249259Sdim  LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ);
665249259Sdim  LLVM_READOBJ_TYPE_CASE(JMPREL);
666249259Sdim  LLVM_READOBJ_TYPE_CASE(NEEDED);
667249259Sdim  LLVM_READOBJ_TYPE_CASE(NULL);
668249259Sdim  LLVM_READOBJ_TYPE_CASE(PLTGOT);
669249259Sdim  LLVM_READOBJ_TYPE_CASE(PLTREL);
670249259Sdim  LLVM_READOBJ_TYPE_CASE(PLTRELSZ);
671249259Sdim  LLVM_READOBJ_TYPE_CASE(REL);
672249259Sdim  LLVM_READOBJ_TYPE_CASE(RELA);
673249259Sdim  LLVM_READOBJ_TYPE_CASE(RELENT);
674249259Sdim  LLVM_READOBJ_TYPE_CASE(RELSZ);
675249259Sdim  LLVM_READOBJ_TYPE_CASE(RELAENT);
676249259Sdim  LLVM_READOBJ_TYPE_CASE(RELASZ);
677249259Sdim  LLVM_READOBJ_TYPE_CASE(RPATH);
678249259Sdim  LLVM_READOBJ_TYPE_CASE(RUNPATH);
679249259Sdim  LLVM_READOBJ_TYPE_CASE(SONAME);
680249259Sdim  LLVM_READOBJ_TYPE_CASE(STRSZ);
681249259Sdim  LLVM_READOBJ_TYPE_CASE(STRTAB);
682249259Sdim  LLVM_READOBJ_TYPE_CASE(SYMBOLIC);
683249259Sdim  LLVM_READOBJ_TYPE_CASE(SYMENT);
684249259Sdim  LLVM_READOBJ_TYPE_CASE(SYMTAB);
685249259Sdim  LLVM_READOBJ_TYPE_CASE(TEXTREL);
686263509Sdim  LLVM_READOBJ_TYPE_CASE(VERNEED);
687263509Sdim  LLVM_READOBJ_TYPE_CASE(VERNEEDNUM);
688263509Sdim  LLVM_READOBJ_TYPE_CASE(VERSYM);
689263509Sdim  LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION);
690263509Sdim  LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS);
691263509Sdim  LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS);
692263509Sdim  LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO);
693263509Sdim  LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO);
694263509Sdim  LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO);
695263509Sdim  LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM);
696249259Sdim  default: return "unknown";
697249259Sdim  }
698249259Sdim}
699249259Sdim
700249259Sdim#undef LLVM_READOBJ_TYPE_CASE
701249259Sdim
702263509Sdimtemplate <class ELFT>
703263509Sdimstatic void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value,
704263509Sdim                       bool Is64, raw_ostream &OS) {
705249259Sdim  switch (Type) {
706249259Sdim  case DT_PLTREL:
707249259Sdim    if (Value == DT_REL) {
708249259Sdim      OS << "REL";
709249259Sdim      break;
710249259Sdim    } else if (Value == DT_RELA) {
711249259Sdim      OS << "RELA";
712249259Sdim      break;
713249259Sdim    }
714249259Sdim  // Fallthrough.
715249259Sdim  case DT_PLTGOT:
716249259Sdim  case DT_HASH:
717249259Sdim  case DT_STRTAB:
718249259Sdim  case DT_SYMTAB:
719249259Sdim  case DT_RELA:
720249259Sdim  case DT_INIT:
721249259Sdim  case DT_FINI:
722249259Sdim  case DT_REL:
723249259Sdim  case DT_JMPREL:
724249259Sdim  case DT_INIT_ARRAY:
725249259Sdim  case DT_FINI_ARRAY:
726249259Sdim  case DT_PREINIT_ARRAY:
727249259Sdim  case DT_DEBUG:
728263509Sdim  case DT_VERNEED:
729263509Sdim  case DT_VERSYM:
730249259Sdim  case DT_NULL:
731263509Sdim  case DT_MIPS_FLAGS:
732263509Sdim  case DT_MIPS_BASE_ADDRESS:
733263509Sdim  case DT_MIPS_GOTSYM:
734249259Sdim    OS << format("0x%" PRIX64, Value);
735249259Sdim    break;
736263509Sdim  case DT_VERNEEDNUM:
737263509Sdim  case DT_MIPS_RLD_VERSION:
738263509Sdim  case DT_MIPS_LOCAL_GOTNO:
739263509Sdim  case DT_MIPS_SYMTABNO:
740263509Sdim  case DT_MIPS_UNREFEXTNO:
741263509Sdim    OS << Value;
742263509Sdim    break;
743249259Sdim  case DT_PLTRELSZ:
744249259Sdim  case DT_RELASZ:
745249259Sdim  case DT_RELAENT:
746249259Sdim  case DT_STRSZ:
747249259Sdim  case DT_SYMENT:
748249259Sdim  case DT_RELSZ:
749249259Sdim  case DT_RELENT:
750249259Sdim  case DT_INIT_ARRAYSZ:
751249259Sdim  case DT_FINI_ARRAYSZ:
752249259Sdim  case DT_PREINIT_ARRAYSZ:
753249259Sdim    OS << Value << " (bytes)";
754249259Sdim    break;
755249259Sdim  case DT_NEEDED:
756263509Sdim    OS << "SharedLibrary (" << O->getDynamicString(Value) << ")";
757249259Sdim    break;
758249259Sdim  case DT_SONAME:
759263509Sdim    OS << "LibrarySoname (" << O->getDynamicString(Value) << ")";
760249259Sdim    break;
761263509Sdim  case DT_RPATH:
762263509Sdim  case DT_RUNPATH:
763263509Sdim    OS << O->getDynamicString(Value);
764263509Sdim    break;
765249259Sdim  }
766249259Sdim}
767249259Sdim
768249259Sdimtemplate<class ELFT>
769249259Sdimvoid ELFDumper<ELFT>::printUnwindInfo() {
770249259Sdim  W.startLine() << "UnwindInfo not implemented.\n";
771249259Sdim}
772249259Sdim
773249259Sdimtemplate<class ELFT>
774249259Sdimvoid ELFDumper<ELFT>::printDynamicTable() {
775263509Sdim  typedef typename ELFO::Elf_Dyn_Iter EDI;
776263509Sdim  EDI Start = Obj->begin_dynamic_table(), End = Obj->end_dynamic_table(true);
777249259Sdim
778249259Sdim  if (Start == End)
779249259Sdim    return;
780249259Sdim
781249259Sdim  ptrdiff_t Total = std::distance(Start, End);
782249259Sdim  raw_ostream &OS = W.getOStream();
783249259Sdim  W.startLine() << "DynamicSection [ (" << Total << " entries)\n";
784249259Sdim
785263509Sdim  bool Is64 = ELFT::Is64Bits;
786249259Sdim
787249259Sdim  W.startLine()
788249259Sdim     << "  Tag" << (Is64 ? "                " : "        ") << "Type"
789249259Sdim     << "                 " << "Name/Value\n";
790249259Sdim  for (; Start != End; ++Start) {
791249259Sdim    W.startLine()
792249259Sdim       << "  "
793249259Sdim       << format(Is64 ? "0x%016" PRIX64 : "0x%08" PRIX64, Start->getTag())
794249259Sdim       << " " << format("%-21s", getTypeString(Start->getTag()));
795249259Sdim    printValue(Obj, Start->getTag(), Start->getVal(), Is64, OS);
796249259Sdim    OS << "\n";
797249259Sdim  }
798249259Sdim
799249259Sdim  W.startLine() << "]\n";
800249259Sdim}
801249259Sdim
802249259Sdimtemplate<class ELFT>
803249259Sdimvoid ELFDumper<ELFT>::printNeededLibraries() {
804249259Sdim  ListScope D(W, "NeededLibraries");
805249259Sdim
806263509Sdim  typedef std::vector<StringRef> LibsTy;
807249259Sdim  LibsTy Libs;
808249259Sdim
809263509Sdim  for (typename ELFO::Elf_Dyn_Iter DynI = Obj->begin_dynamic_table(),
810263509Sdim                                   DynE = Obj->end_dynamic_table();
811263509Sdim       DynI != DynE; ++DynI)
812263509Sdim    if (DynI->d_tag == ELF::DT_NEEDED)
813263509Sdim      Libs.push_back(Obj->getDynamicString(DynI->d_un.d_val));
814249259Sdim
815263509Sdim  std::stable_sort(Libs.begin(), Libs.end());
816249259Sdim
817263509Sdim  for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); I != E; ++I) {
818263509Sdim    outs() << "  " << *I << "\n";
819249259Sdim  }
820249259Sdim}
821252723Sdim
822252723Sdimtemplate<class ELFT>
823252723Sdimvoid ELFDumper<ELFT>::printProgramHeaders() {
824252723Sdim  ListScope L(W, "ProgramHeaders");
825252723Sdim
826252723Sdim  for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(),
827252723Sdim                                    PE = Obj->end_program_headers();
828252723Sdim                                    PI != PE; ++PI) {
829252723Sdim    DictScope P(W, "ProgramHeader");
830263509Sdim    W.printHex   ("Type",
831263509Sdim                  getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type),
832263509Sdim                  PI->p_type);
833252723Sdim    W.printHex   ("Offset", PI->p_offset);
834252723Sdim    W.printHex   ("VirtualAddress", PI->p_vaddr);
835252723Sdim    W.printHex   ("PhysicalAddress", PI->p_paddr);
836252723Sdim    W.printNumber("FileSize", PI->p_filesz);
837252723Sdim    W.printNumber("MemSize", PI->p_memsz);
838252723Sdim    W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags));
839252723Sdim    W.printNumber("Alignment", PI->p_align);
840252723Sdim  }
841252723Sdim}
842