blob: ae9bce9e04fadd3f48084c8058984d40916e7a9f [file] [log] [blame]
George Rimar47936762016-01-16 00:49:19 +00001//===-- 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 "StackMapPrinter.h"
21#include "StreamWriter.h"
22#include "llvm/ADT/Optional.h"
23#include "llvm/ADT/SmallString.h"
24#include "llvm/ADT/StringExtras.h"
25#include "llvm/Object/ELFObjectFile.h"
26#include "llvm/Support/ARMBuildAttributes.h"
27#include "llvm/Support/Compiler.h"
28#include "llvm/Support/Format.h"
29#include "llvm/Support/MathExtras.h"
30#include "llvm/Support/MipsABIFlags.h"
31#include "llvm/Support/raw_ostream.h"
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +000032#include "llvm/Support/FormattedStream.h"
George Rimar47936762016-01-16 00:49:19 +000033
34using namespace llvm;
35using namespace llvm::object;
36using namespace ELF;
37
38#define LLVM_READOBJ_ENUM_CASE(ns, enum) \
39 case ns::enum: return #enum;
40
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +000041#define ENUM_ENT(enum, altName) \
42 { #enum, altName, ELF::enum }
43
44#define ENUM_ENT_1(enum) \
45 { #enum, #enum, ELF::enum }
46
Hemant Kulkarni206ba842016-03-09 19:16:13 +000047#define TYPEDEF_ELF_TYPES(ELFT) \
48 typedef ELFFile<ELFT> ELFO; \
49 typedef typename ELFO::Elf_Shdr Elf_Shdr; \
50 typedef typename ELFO::Elf_Sym Elf_Sym; \
51 typedef typename ELFO::Elf_Dyn Elf_Dyn; \
52 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range; \
53 typedef typename ELFO::Elf_Rel Elf_Rel; \
54 typedef typename ELFO::Elf_Rela Elf_Rela; \
55 typedef typename ELFO::Elf_Rela_Range Elf_Rela_Range; \
56 typedef typename ELFO::Elf_Phdr Elf_Phdr; \
57 typedef typename ELFO::Elf_Half Elf_Half; \
58 typedef typename ELFO::Elf_Ehdr Elf_Ehdr; \
59 typedef typename ELFO::Elf_Word Elf_Word; \
60 typedef typename ELFO::uintX_t uintX_t;
61
George Rimar47936762016-01-16 00:49:19 +000062namespace {
63
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +000064template <class ELFT> class DumpStyle;
65
Rafael Espindolace2fbdd2016-02-17 15:38:21 +000066/// Represents a contiguous uniform range in the file. We cannot just create a
67/// range directly because when creating one of these from the .dynamic table
68/// the size, entity size and virtual address are different entries in arbitrary
69/// order (DT_REL, DT_RELSZ, DT_RELENT for example).
Rafael Espindola65a6fd82016-02-16 14:27:33 +000070struct DynRegionInfo {
71 DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {}
Rafael Espindolace2fbdd2016-02-17 15:38:21 +000072 DynRegionInfo(const void *A, uint64_t S, uint64_t ES)
73 : Addr(A), Size(S), EntSize(ES) {}
Rafael Espindola65a6fd82016-02-16 14:27:33 +000074 /// \brief Address in current address space.
75 const void *Addr;
76 /// \brief Size in bytes of the region.
77 uint64_t Size;
78 /// \brief Size of each entity in the region.
79 uint64_t EntSize;
Rafael Espindolac70aeda2016-02-16 14:50:39 +000080
81 template <typename Type> iterator_range<const Type *> getAsRange() const {
82 const Type *Start = reinterpret_cast<const Type *>(Addr);
Rafael Espindola944f6552016-02-16 15:16:00 +000083 if (!Start)
84 return {Start, Start};
Rafael Espindolac70aeda2016-02-16 14:50:39 +000085 if (EntSize != sizeof(Type) || Size % EntSize)
86 reportError("Invalid entity size");
87 return {Start, Start + (Size / EntSize)};
88 }
Rafael Espindola65a6fd82016-02-16 14:27:33 +000089};
90
George Rimar47936762016-01-16 00:49:19 +000091template<typename ELFT>
92class ELFDumper : public ObjDumper {
93public:
94 ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer);
95
96 void printFileHeaders() override;
97 void printSections() override;
98 void printRelocations() override;
99 void printDynamicRelocations() override;
100 void printSymbols() override;
101 void printDynamicSymbols() override;
102 void printUnwindInfo() override;
103
104 void printDynamicTable() override;
105 void printNeededLibraries() override;
106 void printProgramHeaders() override;
107 void printHashTable() override;
108 void printGnuHashTable() override;
109 void printLoadName() override;
110 void printVersionInfo() override;
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +0000111 void printGroupSections() override;
George Rimar47936762016-01-16 00:49:19 +0000112
113 void printAttributes() override;
114 void printMipsPLTGOT() override;
115 void printMipsABIFlags() override;
116 void printMipsReginfo() override;
117
118 void printStackMap() const override;
119
120private:
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000121 std::unique_ptr<DumpStyle<ELFT>> ELFDumperStyle;
George Rimar47936762016-01-16 00:49:19 +0000122 typedef ELFFile<ELFT> ELFO;
123 typedef typename ELFO::Elf_Shdr Elf_Shdr;
124 typedef typename ELFO::Elf_Sym Elf_Sym;
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000125 typedef typename ELFO::Elf_Sym_Range Elf_Sym_Range;
George Rimar47936762016-01-16 00:49:19 +0000126 typedef typename ELFO::Elf_Dyn Elf_Dyn;
127 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range;
128 typedef typename ELFO::Elf_Rel Elf_Rel;
129 typedef typename ELFO::Elf_Rela Elf_Rela;
Simon Atanasyan72155c32016-01-16 22:40:09 +0000130 typedef typename ELFO::Elf_Rel_Range Elf_Rel_Range;
George Rimar47936762016-01-16 00:49:19 +0000131 typedef typename ELFO::Elf_Rela_Range Elf_Rela_Range;
132 typedef typename ELFO::Elf_Phdr Elf_Phdr;
133 typedef typename ELFO::Elf_Half Elf_Half;
134 typedef typename ELFO::Elf_Hash Elf_Hash;
135 typedef typename ELFO::Elf_GnuHash Elf_GnuHash;
136 typedef typename ELFO::Elf_Ehdr Elf_Ehdr;
137 typedef typename ELFO::Elf_Word Elf_Word;
138 typedef typename ELFO::uintX_t uintX_t;
139 typedef typename ELFO::Elf_Versym Elf_Versym;
140 typedef typename ELFO::Elf_Verneed Elf_Verneed;
141 typedef typename ELFO::Elf_Vernaux Elf_Vernaux;
142 typedef typename ELFO::Elf_Verdef Elf_Verdef;
143 typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
144
Rafael Espindolae17c3f32016-02-17 16:48:00 +0000145 DynRegionInfo checkDRI(DynRegionInfo DRI) {
146 if (DRI.Addr < Obj->base() ||
147 (const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize())
148 error(llvm::object::object_error::parse_failed);
149 return DRI;
150 }
151
152 DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
153 return checkDRI({Obj->base() + P->p_offset, P->p_filesz, EntSize});
154 }
155
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000156 DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
Rafael Espindolae17c3f32016-02-17 16:48:00 +0000157 return checkDRI({Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize});
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000158 }
159
Michael J. Spencer60d82b22016-02-11 04:59:37 +0000160 void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments);
161
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000162 void printSymbol(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
George Rimar47936762016-01-16 00:49:19 +0000163 StringRef StrTable, bool IsDynamic);
164
George Rimar47936762016-01-16 00:49:19 +0000165 void printValue(uint64_t Type, uint64_t Value);
166
George Rimar47936762016-01-16 00:49:19 +0000167 StringRef getDynamicString(uint64_t Offset) const;
George Rimar47936762016-01-16 00:49:19 +0000168 StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000169 bool &IsDefault) const;
170 void LoadVersionMap() const;
George Rimar47936762016-01-16 00:49:19 +0000171 void LoadVersionNeeds(const Elf_Shdr *ec) const;
172 void LoadVersionDefs(const Elf_Shdr *sec) const;
173
174 const ELFO *Obj;
Simon Atanasyan72155c32016-01-16 22:40:09 +0000175 DynRegionInfo DynRelRegion;
George Rimar47936762016-01-16 00:49:19 +0000176 DynRegionInfo DynRelaRegion;
Rafael Espindola944f6552016-02-16 15:16:00 +0000177 DynRegionInfo DynPLTRelRegion;
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000178 DynRegionInfo DynSymRegion;
Rafael Espindolae17c3f32016-02-17 16:48:00 +0000179 DynRegionInfo DynamicTable;
George Rimar47936762016-01-16 00:49:19 +0000180 StringRef DynamicStringTable;
George Rimar47936762016-01-16 00:49:19 +0000181 StringRef SOName;
182 const Elf_Hash *HashTable = nullptr;
183 const Elf_GnuHash *GnuHashTable = nullptr;
George Rimar47936762016-01-16 00:49:19 +0000184 const Elf_Shdr *DotSymtabSec = nullptr;
185 ArrayRef<Elf_Word> ShndxTable;
186
187 const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version
188 const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r
189 const Elf_Shdr *dot_gnu_version_d_sec = nullptr; // .gnu.version_d
190
191 // Records for each version index the corresponding Verdef or Vernaux entry.
192 // This is filled the first time LoadVersionMap() is called.
193 class VersionMapEntry : public PointerIntPair<const void *, 1> {
194 public:
195 // If the integer is 0, this is an Elf_Verdef*.
196 // If the integer is 1, this is an Elf_Vernaux*.
197 VersionMapEntry() : PointerIntPair<const void *, 1>(nullptr, 0) {}
198 VersionMapEntry(const Elf_Verdef *verdef)
199 : PointerIntPair<const void *, 1>(verdef, 0) {}
200 VersionMapEntry(const Elf_Vernaux *vernaux)
201 : PointerIntPair<const void *, 1>(vernaux, 1) {}
202 bool isNull() const { return getPointer() == nullptr; }
203 bool isVerdef() const { return !isNull() && getInt() == 0; }
204 bool isVernaux() const { return !isNull() && getInt() == 1; }
205 const Elf_Verdef *getVerdef() const {
206 return isVerdef() ? (const Elf_Verdef *)getPointer() : nullptr;
207 }
208 const Elf_Vernaux *getVernaux() const {
209 return isVernaux() ? (const Elf_Vernaux *)getPointer() : nullptr;
210 }
211 };
212 mutable SmallVector<VersionMapEntry, 16> VersionMap;
213
214public:
215 Elf_Dyn_Range dynamic_table() const {
Rafael Espindolae17c3f32016-02-17 16:48:00 +0000216 return DynamicTable.getAsRange<Elf_Dyn>();
George Rimar47936762016-01-16 00:49:19 +0000217 }
218
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000219 Elf_Sym_Range dynamic_symbols() const {
220 return DynSymRegion.getAsRange<Elf_Sym>();
221 }
222
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000223 Elf_Rel_Range dyn_rels() const;
224 Elf_Rela_Range dyn_relas() const;
George Rimar47936762016-01-16 00:49:19 +0000225 std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000226 bool IsDynamic) const;
George Rimar47936762016-01-16 00:49:19 +0000227 const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000228 ArrayRef<Elf_Word> getShndxTable() const { return ShndxTable; }
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000229 StringRef getDynamicStringTable() const { return DynamicStringTable; }
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000230 const DynRegionInfo &getDynRelRegion() const { return DynRelRegion; }
231 const DynRegionInfo &getDynRelaRegion() const { return DynRelaRegion; }
232 const DynRegionInfo &getDynPLTRelRegion() const { return DynPLTRelRegion; }
George Rimar47936762016-01-16 00:49:19 +0000233};
234
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000235template <typename ELFT> class DumpStyle {
236public:
Hemant Kulkarnide1152f2016-02-25 20:47:07 +0000237 virtual void printFileHeaders(const ELFFile<ELFT> *Obj) = 0;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000238 virtual ~DumpStyle() { }
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000239 DumpStyle(ELFDumper<ELFT> *Dumper) : Dumper(Dumper) {}
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000240 virtual void printGroupSections(const ELFFile<ELFT> *Obj) = 0;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000241 virtual void printRelocations(const ELFFile<ELFT> *Obj) = 0;
242 virtual void printSections(const ELFFile<ELFT> *Obj) = 0;
243 virtual void printSymbols(const ELFFile<ELFT> *Obj) = 0;
244 virtual void printDynamicSymbols(const ELFFile<ELFT> *Obj) = 0;
245 virtual void printDynamicRelocations(const ELFFile<ELFT> *Obj) = 0;
246 const ELFDumper<ELFT> *dumper() const { return Dumper; }
247
248private:
249 const ELFDumper<ELFT> *Dumper;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000250};
251
252template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
253 formatted_raw_ostream OS;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000254public:
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000255 TYPEDEF_ELF_TYPES(ELFT)
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000256 GNUStyle(StreamWriter &W, ELFDumper<ELFT> *Dumper)
257 : DumpStyle<ELFT>(Dumper), OS(W.getOStream()) {}
258 void printFileHeaders(const ELFO *Obj) override;
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000259 void printGroupSections(const ELFFile<ELFT> *Obj) override;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000260 void printRelocations(const ELFO *Obj) override;
261 void printSections(const ELFO *Obj) override;
262 void printSymbols(const ELFO *Obj) override;
263 void printDynamicSymbols(const ELFO *Obj) override;
264 void printDynamicRelocations(const ELFO *Obj) override;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000265
266private:
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000267 struct Field {
268 StringRef Str;
269 unsigned Column;
270 Field(StringRef S, unsigned Col) : Str(S), Column(Col) {}
271 Field(unsigned Col) : Str(""), Column(Col) {}
272 };
273
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000274 template <typename T, typename TEnum>
275 std::string printEnum(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) {
276 for (const auto &EnumItem : EnumValues)
277 if (EnumItem.Value == Value)
278 return EnumItem.AltName;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000279 return to_hexString(Value, false);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000280 }
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000281 formatted_raw_ostream &printField(struct Field F) {
282 if (F.Column != 0)
283 OS.PadToColumn(F.Column);
284 OS << F.Str;
285 OS.flush();
286 return OS;
287 }
288 void printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
289 const Elf_Rela &R, bool IsRela);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000290};
291
292template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
293public:
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000294 TYPEDEF_ELF_TYPES(ELFT)
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000295 LLVMStyle(StreamWriter &W, ELFDumper<ELFT> *Dumper)
296 : DumpStyle<ELFT>(Dumper), W(W) {}
297
298 void printFileHeaders(const ELFO *Obj) override;
Hemant Kulkarni206ba842016-03-09 19:16:13 +0000299 void printGroupSections(const ELFFile<ELFT> *Obj) override;
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000300 void printRelocations(const ELFO *Obj) override;
301 void printRelocations(const Elf_Shdr *Sec, const ELFO *Obj);
302 void printSections(const ELFO *Obj) override;
303 void printSymbolsHelper(const ELFO *Obj, bool IsDynamic);
304 void printSymbols(const ELFO *Obj) override;
305 void printDynamicSymbols(const ELFO *Obj) override;
306 void printDynamicRelocations(const ELFO *Obj) override;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000307
308private:
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000309 void printRelocation(const ELFO *Obj, Elf_Rela Rel, const Elf_Shdr *SymTab);
310 void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
311 StringRef StrTable, bool IsDynamic);
312 void printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel);
313
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000314 StreamWriter &W;
315};
316
George Rimar47936762016-01-16 00:49:19 +0000317} // namespace
318
319namespace llvm {
320
321template <class ELFT>
322static std::error_code createELFDumper(const ELFFile<ELFT> *Obj,
323 StreamWriter &Writer,
324 std::unique_ptr<ObjDumper> &Result) {
325 Result.reset(new ELFDumper<ELFT>(Obj, Writer));
326 return readobj_error::success;
327}
328
329std::error_code createELFDumper(const object::ObjectFile *Obj,
330 StreamWriter &Writer,
331 std::unique_ptr<ObjDumper> &Result) {
332 // Little-endian 32-bit
333 if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
334 return createELFDumper(ELFObj->getELFFile(), Writer, Result);
335
336 // Big-endian 32-bit
337 if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
338 return createELFDumper(ELFObj->getELFFile(), Writer, Result);
339
340 // Little-endian 64-bit
341 if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
342 return createELFDumper(ELFObj->getELFFile(), Writer, Result);
343
344 // Big-endian 64-bit
345 if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
346 return createELFDumper(ELFObj->getELFFile(), Writer, Result);
347
348 return readobj_error::unsupported_obj_file_format;
349}
350
351} // namespace llvm
352
353// Iterate through the versions needed section, and place each Elf_Vernaux
354// in the VersionMap according to its index.
355template <class ELFT>
356void ELFDumper<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
357 unsigned vn_size = sec->sh_size; // Size of section in bytes
358 unsigned vn_count = sec->sh_info; // Number of Verneed entries
359 const char *sec_start = (const char *)Obj->base() + sec->sh_offset;
360 const char *sec_end = sec_start + vn_size;
361 // The first Verneed entry is at the start of the section.
362 const char *p = sec_start;
363 for (unsigned i = 0; i < vn_count; i++) {
364 if (p + sizeof(Elf_Verneed) > sec_end)
365 report_fatal_error("Section ended unexpectedly while scanning "
366 "version needed records.");
367 const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p);
368 if (vn->vn_version != ELF::VER_NEED_CURRENT)
369 report_fatal_error("Unexpected verneed version");
370 // Iterate through the Vernaux entries
371 const char *paux = p + vn->vn_aux;
372 for (unsigned j = 0; j < vn->vn_cnt; j++) {
373 if (paux + sizeof(Elf_Vernaux) > sec_end)
374 report_fatal_error("Section ended unexpected while scanning auxiliary "
375 "version needed records.");
376 const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux);
377 size_t index = vna->vna_other & ELF::VERSYM_VERSION;
378 if (index >= VersionMap.size())
379 VersionMap.resize(index + 1);
380 VersionMap[index] = VersionMapEntry(vna);
381 paux += vna->vna_next;
382 }
383 p += vn->vn_next;
384 }
385}
386
387// Iterate through the version definitions, and place each Elf_Verdef
388// in the VersionMap according to its index.
389template <class ELFT>
390void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
391 unsigned vd_size = sec->sh_size; // Size of section in bytes
392 unsigned vd_count = sec->sh_info; // Number of Verdef entries
393 const char *sec_start = (const char *)Obj->base() + sec->sh_offset;
394 const char *sec_end = sec_start + vd_size;
395 // The first Verdef entry is at the start of the section.
396 const char *p = sec_start;
397 for (unsigned i = 0; i < vd_count; i++) {
398 if (p + sizeof(Elf_Verdef) > sec_end)
399 report_fatal_error("Section ended unexpectedly while scanning "
400 "version definitions.");
401 const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p);
402 if (vd->vd_version != ELF::VER_DEF_CURRENT)
403 report_fatal_error("Unexpected verdef version");
404 size_t index = vd->vd_ndx & ELF::VERSYM_VERSION;
405 if (index >= VersionMap.size())
406 VersionMap.resize(index + 1);
407 VersionMap[index] = VersionMapEntry(vd);
408 p += vd->vd_next;
409 }
410}
411
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000412template <class ELFT> void ELFDumper<ELFT>::LoadVersionMap() const {
George Rimar47936762016-01-16 00:49:19 +0000413 // If there is no dynamic symtab or version table, there is nothing to do.
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000414 if (!DynSymRegion.Addr || !dot_gnu_version_sec)
George Rimar47936762016-01-16 00:49:19 +0000415 return;
416
417 // Has the VersionMap already been loaded?
418 if (VersionMap.size() > 0)
419 return;
420
421 // The first two version indexes are reserved.
422 // Index 0 is LOCAL, index 1 is GLOBAL.
423 VersionMap.push_back(VersionMapEntry());
424 VersionMap.push_back(VersionMapEntry());
425
426 if (dot_gnu_version_d_sec)
427 LoadVersionDefs(dot_gnu_version_d_sec);
428
429 if (dot_gnu_version_r_sec)
430 LoadVersionNeeds(dot_gnu_version_r_sec);
431}
432
433
434template <typename ELFO, class ELFT>
435static void printVersionSymbolSection(ELFDumper<ELFT> *Dumper,
436 const ELFO *Obj,
437 const typename ELFO::Elf_Shdr *Sec,
438 StreamWriter &W) {
439 DictScope SS(W, "Version symbols");
440 if (!Sec)
441 return;
Rafael Espindolaf04f1842016-02-17 16:21:49 +0000442 StringRef Name = unwrapOrError(Obj->getSectionName(Sec));
George Rimar47936762016-01-16 00:49:19 +0000443 W.printNumber("Section Name", Name, Sec->sh_name);
444 W.printHex("Address", Sec->sh_addr);
445 W.printHex("Offset", Sec->sh_offset);
446 W.printNumber("Link", Sec->sh_link);
447
George Rimar47936762016-01-16 00:49:19 +0000448 const uint8_t *P = (const uint8_t *)Obj->base() + Sec->sh_offset;
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000449 StringRef StrTable = Dumper->getDynamicStringTable();
George Rimar47936762016-01-16 00:49:19 +0000450
451 // Same number of entries in the dynamic symbol table (DT_SYMTAB).
452 ListScope Syms(W, "Symbols");
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000453 for (const typename ELFO::Elf_Sym &Sym : Dumper->dynamic_symbols()) {
George Rimar47936762016-01-16 00:49:19 +0000454 DictScope S(W, "Symbol");
455 std::string FullSymbolName =
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000456 Dumper->getFullSymbolName(&Sym, StrTable, true /* IsDynamic */);
George Rimar47936762016-01-16 00:49:19 +0000457 W.printNumber("Version", *P);
458 W.printString("Name", FullSymbolName);
459 P += sizeof(typename ELFO::Elf_Half);
460 }
461}
462
463template <typename ELFO, class ELFT>
464static void printVersionDefinitionSection(ELFDumper<ELFT> *Dumper,
465 const ELFO *Obj,
466 const typename ELFO::Elf_Shdr *Sec,
467 StreamWriter &W) {
468 DictScope SD(W, "Version definition");
469 if (!Sec)
470 return;
Rafael Espindolaf04f1842016-02-17 16:21:49 +0000471 StringRef Name = unwrapOrError(Obj->getSectionName(Sec));
George Rimar47936762016-01-16 00:49:19 +0000472 W.printNumber("Section Name", Name, Sec->sh_name);
473 W.printHex("Address", Sec->sh_addr);
474 W.printHex("Offset", Sec->sh_offset);
475 W.printNumber("Link", Sec->sh_link);
476
477 unsigned verdef_entries = 0;
478 // The number of entries in the section SHT_GNU_verdef
479 // is determined by DT_VERDEFNUM tag.
480 for (const typename ELFO::Elf_Dyn &Dyn : Dumper->dynamic_table()) {
481 if (Dyn.d_tag == DT_VERDEFNUM)
482 verdef_entries = Dyn.d_un.d_val;
483 }
484 const uint8_t *SecStartAddress =
485 (const uint8_t *)Obj->base() + Sec->sh_offset;
486 const uint8_t *SecEndAddress = SecStartAddress + Sec->sh_size;
487 const uint8_t *P = SecStartAddress;
Rafael Espindolaf04f1842016-02-17 16:21:49 +0000488 const typename ELFO::Elf_Shdr *StrTab =
489 unwrapOrError(Obj->getSection(Sec->sh_link));
George Rimar47936762016-01-16 00:49:19 +0000490
491 ListScope Entries(W, "Entries");
492 for (unsigned i = 0; i < verdef_entries; ++i) {
493 if (P + sizeof(typename ELFO::Elf_Verdef) > SecEndAddress)
494 report_fatal_error("invalid offset in the section");
495 auto *VD = reinterpret_cast<const typename ELFO::Elf_Verdef *>(P);
496 DictScope Entry(W, "Entry");
497 W.printHex("Offset", (uintptr_t)P - (uintptr_t)SecStartAddress);
498 W.printNumber("Rev", VD->vd_version);
499 // FIXME: print something more readable.
500 W.printNumber("Flags", VD->vd_flags);
501 W.printNumber("Index", VD->vd_ndx);
502 W.printNumber("Cnt", VD->vd_cnt);
Rafael Espindolaf04f1842016-02-17 16:21:49 +0000503 W.printString("Name",
504 StringRef((const char *)(Obj->base() + StrTab->sh_offset +
505 VD->getAux()->vda_name)));
George Rimar47936762016-01-16 00:49:19 +0000506 P += VD->vd_next;
507 }
508}
509
510template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
511 // Dump version symbol section.
512 printVersionSymbolSection(this, Obj, dot_gnu_version_sec, W);
513
514 // Dump version definition section.
515 printVersionDefinitionSection(this, Obj, dot_gnu_version_d_sec, W);
516}
517
518template <typename ELFT>
519StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
520 const Elf_Sym *symb,
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000521 bool &IsDefault) const {
George Rimar47936762016-01-16 00:49:19 +0000522 // This is a dynamic symbol. Look in the GNU symbol version table.
523 if (!dot_gnu_version_sec) {
524 // No version table.
525 IsDefault = false;
526 return StringRef("");
527 }
528
529 // Determine the position in the symbol table of this entry.
530 size_t entry_index = (reinterpret_cast<uintptr_t>(symb) -
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000531 reinterpret_cast<uintptr_t>(DynSymRegion.Addr)) /
George Rimar47936762016-01-16 00:49:19 +0000532 sizeof(Elf_Sym);
533
534 // Get the corresponding version index entry
535 const Elf_Versym *vs =
536 Obj->template getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index);
537 size_t version_index = vs->vs_index & ELF::VERSYM_VERSION;
538
539 // Special markers for unversioned symbols.
540 if (version_index == ELF::VER_NDX_LOCAL ||
541 version_index == ELF::VER_NDX_GLOBAL) {
542 IsDefault = false;
543 return StringRef("");
544 }
545
546 // Lookup this symbol in the version table
547 LoadVersionMap();
548 if (version_index >= VersionMap.size() || VersionMap[version_index].isNull())
549 reportError("Invalid version entry");
550 const VersionMapEntry &entry = VersionMap[version_index];
551
552 // Get the version name string
553 size_t name_offset;
554 if (entry.isVerdef()) {
555 // The first Verdaux entry holds the name.
556 name_offset = entry.getVerdef()->getAux()->vda_name;
557 IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN);
558 } else {
559 name_offset = entry.getVernaux()->vna_name;
560 IsDefault = false;
561 }
562 if (name_offset >= StrTab.size())
563 reportError("Invalid string offset");
564 return StringRef(StrTab.data() + name_offset);
565}
566
567template <typename ELFT>
568std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol,
569 StringRef StrTable,
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000570 bool IsDynamic) const {
Rafael Espindolaf04f1842016-02-17 16:21:49 +0000571 StringRef SymbolName = unwrapOrError(Symbol->getName(StrTable));
George Rimar47936762016-01-16 00:49:19 +0000572 if (!IsDynamic)
573 return SymbolName;
574
575 std::string FullSymbolName(SymbolName);
576
577 bool IsDefault;
578 StringRef Version = getSymbolVersion(StrTable, &*Symbol, IsDefault);
579 FullSymbolName += (IsDefault ? "@@" : "@");
580 FullSymbolName += Version;
581 return FullSymbolName;
582}
583
584template <typename ELFO>
585static void
586getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000587 const typename ELFO::Elf_Sym *FirstSym,
George Rimar47936762016-01-16 00:49:19 +0000588 ArrayRef<typename ELFO::Elf_Word> ShndxTable,
589 StringRef &SectionName, unsigned &SectionIndex) {
590 SectionIndex = Symbol->st_shndx;
591 if (Symbol->isUndefined())
592 SectionName = "Undefined";
593 else if (Symbol->isProcessorSpecific())
594 SectionName = "Processor Specific";
595 else if (Symbol->isOSSpecific())
596 SectionName = "Operating System Specific";
597 else if (Symbol->isAbsolute())
598 SectionName = "Absolute";
599 else if (Symbol->isCommon())
600 SectionName = "Common";
601 else if (Symbol->isReserved() && SectionIndex != SHN_XINDEX)
602 SectionName = "Reserved";
603 else {
604 if (SectionIndex == SHN_XINDEX)
605 SectionIndex =
Rafael Espindolace2fbdd2016-02-17 15:38:21 +0000606 Obj.getExtendedSymbolTableIndex(Symbol, FirstSym, ShndxTable);
Rafael Espindolaf04f1842016-02-17 16:21:49 +0000607 const typename ELFO::Elf_Shdr *Sec =
608 unwrapOrError(Obj.getSection(SectionIndex));
609 SectionName = unwrapOrError(Obj.getSectionName(Sec));
George Rimar47936762016-01-16 00:49:19 +0000610 }
611}
612
613template <class ELFO>
Simon Atanasyancb1175c2016-02-09 18:45:35 +0000614static const typename ELFO::Elf_Shdr *
615findNotEmptySectionByAddress(const ELFO *Obj, uint64_t Addr) {
George Rimar47936762016-01-16 00:49:19 +0000616 for (const auto &Shdr : Obj->sections())
Simon Atanasyancb1175c2016-02-09 18:45:35 +0000617 if (Shdr.sh_addr == Addr && Shdr.sh_size > 0)
George Rimar47936762016-01-16 00:49:19 +0000618 return &Shdr;
619 return nullptr;
620}
621
622template <class ELFO>
623static const typename ELFO::Elf_Shdr *findSectionByName(const ELFO &Obj,
624 StringRef Name) {
625 for (const auto &Shdr : Obj.sections()) {
Rafael Espindolaf04f1842016-02-17 16:21:49 +0000626 if (Name == unwrapOrError(Obj.getSectionName(&Shdr)))
George Rimar47936762016-01-16 00:49:19 +0000627 return &Shdr;
628 }
629 return nullptr;
630}
631
632static const EnumEntry<unsigned> ElfClass[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000633 {"None", "none", ELF::ELFCLASSNONE},
634 {"32-bit", "ELF32", ELF::ELFCLASS32},
635 {"64-bit", "ELF64", ELF::ELFCLASS64},
George Rimar47936762016-01-16 00:49:19 +0000636};
637
638static const EnumEntry<unsigned> ElfDataEncoding[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000639 {"None", "none", ELF::ELFDATANONE},
640 {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB},
641 {"BigEndian", "2's complement, big endian", ELF::ELFDATA2MSB},
George Rimar47936762016-01-16 00:49:19 +0000642};
643
644static const EnumEntry<unsigned> ElfObjectFileType[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000645 {"None", "NONE (none)", ELF::ET_NONE},
646 {"Relocatable", "REL (Relocatable file)", ELF::ET_REL},
647 {"Executable", "EXEC (Executable file)", ELF::ET_EXEC},
648 {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN},
649 {"Core", "CORE (Core file)", ELF::ET_CORE},
George Rimar47936762016-01-16 00:49:19 +0000650};
651
652static const EnumEntry<unsigned> ElfOSABI[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000653 {"SystemV", "UNIX - System V", ELF::ELFOSABI_NONE},
654 {"HPUX", "UNIX - HP-UX", ELF::ELFOSABI_HPUX},
655 {"NetBSD", "UNIX - NetBSD", ELF::ELFOSABI_NETBSD},
656 {"GNU/Linux", "UNIX - GNU", ELF::ELFOSABI_LINUX},
657 {"GNU/Hurd", "GNU/Hurd", ELF::ELFOSABI_HURD},
658 {"Solaris", "UNIX - Solaris", ELF::ELFOSABI_SOLARIS},
659 {"AIX", "UNIX - AIX", ELF::ELFOSABI_AIX},
660 {"IRIX", "UNIX - IRIX", ELF::ELFOSABI_IRIX},
661 {"FreeBSD", "UNIX - FreeBSD", ELF::ELFOSABI_FREEBSD},
662 {"TRU64", "UNIX - TRU64", ELF::ELFOSABI_TRU64},
663 {"Modesto", "Novell - Modesto", ELF::ELFOSABI_MODESTO},
664 {"OpenBSD", "UNIX - OpenBSD", ELF::ELFOSABI_OPENBSD},
665 {"OpenVMS", "VMS - OpenVMS", ELF::ELFOSABI_OPENVMS},
666 {"NSK", "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK},
667 {"AROS", "AROS", ELF::ELFOSABI_AROS},
668 {"FenixOS", "FenixOS", ELF::ELFOSABI_FENIXOS},
669 {"CloudABI", "CloudABI", ELF::ELFOSABI_CLOUDABI},
670 {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI},
671 {"C6000_LINUX", "Linux C6000", ELF::ELFOSABI_C6000_LINUX},
672 {"ARM", "ARM", ELF::ELFOSABI_ARM},
673 {"Standalone", "Standalone App", ELF::ELFOSABI_STANDALONE}
George Rimar47936762016-01-16 00:49:19 +0000674};
675
676static const EnumEntry<unsigned> ElfMachineType[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000677 ENUM_ENT(EM_NONE, "None"),
678 ENUM_ENT(EM_M32, "WE32100"),
679 ENUM_ENT(EM_SPARC, "Sparc"),
680 ENUM_ENT(EM_386, "Intel 80386"),
681 ENUM_ENT(EM_68K, "MC68000"),
682 ENUM_ENT(EM_88K, "MC88000"),
683 ENUM_ENT(EM_IAMCU, "EM_IAMCU"),
684 ENUM_ENT(EM_860, "Intel 80860"),
685 ENUM_ENT(EM_MIPS, "MIPS R3000"),
686 ENUM_ENT(EM_S370, "IBM System/370"),
687 ENUM_ENT(EM_MIPS_RS3_LE, "MIPS R3000 little-endian"),
688 ENUM_ENT(EM_PARISC, "HPPA"),
689 ENUM_ENT(EM_VPP500, "Fujitsu VPP500"),
690 ENUM_ENT(EM_SPARC32PLUS, "Sparc v8+"),
691 ENUM_ENT(EM_960, "Intel 80960"),
692 ENUM_ENT(EM_PPC, "PowerPC"),
693 ENUM_ENT(EM_PPC64, "PowerPC64"),
694 ENUM_ENT(EM_S390, "IBM S/390"),
695 ENUM_ENT(EM_SPU, "SPU"),
696 ENUM_ENT(EM_V800, "NEC V800 series"),
697 ENUM_ENT(EM_FR20, "Fujistsu FR20"),
698 ENUM_ENT(EM_RH32, "TRW RH-32"),
699 ENUM_ENT(EM_RCE, "Motorola RCE"),
700 ENUM_ENT(EM_ARM, "ARM"),
701 ENUM_ENT(EM_ALPHA, "EM_ALPHA"),
702 ENUM_ENT(EM_SH, "Hitachi SH"),
703 ENUM_ENT(EM_SPARCV9, "Sparc v9"),
704 ENUM_ENT(EM_TRICORE, "Siemens Tricore"),
705 ENUM_ENT(EM_ARC, "ARC"),
706 ENUM_ENT(EM_H8_300, "Hitachi H8/300"),
707 ENUM_ENT(EM_H8_300H, "Hitachi H8/300H"),
708 ENUM_ENT(EM_H8S, "Hitachi H8S"),
709 ENUM_ENT(EM_H8_500, "Hitachi H8/500"),
710 ENUM_ENT(EM_IA_64, "Intel IA-64"),
711 ENUM_ENT(EM_MIPS_X, "Stanford MIPS-X"),
712 ENUM_ENT(EM_COLDFIRE, "Motorola Coldfire"),
713 ENUM_ENT(EM_68HC12, "Motorola MC68HC12 Microcontroller"),
714 ENUM_ENT(EM_MMA, "Fujitsu Multimedia Accelerator"),
715 ENUM_ENT(EM_PCP, "Siemens PCP"),
716 ENUM_ENT(EM_NCPU, "Sony nCPU embedded RISC processor"),
717 ENUM_ENT(EM_NDR1, "Denso NDR1 microprocesspr"),
718 ENUM_ENT(EM_STARCORE, "Motorola Star*Core processor"),
719 ENUM_ENT(EM_ME16, "Toyota ME16 processor"),
720 ENUM_ENT(EM_ST100, "STMicroelectronics ST100 processor"),
721 ENUM_ENT(EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor"),
722 ENUM_ENT(EM_X86_64, "Advanced Micro Devices X86-64"),
723 ENUM_ENT(EM_PDSP, "Sony DSP processor"),
724 ENUM_ENT(EM_PDP10, "Digital Equipment Corp. PDP-10"),
725 ENUM_ENT(EM_PDP11, "Digital Equipment Corp. PDP-11"),
726 ENUM_ENT(EM_FX66, "Siemens FX66 microcontroller"),
727 ENUM_ENT(EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller"),
728 ENUM_ENT(EM_ST7, "STMicroelectronics ST7 8-bit microcontroller"),
729 ENUM_ENT(EM_68HC16, "Motorola MC68HC16 Microcontroller"),
730 ENUM_ENT(EM_68HC11, "Motorola MC68HC11 Microcontroller"),
731 ENUM_ENT(EM_68HC08, "Motorola MC68HC08 Microcontroller"),
732 ENUM_ENT(EM_68HC05, "Motorola MC68HC05 Microcontroller"),
733 ENUM_ENT(EM_SVX, "Silicon Graphics SVx"),
734 ENUM_ENT(EM_ST19, "STMicroelectronics ST19 8-bit microcontroller"),
735 ENUM_ENT(EM_VAX, "Digital VAX"),
736 ENUM_ENT(EM_CRIS, "Axis Communications 32-bit embedded processor"),
737 ENUM_ENT(EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu"),
738 ENUM_ENT(EM_FIREPATH, "Element 14 64-bit DSP processor"),
739 ENUM_ENT(EM_ZSP, "LSI Logic's 16-bit DSP processor"),
740 ENUM_ENT(EM_MMIX, "Donald Knuth's educational 64-bit processor"),
741 ENUM_ENT(EM_HUANY, "Harvard Universitys's machine-independent object format"),
742 ENUM_ENT(EM_PRISM, "Vitesse Prism"),
743 ENUM_ENT(EM_AVR, "Atmel AVR 8-bit microcontroller"),
744 ENUM_ENT(EM_FR30, "Fujitsu FR30"),
745 ENUM_ENT(EM_D10V, "Mitsubishi D10V"),
746 ENUM_ENT(EM_D30V, "Mitsubishi D30V"),
747 ENUM_ENT(EM_V850, "NEC v850"),
748 ENUM_ENT(EM_M32R, "Renesas M32R (formerly Mitsubishi M32r)"),
749 ENUM_ENT(EM_MN10300, "Matsushita MN10300"),
750 ENUM_ENT(EM_MN10200, "Matsushita MN10200"),
751 ENUM_ENT(EM_PJ, "picoJava"),
752 ENUM_ENT(EM_OPENRISC, "OpenRISC 32-bit embedded processor"),
753 ENUM_ENT(EM_ARC_COMPACT, "EM_ARC_COMPACT"),
754 ENUM_ENT(EM_XTENSA, "Tensilica Xtensa Processor"),
755 ENUM_ENT(EM_VIDEOCORE, "Alphamosaic VideoCore processor"),
756 ENUM_ENT(EM_TMM_GPP, "Thompson Multimedia General Purpose Processor"),
757 ENUM_ENT(EM_NS32K, "National Semiconductor 32000 series"),
758 ENUM_ENT(EM_TPC, "Tenor Network TPC processor"),
759 ENUM_ENT(EM_SNP1K, "EM_SNP1K"),
760 ENUM_ENT(EM_ST200, "STMicroelectronics ST200 microcontroller"),
761 ENUM_ENT(EM_IP2K, "Ubicom IP2xxx 8-bit microcontrollers"),
762 ENUM_ENT(EM_MAX, "MAX Processor"),
763 ENUM_ENT(EM_CR, "National Semiconductor CompactRISC"),
764 ENUM_ENT(EM_F2MC16, "Fujitsu F2MC16"),
765 ENUM_ENT(EM_MSP430, "Texas Instruments msp430 microcontroller"),
766 ENUM_ENT(EM_BLACKFIN, "Analog Devices Blackfin"),
767 ENUM_ENT(EM_SE_C33, "S1C33 Family of Seiko Epson processors"),
768 ENUM_ENT(EM_SEP, "Sharp embedded microprocessor"),
769 ENUM_ENT(EM_ARCA, "Arca RISC microprocessor"),
770 ENUM_ENT(EM_UNICORE, "Unicore"),
771 ENUM_ENT(EM_EXCESS, "eXcess 16/32/64-bit configurable embedded CPU"),
772 ENUM_ENT(EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor"),
773 ENUM_ENT(EM_ALTERA_NIOS2, "Altera Nios"),
774 ENUM_ENT(EM_CRX, "National Semiconductor CRX microprocessor"),
775 ENUM_ENT(EM_XGATE, "Motorola XGATE embedded processor"),
776 ENUM_ENT(EM_C166, "Infineon Technologies xc16x"),
777 ENUM_ENT(EM_M16C, "Renesas M16C"),
778 ENUM_ENT(EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller"),
779 ENUM_ENT(EM_CE, "Freescale Communication Engine RISC core"),
780 ENUM_ENT(EM_M32C, "Renesas M32C"),
781 ENUM_ENT(EM_TSK3000, "Altium TSK3000 core"),
782 ENUM_ENT(EM_RS08, "Freescale RS08 embedded processor"),
783 ENUM_ENT(EM_SHARC, "EM_SHARC"),
784 ENUM_ENT(EM_ECOG2, "Cyan Technology eCOG2 microprocessor"),
785 ENUM_ENT(EM_SCORE7, "SUNPLUS S+Core"),
786 ENUM_ENT(EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor"),
787 ENUM_ENT(EM_VIDEOCORE3, "Broadcom VideoCore III processor"),
788 ENUM_ENT(EM_LATTICEMICO32, "Lattice Mico32"),
789 ENUM_ENT(EM_SE_C17, "Seiko Epson C17 family"),
790 ENUM_ENT(EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family"),
791 ENUM_ENT(EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family"),
792 ENUM_ENT(EM_TI_C5500, "Texas Instruments TMS320C55x DSP family"),
793 ENUM_ENT(EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor"),
794 ENUM_ENT(EM_CYPRESS_M8C, "Cypress M8C microprocessor"),
795 ENUM_ENT(EM_R32C, "Renesas R32C series microprocessors"),
796 ENUM_ENT(EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family"),
797 ENUM_ENT(EM_HEXAGON, "Qualcomm Hexagon"),
798 ENUM_ENT(EM_8051, "Intel 8051 and variants"),
799 ENUM_ENT(EM_STXP7X, "STMicroelectronics STxP7x family"),
800 ENUM_ENT(EM_NDS32, "Andes Technology compact code size embedded RISC processor family"),
801 ENUM_ENT(EM_ECOG1, "Cyan Technology eCOG1 microprocessor"),
802 ENUM_ENT(EM_ECOG1X, "Cyan Technology eCOG1X family"),
803 ENUM_ENT(EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core microcontrollers"),
804 ENUM_ENT(EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor"),
805 ENUM_ENT(EM_MANIK, "M2000 Reconfigurable RISC Microprocessor"),
806 ENUM_ENT(EM_CRAYNV2, "Cray Inc. NV2 vector architecture"),
807 ENUM_ENT(EM_RX, "Renesas RX"),
808 ENUM_ENT(EM_METAG, "Imagination Technologies Meta processor architecture"),
809 ENUM_ENT(EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture"),
810 ENUM_ENT(EM_ECOG16, "Cyan Technology eCOG16 family"),
811 ENUM_ENT(EM_CR16, "Xilinx MicroBlaze"),
812 ENUM_ENT(EM_ETPU, "Freescale Extended Time Processing Unit"),
813 ENUM_ENT(EM_SLE9X, "Infineon Technologies SLE9X core"),
814 ENUM_ENT(EM_L10M, "EM_L10M"),
815 ENUM_ENT(EM_K10M, "EM_K10M"),
816 ENUM_ENT(EM_AARCH64, "AArch64"),
817 ENUM_ENT(EM_AVR32, "Atmel AVR 8-bit microcontroller"),
818 ENUM_ENT(EM_STM8, "STMicroeletronics STM8 8-bit microcontroller"),
819 ENUM_ENT(EM_TILE64, "Tilera TILE64 multicore architecture family"),
820 ENUM_ENT(EM_TILEPRO, "Tilera TILEPro multicore architecture family"),
821 ENUM_ENT(EM_CUDA, "NVIDIA CUDA architecture"),
822 ENUM_ENT(EM_TILEGX, "Tilera TILE-Gx multicore architecture family"),
823 ENUM_ENT(EM_CLOUDSHIELD, "EM_CLOUDSHIELD"),
824 ENUM_ENT(EM_COREA_1ST, "EM_COREA_1ST"),
825 ENUM_ENT(EM_COREA_2ND, "EM_COREA_2ND"),
826 ENUM_ENT(EM_ARC_COMPACT2, "EM_ARC_COMPACT2"),
827 ENUM_ENT(EM_OPEN8, "EM_OPEN8"),
828 ENUM_ENT(EM_RL78, "Renesas RL78"),
829 ENUM_ENT(EM_VIDEOCORE5, "Broadcom VideoCore V processor"),
830 ENUM_ENT(EM_78KOR, "EM_78KOR"),
831 ENUM_ENT(EM_56800EX, "EM_56800EX"),
832 ENUM_ENT(EM_AMDGPU, "EM_AMDGPU"),
Jacques Pienaarea9f25a2016-03-01 21:21:42 +0000833 ENUM_ENT(EM_WEBASSEMBLY, "EM_WEBASSEMBLY"),
834 ENUM_ENT(EM_LANAI, "EM_LANAI"),
George Rimar47936762016-01-16 00:49:19 +0000835};
836
837static const EnumEntry<unsigned> ElfSymbolBindings[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000838 {"Local", "LOCAL", ELF::STB_LOCAL},
839 {"Global", "GLOBAL", ELF::STB_GLOBAL},
840 {"Weak", "WEAK", ELF::STB_WEAK},
841 {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE}};
George Rimar47936762016-01-16 00:49:19 +0000842
843static const EnumEntry<unsigned> ElfSymbolTypes[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000844 {"None", "NOTYPE", ELF::STT_NOTYPE},
845 {"Object", "OBJECT", ELF::STT_OBJECT},
846 {"Function", "FUNCTION", ELF::STT_FUNC},
847 {"Section", "SECTION", ELF::STT_SECTION},
848 {"File", "FILE", ELF::STT_FILE},
849 {"Common", "COMMON", ELF::STT_COMMON},
850 {"TLS", "TLS", ELF::STT_TLS},
851 {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}};
George Rimar47936762016-01-16 00:49:19 +0000852
853static const EnumEntry<unsigned> AMDGPUSymbolTypes[] = {
854 { "AMDGPU_HSA_KERNEL", ELF::STT_AMDGPU_HSA_KERNEL },
855 { "AMDGPU_HSA_INDIRECT_FUNCTION", ELF::STT_AMDGPU_HSA_INDIRECT_FUNCTION },
856 { "AMDGPU_HSA_METADATA", ELF::STT_AMDGPU_HSA_METADATA }
857};
858
859static const char *getElfSectionType(unsigned Arch, unsigned Type) {
860 switch (Arch) {
861 case ELF::EM_ARM:
862 switch (Type) {
863 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX);
864 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
865 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
866 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
867 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
868 }
869 case ELF::EM_HEXAGON:
870 switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
871 case ELF::EM_X86_64:
872 switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
873 case ELF::EM_MIPS:
874 case ELF::EM_MIPS_RS3_LE:
875 switch (Type) {
876 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
877 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
878 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
879 }
880 }
881
882 switch (Type) {
883 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL );
884 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS );
885 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB );
886 LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB );
887 LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA );
888 LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH );
889 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC );
890 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE );
891 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS );
892 LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL );
893 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB );
894 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM );
895 LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY );
896 LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY );
897 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY );
898 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP );
899 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX );
900 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES );
901 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH );
902 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef );
903 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed );
904 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym );
905 default: return "";
906 }
907}
908
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +0000909static const char *getGroupType(uint32_t Flag) {
910 if (Flag & ELF::GRP_COMDAT)
911 return "COMDAT";
912 else
913 return "(unknown)";
914}
915
George Rimar47936762016-01-16 00:49:19 +0000916static const EnumEntry<unsigned> ElfSectionFlags[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000917 ENUM_ENT(SHF_WRITE, "W"),
918 ENUM_ENT(SHF_ALLOC, "A"),
919 ENUM_ENT(SHF_EXCLUDE, "E"),
920 ENUM_ENT(SHF_EXECINSTR, "X"),
921 ENUM_ENT(SHF_MERGE, "M"),
922 ENUM_ENT(SHF_STRINGS, "S"),
923 ENUM_ENT(SHF_INFO_LINK, "I"),
924 ENUM_ENT(SHF_LINK_ORDER, "L"),
925 ENUM_ENT(SHF_OS_NONCONFORMING, "o"),
926 ENUM_ENT(SHF_GROUP, "G"),
927 ENUM_ENT(SHF_TLS, "T"),
928 ENUM_ENT_1(XCORE_SHF_CP_SECTION),
929 ENUM_ENT_1(XCORE_SHF_DP_SECTION),
Simon Atanasyan2d0d8532016-01-20 19:15:18 +0000930};
931
932static const EnumEntry<unsigned> ElfAMDGPUSectionFlags[] = {
George Rimar47936762016-01-16 00:49:19 +0000933 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_GLOBAL),
934 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_READONLY),
935 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_CODE),
936 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_AGENT)
937};
938
Simon Atanasyan2d0d8532016-01-20 19:15:18 +0000939static const EnumEntry<unsigned> ElfHexagonSectionFlags[] = {
940 LLVM_READOBJ_ENUM_ENT(ELF, SHF_HEX_GPREL)
941};
942
943static const EnumEntry<unsigned> ElfMipsSectionFlags[] = {
944 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NODUPES),
945 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NAMES ),
946 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_LOCAL ),
947 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP),
948 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_GPREL ),
949 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_MERGE ),
950 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_ADDR ),
951 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_STRING )
952};
953
954static const EnumEntry<unsigned> ElfX86_64SectionFlags[] = {
955 LLVM_READOBJ_ENUM_ENT(ELF, SHF_X86_64_LARGE)
956};
957
Hemant Kulkarnic030f232016-03-15 17:25:31 +0000958static std::string getGNUFlags(uint64_t Flags) {
959 std::string Str;
960 for (auto Entry : ElfSectionFlags) {
961 uint64_t Flag = Entry.Value & Flags;
962 Flags &= ~Entry.Value;
963 switch (Flag) {
964 case ELF::SHF_WRITE:
965 case ELF::SHF_ALLOC:
966 case ELF::SHF_EXECINSTR:
967 case ELF::SHF_MERGE:
968 case ELF::SHF_STRINGS:
969 case ELF::SHF_INFO_LINK:
970 case ELF::SHF_LINK_ORDER:
971 case ELF::SHF_OS_NONCONFORMING:
972 case ELF::SHF_GROUP:
973 case ELF::SHF_TLS:
974 case ELF::SHF_EXCLUDE:
975 Str += Entry.AltName;
976 break;
977 default:
978 if (Flags & ELF::SHF_MASKOS)
979 Str += "o";
980 else if (Flags & ELF::SHF_MASKPROC)
981 Str += "p";
982 else if (Flag)
983 Str += "x";
984 }
985 }
986 return Str;
987}
988
George Rimar47936762016-01-16 00:49:19 +0000989static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
990 // Check potentially overlapped processor-specific
991 // program header type.
992 switch (Arch) {
993 case ELF::EM_AMDGPU:
994 switch (Type) {
995 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM);
996 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT);
997 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_READONLY_AGENT);
998 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_CODE_AGENT);
999 }
1000 case ELF::EM_ARM:
1001 switch (Type) {
1002 LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX);
1003 }
1004 case ELF::EM_MIPS:
1005 case ELF::EM_MIPS_RS3_LE:
1006 switch (Type) {
1007 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
1008 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
1009 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
1010 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);
1011 }
1012 }
1013
1014 switch (Type) {
1015 LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL );
1016 LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD );
1017 LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
1018 LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP );
1019 LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE );
1020 LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB );
1021 LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR );
1022 LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS );
1023
1024 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
1025 LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
1026
1027 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
1028 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
1029 default: return "";
1030 }
1031}
1032
1033static const EnumEntry<unsigned> ElfSegmentFlags[] = {
1034 LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
1035 LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
1036 LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
1037};
1038
1039static const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
1040 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NOREORDER),
1041 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_PIC),
1042 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_CPIC),
1043 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI2),
1044 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_32BITMODE),
1045 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_FP64),
1046 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NAN2008),
1047 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O32),
1048 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O64),
1049 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI32),
1050 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI64),
1051 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_3900),
1052 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4010),
1053 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4100),
1054 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4650),
1055 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4120),
1056 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4111),
1057 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_SB1),
1058 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON),
1059 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_XLR),
1060 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON2),
1061 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON3),
1062 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5400),
1063 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5900),
1064 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5500),
1065 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_9000),
1066 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2E),
1067 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2F),
1068 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS3A),
1069 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MICROMIPS),
1070 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_M16),
1071 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_MDMX),
1072 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_1),
1073 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_2),
1074 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_3),
1075 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_4),
1076 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_5),
1077 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32),
1078 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64),
1079 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R2),
1080 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R2),
1081 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R6),
1082 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6)
1083};
1084
1085template <typename ELFT>
1086ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer)
1087 : ObjDumper(Writer), Obj(Obj) {
1088
1089 SmallVector<const Elf_Phdr *, 4> LoadSegments;
1090 for (const Elf_Phdr &Phdr : Obj->program_headers()) {
1091 if (Phdr.p_type == ELF::PT_DYNAMIC) {
Rafael Espindolae17c3f32016-02-17 16:48:00 +00001092 DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn));
George Rimar47936762016-01-16 00:49:19 +00001093 continue;
1094 }
1095 if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0)
1096 continue;
1097 LoadSegments.push_back(&Phdr);
1098 }
1099
Michael J. Spencer37304f12016-02-11 04:59:26 +00001100 for (const Elf_Shdr &Sec : Obj->sections()) {
1101 switch (Sec.sh_type) {
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001102 case ELF::SHT_SYMTAB:
1103 if (DotSymtabSec != nullptr)
1104 reportError("Multilpe SHT_SYMTAB");
1105 DotSymtabSec = &Sec;
1106 break;
1107 case ELF::SHT_DYNSYM:
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001108 if (DynSymRegion.Size)
Rafael Espindola6009db62016-02-16 14:17:48 +00001109 reportError("Multilpe SHT_DYNSYM");
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001110 DynSymRegion = createDRIFrom(&Sec);
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001111 break;
Michael J. Spencer1c793ef2016-02-17 22:30:41 +00001112 case ELF::SHT_SYMTAB_SHNDX:
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001113 ShndxTable = unwrapOrError(Obj->getSHNDXTable(Sec));
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001114 break;
Michael J. Spencer37304f12016-02-11 04:59:26 +00001115 case ELF::SHT_GNU_versym:
1116 if (dot_gnu_version_sec != nullptr)
1117 reportError("Multiple SHT_GNU_versym");
1118 dot_gnu_version_sec = &Sec;
1119 break;
1120 case ELF::SHT_GNU_verdef:
1121 if (dot_gnu_version_d_sec != nullptr)
1122 reportError("Multiple SHT_GNU_verdef");
1123 dot_gnu_version_d_sec = &Sec;
1124 break;
1125 case ELF::SHT_GNU_verneed:
1126 if (dot_gnu_version_r_sec != nullptr)
1127 reportError("Multilpe SHT_GNU_verneed");
1128 dot_gnu_version_r_sec = &Sec;
1129 break;
Michael J. Spencer37304f12016-02-11 04:59:26 +00001130 }
1131 }
1132
Michael J. Spencer60d82b22016-02-11 04:59:37 +00001133 parseDynamicTable(LoadSegments);
1134
1135 if (opts::Output == opts::GNU)
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001136 ELFDumperStyle.reset(new GNUStyle<ELFT>(Writer, this));
Michael J. Spencer60d82b22016-02-11 04:59:37 +00001137 else
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001138 ELFDumperStyle.reset(new LLVMStyle<ELFT>(Writer, this));
Michael J. Spencer60d82b22016-02-11 04:59:37 +00001139}
1140
1141template <typename ELFT>
1142void ELFDumper<ELFT>::parseDynamicTable(
1143 ArrayRef<const Elf_Phdr *> LoadSegments) {
George Rimar47936762016-01-16 00:49:19 +00001144 auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * {
Michael J. Spencer60d82b22016-02-11 04:59:37 +00001145 const Elf_Phdr *const *I = std::upper_bound(
George Rimar47936762016-01-16 00:49:19 +00001146 LoadSegments.begin(), LoadSegments.end(), VAddr, compareAddr<ELFT>);
1147 if (I == LoadSegments.begin())
Rafael Espindola6009db62016-02-16 14:17:48 +00001148 report_fatal_error("Virtual address is not in any segment");
George Rimar47936762016-01-16 00:49:19 +00001149 --I;
1150 const Elf_Phdr &Phdr = **I;
1151 uint64_t Delta = VAddr - Phdr.p_vaddr;
1152 if (Delta >= Phdr.p_filesz)
Rafael Espindola6009db62016-02-16 14:17:48 +00001153 report_fatal_error("Virtual address is not in any segment");
George Rimar47936762016-01-16 00:49:19 +00001154 return Obj->base() + Phdr.p_offset + Delta;
1155 };
1156
1157 uint64_t SONameOffset = 0;
1158 const char *StringTableBegin = nullptr;
1159 uint64_t StringTableSize = 0;
1160 for (const Elf_Dyn &Dyn : dynamic_table()) {
1161 switch (Dyn.d_tag) {
1162 case ELF::DT_HASH:
1163 HashTable =
1164 reinterpret_cast<const Elf_Hash *>(toMappedAddr(Dyn.getPtr()));
1165 break;
1166 case ELF::DT_GNU_HASH:
1167 GnuHashTable =
1168 reinterpret_cast<const Elf_GnuHash *>(toMappedAddr(Dyn.getPtr()));
1169 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001170 case ELF::DT_STRTAB:
1171 StringTableBegin = (const char *)toMappedAddr(Dyn.getPtr());
Simon Atanasyan72155c32016-01-16 22:40:09 +00001172 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001173 case ELF::DT_STRSZ:
1174 StringTableSize = Dyn.getVal();
Simon Atanasyan72155c32016-01-16 22:40:09 +00001175 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001176 case ELF::DT_SYMTAB:
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001177 DynSymRegion.Addr = toMappedAddr(Dyn.getPtr());
1178 DynSymRegion.EntSize = sizeof(Elf_Sym);
Simon Atanasyan72155c32016-01-16 22:40:09 +00001179 break;
George Rimar47936762016-01-16 00:49:19 +00001180 case ELF::DT_RELA:
1181 DynRelaRegion.Addr = toMappedAddr(Dyn.getPtr());
1182 break;
1183 case ELF::DT_RELASZ:
1184 DynRelaRegion.Size = Dyn.getVal();
1185 break;
1186 case ELF::DT_RELAENT:
1187 DynRelaRegion.EntSize = Dyn.getVal();
1188 break;
1189 case ELF::DT_SONAME:
1190 SONameOffset = Dyn.getVal();
1191 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001192 case ELF::DT_REL:
1193 DynRelRegion.Addr = toMappedAddr(Dyn.getPtr());
George Rimar47936762016-01-16 00:49:19 +00001194 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001195 case ELF::DT_RELSZ:
1196 DynRelRegion.Size = Dyn.getVal();
George Rimar47936762016-01-16 00:49:19 +00001197 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001198 case ELF::DT_RELENT:
1199 DynRelRegion.EntSize = Dyn.getVal();
George Rimar47936762016-01-16 00:49:19 +00001200 break;
Rafael Espindola944f6552016-02-16 15:16:00 +00001201 case ELF::DT_PLTREL:
1202 if (Dyn.getVal() == DT_REL)
1203 DynPLTRelRegion.EntSize = sizeof(Elf_Rel);
1204 else if (Dyn.getVal() == DT_RELA)
1205 DynPLTRelRegion.EntSize = sizeof(Elf_Rela);
1206 else
1207 reportError(Twine("unknown DT_PLTREL value of ") +
1208 Twine((uint64_t)Dyn.getVal()));
1209 break;
1210 case ELF::DT_JMPREL:
1211 DynPLTRelRegion.Addr = toMappedAddr(Dyn.getPtr());
1212 break;
1213 case ELF::DT_PLTRELSZ:
1214 DynPLTRelRegion.Size = Dyn.getVal();
1215 break;
George Rimar47936762016-01-16 00:49:19 +00001216 }
1217 }
1218 if (StringTableBegin)
1219 DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
1220 if (SONameOffset)
1221 SOName = getDynamicString(SONameOffset);
Rafael Espindola6009db62016-02-16 14:17:48 +00001222}
George Rimar47936762016-01-16 00:49:19 +00001223
Rafael Espindola6009db62016-02-16 14:17:48 +00001224template <typename ELFT>
Simon Atanasyan72155c32016-01-16 22:40:09 +00001225typename ELFDumper<ELFT>::Elf_Rel_Range ELFDumper<ELFT>::dyn_rels() const {
Rafael Espindolac70aeda2016-02-16 14:50:39 +00001226 return DynRelRegion.getAsRange<Elf_Rel>();
George Rimar47936762016-01-16 00:49:19 +00001227}
1228
1229template <typename ELFT>
1230typename ELFDumper<ELFT>::Elf_Rela_Range ELFDumper<ELFT>::dyn_relas() const {
Rafael Espindolac70aeda2016-02-16 14:50:39 +00001231 return DynRelaRegion.getAsRange<Elf_Rela>();
George Rimar47936762016-01-16 00:49:19 +00001232}
1233
1234template<class ELFT>
1235void ELFDumper<ELFT>::printFileHeaders() {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00001236 ELFDumperStyle->printFileHeaders(Obj);
George Rimar47936762016-01-16 00:49:19 +00001237}
1238
1239template<class ELFT>
1240void ELFDumper<ELFT>::printSections() {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001241 ELFDumperStyle->printSections(Obj);
George Rimar47936762016-01-16 00:49:19 +00001242}
1243
1244template<class ELFT>
1245void ELFDumper<ELFT>::printRelocations() {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001246 ELFDumperStyle->printRelocations(Obj);
George Rimar47936762016-01-16 00:49:19 +00001247}
1248
Simon Atanasyan72155c32016-01-16 22:40:09 +00001249template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001250 ELFDumperStyle->printDynamicRelocations(Obj);
George Rimar47936762016-01-16 00:49:19 +00001251}
1252
George Rimar47936762016-01-16 00:49:19 +00001253
1254template<class ELFT>
1255void ELFDumper<ELFT>::printSymbols() {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001256 ELFDumperStyle->printSymbols(Obj);
George Rimar47936762016-01-16 00:49:19 +00001257}
1258
1259template<class ELFT>
1260void ELFDumper<ELFT>::printDynamicSymbols() {
Hemant Kulkarnic030f232016-03-15 17:25:31 +00001261 ELFDumperStyle->printDynamicSymbols(Obj);
George Rimar47936762016-01-16 00:49:19 +00001262}
1263
George Rimar47936762016-01-16 00:49:19 +00001264
1265#define LLVM_READOBJ_TYPE_CASE(name) \
1266 case DT_##name: return #name
1267
1268static const char *getTypeString(uint64_t Type) {
1269 switch (Type) {
1270 LLVM_READOBJ_TYPE_CASE(BIND_NOW);
1271 LLVM_READOBJ_TYPE_CASE(DEBUG);
1272 LLVM_READOBJ_TYPE_CASE(FINI);
1273 LLVM_READOBJ_TYPE_CASE(FINI_ARRAY);
1274 LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ);
1275 LLVM_READOBJ_TYPE_CASE(FLAGS);
1276 LLVM_READOBJ_TYPE_CASE(FLAGS_1);
1277 LLVM_READOBJ_TYPE_CASE(HASH);
1278 LLVM_READOBJ_TYPE_CASE(INIT);
1279 LLVM_READOBJ_TYPE_CASE(INIT_ARRAY);
1280 LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ);
1281 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY);
1282 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ);
1283 LLVM_READOBJ_TYPE_CASE(JMPREL);
1284 LLVM_READOBJ_TYPE_CASE(NEEDED);
1285 LLVM_READOBJ_TYPE_CASE(NULL);
1286 LLVM_READOBJ_TYPE_CASE(PLTGOT);
1287 LLVM_READOBJ_TYPE_CASE(PLTREL);
1288 LLVM_READOBJ_TYPE_CASE(PLTRELSZ);
1289 LLVM_READOBJ_TYPE_CASE(REL);
1290 LLVM_READOBJ_TYPE_CASE(RELA);
1291 LLVM_READOBJ_TYPE_CASE(RELENT);
1292 LLVM_READOBJ_TYPE_CASE(RELSZ);
1293 LLVM_READOBJ_TYPE_CASE(RELAENT);
1294 LLVM_READOBJ_TYPE_CASE(RELASZ);
1295 LLVM_READOBJ_TYPE_CASE(RPATH);
1296 LLVM_READOBJ_TYPE_CASE(RUNPATH);
1297 LLVM_READOBJ_TYPE_CASE(SONAME);
1298 LLVM_READOBJ_TYPE_CASE(STRSZ);
1299 LLVM_READOBJ_TYPE_CASE(STRTAB);
1300 LLVM_READOBJ_TYPE_CASE(SYMBOLIC);
1301 LLVM_READOBJ_TYPE_CASE(SYMENT);
1302 LLVM_READOBJ_TYPE_CASE(SYMTAB);
1303 LLVM_READOBJ_TYPE_CASE(TEXTREL);
1304 LLVM_READOBJ_TYPE_CASE(VERDEF);
1305 LLVM_READOBJ_TYPE_CASE(VERDEFNUM);
1306 LLVM_READOBJ_TYPE_CASE(VERNEED);
1307 LLVM_READOBJ_TYPE_CASE(VERNEEDNUM);
George Rimare05fcec2016-01-16 10:38:32 +00001308 LLVM_READOBJ_TYPE_CASE(VERSYM);
Davide Italiano8c503672016-01-16 06:06:36 +00001309 LLVM_READOBJ_TYPE_CASE(RELACOUNT);
George Rimare05fcec2016-01-16 10:38:32 +00001310 LLVM_READOBJ_TYPE_CASE(RELCOUNT);
1311 LLVM_READOBJ_TYPE_CASE(GNU_HASH);
1312 LLVM_READOBJ_TYPE_CASE(TLSDESC_PLT);
1313 LLVM_READOBJ_TYPE_CASE(TLSDESC_GOT);
1314 LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION);
1315 LLVM_READOBJ_TYPE_CASE(MIPS_RLD_MAP_REL);
1316 LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS);
George Rimar47936762016-01-16 00:49:19 +00001317 LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS);
1318 LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO);
1319 LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO);
1320 LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO);
1321 LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM);
1322 LLVM_READOBJ_TYPE_CASE(MIPS_RLD_MAP);
1323 LLVM_READOBJ_TYPE_CASE(MIPS_PLTGOT);
1324 LLVM_READOBJ_TYPE_CASE(MIPS_OPTIONS);
1325 default: return "unknown";
1326 }
1327}
1328
1329#undef LLVM_READOBJ_TYPE_CASE
1330
1331#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \
1332 { #enum, prefix##_##enum }
1333
1334static const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
1335 LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
1336 LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
1337 LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
1338 LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
1339 LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
1340};
1341
1342static const EnumEntry<unsigned> ElfDynamicDTFlags1[] = {
1343 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW),
1344 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL),
1345 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP),
1346 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE),
1347 LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR),
1348 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST),
1349 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN),
1350 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN),
1351 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT),
1352 LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS),
1353 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE),
1354 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB),
1355 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP),
1356 LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT),
1357 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE),
1358 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE),
1359 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT),
1360 LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF),
1361 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS),
1362 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR),
1363 LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED),
1364 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC),
1365 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE),
1366 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT),
1367 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON)
1368};
1369
1370static const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
1371 LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
1372 LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
1373 LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
1374 LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
1375 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
1376 LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
1377 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
1378 LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
1379 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
1380 LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
1381 LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
1382 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
1383 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
1384 LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
1385 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
1386 LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
1387};
1388
1389#undef LLVM_READOBJ_DT_FLAG_ENT
1390
1391template <typename T, typename TFlag>
1392void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
1393 typedef EnumEntry<TFlag> FlagEntry;
1394 typedef SmallVector<FlagEntry, 10> FlagVector;
1395 FlagVector SetFlags;
1396
1397 for (const auto &Flag : Flags) {
1398 if (Flag.Value == 0)
1399 continue;
1400
1401 if ((Value & Flag.Value) == Flag.Value)
1402 SetFlags.push_back(Flag);
1403 }
1404
1405 for (const auto &Flag : SetFlags) {
1406 OS << Flag.Name << " ";
1407 }
1408}
1409
1410template <class ELFT>
1411StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
1412 if (Value >= DynamicStringTable.size())
1413 reportError("Invalid dynamic string table reference");
1414 return StringRef(DynamicStringTable.data() + Value);
1415}
1416
1417template <class ELFT>
1418void ELFDumper<ELFT>::printValue(uint64_t Type, uint64_t Value) {
1419 raw_ostream &OS = W.getOStream();
1420 switch (Type) {
1421 case DT_PLTREL:
1422 if (Value == DT_REL) {
1423 OS << "REL";
1424 break;
1425 } else if (Value == DT_RELA) {
1426 OS << "RELA";
1427 break;
1428 }
1429 // Fallthrough.
1430 case DT_PLTGOT:
1431 case DT_HASH:
1432 case DT_STRTAB:
1433 case DT_SYMTAB:
1434 case DT_RELA:
1435 case DT_INIT:
1436 case DT_FINI:
1437 case DT_REL:
1438 case DT_JMPREL:
1439 case DT_INIT_ARRAY:
1440 case DT_FINI_ARRAY:
1441 case DT_PREINIT_ARRAY:
1442 case DT_DEBUG:
1443 case DT_VERDEF:
1444 case DT_VERNEED:
1445 case DT_VERSYM:
1446 case DT_GNU_HASH:
1447 case DT_NULL:
1448 case DT_MIPS_BASE_ADDRESS:
1449 case DT_MIPS_GOTSYM:
1450 case DT_MIPS_RLD_MAP:
1451 case DT_MIPS_RLD_MAP_REL:
1452 case DT_MIPS_PLTGOT:
1453 case DT_MIPS_OPTIONS:
1454 OS << format("0x%" PRIX64, Value);
1455 break;
Davide Italiano8c503672016-01-16 06:06:36 +00001456 case DT_RELACOUNT:
George Rimar47936762016-01-16 00:49:19 +00001457 case DT_RELCOUNT:
1458 case DT_VERDEFNUM:
1459 case DT_VERNEEDNUM:
1460 case DT_MIPS_RLD_VERSION:
1461 case DT_MIPS_LOCAL_GOTNO:
1462 case DT_MIPS_SYMTABNO:
1463 case DT_MIPS_UNREFEXTNO:
1464 OS << Value;
1465 break;
1466 case DT_PLTRELSZ:
1467 case DT_RELASZ:
1468 case DT_RELAENT:
1469 case DT_STRSZ:
1470 case DT_SYMENT:
1471 case DT_RELSZ:
1472 case DT_RELENT:
1473 case DT_INIT_ARRAYSZ:
1474 case DT_FINI_ARRAYSZ:
1475 case DT_PREINIT_ARRAYSZ:
1476 OS << Value << " (bytes)";
1477 break;
1478 case DT_NEEDED:
1479 OS << "SharedLibrary (" << getDynamicString(Value) << ")";
1480 break;
1481 case DT_SONAME:
1482 OS << "LibrarySoname (" << getDynamicString(Value) << ")";
1483 break;
1484 case DT_RPATH:
1485 case DT_RUNPATH:
1486 OS << getDynamicString(Value);
1487 break;
1488 case DT_MIPS_FLAGS:
1489 printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS);
1490 break;
1491 case DT_FLAGS:
1492 printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
1493 break;
1494 case DT_FLAGS_1:
1495 printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS);
1496 break;
1497 default:
1498 OS << format("0x%" PRIX64, Value);
1499 break;
1500 }
1501}
1502
1503template<class ELFT>
1504void ELFDumper<ELFT>::printUnwindInfo() {
1505 W.startLine() << "UnwindInfo not implemented.\n";
1506}
1507
1508namespace {
1509template <> void ELFDumper<ELFType<support::little, false>>::printUnwindInfo() {
1510 const unsigned Machine = Obj->getHeader()->e_machine;
1511 if (Machine == EM_ARM) {
1512 ARM::EHABI::PrinterContext<ELFType<support::little, false>> Ctx(
1513 W, Obj, DotSymtabSec);
1514 return Ctx.PrintUnwindInformation();
1515 }
1516 W.startLine() << "UnwindInfo not implemented.\n";
1517}
1518}
1519
1520template<class ELFT>
1521void ELFDumper<ELFT>::printDynamicTable() {
Rafael Espindolae17c3f32016-02-17 16:48:00 +00001522 auto I = dynamic_table().begin();
1523 auto E = dynamic_table().end();
George Rimar47936762016-01-16 00:49:19 +00001524
1525 if (I == E)
1526 return;
1527
1528 --E;
1529 while (I != E && E->getTag() == ELF::DT_NULL)
1530 --E;
1531 if (E->getTag() != ELF::DT_NULL)
1532 ++E;
1533 ++E;
1534
1535 ptrdiff_t Total = std::distance(I, E);
1536 if (Total == 0)
1537 return;
1538
1539 raw_ostream &OS = W.getOStream();
1540 W.startLine() << "DynamicSection [ (" << Total << " entries)\n";
1541
1542 bool Is64 = ELFT::Is64Bits;
1543
1544 W.startLine()
1545 << " Tag" << (Is64 ? " " : " ") << "Type"
1546 << " " << "Name/Value\n";
1547 while (I != E) {
1548 const Elf_Dyn &Entry = *I;
1549 uintX_t Tag = Entry.getTag();
1550 ++I;
1551 W.startLine() << " " << format_hex(Tag, Is64 ? 18 : 10, true) << " "
1552 << format("%-21s", getTypeString(Tag));
1553 printValue(Tag, Entry.getVal());
1554 OS << "\n";
1555 }
1556
1557 W.startLine() << "]\n";
1558}
1559
1560template<class ELFT>
1561void ELFDumper<ELFT>::printNeededLibraries() {
1562 ListScope D(W, "NeededLibraries");
1563
1564 typedef std::vector<StringRef> LibsTy;
1565 LibsTy Libs;
1566
1567 for (const auto &Entry : dynamic_table())
1568 if (Entry.d_tag == ELF::DT_NEEDED)
1569 Libs.push_back(getDynamicString(Entry.d_un.d_val));
1570
1571 std::stable_sort(Libs.begin(), Libs.end());
1572
1573 for (const auto &L : Libs) {
1574 outs() << " " << L << "\n";
1575 }
1576}
1577
1578template<class ELFT>
1579void ELFDumper<ELFT>::printProgramHeaders() {
1580 ListScope L(W, "ProgramHeaders");
1581
1582 for (const Elf_Phdr &Phdr : Obj->program_headers()) {
1583 DictScope P(W, "ProgramHeader");
1584 W.printHex("Type",
1585 getElfSegmentType(Obj->getHeader()->e_machine, Phdr.p_type),
1586 Phdr.p_type);
1587 W.printHex("Offset", Phdr.p_offset);
1588 W.printHex("VirtualAddress", Phdr.p_vaddr);
1589 W.printHex("PhysicalAddress", Phdr.p_paddr);
1590 W.printNumber("FileSize", Phdr.p_filesz);
1591 W.printNumber("MemSize", Phdr.p_memsz);
1592 W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags));
1593 W.printNumber("Alignment", Phdr.p_align);
1594 }
1595}
1596
1597template <typename ELFT>
1598void ELFDumper<ELFT>::printHashTable() {
1599 DictScope D(W, "HashTable");
1600 if (!HashTable)
1601 return;
1602 W.printNumber("Num Buckets", HashTable->nbucket);
1603 W.printNumber("Num Chains", HashTable->nchain);
1604 W.printList("Buckets", HashTable->buckets());
1605 W.printList("Chains", HashTable->chains());
1606}
1607
1608template <typename ELFT>
1609void ELFDumper<ELFT>::printGnuHashTable() {
1610 DictScope D(W, "GnuHashTable");
1611 if (!GnuHashTable)
1612 return;
1613 W.printNumber("Num Buckets", GnuHashTable->nbuckets);
1614 W.printNumber("First Hashed Symbol Index", GnuHashTable->symndx);
1615 W.printNumber("Num Mask Words", GnuHashTable->maskwords);
1616 W.printNumber("Shift Count", GnuHashTable->shift2);
1617 W.printHexList("Bloom Filter", GnuHashTable->filter());
1618 W.printList("Buckets", GnuHashTable->buckets());
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001619 Elf_Sym_Range Syms = dynamic_symbols();
1620 unsigned NumSyms = std::distance(Syms.begin(), Syms.end());
1621 if (!NumSyms)
George Rimar47936762016-01-16 00:49:19 +00001622 reportError("No dynamic symbol section");
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001623 W.printHexList("Values", GnuHashTable->values(NumSyms));
George Rimar47936762016-01-16 00:49:19 +00001624}
1625
1626template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {
1627 outs() << "LoadName: " << SOName << '\n';
1628}
1629
1630template <class ELFT>
1631void ELFDumper<ELFT>::printAttributes() {
1632 W.startLine() << "Attributes not implemented.\n";
1633}
1634
1635namespace {
1636template <> void ELFDumper<ELFType<support::little, false>>::printAttributes() {
1637 if (Obj->getHeader()->e_machine != EM_ARM) {
1638 W.startLine() << "Attributes not implemented.\n";
1639 return;
1640 }
1641
1642 DictScope BA(W, "BuildAttributes");
1643 for (const ELFO::Elf_Shdr &Sec : Obj->sections()) {
1644 if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES)
1645 continue;
1646
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001647 ArrayRef<uint8_t> Contents = unwrapOrError(Obj->getSectionContents(&Sec));
1648 if (Contents[0] != ARMBuildAttrs::Format_Version) {
1649 errs() << "unrecognised FormatVersion: 0x" << utohexstr(Contents[0])
George Rimar47936762016-01-16 00:49:19 +00001650 << '\n';
1651 continue;
1652 }
1653
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001654 W.printHex("FormatVersion", Contents[0]);
1655 if (Contents.size() == 1)
George Rimar47936762016-01-16 00:49:19 +00001656 continue;
1657
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001658 ARMAttributeParser(W).Parse(Contents);
George Rimar47936762016-01-16 00:49:19 +00001659 }
1660}
1661}
1662
1663namespace {
1664template <class ELFT> class MipsGOTParser {
1665public:
1666 typedef object::ELFFile<ELFT> ELFO;
1667 typedef typename ELFO::Elf_Shdr Elf_Shdr;
1668 typedef typename ELFO::Elf_Sym Elf_Sym;
1669 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range;
1670 typedef typename ELFO::Elf_Addr GOTEntry;
1671 typedef typename ELFO::Elf_Rel Elf_Rel;
1672 typedef typename ELFO::Elf_Rela Elf_Rela;
1673
1674 MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
1675 Elf_Dyn_Range DynTable, StreamWriter &W);
1676
1677 void parseGOT();
1678 void parsePLT();
1679
1680private:
1681 ELFDumper<ELFT> *Dumper;
1682 const ELFO *Obj;
1683 StreamWriter &W;
1684 llvm::Optional<uint64_t> DtPltGot;
1685 llvm::Optional<uint64_t> DtLocalGotNum;
1686 llvm::Optional<uint64_t> DtGotSym;
1687 llvm::Optional<uint64_t> DtMipsPltGot;
1688 llvm::Optional<uint64_t> DtJmpRel;
1689
1690 std::size_t getGOTTotal(ArrayRef<uint8_t> GOT) const;
1691 const GOTEntry *makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum);
1692
1693 void printGotEntry(uint64_t GotAddr, const GOTEntry *BeginIt,
1694 const GOTEntry *It);
1695 void printGlobalGotEntry(uint64_t GotAddr, const GOTEntry *BeginIt,
1696 const GOTEntry *It, const Elf_Sym *Sym,
1697 StringRef StrTable, bool IsDynamic);
1698 void printPLTEntry(uint64_t PLTAddr, const GOTEntry *BeginIt,
1699 const GOTEntry *It, StringRef Purpose);
1700 void printPLTEntry(uint64_t PLTAddr, const GOTEntry *BeginIt,
1701 const GOTEntry *It, StringRef StrTable,
1702 const Elf_Sym *Sym);
1703};
1704}
1705
1706template <class ELFT>
1707MipsGOTParser<ELFT>::MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
1708 Elf_Dyn_Range DynTable, StreamWriter &W)
1709 : Dumper(Dumper), Obj(Obj), W(W) {
1710 for (const auto &Entry : DynTable) {
1711 switch (Entry.getTag()) {
1712 case ELF::DT_PLTGOT:
1713 DtPltGot = Entry.getVal();
1714 break;
1715 case ELF::DT_MIPS_LOCAL_GOTNO:
1716 DtLocalGotNum = Entry.getVal();
1717 break;
1718 case ELF::DT_MIPS_GOTSYM:
1719 DtGotSym = Entry.getVal();
1720 break;
1721 case ELF::DT_MIPS_PLTGOT:
1722 DtMipsPltGot = Entry.getVal();
1723 break;
1724 case ELF::DT_JMPREL:
1725 DtJmpRel = Entry.getVal();
1726 break;
1727 }
1728 }
1729}
1730
1731template <class ELFT> void MipsGOTParser<ELFT>::parseGOT() {
1732 // See "Global Offset Table" in Chapter 5 in the following document
1733 // for detailed GOT description.
1734 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1735 if (!DtPltGot) {
1736 W.startLine() << "Cannot find PLTGOT dynamic table tag.\n";
1737 return;
1738 }
1739 if (!DtLocalGotNum) {
1740 W.startLine() << "Cannot find MIPS_LOCAL_GOTNO dynamic table tag.\n";
1741 return;
1742 }
1743 if (!DtGotSym) {
1744 W.startLine() << "Cannot find MIPS_GOTSYM dynamic table tag.\n";
1745 return;
1746 }
1747
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001748 StringRef StrTable = Dumper->getDynamicStringTable();
1749 const Elf_Sym *DynSymBegin = Dumper->dynamic_symbols().begin();
1750 const Elf_Sym *DynSymEnd = Dumper->dynamic_symbols().end();
George Rimar47936762016-01-16 00:49:19 +00001751 std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
1752
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001753 if (*DtGotSym > DynSymTotal)
1754 report_fatal_error("MIPS_GOTSYM exceeds a number of dynamic symbols");
George Rimar47936762016-01-16 00:49:19 +00001755
1756 std::size_t GlobalGotNum = DynSymTotal - *DtGotSym;
1757
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001758 if (*DtLocalGotNum + GlobalGotNum == 0) {
1759 W.startLine() << "GOT is empty.\n";
George Rimar47936762016-01-16 00:49:19 +00001760 return;
1761 }
1762
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001763 const Elf_Shdr *GOTShdr = findNotEmptySectionByAddress(Obj, *DtPltGot);
1764 if (!GOTShdr)
1765 report_fatal_error("There is no not empty GOT section at 0x" +
1766 Twine::utohexstr(*DtPltGot));
1767
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001768 ArrayRef<uint8_t> GOT = unwrapOrError(Obj->getSectionContents(GOTShdr));
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001769
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001770 if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(GOT))
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001771 report_fatal_error("Number of GOT entries exceeds the size of GOT section");
1772
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001773 const GOTEntry *GotBegin = makeGOTIter(GOT, 0);
1774 const GOTEntry *GotLocalEnd = makeGOTIter(GOT, *DtLocalGotNum);
George Rimar47936762016-01-16 00:49:19 +00001775 const GOTEntry *It = GotBegin;
1776
1777 DictScope GS(W, "Primary GOT");
1778
1779 W.printHex("Canonical gp value", GOTShdr->sh_addr + 0x7ff0);
1780 {
1781 ListScope RS(W, "Reserved entries");
1782
1783 {
1784 DictScope D(W, "Entry");
1785 printGotEntry(GOTShdr->sh_addr, GotBegin, It++);
1786 W.printString("Purpose", StringRef("Lazy resolver"));
1787 }
1788
1789 if (It != GotLocalEnd && (*It >> (sizeof(GOTEntry) * 8 - 1)) != 0) {
1790 DictScope D(W, "Entry");
1791 printGotEntry(GOTShdr->sh_addr, GotBegin, It++);
1792 W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
1793 }
1794 }
1795 {
1796 ListScope LS(W, "Local entries");
1797 for (; It != GotLocalEnd; ++It) {
1798 DictScope D(W, "Entry");
1799 printGotEntry(GOTShdr->sh_addr, GotBegin, It);
1800 }
1801 }
1802 {
1803 ListScope GS(W, "Global entries");
1804
1805 const GOTEntry *GotGlobalEnd =
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001806 makeGOTIter(GOT, *DtLocalGotNum + GlobalGotNum);
George Rimar47936762016-01-16 00:49:19 +00001807 const Elf_Sym *GotDynSym = DynSymBegin + *DtGotSym;
1808 for (; It != GotGlobalEnd; ++It) {
1809 DictScope D(W, "Entry");
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001810 printGlobalGotEntry(GOTShdr->sh_addr, GotBegin, It, GotDynSym++, StrTable,
1811 true);
George Rimar47936762016-01-16 00:49:19 +00001812 }
1813 }
1814
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001815 std::size_t SpecGotNum = getGOTTotal(GOT) - *DtLocalGotNum - GlobalGotNum;
George Rimar47936762016-01-16 00:49:19 +00001816 W.printNumber("Number of TLS and multi-GOT entries", uint64_t(SpecGotNum));
1817}
1818
1819template <class ELFT> void MipsGOTParser<ELFT>::parsePLT() {
1820 if (!DtMipsPltGot) {
1821 W.startLine() << "Cannot find MIPS_PLTGOT dynamic table tag.\n";
1822 return;
1823 }
1824 if (!DtJmpRel) {
1825 W.startLine() << "Cannot find JMPREL dynamic table tag.\n";
1826 return;
1827 }
1828
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001829 const Elf_Shdr *PLTShdr = findNotEmptySectionByAddress(Obj, *DtMipsPltGot);
1830 if (!PLTShdr)
1831 report_fatal_error("There is no not empty PLTGOT section at 0x " +
1832 Twine::utohexstr(*DtMipsPltGot));
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001833 ArrayRef<uint8_t> PLT = unwrapOrError(Obj->getSectionContents(PLTShdr));
George Rimar47936762016-01-16 00:49:19 +00001834
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001835 const Elf_Shdr *PLTRelShdr = findNotEmptySectionByAddress(Obj, *DtJmpRel);
1836 if (!PLTRelShdr)
1837 report_fatal_error("There is no not empty RELPLT section at 0x" +
1838 Twine::utohexstr(*DtJmpRel));
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001839 const Elf_Shdr *SymTable =
1840 unwrapOrError(Obj->getSection(PLTRelShdr->sh_link));
1841 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTable));
George Rimar47936762016-01-16 00:49:19 +00001842
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001843 const GOTEntry *PLTBegin = makeGOTIter(PLT, 0);
1844 const GOTEntry *PLTEnd = makeGOTIter(PLT, getGOTTotal(PLT));
George Rimar47936762016-01-16 00:49:19 +00001845 const GOTEntry *It = PLTBegin;
1846
1847 DictScope GS(W, "PLT GOT");
1848 {
1849 ListScope RS(W, "Reserved entries");
1850 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It++, "PLT lazy resolver");
1851 if (It != PLTEnd)
1852 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It++, "Module pointer");
1853 }
1854 {
1855 ListScope GS(W, "Entries");
1856
1857 switch (PLTRelShdr->sh_type) {
1858 case ELF::SHT_REL:
1859 for (const Elf_Rel *RI = Obj->rel_begin(PLTRelShdr),
1860 *RE = Obj->rel_end(PLTRelShdr);
1861 RI != RE && It != PLTEnd; ++RI, ++It) {
1862 const Elf_Sym *Sym = Obj->getRelocationSymbol(&*RI, SymTable);
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001863 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, StrTable, Sym);
George Rimar47936762016-01-16 00:49:19 +00001864 }
1865 break;
1866 case ELF::SHT_RELA:
1867 for (const Elf_Rela *RI = Obj->rela_begin(PLTRelShdr),
1868 *RE = Obj->rela_end(PLTRelShdr);
1869 RI != RE && It != PLTEnd; ++RI, ++It) {
1870 const Elf_Sym *Sym = Obj->getRelocationSymbol(&*RI, SymTable);
Rafael Espindolaf04f1842016-02-17 16:21:49 +00001871 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, StrTable, Sym);
George Rimar47936762016-01-16 00:49:19 +00001872 }
1873 break;
1874 }
1875 }
1876}
1877
1878template <class ELFT>
1879std::size_t MipsGOTParser<ELFT>::getGOTTotal(ArrayRef<uint8_t> GOT) const {
1880 return GOT.size() / sizeof(GOTEntry);
1881}
1882
1883template <class ELFT>
1884const typename MipsGOTParser<ELFT>::GOTEntry *
1885MipsGOTParser<ELFT>::makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum) {
1886 const char *Data = reinterpret_cast<const char *>(GOT.data());
1887 return reinterpret_cast<const GOTEntry *>(Data + EntryNum * sizeof(GOTEntry));
1888}
1889
1890template <class ELFT>
1891void MipsGOTParser<ELFT>::printGotEntry(uint64_t GotAddr,
1892 const GOTEntry *BeginIt,
1893 const GOTEntry *It) {
1894 int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry);
1895 W.printHex("Address", GotAddr + Offset);
1896 W.printNumber("Access", Offset - 0x7ff0);
1897 W.printHex("Initial", *It);
1898}
1899
1900template <class ELFT>
1901void MipsGOTParser<ELFT>::printGlobalGotEntry(
1902 uint64_t GotAddr, const GOTEntry *BeginIt, const GOTEntry *It,
1903 const Elf_Sym *Sym, StringRef StrTable, bool IsDynamic) {
1904 printGotEntry(GotAddr, BeginIt, It);
1905
1906 W.printHex("Value", Sym->st_value);
1907 W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes));
1908
1909 unsigned SectionIndex = 0;
1910 StringRef SectionName;
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001911 getSectionNameIndex(*Obj, Sym, Dumper->dynamic_symbols().begin(),
George Rimar47936762016-01-16 00:49:19 +00001912 Dumper->getShndxTable(), SectionName, SectionIndex);
1913 W.printHex("Section", SectionName, SectionIndex);
1914
1915 std::string FullSymbolName =
1916 Dumper->getFullSymbolName(Sym, StrTable, IsDynamic);
1917 W.printNumber("Name", FullSymbolName, Sym->st_name);
1918}
1919
1920template <class ELFT>
1921void MipsGOTParser<ELFT>::printPLTEntry(uint64_t PLTAddr,
1922 const GOTEntry *BeginIt,
1923 const GOTEntry *It, StringRef Purpose) {
1924 DictScope D(W, "Entry");
1925 int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry);
1926 W.printHex("Address", PLTAddr + Offset);
1927 W.printHex("Initial", *It);
1928 W.printString("Purpose", Purpose);
1929}
1930
1931template <class ELFT>
1932void MipsGOTParser<ELFT>::printPLTEntry(uint64_t PLTAddr,
1933 const GOTEntry *BeginIt,
1934 const GOTEntry *It, StringRef StrTable,
1935 const Elf_Sym *Sym) {
1936 DictScope D(W, "Entry");
1937 int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry);
1938 W.printHex("Address", PLTAddr + Offset);
1939 W.printHex("Initial", *It);
1940 W.printHex("Value", Sym->st_value);
1941 W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes));
1942
1943 unsigned SectionIndex = 0;
1944 StringRef SectionName;
Rafael Espindolace2fbdd2016-02-17 15:38:21 +00001945 getSectionNameIndex(*Obj, Sym, Dumper->dynamic_symbols().begin(),
George Rimar47936762016-01-16 00:49:19 +00001946 Dumper->getShndxTable(), SectionName, SectionIndex);
1947 W.printHex("Section", SectionName, SectionIndex);
1948
1949 std::string FullSymbolName = Dumper->getFullSymbolName(Sym, StrTable, true);
1950 W.printNumber("Name", FullSymbolName, Sym->st_name);
1951}
1952
1953template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
1954 if (Obj->getHeader()->e_machine != EM_MIPS) {
1955 W.startLine() << "MIPS PLT GOT is available for MIPS targets only.\n";
1956 return;
1957 }
1958
1959 MipsGOTParser<ELFT> GOTParser(this, Obj, dynamic_table(), W);
1960 GOTParser.parseGOT();
1961 GOTParser.parsePLT();
1962}
1963
1964static const EnumEntry<unsigned> ElfMipsISAExtType[] = {
1965 {"None", Mips::AFL_EXT_NONE},
1966 {"Broadcom SB-1", Mips::AFL_EXT_SB1},
1967 {"Cavium Networks Octeon", Mips::AFL_EXT_OCTEON},
1968 {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2},
1969 {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP},
1970 {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3},
1971 {"LSI R4010", Mips::AFL_EXT_4010},
1972 {"Loongson 2E", Mips::AFL_EXT_LOONGSON_2E},
1973 {"Loongson 2F", Mips::AFL_EXT_LOONGSON_2F},
1974 {"Loongson 3A", Mips::AFL_EXT_LOONGSON_3A},
1975 {"MIPS R4650", Mips::AFL_EXT_4650},
1976 {"MIPS R5900", Mips::AFL_EXT_5900},
1977 {"MIPS R10000", Mips::AFL_EXT_10000},
1978 {"NEC VR4100", Mips::AFL_EXT_4100},
1979 {"NEC VR4111/VR4181", Mips::AFL_EXT_4111},
1980 {"NEC VR4120", Mips::AFL_EXT_4120},
1981 {"NEC VR5400", Mips::AFL_EXT_5400},
1982 {"NEC VR5500", Mips::AFL_EXT_5500},
1983 {"RMI Xlr", Mips::AFL_EXT_XLR},
1984 {"Toshiba R3900", Mips::AFL_EXT_3900}
1985};
1986
1987static const EnumEntry<unsigned> ElfMipsASEFlags[] = {
1988 {"DSP", Mips::AFL_ASE_DSP},
1989 {"DSPR2", Mips::AFL_ASE_DSPR2},
1990 {"Enhanced VA Scheme", Mips::AFL_ASE_EVA},
1991 {"MCU", Mips::AFL_ASE_MCU},
1992 {"MDMX", Mips::AFL_ASE_MDMX},
1993 {"MIPS-3D", Mips::AFL_ASE_MIPS3D},
1994 {"MT", Mips::AFL_ASE_MT},
1995 {"SmartMIPS", Mips::AFL_ASE_SMARTMIPS},
1996 {"VZ", Mips::AFL_ASE_VIRT},
1997 {"MSA", Mips::AFL_ASE_MSA},
1998 {"MIPS16", Mips::AFL_ASE_MIPS16},
1999 {"microMIPS", Mips::AFL_ASE_MICROMIPS},
2000 {"XPA", Mips::AFL_ASE_XPA}
2001};
2002
2003static const EnumEntry<unsigned> ElfMipsFpABIType[] = {
2004 {"Hard or soft float", Mips::Val_GNU_MIPS_ABI_FP_ANY},
2005 {"Hard float (double precision)", Mips::Val_GNU_MIPS_ABI_FP_DOUBLE},
2006 {"Hard float (single precision)", Mips::Val_GNU_MIPS_ABI_FP_SINGLE},
2007 {"Soft float", Mips::Val_GNU_MIPS_ABI_FP_SOFT},
2008 {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)",
2009 Mips::Val_GNU_MIPS_ABI_FP_OLD_64},
2010 {"Hard float (32-bit CPU, Any FPU)", Mips::Val_GNU_MIPS_ABI_FP_XX},
2011 {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64},
2012 {"Hard float compat (32-bit CPU, 64-bit FPU)",
2013 Mips::Val_GNU_MIPS_ABI_FP_64A}
2014};
2015
2016static const EnumEntry<unsigned> ElfMipsFlags1[] {
2017 {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG},
2018};
2019
2020static int getMipsRegisterSize(uint8_t Flag) {
2021 switch (Flag) {
2022 case Mips::AFL_REG_NONE:
2023 return 0;
2024 case Mips::AFL_REG_32:
2025 return 32;
2026 case Mips::AFL_REG_64:
2027 return 64;
2028 case Mips::AFL_REG_128:
2029 return 128;
2030 default:
2031 return -1;
2032 }
2033}
2034
2035template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() {
2036 const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.abiflags");
2037 if (!Shdr) {
2038 W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
2039 return;
2040 }
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002041 ArrayRef<uint8_t> Sec = unwrapOrError(Obj->getSectionContents(Shdr));
2042 if (Sec.size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) {
George Rimar47936762016-01-16 00:49:19 +00002043 W.startLine() << "The .MIPS.abiflags section has a wrong size.\n";
2044 return;
2045 }
2046
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002047 auto *Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(Sec.data());
George Rimar47936762016-01-16 00:49:19 +00002048
2049 raw_ostream &OS = W.getOStream();
2050 DictScope GS(W, "MIPS ABI Flags");
2051
2052 W.printNumber("Version", Flags->version);
2053 W.startLine() << "ISA: ";
2054 if (Flags->isa_rev <= 1)
2055 OS << format("MIPS%u", Flags->isa_level);
2056 else
2057 OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev);
2058 OS << "\n";
2059 W.printEnum("ISA Extension", Flags->isa_ext, makeArrayRef(ElfMipsISAExtType));
2060 W.printFlags("ASEs", Flags->ases, makeArrayRef(ElfMipsASEFlags));
2061 W.printEnum("FP ABI", Flags->fp_abi, makeArrayRef(ElfMipsFpABIType));
2062 W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size));
2063 W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size));
2064 W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size));
2065 W.printFlags("Flags 1", Flags->flags1, makeArrayRef(ElfMipsFlags1));
2066 W.printHex("Flags 2", Flags->flags2);
2067}
2068
2069template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
2070 const Elf_Shdr *Shdr = findSectionByName(*Obj, ".reginfo");
2071 if (!Shdr) {
2072 W.startLine() << "There is no .reginfo section in the file.\n";
2073 return;
2074 }
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002075 ArrayRef<uint8_t> Sec = unwrapOrError(Obj->getSectionContents(Shdr));
2076 if (Sec.size() != sizeof(Elf_Mips_RegInfo<ELFT>)) {
George Rimar47936762016-01-16 00:49:19 +00002077 W.startLine() << "The .reginfo section has a wrong size.\n";
2078 return;
2079 }
2080
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002081 auto *Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(Sec.data());
George Rimar47936762016-01-16 00:49:19 +00002082
2083 DictScope GS(W, "MIPS RegInfo");
2084 W.printHex("GP", Reginfo->ri_gp_value);
2085 W.printHex("General Mask", Reginfo->ri_gprmask);
2086 W.printHex("Co-Proc Mask0", Reginfo->ri_cprmask[0]);
2087 W.printHex("Co-Proc Mask1", Reginfo->ri_cprmask[1]);
2088 W.printHex("Co-Proc Mask2", Reginfo->ri_cprmask[2]);
2089 W.printHex("Co-Proc Mask3", Reginfo->ri_cprmask[3]);
2090}
2091
2092template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
2093 const Elf_Shdr *StackMapSection = nullptr;
2094 for (const auto &Sec : Obj->sections()) {
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002095 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2096 if (Name == ".llvm_stackmaps") {
George Rimar47936762016-01-16 00:49:19 +00002097 StackMapSection = &Sec;
2098 break;
2099 }
2100 }
2101
2102 if (!StackMapSection)
2103 return;
2104
2105 StringRef StackMapContents;
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002106 ArrayRef<uint8_t> StackMapContentsArray =
2107 unwrapOrError(Obj->getSectionContents(StackMapSection));
George Rimar47936762016-01-16 00:49:19 +00002108
Rafael Espindolaf04f1842016-02-17 16:21:49 +00002109 prettyPrintStackMap(llvm::outs(), StackMapV1Parser<ELFT::TargetEndianness>(
2110 StackMapContentsArray));
George Rimar47936762016-01-16 00:49:19 +00002111}
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002112
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +00002113template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
Hemant Kulkarni206ba842016-03-09 19:16:13 +00002114 ELFDumperStyle->printGroupSections(Obj);
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +00002115}
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002116
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002117static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
2118 StringRef Str2) {
2119 OS.PadToColumn(2u);
2120 OS << Str1;
2121 OS.PadToColumn(37u);
2122 OS << Str2 << "\n";
2123 OS.flush();
2124}
2125
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002126template <class ELFT> void GNUStyle<ELFT>::printFileHeaders(const ELFO *Obj) {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002127 const Elf_Ehdr *e = Obj->getHeader();
2128 OS << "ELF Header:\n";
2129 OS << " Magic: ";
2130 std::string Str;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002131 for (int i = 0; i < ELF::EI_NIDENT; i++)
2132 OS << format(" %02x", static_cast<int>(e->e_ident[i]));
2133 OS << "\n";
2134 Str = printEnum(e->e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002135 printFields(OS, "Class:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002136 Str = printEnum(e->e_ident[ELF::EI_DATA], makeArrayRef(ElfDataEncoding));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002137 printFields(OS, "Data:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002138 OS.PadToColumn(2u);
2139 OS << "Version:";
2140 OS.PadToColumn(37u);
2141 OS << to_hexString(e->e_ident[ELF::EI_VERSION]);
2142 if (e->e_version == ELF::EV_CURRENT)
2143 OS << " (current)";
2144 OS << "\n";
2145 Str = printEnum(e->e_ident[ELF::EI_OSABI], makeArrayRef(ElfOSABI));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002146 printFields(OS, "OS/ABI:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002147 Str = "0x" + to_hexString(e->e_version);
2148 Str = to_hexString(e->e_ident[ELF::EI_ABIVERSION]);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002149 printFields(OS, "ABI Version:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002150 Str = printEnum(e->e_type, makeArrayRef(ElfObjectFileType));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002151 printFields(OS, "Type:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002152 Str = printEnum(e->e_machine, makeArrayRef(ElfMachineType));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002153 printFields(OS, "Machine:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002154 Str = "0x" + to_hexString(e->e_version);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002155 printFields(OS, "Version:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002156 Str = "0x" + to_hexString(e->e_entry);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002157 printFields(OS, "Entry point address:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002158 Str = to_string(e->e_phoff) + " (bytes into file)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002159 printFields(OS, "Start of program headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002160 Str = to_string(e->e_shoff) + " (bytes into file)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002161 printFields(OS, "Start of section headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002162 Str = "0x" + to_hexString(e->e_flags);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002163 printFields(OS, "Flags:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002164 Str = to_string(e->e_ehsize) + " (bytes)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002165 printFields(OS, "Size of this header:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002166 Str = to_string(e->e_phentsize) + " (bytes)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002167 printFields(OS, "Size of program headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002168 Str = to_string(e->e_phnum);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002169 printFields(OS, "Number of program headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002170 Str = to_string(e->e_shentsize) + " (bytes)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002171 printFields(OS, "Size of section headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002172 Str = to_string(e->e_shnum);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002173 printFields(OS, "Number of section headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002174 Str = to_string(e->e_shstrndx);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002175 printFields(OS, "Section header string table index:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002176}
2177
Hemant Kulkarni206ba842016-03-09 19:16:13 +00002178template <class ELFT> void GNUStyle<ELFT>::printGroupSections(const ELFO *Obj) {
2179 uint32_t SectionIndex = 0;
2180 bool HasGroups = false;
2181 for (const Elf_Shdr &Sec : Obj->sections()) {
2182 if (Sec.sh_type == ELF::SHT_GROUP) {
2183 HasGroups = true;
2184 const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link));
2185 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
2186 const Elf_Sym *Signature =
2187 Obj->template getEntry<Elf_Sym>(Symtab, Sec.sh_info);
2188 ArrayRef<Elf_Word> Data = unwrapOrError(
2189 Obj->template getSectionContentsAsArray<Elf_Word>(&Sec));
2190 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2191 OS << "\n" << getGroupType(Data[0]) << " group section ["
2192 << format_decimal(SectionIndex, 5) << "] `" << Name << "' ["
2193 << StrTable.data() + Signature->st_name << "] contains "
2194 << (Data.size() - 1) << " sections:\n"
2195 << " [Index] Name\n";
2196 for (auto &Ndx : Data.slice(1)) {
2197 auto Sec = unwrapOrError(Obj->getSection(Ndx));
2198 const StringRef Name = unwrapOrError(Obj->getSectionName(Sec));
2199 OS << " [" << format_decimal(Ndx, 5) << "] " << Name
2200 << "\n";
2201 }
2202 }
2203 ++SectionIndex;
2204 }
2205 if (!HasGroups)
2206 OS << "There are no section groups in this file.\n";
2207}
2208
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002209template <class ELFT>
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002210void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
2211 const Elf_Rela &R, bool IsRela) {
2212 std::string Offset, Info, Addend = "", Value;
2213 SmallString<32> RelocName;
2214 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
2215 StringRef TargetName;
2216 const Elf_Sym *Sym = nullptr;
2217 unsigned Bias;
2218 unsigned Width;
2219
2220 if (ELFT::Is64Bits) {
2221 Bias = 8;
2222 Width = 16;
2223 } else {
2224 Bias = 0;
2225 Width = 8;
2226 }
2227
2228 // First two fields are bit width dependent. The rest of them are after are
2229 // fixed width.
2230 Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
2231 Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
2232 Sym = Obj->getRelocationSymbol(&R, SymTab);
2233 if (Sym && Sym->getType() == ELF::STT_SECTION) {
2234 const Elf_Shdr *Sec = unwrapOrError(
2235 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
2236 TargetName = unwrapOrError(Obj->getSectionName(Sec));
2237 } else if (Sym) {
2238 TargetName = unwrapOrError(Sym->getName(StrTable));
2239 }
2240
2241 if (Sym && IsRela) {
2242 if (R.r_addend < 0)
2243 Addend = " - ";
2244 else
2245 Addend = " + ";
2246 }
2247
2248 Offset = to_string(format_hex_no_prefix(R.r_offset, Width));
2249 Info = to_string(format_hex_no_prefix(R.r_info, Width));
2250
2251 int64_t RelAddend = R.r_addend;
2252 if (IsRela)
2253 Addend += to_hexString(std::abs(RelAddend), false);
2254
2255 if (Sym)
2256 Value = to_string(format_hex_no_prefix(Sym->getValue(), Width));
2257
2258 Fields[0].Str = Offset;
2259 Fields[1].Str = Info;
2260 Fields[2].Str = RelocName;
2261 Fields[3].Str = Value;
2262 Fields[4].Str = TargetName;
2263 for (auto &field : Fields)
2264 printField(field);
2265 if (IsRela)
2266 OS << Addend;
2267 OS << "\n";
2268}
2269
2270template <class ELFT> void GNUStyle<ELFT>::printRelocations(const ELFO *Obj) {
2271 bool HasRelocSections = false;
2272 for (const Elf_Shdr &Sec : Obj->sections()) {
2273 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA)
2274 continue;
2275 HasRelocSections = true;
2276 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2277 unsigned Entries = Sec.getEntityCount();
2278 uintX_t Offset = Sec.sh_offset;
2279 OS << "\nRelocation section '" << Name << "' at offset 0x"
2280 << to_hexString(Offset, false) << " contains " << Entries
2281 << " entries:\n";
2282 if (ELFT::Is64Bits)
2283 OS << " Offset Info Type"
2284 << " Symbol's Value Symbol's Name";
2285 else
2286 OS << " Offset Info Type Sym. Value "
2287 << "Symbol's Name";
2288 OS << ((Sec.sh_type == ELF::SHT_RELA) ? " + Addend" : "") << "\n";
2289
2290 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec.sh_link));
2291 if (Sec.sh_type == ELF::SHT_REL) {
2292 for (const auto &R : Obj->rels(&Sec)) {
2293 Elf_Rela Rela;
2294 Rela.r_offset = R.r_offset;
2295 Rela.r_info = R.r_info;
2296 Rela.r_addend = 0;
2297 printRelocation(Obj, SymTab, Rela, false);
2298 }
2299 } else {
2300 for (const auto &R : Obj->relas(&Sec))
2301 printRelocation(Obj, SymTab, R, true);
2302 }
2303 }
2304 if (!HasRelocSections)
2305 OS << "\nThere are no relocations in this file.\n";
2306}
2307
2308std::string getSectionTypeString(unsigned Arch, unsigned Type) {
2309 using namespace ELF;
2310 switch (Arch) {
2311 case EM_ARM:
2312 switch (Type) {
2313 case SHT_ARM_EXIDX:
2314 return "ARM_EXIDX";
2315 case SHT_ARM_PREEMPTMAP:
2316 return "ARM_PREEMPTMAP";
2317 case SHT_ARM_ATTRIBUTES:
2318 return "ARM_ATTRIBUTES";
2319 case SHT_ARM_DEBUGOVERLAY:
2320 return "ARM_DEBUGOVERLAY";
2321 case SHT_ARM_OVERLAYSECTION:
2322 return "ARM_OVERLAYSECTION";
2323 }
2324 case EM_X86_64:
2325 switch (Type) {
2326 case SHT_X86_64_UNWIND:
2327 return "X86_64_UNWIND";
2328 }
2329 case EM_MIPS:
2330 case EM_MIPS_RS3_LE:
2331 switch (Type) {
2332 case SHT_MIPS_REGINFO:
2333 return "MIPS_REGINFO";
2334 case SHT_MIPS_OPTIONS:
2335 return "MIPS_OPTIONS";
2336 case SHT_MIPS_ABIFLAGS:
2337 return "MIPS_ABIFLAGS";
2338 }
2339 }
2340 switch (Type) {
2341 case SHT_NULL:
2342 return "NULL";
2343 case SHT_PROGBITS:
2344 return "PROGBITS";
2345 case SHT_SYMTAB:
2346 return "SYMTAB";
2347 case SHT_STRTAB:
2348 return "STRTAB";
2349 case SHT_RELA:
2350 return "RELA";
2351 case SHT_HASH:
2352 return "HASH";
2353 case SHT_DYNAMIC:
2354 return "DYNAMIC";
2355 case SHT_NOTE:
2356 return "NOTE";
2357 case SHT_NOBITS:
2358 return "NOBITS";
2359 case SHT_REL:
2360 return "REL";
2361 case SHT_SHLIB:
2362 return "SHLIB";
2363 case SHT_DYNSYM:
2364 return "DYNSYM";
2365 case SHT_INIT_ARRAY:
2366 return "INIT_ARRAY";
2367 case SHT_FINI_ARRAY:
2368 return "FINI_ARRAY";
2369 case SHT_PREINIT_ARRAY:
2370 return "PREINIT_ARRAY";
2371 case SHT_GROUP:
2372 return "GROUP";
2373 case SHT_SYMTAB_SHNDX:
2374 return "SYMTAB SECTION INDICES";
2375 // FIXME: Parse processor specific GNU attributes
2376 case SHT_GNU_ATTRIBUTES:
2377 return "ATTRIBUTES";
2378 case SHT_GNU_HASH:
2379 return "GNU_HASH";
2380 case SHT_GNU_verdef:
2381 return "VERDEF";
2382 case SHT_GNU_verneed:
2383 return "VERNEED";
2384 case SHT_GNU_versym:
2385 return "VERSYM";
2386 default:
2387 return "";
2388 }
2389 return "";
2390}
2391
2392template <class ELFT> void GNUStyle<ELFT>::printSections(const ELFO *Obj) {
2393 size_t SectionIndex = 0;
2394 std::string Number, Type, Size, Address, Offset, Flags, Link, Info, EntrySize,
2395 Alignment;
2396 unsigned Bias;
2397 unsigned Width;
2398
2399 if (ELFT::Is64Bits) {
2400 Bias = 0;
2401 Width = 16;
2402 } else {
2403 Bias = 8;
2404 Width = 8;
2405 }
2406 OS << "There are " << to_string(Obj->getHeader()->e_shnum)
2407 << " section headers, starting at offset "
2408 << "0x" << to_hexString(Obj->getHeader()->e_shoff, false) << ":\n\n";
2409 OS << "Section Headers:\n";
2410 Field Fields[11] = {{"[Nr]", 2},
2411 {"Name", 7},
2412 {"Type", 25},
2413 {"Address", 41},
2414 {"Off", 58 - Bias},
2415 {"Size", 65 - Bias},
2416 {"ES", 72 - Bias},
2417 {"Flg", 75 - Bias},
2418 {"Lk", 79 - Bias},
2419 {"Inf", 82 - Bias},
2420 {"Al", 86 - Bias}};
2421 for (auto &f : Fields)
2422 printField(f);
2423 OS << "\n";
2424
2425 for (const Elf_Shdr &Sec : Obj->sections()) {
2426 Number = to_string(SectionIndex);
2427 Fields[0].Str = Number;
2428 Fields[1].Str = unwrapOrError(Obj->getSectionName(&Sec));
2429 Type = getSectionTypeString(Obj->getHeader()->e_machine, Sec.sh_type);
2430 Fields[2].Str = Type;
2431 Address = to_string(format_hex_no_prefix(Sec.sh_addr, Width));
2432 Fields[3].Str = Address;
2433 Offset = to_string(format_hex_no_prefix(Sec.sh_offset, 6));
2434 Fields[4].Str = Offset;
2435 Size = to_string(format_hex_no_prefix(Sec.sh_size, 6));
2436 Fields[5].Str = Size;
2437 EntrySize = to_string(format_hex_no_prefix(Sec.sh_entsize, 2));
2438 Fields[6].Str = EntrySize;
2439 Flags = getGNUFlags(Sec.sh_flags);
2440 Fields[7].Str = Flags;
2441 Link = to_string(Sec.sh_link);
2442 Fields[8].Str = Link;
2443 Info = to_string(Sec.sh_info);
2444 Fields[9].Str = Info;
2445 Alignment = to_string(Sec.sh_addralign);
2446 Fields[10].Str = Alignment;
2447 OS.PadToColumn(Fields[0].Column);
2448 OS << "[" << right_justify(Fields[0].Str, 2) << "]";
2449 for (int i = 1; i < 7; i++)
2450 printField(Fields[i]);
2451 OS.PadToColumn(Fields[7].Column);
2452 OS << right_justify(Fields[7].Str, 3);
2453 OS.PadToColumn(Fields[8].Column);
2454 OS << right_justify(Fields[8].Str, 2);
2455 OS.PadToColumn(Fields[9].Column);
2456 OS << right_justify(Fields[9].Str, 3);
2457 OS.PadToColumn(Fields[10].Column);
2458 OS << right_justify(Fields[10].Str, 2);
2459 OS << "\n";
2460 ++SectionIndex;
2461 }
2462 OS << "Key to Flags:\n"
2463 << " W (write), A (alloc), X (execute), M (merge), S (strings), l "
2464 "(large)\n"
2465 << " I (info), L (link order), G (group), T (TLS), E (exclude),\
2466 x (unknown)\n"
2467 << " O (extra OS processing required) o (OS specific),\
2468 p (processor specific)\n";
2469}
2470
2471template <class ELFT> void GNUStyle<ELFT>::printSymbols(const ELFO *Obj) {
2472 OS << "GNU style symbols not implemented!\n";
2473}
2474
2475template <class ELFT>
2476void GNUStyle<ELFT>::printDynamicSymbols(const ELFO *Obj) {
2477 OS << "GNU style dynamic symbols not implemented!\n";
2478}
2479
2480template <class ELFT>
2481void GNUStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
2482 OS << "GNU style dynamic relocations not implemented!\n";
2483}
2484
2485template <class ELFT> void LLVMStyle<ELFT>::printFileHeaders(const ELFO *Obj) {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002486 const Elf_Ehdr *e = Obj->getHeader();
2487 {
2488 DictScope D(W, "ElfHeader");
2489 {
2490 DictScope D(W, "Ident");
2491 W.printBinary("Magic", makeArrayRef(e->e_ident).slice(ELF::EI_MAG0, 4));
2492 W.printEnum("Class", e->e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
2493 W.printEnum("DataEncoding", e->e_ident[ELF::EI_DATA],
2494 makeArrayRef(ElfDataEncoding));
2495 W.printNumber("FileVersion", e->e_ident[ELF::EI_VERSION]);
2496
2497 // Handle architecture specific OS/ABI values.
2498 if (e->e_machine == ELF::EM_AMDGPU &&
2499 e->e_ident[ELF::EI_OSABI] == ELF::ELFOSABI_AMDGPU_HSA)
2500 W.printHex("OS/ABI", "AMDGPU_HSA", ELF::ELFOSABI_AMDGPU_HSA);
2501 else
2502 W.printEnum("OS/ABI", e->e_ident[ELF::EI_OSABI],
2503 makeArrayRef(ElfOSABI));
2504 W.printNumber("ABIVersion", e->e_ident[ELF::EI_ABIVERSION]);
2505 W.printBinary("Unused", makeArrayRef(e->e_ident).slice(ELF::EI_PAD));
2506 }
2507
2508 W.printEnum("Type", e->e_type, makeArrayRef(ElfObjectFileType));
2509 W.printEnum("Machine", e->e_machine, makeArrayRef(ElfMachineType));
2510 W.printNumber("Version", e->e_version);
2511 W.printHex("Entry", e->e_entry);
2512 W.printHex("ProgramHeaderOffset", e->e_phoff);
2513 W.printHex("SectionHeaderOffset", e->e_shoff);
2514 if (e->e_machine == EM_MIPS)
2515 W.printFlags("Flags", e->e_flags, makeArrayRef(ElfHeaderMipsFlags),
2516 unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
2517 unsigned(ELF::EF_MIPS_MACH));
2518 else
2519 W.printFlags("Flags", e->e_flags);
2520 W.printNumber("HeaderSize", e->e_ehsize);
2521 W.printNumber("ProgramHeaderEntrySize", e->e_phentsize);
2522 W.printNumber("ProgramHeaderCount", e->e_phnum);
2523 W.printNumber("SectionHeaderEntrySize", e->e_shentsize);
2524 W.printNumber("SectionHeaderCount", e->e_shnum);
2525 W.printNumber("StringTableSectionIndex", e->e_shstrndx);
2526 }
2527}
Hemant Kulkarni206ba842016-03-09 19:16:13 +00002528
2529template <class ELFT>
2530void LLVMStyle<ELFT>::printGroupSections(const ELFO *Obj) {
2531 DictScope Lists(W, "Groups");
2532 uint32_t SectionIndex = 0;
2533 bool HasGroups = false;
2534 for (const Elf_Shdr &Sec : Obj->sections()) {
2535 if (Sec.sh_type == ELF::SHT_GROUP) {
2536 HasGroups = true;
2537 const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link));
2538 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
2539 const Elf_Sym *Sym = Obj->template getEntry<Elf_Sym>(Symtab, Sec.sh_info);
2540 auto Data = unwrapOrError(
2541 Obj->template getSectionContentsAsArray<Elf_Word>(&Sec));
2542 DictScope D(W, "Group");
2543 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2544 W.printNumber("Name", Name, Sec.sh_name);
2545 W.printNumber("Index", SectionIndex);
2546 W.printHex("Type", getGroupType(Data[0]), Data[0]);
2547 W.startLine() << "Signature: " << StrTable.data() + Sym->st_name << "\n";
2548 {
2549 ListScope L(W, "Section(s) in group");
2550 size_t Member = 1;
2551 while (Member < Data.size()) {
2552 auto Sec = unwrapOrError(Obj->getSection(Data[Member]));
2553 const StringRef Name = unwrapOrError(Obj->getSectionName(Sec));
2554 W.startLine() << Name << " (" << Data[Member++] << ")\n";
2555 }
2556 }
2557 }
2558 ++SectionIndex;
2559 }
2560 if (!HasGroups)
2561 W.startLine() << "There are no group sections in the file.\n";
2562}
Hemant Kulkarnic030f232016-03-15 17:25:31 +00002563
2564template <class ELFT> void LLVMStyle<ELFT>::printRelocations(const ELFO *Obj) {
2565 ListScope D(W, "Relocations");
2566
2567 int SectionNumber = -1;
2568 for (const Elf_Shdr &Sec : Obj->sections()) {
2569 ++SectionNumber;
2570
2571 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA)
2572 continue;
2573
2574 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2575
2576 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
2577 W.indent();
2578
2579 printRelocations(&Sec, Obj);
2580
2581 W.unindent();
2582 W.startLine() << "}\n";
2583 }
2584}
2585
2586template <class ELFT>
2587void LLVMStyle<ELFT>::printRelocations(const Elf_Shdr *Sec, const ELFO *Obj) {
2588 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link));
2589
2590 switch (Sec->sh_type) {
2591 case ELF::SHT_REL:
2592 for (const Elf_Rel &R : Obj->rels(Sec)) {
2593 Elf_Rela Rela;
2594 Rela.r_offset = R.r_offset;
2595 Rela.r_info = R.r_info;
2596 Rela.r_addend = 0;
2597 printRelocation(Obj, Rela, SymTab);
2598 }
2599 break;
2600 case ELF::SHT_RELA:
2601 for (const Elf_Rela &R : Obj->relas(Sec))
2602 printRelocation(Obj, R, SymTab);
2603 break;
2604 }
2605}
2606
2607template <class ELFT>
2608void LLVMStyle<ELFT>::printRelocation(const ELFO *Obj, Elf_Rela Rel,
2609 const Elf_Shdr *SymTab) {
2610 SmallString<32> RelocName;
2611 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
2612 StringRef TargetName;
2613 const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTab);
2614 if (Sym && Sym->getType() == ELF::STT_SECTION) {
2615 const Elf_Shdr *Sec = unwrapOrError(
2616 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
2617 TargetName = unwrapOrError(Obj->getSectionName(Sec));
2618 } else if (Sym) {
2619 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
2620 TargetName = unwrapOrError(Sym->getName(StrTable));
2621 }
2622
2623 if (opts::ExpandRelocs) {
2624 DictScope Group(W, "Relocation");
2625 W.printHex("Offset", Rel.r_offset);
2626 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
2627 W.printNumber("Symbol", TargetName.size() > 0 ? TargetName : "-",
2628 Rel.getSymbol(Obj->isMips64EL()));
2629 W.printHex("Addend", Rel.r_addend);
2630 } else {
2631 raw_ostream &OS = W.startLine();
2632 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
2633 << (TargetName.size() > 0 ? TargetName : "-") << " "
2634 << W.hex(Rel.r_addend) << "\n";
2635 }
2636}
2637
2638template <class ELFT> void LLVMStyle<ELFT>::printSections(const ELFO *Obj) {
2639 ListScope SectionsD(W, "Sections");
2640
2641 int SectionIndex = -1;
2642 for (const Elf_Shdr &Sec : Obj->sections()) {
2643 ++SectionIndex;
2644
2645 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
2646
2647 DictScope SectionD(W, "Section");
2648 W.printNumber("Index", SectionIndex);
2649 W.printNumber("Name", Name, Sec.sh_name);
2650 W.printHex("Type",
2651 getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type),
2652 Sec.sh_type);
2653 std::vector<EnumEntry<unsigned>> SectionFlags(std::begin(ElfSectionFlags),
2654 std::end(ElfSectionFlags));
2655 switch (Obj->getHeader()->e_machine) {
2656 case EM_AMDGPU:
2657 SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags),
2658 std::end(ElfAMDGPUSectionFlags));
2659 break;
2660 case EM_HEXAGON:
2661 SectionFlags.insert(SectionFlags.end(),
2662 std::begin(ElfHexagonSectionFlags),
2663 std::end(ElfHexagonSectionFlags));
2664 break;
2665 case EM_MIPS:
2666 SectionFlags.insert(SectionFlags.end(), std::begin(ElfMipsSectionFlags),
2667 std::end(ElfMipsSectionFlags));
2668 break;
2669 case EM_X86_64:
2670 SectionFlags.insert(SectionFlags.end(), std::begin(ElfX86_64SectionFlags),
2671 std::end(ElfX86_64SectionFlags));
2672 break;
2673 default:
2674 // Nothing to do.
2675 break;
2676 }
2677 W.printFlags("Flags", Sec.sh_flags, makeArrayRef(SectionFlags));
2678 W.printHex("Address", Sec.sh_addr);
2679 W.printHex("Offset", Sec.sh_offset);
2680 W.printNumber("Size", Sec.sh_size);
2681 W.printNumber("Link", Sec.sh_link);
2682 W.printNumber("Info", Sec.sh_info);
2683 W.printNumber("AddressAlignment", Sec.sh_addralign);
2684 W.printNumber("EntrySize", Sec.sh_entsize);
2685
2686 if (opts::SectionRelocations) {
2687 ListScope D(W, "Relocations");
2688 printRelocations(&Sec, Obj);
2689 }
2690
2691 if (opts::SectionSymbols) {
2692 ListScope D(W, "Symbols");
2693 const Elf_Shdr *Symtab = this->dumper()->getDotSymtabSec();
2694 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
2695
2696 for (const Elf_Sym &Sym : Obj->symbols(Symtab)) {
2697 const Elf_Shdr *SymSec = unwrapOrError(
2698 Obj->getSection(&Sym, Symtab, this->dumper()->getShndxTable()));
2699 if (SymSec == &Sec)
2700 printSymbol(Obj, &Sym, Obj->symbol_begin(Symtab), StrTable, false);
2701 }
2702 }
2703
2704 if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
2705 ArrayRef<uint8_t> Data = unwrapOrError(Obj->getSectionContents(&Sec));
2706 W.printBinaryBlock("SectionData",
2707 StringRef((const char *)Data.data(), Data.size()));
2708 }
2709 }
2710}
2711
2712template <class ELFT>
2713void LLVMStyle<ELFT>::printSymbol(const ELFO *Obj, const Elf_Sym *Symbol,
2714 const Elf_Sym *First, StringRef StrTable,
2715 bool IsDynamic) {
2716 unsigned SectionIndex = 0;
2717 StringRef SectionName;
2718 getSectionNameIndex(*Obj, Symbol, First, this->dumper()->getShndxTable(),
2719 SectionName, SectionIndex);
2720 std::string FullSymbolName =
2721 this->dumper()->getFullSymbolName(Symbol, StrTable, IsDynamic);
2722 unsigned char SymbolType = Symbol->getType();
2723
2724 DictScope D(W, "Symbol");
2725 W.printNumber("Name", FullSymbolName, Symbol->st_name);
2726 W.printHex("Value", Symbol->st_value);
2727 W.printNumber("Size", Symbol->st_size);
2728 W.printEnum("Binding", Symbol->getBinding(), makeArrayRef(ElfSymbolBindings));
2729 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU &&
2730 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
2731 W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
2732 else
2733 W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
2734 W.printNumber("Other", Symbol->st_other);
2735 W.printHex("Section", SectionName, SectionIndex);
2736}
2737
2738template <class ELFT>
2739void LLVMStyle<ELFT>::printSymbolsHelper(const ELFO *Obj, bool IsDynamic) {
2740 StringRef StrTable;
2741 typename ELFO::Elf_Sym_Range Syms(nullptr, nullptr);
2742 if (IsDynamic) {
2743 StrTable = this->dumper()->getDynamicStringTable();
2744 Syms = this->dumper()->dynamic_symbols();
2745 } else {
2746 if (!this->dumper()->getDotSymtabSec())
2747 return;
2748 const auto DotSymtabSec = this->dumper()->getDotSymtabSec();
2749 StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
2750 Syms = Obj->symbols(DotSymtabSec);
2751 }
2752 for (const Elf_Sym &Sym : Syms)
2753 printSymbol(Obj, &Sym, Syms.begin(), StrTable, IsDynamic);
2754}
2755
2756template <class ELFT> void LLVMStyle<ELFT>::printSymbols(const ELFO *Obj) {
2757 ListScope Group(W, "Symbols");
2758 printSymbolsHelper(Obj, false);
2759}
2760
2761template <class ELFT>
2762void LLVMStyle<ELFT>::printDynamicSymbols(const ELFO *Obj) {
2763 ListScope Group(W, "DynamicSymbols");
2764 printSymbolsHelper(Obj, true);
2765}
2766
2767template <class ELFT>
2768void LLVMStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
2769 const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
2770 const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
2771 const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
2772 if (DynRelRegion.Size && DynRelaRegion.Size)
2773 report_fatal_error("There are both REL and RELA dynamic relocations");
2774 W.startLine() << "Dynamic Relocations {\n";
2775 W.indent();
2776 if (DynRelaRegion.Size > 0)
2777 for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
2778 printDynamicRelocation(Obj, Rela);
2779 else
2780 for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
2781 Elf_Rela Rela;
2782 Rela.r_offset = Rel.r_offset;
2783 Rela.r_info = Rel.r_info;
2784 Rela.r_addend = 0;
2785 printDynamicRelocation(Obj, Rela);
2786 }
2787 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
2788 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange<Elf_Rela>())
2789 printDynamicRelocation(Obj, Rela);
2790 else
2791 for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange<Elf_Rel>()) {
2792 Elf_Rela Rela;
2793 Rela.r_offset = Rel.r_offset;
2794 Rela.r_info = Rel.r_info;
2795 Rela.r_addend = 0;
2796 printDynamicRelocation(Obj, Rela);
2797 }
2798 W.unindent();
2799 W.startLine() << "}\n";
2800}
2801
2802template <class ELFT>
2803void LLVMStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel) {
2804 SmallString<32> RelocName;
2805 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
2806 StringRef SymbolName;
2807 uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
2808 const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex;
2809 SymbolName =
2810 unwrapOrError(Sym->getName(this->dumper()->getDynamicStringTable()));
2811 if (opts::ExpandRelocs) {
2812 DictScope Group(W, "Relocation");
2813 W.printHex("Offset", Rel.r_offset);
2814 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
2815 W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
2816 W.printHex("Addend", Rel.r_addend);
2817 } else {
2818 raw_ostream &OS = W.startLine();
2819 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
2820 << (SymbolName.size() > 0 ? SymbolName : "-") << " "
2821 << W.hex(Rel.r_addend) << "\n";
2822 }
2823}