blob: 92b92f1fad1053c7426e7f5042d6763ba4f7d589 [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
George Rimar47936762016-01-16 00:49:19 +000047namespace {
48
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +000049template <class ELFT> class DumpStyle;
50
George Rimar47936762016-01-16 00:49:19 +000051template<typename ELFT>
52class ELFDumper : public ObjDumper {
53public:
54 ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer);
55
56 void printFileHeaders() override;
57 void printSections() override;
58 void printRelocations() override;
59 void printDynamicRelocations() override;
60 void printSymbols() override;
61 void printDynamicSymbols() override;
62 void printUnwindInfo() override;
63
64 void printDynamicTable() override;
65 void printNeededLibraries() override;
66 void printProgramHeaders() override;
67 void printHashTable() override;
68 void printGnuHashTable() override;
69 void printLoadName() override;
70 void printVersionInfo() override;
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +000071 void printGroupSections() override;
George Rimar47936762016-01-16 00:49:19 +000072
73 void printAttributes() override;
74 void printMipsPLTGOT() override;
75 void printMipsABIFlags() override;
76 void printMipsReginfo() override;
77
78 void printStackMap() const override;
79
80private:
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +000081 std::unique_ptr<DumpStyle<ELFT>> ELFDumperStyle;
George Rimar47936762016-01-16 00:49:19 +000082 typedef ELFFile<ELFT> ELFO;
83 typedef typename ELFO::Elf_Shdr Elf_Shdr;
84 typedef typename ELFO::Elf_Sym Elf_Sym;
85 typedef typename ELFO::Elf_Dyn Elf_Dyn;
86 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range;
87 typedef typename ELFO::Elf_Rel Elf_Rel;
88 typedef typename ELFO::Elf_Rela Elf_Rela;
Simon Atanasyan72155c32016-01-16 22:40:09 +000089 typedef typename ELFO::Elf_Rel_Range Elf_Rel_Range;
George Rimar47936762016-01-16 00:49:19 +000090 typedef typename ELFO::Elf_Rela_Range Elf_Rela_Range;
91 typedef typename ELFO::Elf_Phdr Elf_Phdr;
92 typedef typename ELFO::Elf_Half Elf_Half;
93 typedef typename ELFO::Elf_Hash Elf_Hash;
94 typedef typename ELFO::Elf_GnuHash Elf_GnuHash;
95 typedef typename ELFO::Elf_Ehdr Elf_Ehdr;
96 typedef typename ELFO::Elf_Word Elf_Word;
97 typedef typename ELFO::uintX_t uintX_t;
98 typedef typename ELFO::Elf_Versym Elf_Versym;
99 typedef typename ELFO::Elf_Verneed Elf_Verneed;
100 typedef typename ELFO::Elf_Vernaux Elf_Vernaux;
101 typedef typename ELFO::Elf_Verdef Elf_Verdef;
102 typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
103
104 /// \brief Represents a region described by entries in the .dynamic table.
105 struct DynRegionInfo {
106 DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {}
107 /// \brief Address in current address space.
108 const void *Addr;
109 /// \brief Size in bytes of the region.
110 uintX_t Size;
111 /// \brief Size of each entity in the region.
112 uintX_t EntSize;
113 };
114
Michael J. Spencer60d82b22016-02-11 04:59:37 +0000115 void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments);
116
George Rimar47936762016-01-16 00:49:19 +0000117 void printSymbolsHelper(bool IsDynamic);
118 void printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
119 StringRef StrTable, bool IsDynamic);
120
Simon Atanasyan72155c32016-01-16 22:40:09 +0000121 void printDynamicRelocation(Elf_Rela Rel);
George Rimar47936762016-01-16 00:49:19 +0000122 void printRelocations(const Elf_Shdr *Sec);
123 void printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab);
124 void printValue(uint64_t Type, uint64_t Value);
125
Simon Atanasyane03126a2016-01-18 18:52:04 +0000126 template <typename REL>
127 static const REL *dyn_rel_begin(const DynRegionInfo &region);
128 template <typename REL>
129 static const REL *dyn_rel_end(const DynRegionInfo &region);
Simon Atanasyan72155c32016-01-16 22:40:09 +0000130 Elf_Rel_Range dyn_rels() const;
George Rimar47936762016-01-16 00:49:19 +0000131 Elf_Rela_Range dyn_relas() const;
132 StringRef getDynamicString(uint64_t Offset) const;
133 const Elf_Dyn *dynamic_table_begin() const {
134 ErrorOr<const Elf_Dyn *> Ret = Obj->dynamic_table_begin(DynamicProgHeader);
135 error(Ret.getError());
136 return *Ret;
137 }
138 const Elf_Dyn *dynamic_table_end() const {
139 ErrorOr<const Elf_Dyn *> Ret = Obj->dynamic_table_end(DynamicProgHeader);
140 error(Ret.getError());
141 return *Ret;
142 }
143 StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
144 bool &IsDefault);
145 void LoadVersionMap();
146 void LoadVersionNeeds(const Elf_Shdr *ec) const;
147 void LoadVersionDefs(const Elf_Shdr *sec) const;
148
149 const ELFO *Obj;
Simon Atanasyan72155c32016-01-16 22:40:09 +0000150 DynRegionInfo DynRelRegion;
George Rimar47936762016-01-16 00:49:19 +0000151 DynRegionInfo DynRelaRegion;
152 const Elf_Phdr *DynamicProgHeader = nullptr;
153 StringRef DynamicStringTable;
154 const Elf_Sym *DynSymStart = nullptr;
155 StringRef SOName;
156 const Elf_Hash *HashTable = nullptr;
157 const Elf_GnuHash *GnuHashTable = nullptr;
158 const Elf_Shdr *DotDynSymSec = nullptr;
159 const Elf_Shdr *DotSymtabSec = nullptr;
160 ArrayRef<Elf_Word> ShndxTable;
161
162 const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version
163 const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r
164 const Elf_Shdr *dot_gnu_version_d_sec = nullptr; // .gnu.version_d
165
166 // Records for each version index the corresponding Verdef or Vernaux entry.
167 // This is filled the first time LoadVersionMap() is called.
168 class VersionMapEntry : public PointerIntPair<const void *, 1> {
169 public:
170 // If the integer is 0, this is an Elf_Verdef*.
171 // If the integer is 1, this is an Elf_Vernaux*.
172 VersionMapEntry() : PointerIntPair<const void *, 1>(nullptr, 0) {}
173 VersionMapEntry(const Elf_Verdef *verdef)
174 : PointerIntPair<const void *, 1>(verdef, 0) {}
175 VersionMapEntry(const Elf_Vernaux *vernaux)
176 : PointerIntPair<const void *, 1>(vernaux, 1) {}
177 bool isNull() const { return getPointer() == nullptr; }
178 bool isVerdef() const { return !isNull() && getInt() == 0; }
179 bool isVernaux() const { return !isNull() && getInt() == 1; }
180 const Elf_Verdef *getVerdef() const {
181 return isVerdef() ? (const Elf_Verdef *)getPointer() : nullptr;
182 }
183 const Elf_Vernaux *getVernaux() const {
184 return isVernaux() ? (const Elf_Vernaux *)getPointer() : nullptr;
185 }
186 };
187 mutable SmallVector<VersionMapEntry, 16> VersionMap;
188
189public:
190 Elf_Dyn_Range dynamic_table() const {
191 ErrorOr<Elf_Dyn_Range> Ret = Obj->dynamic_table(DynamicProgHeader);
192 error(Ret.getError());
193 return *Ret;
194 }
195
196 std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
197 bool IsDynamic);
198 const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; }
199 const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
200 ArrayRef<Elf_Word> getShndxTable() { return ShndxTable; }
201};
202
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000203template <typename ELFT> class DumpStyle {
204public:
205 virtual void printFileHeaders(const ELFFile<ELFT> *Obj) = 0;
206 virtual ~DumpStyle() { }
207};
208
209template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
210 formatted_raw_ostream OS;
211
212public:
213 typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
214 GNUStyle(StreamWriter &W) : OS(W.getOStream()) {}
215 void printFileHeaders(const ELFFile<ELFT> *Obj) override;
216
217private:
218 template <typename T, typename TEnum>
219 std::string printEnum(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) {
220 for (const auto &EnumItem : EnumValues)
221 if (EnumItem.Value == Value)
222 return EnumItem.AltName;
223 return to_hexString(Value);
224 }
225};
226
227template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
228public:
229 typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
230 LLVMStyle(StreamWriter &W) : W(W) {}
231
232 void printFileHeaders(const ELFFile<ELFT> *Obj) override;
233
234private:
235 StreamWriter &W;
236};
237
George Rimar47936762016-01-16 00:49:19 +0000238template <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) {
239 if (!Val) {
240 error(Val.getError());
241 return Default;
242 }
243
244 return *Val;
245}
246} // namespace
247
248namespace llvm {
249
250template <class ELFT>
251static std::error_code createELFDumper(const ELFFile<ELFT> *Obj,
252 StreamWriter &Writer,
253 std::unique_ptr<ObjDumper> &Result) {
254 Result.reset(new ELFDumper<ELFT>(Obj, Writer));
255 return readobj_error::success;
256}
257
258std::error_code createELFDumper(const object::ObjectFile *Obj,
259 StreamWriter &Writer,
260 std::unique_ptr<ObjDumper> &Result) {
261 // Little-endian 32-bit
262 if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
263 return createELFDumper(ELFObj->getELFFile(), Writer, Result);
264
265 // Big-endian 32-bit
266 if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
267 return createELFDumper(ELFObj->getELFFile(), Writer, Result);
268
269 // Little-endian 64-bit
270 if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
271 return createELFDumper(ELFObj->getELFFile(), Writer, Result);
272
273 // Big-endian 64-bit
274 if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
275 return createELFDumper(ELFObj->getELFFile(), Writer, Result);
276
277 return readobj_error::unsupported_obj_file_format;
278}
279
280} // namespace llvm
281
282// Iterate through the versions needed section, and place each Elf_Vernaux
283// in the VersionMap according to its index.
284template <class ELFT>
285void ELFDumper<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
286 unsigned vn_size = sec->sh_size; // Size of section in bytes
287 unsigned vn_count = sec->sh_info; // Number of Verneed entries
288 const char *sec_start = (const char *)Obj->base() + sec->sh_offset;
289 const char *sec_end = sec_start + vn_size;
290 // The first Verneed entry is at the start of the section.
291 const char *p = sec_start;
292 for (unsigned i = 0; i < vn_count; i++) {
293 if (p + sizeof(Elf_Verneed) > sec_end)
294 report_fatal_error("Section ended unexpectedly while scanning "
295 "version needed records.");
296 const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p);
297 if (vn->vn_version != ELF::VER_NEED_CURRENT)
298 report_fatal_error("Unexpected verneed version");
299 // Iterate through the Vernaux entries
300 const char *paux = p + vn->vn_aux;
301 for (unsigned j = 0; j < vn->vn_cnt; j++) {
302 if (paux + sizeof(Elf_Vernaux) > sec_end)
303 report_fatal_error("Section ended unexpected while scanning auxiliary "
304 "version needed records.");
305 const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux);
306 size_t index = vna->vna_other & ELF::VERSYM_VERSION;
307 if (index >= VersionMap.size())
308 VersionMap.resize(index + 1);
309 VersionMap[index] = VersionMapEntry(vna);
310 paux += vna->vna_next;
311 }
312 p += vn->vn_next;
313 }
314}
315
316// Iterate through the version definitions, and place each Elf_Verdef
317// in the VersionMap according to its index.
318template <class ELFT>
319void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
320 unsigned vd_size = sec->sh_size; // Size of section in bytes
321 unsigned vd_count = sec->sh_info; // Number of Verdef entries
322 const char *sec_start = (const char *)Obj->base() + sec->sh_offset;
323 const char *sec_end = sec_start + vd_size;
324 // The first Verdef entry is at the start of the section.
325 const char *p = sec_start;
326 for (unsigned i = 0; i < vd_count; i++) {
327 if (p + sizeof(Elf_Verdef) > sec_end)
328 report_fatal_error("Section ended unexpectedly while scanning "
329 "version definitions.");
330 const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p);
331 if (vd->vd_version != ELF::VER_DEF_CURRENT)
332 report_fatal_error("Unexpected verdef version");
333 size_t index = vd->vd_ndx & ELF::VERSYM_VERSION;
334 if (index >= VersionMap.size())
335 VersionMap.resize(index + 1);
336 VersionMap[index] = VersionMapEntry(vd);
337 p += vd->vd_next;
338 }
339}
340
341template <class ELFT> void ELFDumper<ELFT>::LoadVersionMap() {
342 // If there is no dynamic symtab or version table, there is nothing to do.
343 if (!DynSymStart || !dot_gnu_version_sec)
344 return;
345
346 // Has the VersionMap already been loaded?
347 if (VersionMap.size() > 0)
348 return;
349
350 // The first two version indexes are reserved.
351 // Index 0 is LOCAL, index 1 is GLOBAL.
352 VersionMap.push_back(VersionMapEntry());
353 VersionMap.push_back(VersionMapEntry());
354
355 if (dot_gnu_version_d_sec)
356 LoadVersionDefs(dot_gnu_version_d_sec);
357
358 if (dot_gnu_version_r_sec)
359 LoadVersionNeeds(dot_gnu_version_r_sec);
360}
361
362
363template <typename ELFO, class ELFT>
364static void printVersionSymbolSection(ELFDumper<ELFT> *Dumper,
365 const ELFO *Obj,
366 const typename ELFO::Elf_Shdr *Sec,
367 StreamWriter &W) {
368 DictScope SS(W, "Version symbols");
369 if (!Sec)
370 return;
371 StringRef Name = errorOrDefault(Obj->getSectionName(Sec));
372 W.printNumber("Section Name", Name, Sec->sh_name);
373 W.printHex("Address", Sec->sh_addr);
374 W.printHex("Offset", Sec->sh_offset);
375 W.printNumber("Link", Sec->sh_link);
376
377 const typename ELFO::Elf_Shdr *DynSymSec = Dumper->getDotDynSymSec();
378 const uint8_t *P = (const uint8_t *)Obj->base() + Sec->sh_offset;
379 ErrorOr<StringRef> StrTableOrErr =
380 Obj->getStringTableForSymtab(*DynSymSec);
381 error(StrTableOrErr.getError());
382
383 // Same number of entries in the dynamic symbol table (DT_SYMTAB).
384 ListScope Syms(W, "Symbols");
385 for (const typename ELFO::Elf_Sym &Sym : Obj->symbols(DynSymSec)) {
386 DictScope S(W, "Symbol");
387 std::string FullSymbolName =
388 Dumper->getFullSymbolName(&Sym, *StrTableOrErr, true /* IsDynamic */);
389 W.printNumber("Version", *P);
390 W.printString("Name", FullSymbolName);
391 P += sizeof(typename ELFO::Elf_Half);
392 }
393}
394
395template <typename ELFO, class ELFT>
396static void printVersionDefinitionSection(ELFDumper<ELFT> *Dumper,
397 const ELFO *Obj,
398 const typename ELFO::Elf_Shdr *Sec,
399 StreamWriter &W) {
400 DictScope SD(W, "Version definition");
401 if (!Sec)
402 return;
403 StringRef Name = errorOrDefault(Obj->getSectionName(Sec));
404 W.printNumber("Section Name", Name, Sec->sh_name);
405 W.printHex("Address", Sec->sh_addr);
406 W.printHex("Offset", Sec->sh_offset);
407 W.printNumber("Link", Sec->sh_link);
408
409 unsigned verdef_entries = 0;
410 // The number of entries in the section SHT_GNU_verdef
411 // is determined by DT_VERDEFNUM tag.
412 for (const typename ELFO::Elf_Dyn &Dyn : Dumper->dynamic_table()) {
413 if (Dyn.d_tag == DT_VERDEFNUM)
414 verdef_entries = Dyn.d_un.d_val;
415 }
416 const uint8_t *SecStartAddress =
417 (const uint8_t *)Obj->base() + Sec->sh_offset;
418 const uint8_t *SecEndAddress = SecStartAddress + Sec->sh_size;
419 const uint8_t *P = SecStartAddress;
420 ErrorOr<const typename ELFO::Elf_Shdr *> StrTabOrErr =
421 Obj->getSection(Sec->sh_link);
422 error(StrTabOrErr.getError());
423
424 ListScope Entries(W, "Entries");
425 for (unsigned i = 0; i < verdef_entries; ++i) {
426 if (P + sizeof(typename ELFO::Elf_Verdef) > SecEndAddress)
427 report_fatal_error("invalid offset in the section");
428 auto *VD = reinterpret_cast<const typename ELFO::Elf_Verdef *>(P);
429 DictScope Entry(W, "Entry");
430 W.printHex("Offset", (uintptr_t)P - (uintptr_t)SecStartAddress);
431 W.printNumber("Rev", VD->vd_version);
432 // FIXME: print something more readable.
433 W.printNumber("Flags", VD->vd_flags);
434 W.printNumber("Index", VD->vd_ndx);
435 W.printNumber("Cnt", VD->vd_cnt);
436 W.printString("Name", StringRef((const char *)(Obj->base() +
437 (*StrTabOrErr)->sh_offset +
438 VD->getAux()->vda_name)));
439 P += VD->vd_next;
440 }
441}
442
443template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
444 // Dump version symbol section.
445 printVersionSymbolSection(this, Obj, dot_gnu_version_sec, W);
446
447 // Dump version definition section.
448 printVersionDefinitionSection(this, Obj, dot_gnu_version_d_sec, W);
449}
450
451template <typename ELFT>
452StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
453 const Elf_Sym *symb,
454 bool &IsDefault) {
455 // This is a dynamic symbol. Look in the GNU symbol version table.
456 if (!dot_gnu_version_sec) {
457 // No version table.
458 IsDefault = false;
459 return StringRef("");
460 }
461
462 // Determine the position in the symbol table of this entry.
463 size_t entry_index = (reinterpret_cast<uintptr_t>(symb) -
464 reinterpret_cast<uintptr_t>(DynSymStart)) /
465 sizeof(Elf_Sym);
466
467 // Get the corresponding version index entry
468 const Elf_Versym *vs =
469 Obj->template getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index);
470 size_t version_index = vs->vs_index & ELF::VERSYM_VERSION;
471
472 // Special markers for unversioned symbols.
473 if (version_index == ELF::VER_NDX_LOCAL ||
474 version_index == ELF::VER_NDX_GLOBAL) {
475 IsDefault = false;
476 return StringRef("");
477 }
478
479 // Lookup this symbol in the version table
480 LoadVersionMap();
481 if (version_index >= VersionMap.size() || VersionMap[version_index].isNull())
482 reportError("Invalid version entry");
483 const VersionMapEntry &entry = VersionMap[version_index];
484
485 // Get the version name string
486 size_t name_offset;
487 if (entry.isVerdef()) {
488 // The first Verdaux entry holds the name.
489 name_offset = entry.getVerdef()->getAux()->vda_name;
490 IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN);
491 } else {
492 name_offset = entry.getVernaux()->vna_name;
493 IsDefault = false;
494 }
495 if (name_offset >= StrTab.size())
496 reportError("Invalid string offset");
497 return StringRef(StrTab.data() + name_offset);
498}
499
500template <typename ELFT>
501std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol,
502 StringRef StrTable,
503 bool IsDynamic) {
504 StringRef SymbolName = errorOrDefault(Symbol->getName(StrTable));
505 if (!IsDynamic)
506 return SymbolName;
507
508 std::string FullSymbolName(SymbolName);
509
510 bool IsDefault;
511 StringRef Version = getSymbolVersion(StrTable, &*Symbol, IsDefault);
512 FullSymbolName += (IsDefault ? "@@" : "@");
513 FullSymbolName += Version;
514 return FullSymbolName;
515}
516
517template <typename ELFO>
518static void
519getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
520 const typename ELFO::Elf_Shdr *SymTab,
521 ArrayRef<typename ELFO::Elf_Word> ShndxTable,
522 StringRef &SectionName, unsigned &SectionIndex) {
523 SectionIndex = Symbol->st_shndx;
524 if (Symbol->isUndefined())
525 SectionName = "Undefined";
526 else if (Symbol->isProcessorSpecific())
527 SectionName = "Processor Specific";
528 else if (Symbol->isOSSpecific())
529 SectionName = "Operating System Specific";
530 else if (Symbol->isAbsolute())
531 SectionName = "Absolute";
532 else if (Symbol->isCommon())
533 SectionName = "Common";
534 else if (Symbol->isReserved() && SectionIndex != SHN_XINDEX)
535 SectionName = "Reserved";
536 else {
537 if (SectionIndex == SHN_XINDEX)
538 SectionIndex =
539 Obj.getExtendedSymbolTableIndex(Symbol, SymTab, ShndxTable);
540 ErrorOr<const typename ELFO::Elf_Shdr *> Sec = Obj.getSection(SectionIndex);
541 error(Sec.getError());
542 SectionName = errorOrDefault(Obj.getSectionName(*Sec));
543 }
544}
545
546template <class ELFO>
Simon Atanasyancb1175c2016-02-09 18:45:35 +0000547static const typename ELFO::Elf_Shdr *
548findNotEmptySectionByAddress(const ELFO *Obj, uint64_t Addr) {
George Rimar47936762016-01-16 00:49:19 +0000549 for (const auto &Shdr : Obj->sections())
Simon Atanasyancb1175c2016-02-09 18:45:35 +0000550 if (Shdr.sh_addr == Addr && Shdr.sh_size > 0)
George Rimar47936762016-01-16 00:49:19 +0000551 return &Shdr;
552 return nullptr;
553}
554
555template <class ELFO>
556static const typename ELFO::Elf_Shdr *findSectionByName(const ELFO &Obj,
557 StringRef Name) {
558 for (const auto &Shdr : Obj.sections()) {
559 if (Name == errorOrDefault(Obj.getSectionName(&Shdr)))
560 return &Shdr;
561 }
562 return nullptr;
563}
564
565static const EnumEntry<unsigned> ElfClass[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000566 {"None", "none", ELF::ELFCLASSNONE},
567 {"32-bit", "ELF32", ELF::ELFCLASS32},
568 {"64-bit", "ELF64", ELF::ELFCLASS64},
George Rimar47936762016-01-16 00:49:19 +0000569};
570
571static const EnumEntry<unsigned> ElfDataEncoding[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000572 {"None", "none", ELF::ELFDATANONE},
573 {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB},
574 {"BigEndian", "2's complement, big endian", ELF::ELFDATA2MSB},
George Rimar47936762016-01-16 00:49:19 +0000575};
576
577static const EnumEntry<unsigned> ElfObjectFileType[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000578 {"None", "NONE (none)", ELF::ET_NONE},
579 {"Relocatable", "REL (Relocatable file)", ELF::ET_REL},
580 {"Executable", "EXEC (Executable file)", ELF::ET_EXEC},
581 {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN},
582 {"Core", "CORE (Core file)", ELF::ET_CORE},
George Rimar47936762016-01-16 00:49:19 +0000583};
584
585static const EnumEntry<unsigned> ElfOSABI[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000586 {"SystemV", "UNIX - System V", ELF::ELFOSABI_NONE},
587 {"HPUX", "UNIX - HP-UX", ELF::ELFOSABI_HPUX},
588 {"NetBSD", "UNIX - NetBSD", ELF::ELFOSABI_NETBSD},
589 {"GNU/Linux", "UNIX - GNU", ELF::ELFOSABI_LINUX},
590 {"GNU/Hurd", "GNU/Hurd", ELF::ELFOSABI_HURD},
591 {"Solaris", "UNIX - Solaris", ELF::ELFOSABI_SOLARIS},
592 {"AIX", "UNIX - AIX", ELF::ELFOSABI_AIX},
593 {"IRIX", "UNIX - IRIX", ELF::ELFOSABI_IRIX},
594 {"FreeBSD", "UNIX - FreeBSD", ELF::ELFOSABI_FREEBSD},
595 {"TRU64", "UNIX - TRU64", ELF::ELFOSABI_TRU64},
596 {"Modesto", "Novell - Modesto", ELF::ELFOSABI_MODESTO},
597 {"OpenBSD", "UNIX - OpenBSD", ELF::ELFOSABI_OPENBSD},
598 {"OpenVMS", "VMS - OpenVMS", ELF::ELFOSABI_OPENVMS},
599 {"NSK", "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK},
600 {"AROS", "AROS", ELF::ELFOSABI_AROS},
601 {"FenixOS", "FenixOS", ELF::ELFOSABI_FENIXOS},
602 {"CloudABI", "CloudABI", ELF::ELFOSABI_CLOUDABI},
603 {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI},
604 {"C6000_LINUX", "Linux C6000", ELF::ELFOSABI_C6000_LINUX},
605 {"ARM", "ARM", ELF::ELFOSABI_ARM},
606 {"Standalone", "Standalone App", ELF::ELFOSABI_STANDALONE}
George Rimar47936762016-01-16 00:49:19 +0000607};
608
609static const EnumEntry<unsigned> ElfMachineType[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000610 ENUM_ENT(EM_NONE, "None"),
611 ENUM_ENT(EM_M32, "WE32100"),
612 ENUM_ENT(EM_SPARC, "Sparc"),
613 ENUM_ENT(EM_386, "Intel 80386"),
614 ENUM_ENT(EM_68K, "MC68000"),
615 ENUM_ENT(EM_88K, "MC88000"),
616 ENUM_ENT(EM_IAMCU, "EM_IAMCU"),
617 ENUM_ENT(EM_860, "Intel 80860"),
618 ENUM_ENT(EM_MIPS, "MIPS R3000"),
619 ENUM_ENT(EM_S370, "IBM System/370"),
620 ENUM_ENT(EM_MIPS_RS3_LE, "MIPS R3000 little-endian"),
621 ENUM_ENT(EM_PARISC, "HPPA"),
622 ENUM_ENT(EM_VPP500, "Fujitsu VPP500"),
623 ENUM_ENT(EM_SPARC32PLUS, "Sparc v8+"),
624 ENUM_ENT(EM_960, "Intel 80960"),
625 ENUM_ENT(EM_PPC, "PowerPC"),
626 ENUM_ENT(EM_PPC64, "PowerPC64"),
627 ENUM_ENT(EM_S390, "IBM S/390"),
628 ENUM_ENT(EM_SPU, "SPU"),
629 ENUM_ENT(EM_V800, "NEC V800 series"),
630 ENUM_ENT(EM_FR20, "Fujistsu FR20"),
631 ENUM_ENT(EM_RH32, "TRW RH-32"),
632 ENUM_ENT(EM_RCE, "Motorola RCE"),
633 ENUM_ENT(EM_ARM, "ARM"),
634 ENUM_ENT(EM_ALPHA, "EM_ALPHA"),
635 ENUM_ENT(EM_SH, "Hitachi SH"),
636 ENUM_ENT(EM_SPARCV9, "Sparc v9"),
637 ENUM_ENT(EM_TRICORE, "Siemens Tricore"),
638 ENUM_ENT(EM_ARC, "ARC"),
639 ENUM_ENT(EM_H8_300, "Hitachi H8/300"),
640 ENUM_ENT(EM_H8_300H, "Hitachi H8/300H"),
641 ENUM_ENT(EM_H8S, "Hitachi H8S"),
642 ENUM_ENT(EM_H8_500, "Hitachi H8/500"),
643 ENUM_ENT(EM_IA_64, "Intel IA-64"),
644 ENUM_ENT(EM_MIPS_X, "Stanford MIPS-X"),
645 ENUM_ENT(EM_COLDFIRE, "Motorola Coldfire"),
646 ENUM_ENT(EM_68HC12, "Motorola MC68HC12 Microcontroller"),
647 ENUM_ENT(EM_MMA, "Fujitsu Multimedia Accelerator"),
648 ENUM_ENT(EM_PCP, "Siemens PCP"),
649 ENUM_ENT(EM_NCPU, "Sony nCPU embedded RISC processor"),
650 ENUM_ENT(EM_NDR1, "Denso NDR1 microprocesspr"),
651 ENUM_ENT(EM_STARCORE, "Motorola Star*Core processor"),
652 ENUM_ENT(EM_ME16, "Toyota ME16 processor"),
653 ENUM_ENT(EM_ST100, "STMicroelectronics ST100 processor"),
654 ENUM_ENT(EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor"),
655 ENUM_ENT(EM_X86_64, "Advanced Micro Devices X86-64"),
656 ENUM_ENT(EM_PDSP, "Sony DSP processor"),
657 ENUM_ENT(EM_PDP10, "Digital Equipment Corp. PDP-10"),
658 ENUM_ENT(EM_PDP11, "Digital Equipment Corp. PDP-11"),
659 ENUM_ENT(EM_FX66, "Siemens FX66 microcontroller"),
660 ENUM_ENT(EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller"),
661 ENUM_ENT(EM_ST7, "STMicroelectronics ST7 8-bit microcontroller"),
662 ENUM_ENT(EM_68HC16, "Motorola MC68HC16 Microcontroller"),
663 ENUM_ENT(EM_68HC11, "Motorola MC68HC11 Microcontroller"),
664 ENUM_ENT(EM_68HC08, "Motorola MC68HC08 Microcontroller"),
665 ENUM_ENT(EM_68HC05, "Motorola MC68HC05 Microcontroller"),
666 ENUM_ENT(EM_SVX, "Silicon Graphics SVx"),
667 ENUM_ENT(EM_ST19, "STMicroelectronics ST19 8-bit microcontroller"),
668 ENUM_ENT(EM_VAX, "Digital VAX"),
669 ENUM_ENT(EM_CRIS, "Axis Communications 32-bit embedded processor"),
670 ENUM_ENT(EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu"),
671 ENUM_ENT(EM_FIREPATH, "Element 14 64-bit DSP processor"),
672 ENUM_ENT(EM_ZSP, "LSI Logic's 16-bit DSP processor"),
673 ENUM_ENT(EM_MMIX, "Donald Knuth's educational 64-bit processor"),
674 ENUM_ENT(EM_HUANY, "Harvard Universitys's machine-independent object format"),
675 ENUM_ENT(EM_PRISM, "Vitesse Prism"),
676 ENUM_ENT(EM_AVR, "Atmel AVR 8-bit microcontroller"),
677 ENUM_ENT(EM_FR30, "Fujitsu FR30"),
678 ENUM_ENT(EM_D10V, "Mitsubishi D10V"),
679 ENUM_ENT(EM_D30V, "Mitsubishi D30V"),
680 ENUM_ENT(EM_V850, "NEC v850"),
681 ENUM_ENT(EM_M32R, "Renesas M32R (formerly Mitsubishi M32r)"),
682 ENUM_ENT(EM_MN10300, "Matsushita MN10300"),
683 ENUM_ENT(EM_MN10200, "Matsushita MN10200"),
684 ENUM_ENT(EM_PJ, "picoJava"),
685 ENUM_ENT(EM_OPENRISC, "OpenRISC 32-bit embedded processor"),
686 ENUM_ENT(EM_ARC_COMPACT, "EM_ARC_COMPACT"),
687 ENUM_ENT(EM_XTENSA, "Tensilica Xtensa Processor"),
688 ENUM_ENT(EM_VIDEOCORE, "Alphamosaic VideoCore processor"),
689 ENUM_ENT(EM_TMM_GPP, "Thompson Multimedia General Purpose Processor"),
690 ENUM_ENT(EM_NS32K, "National Semiconductor 32000 series"),
691 ENUM_ENT(EM_TPC, "Tenor Network TPC processor"),
692 ENUM_ENT(EM_SNP1K, "EM_SNP1K"),
693 ENUM_ENT(EM_ST200, "STMicroelectronics ST200 microcontroller"),
694 ENUM_ENT(EM_IP2K, "Ubicom IP2xxx 8-bit microcontrollers"),
695 ENUM_ENT(EM_MAX, "MAX Processor"),
696 ENUM_ENT(EM_CR, "National Semiconductor CompactRISC"),
697 ENUM_ENT(EM_F2MC16, "Fujitsu F2MC16"),
698 ENUM_ENT(EM_MSP430, "Texas Instruments msp430 microcontroller"),
699 ENUM_ENT(EM_BLACKFIN, "Analog Devices Blackfin"),
700 ENUM_ENT(EM_SE_C33, "S1C33 Family of Seiko Epson processors"),
701 ENUM_ENT(EM_SEP, "Sharp embedded microprocessor"),
702 ENUM_ENT(EM_ARCA, "Arca RISC microprocessor"),
703 ENUM_ENT(EM_UNICORE, "Unicore"),
704 ENUM_ENT(EM_EXCESS, "eXcess 16/32/64-bit configurable embedded CPU"),
705 ENUM_ENT(EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor"),
706 ENUM_ENT(EM_ALTERA_NIOS2, "Altera Nios"),
707 ENUM_ENT(EM_CRX, "National Semiconductor CRX microprocessor"),
708 ENUM_ENT(EM_XGATE, "Motorola XGATE embedded processor"),
709 ENUM_ENT(EM_C166, "Infineon Technologies xc16x"),
710 ENUM_ENT(EM_M16C, "Renesas M16C"),
711 ENUM_ENT(EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller"),
712 ENUM_ENT(EM_CE, "Freescale Communication Engine RISC core"),
713 ENUM_ENT(EM_M32C, "Renesas M32C"),
714 ENUM_ENT(EM_TSK3000, "Altium TSK3000 core"),
715 ENUM_ENT(EM_RS08, "Freescale RS08 embedded processor"),
716 ENUM_ENT(EM_SHARC, "EM_SHARC"),
717 ENUM_ENT(EM_ECOG2, "Cyan Technology eCOG2 microprocessor"),
718 ENUM_ENT(EM_SCORE7, "SUNPLUS S+Core"),
719 ENUM_ENT(EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor"),
720 ENUM_ENT(EM_VIDEOCORE3, "Broadcom VideoCore III processor"),
721 ENUM_ENT(EM_LATTICEMICO32, "Lattice Mico32"),
722 ENUM_ENT(EM_SE_C17, "Seiko Epson C17 family"),
723 ENUM_ENT(EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family"),
724 ENUM_ENT(EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family"),
725 ENUM_ENT(EM_TI_C5500, "Texas Instruments TMS320C55x DSP family"),
726 ENUM_ENT(EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor"),
727 ENUM_ENT(EM_CYPRESS_M8C, "Cypress M8C microprocessor"),
728 ENUM_ENT(EM_R32C, "Renesas R32C series microprocessors"),
729 ENUM_ENT(EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family"),
730 ENUM_ENT(EM_HEXAGON, "Qualcomm Hexagon"),
731 ENUM_ENT(EM_8051, "Intel 8051 and variants"),
732 ENUM_ENT(EM_STXP7X, "STMicroelectronics STxP7x family"),
733 ENUM_ENT(EM_NDS32, "Andes Technology compact code size embedded RISC processor family"),
734 ENUM_ENT(EM_ECOG1, "Cyan Technology eCOG1 microprocessor"),
735 ENUM_ENT(EM_ECOG1X, "Cyan Technology eCOG1X family"),
736 ENUM_ENT(EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core microcontrollers"),
737 ENUM_ENT(EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor"),
738 ENUM_ENT(EM_MANIK, "M2000 Reconfigurable RISC Microprocessor"),
739 ENUM_ENT(EM_CRAYNV2, "Cray Inc. NV2 vector architecture"),
740 ENUM_ENT(EM_RX, "Renesas RX"),
741 ENUM_ENT(EM_METAG, "Imagination Technologies Meta processor architecture"),
742 ENUM_ENT(EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture"),
743 ENUM_ENT(EM_ECOG16, "Cyan Technology eCOG16 family"),
744 ENUM_ENT(EM_CR16, "Xilinx MicroBlaze"),
745 ENUM_ENT(EM_ETPU, "Freescale Extended Time Processing Unit"),
746 ENUM_ENT(EM_SLE9X, "Infineon Technologies SLE9X core"),
747 ENUM_ENT(EM_L10M, "EM_L10M"),
748 ENUM_ENT(EM_K10M, "EM_K10M"),
749 ENUM_ENT(EM_AARCH64, "AArch64"),
750 ENUM_ENT(EM_AVR32, "Atmel AVR 8-bit microcontroller"),
751 ENUM_ENT(EM_STM8, "STMicroeletronics STM8 8-bit microcontroller"),
752 ENUM_ENT(EM_TILE64, "Tilera TILE64 multicore architecture family"),
753 ENUM_ENT(EM_TILEPRO, "Tilera TILEPro multicore architecture family"),
754 ENUM_ENT(EM_CUDA, "NVIDIA CUDA architecture"),
755 ENUM_ENT(EM_TILEGX, "Tilera TILE-Gx multicore architecture family"),
756 ENUM_ENT(EM_CLOUDSHIELD, "EM_CLOUDSHIELD"),
757 ENUM_ENT(EM_COREA_1ST, "EM_COREA_1ST"),
758 ENUM_ENT(EM_COREA_2ND, "EM_COREA_2ND"),
759 ENUM_ENT(EM_ARC_COMPACT2, "EM_ARC_COMPACT2"),
760 ENUM_ENT(EM_OPEN8, "EM_OPEN8"),
761 ENUM_ENT(EM_RL78, "Renesas RL78"),
762 ENUM_ENT(EM_VIDEOCORE5, "Broadcom VideoCore V processor"),
763 ENUM_ENT(EM_78KOR, "EM_78KOR"),
764 ENUM_ENT(EM_56800EX, "EM_56800EX"),
765 ENUM_ENT(EM_AMDGPU, "EM_AMDGPU"),
766 ENUM_ENT(EM_WEBASSEMBLY, "EM_WEBASSEMBLY")
George Rimar47936762016-01-16 00:49:19 +0000767};
768
769static const EnumEntry<unsigned> ElfSymbolBindings[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000770 {"Local", "LOCAL", ELF::STB_LOCAL},
771 {"Global", "GLOBAL", ELF::STB_GLOBAL},
772 {"Weak", "WEAK", ELF::STB_WEAK},
773 {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE}};
George Rimar47936762016-01-16 00:49:19 +0000774
775static const EnumEntry<unsigned> ElfSymbolTypes[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000776 {"None", "NOTYPE", ELF::STT_NOTYPE},
777 {"Object", "OBJECT", ELF::STT_OBJECT},
778 {"Function", "FUNCTION", ELF::STT_FUNC},
779 {"Section", "SECTION", ELF::STT_SECTION},
780 {"File", "FILE", ELF::STT_FILE},
781 {"Common", "COMMON", ELF::STT_COMMON},
782 {"TLS", "TLS", ELF::STT_TLS},
783 {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}};
George Rimar47936762016-01-16 00:49:19 +0000784
785static const EnumEntry<unsigned> AMDGPUSymbolTypes[] = {
786 { "AMDGPU_HSA_KERNEL", ELF::STT_AMDGPU_HSA_KERNEL },
787 { "AMDGPU_HSA_INDIRECT_FUNCTION", ELF::STT_AMDGPU_HSA_INDIRECT_FUNCTION },
788 { "AMDGPU_HSA_METADATA", ELF::STT_AMDGPU_HSA_METADATA }
789};
790
791static const char *getElfSectionType(unsigned Arch, unsigned Type) {
792 switch (Arch) {
793 case ELF::EM_ARM:
794 switch (Type) {
795 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX);
796 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
797 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
798 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
799 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
800 }
801 case ELF::EM_HEXAGON:
802 switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
803 case ELF::EM_X86_64:
804 switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
805 case ELF::EM_MIPS:
806 case ELF::EM_MIPS_RS3_LE:
807 switch (Type) {
808 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
809 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
810 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
811 }
812 }
813
814 switch (Type) {
815 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL );
816 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS );
817 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB );
818 LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB );
819 LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA );
820 LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH );
821 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC );
822 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE );
823 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS );
824 LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL );
825 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB );
826 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM );
827 LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY );
828 LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY );
829 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY );
830 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP );
831 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX );
832 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES );
833 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH );
834 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef );
835 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed );
836 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym );
837 default: return "";
838 }
839}
840
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +0000841static const char *getGroupType(uint32_t Flag) {
842 if (Flag & ELF::GRP_COMDAT)
843 return "COMDAT";
844 else
845 return "(unknown)";
846}
847
George Rimar47936762016-01-16 00:49:19 +0000848static const EnumEntry<unsigned> ElfSectionFlags[] = {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +0000849 ENUM_ENT(SHF_WRITE, "W"),
850 ENUM_ENT(SHF_ALLOC, "A"),
851 ENUM_ENT(SHF_EXCLUDE, "E"),
852 ENUM_ENT(SHF_EXECINSTR, "X"),
853 ENUM_ENT(SHF_MERGE, "M"),
854 ENUM_ENT(SHF_STRINGS, "S"),
855 ENUM_ENT(SHF_INFO_LINK, "I"),
856 ENUM_ENT(SHF_LINK_ORDER, "L"),
857 ENUM_ENT(SHF_OS_NONCONFORMING, "o"),
858 ENUM_ENT(SHF_GROUP, "G"),
859 ENUM_ENT(SHF_TLS, "T"),
860 ENUM_ENT_1(XCORE_SHF_CP_SECTION),
861 ENUM_ENT_1(XCORE_SHF_DP_SECTION),
Simon Atanasyan2d0d8532016-01-20 19:15:18 +0000862};
863
864static const EnumEntry<unsigned> ElfAMDGPUSectionFlags[] = {
George Rimar47936762016-01-16 00:49:19 +0000865 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_GLOBAL),
866 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_READONLY),
867 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_CODE),
868 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_AGENT)
869};
870
Simon Atanasyan2d0d8532016-01-20 19:15:18 +0000871static const EnumEntry<unsigned> ElfHexagonSectionFlags[] = {
872 LLVM_READOBJ_ENUM_ENT(ELF, SHF_HEX_GPREL)
873};
874
875static const EnumEntry<unsigned> ElfMipsSectionFlags[] = {
876 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NODUPES),
877 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NAMES ),
878 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_LOCAL ),
879 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP),
880 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_GPREL ),
881 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_MERGE ),
882 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_ADDR ),
883 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_STRING )
884};
885
886static const EnumEntry<unsigned> ElfX86_64SectionFlags[] = {
887 LLVM_READOBJ_ENUM_ENT(ELF, SHF_X86_64_LARGE)
888};
889
George Rimar47936762016-01-16 00:49:19 +0000890static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
891 // Check potentially overlapped processor-specific
892 // program header type.
893 switch (Arch) {
894 case ELF::EM_AMDGPU:
895 switch (Type) {
896 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM);
897 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT);
898 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_READONLY_AGENT);
899 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_CODE_AGENT);
900 }
901 case ELF::EM_ARM:
902 switch (Type) {
903 LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX);
904 }
905 case ELF::EM_MIPS:
906 case ELF::EM_MIPS_RS3_LE:
907 switch (Type) {
908 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
909 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
910 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
911 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);
912 }
913 }
914
915 switch (Type) {
916 LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL );
917 LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD );
918 LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
919 LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP );
920 LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE );
921 LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB );
922 LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR );
923 LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS );
924
925 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
926 LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
927
928 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
929 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
930 default: return "";
931 }
932}
933
934static const EnumEntry<unsigned> ElfSegmentFlags[] = {
935 LLVM_READOBJ_ENUM_ENT(ELF, PF_X),
936 LLVM_READOBJ_ENUM_ENT(ELF, PF_W),
937 LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
938};
939
940static const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
941 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NOREORDER),
942 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_PIC),
943 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_CPIC),
944 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI2),
945 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_32BITMODE),
946 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_FP64),
947 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NAN2008),
948 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O32),
949 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O64),
950 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI32),
951 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI64),
952 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_3900),
953 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4010),
954 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4100),
955 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4650),
956 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4120),
957 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4111),
958 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_SB1),
959 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON),
960 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_XLR),
961 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON2),
962 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON3),
963 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5400),
964 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5900),
965 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5500),
966 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_9000),
967 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2E),
968 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2F),
969 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS3A),
970 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MICROMIPS),
971 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_M16),
972 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_MDMX),
973 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_1),
974 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_2),
975 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_3),
976 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_4),
977 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_5),
978 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32),
979 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64),
980 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R2),
981 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R2),
982 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R6),
983 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6)
984};
985
986template <typename ELFT>
987ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer)
988 : ObjDumper(Writer), Obj(Obj) {
989
990 SmallVector<const Elf_Phdr *, 4> LoadSegments;
991 for (const Elf_Phdr &Phdr : Obj->program_headers()) {
992 if (Phdr.p_type == ELF::PT_DYNAMIC) {
993 DynamicProgHeader = &Phdr;
994 continue;
995 }
996 if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0)
997 continue;
998 LoadSegments.push_back(&Phdr);
999 }
1000
Michael J. Spencer37304f12016-02-11 04:59:26 +00001001 for (const Elf_Shdr &Sec : Obj->sections()) {
1002 switch (Sec.sh_type) {
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001003 case ELF::SHT_SYMTAB:
1004 if (DotSymtabSec != nullptr)
1005 reportError("Multilpe SHT_SYMTAB");
1006 DotSymtabSec = &Sec;
1007 break;
1008 case ELF::SHT_DYNSYM:
1009 if (DotDynSymSec != nullptr)
1010 reportError("Multilpe SHT_DYNSYM");
1011 DotDynSymSec = &Sec;
1012 break;
1013 case ELF::SHT_SYMTAB_SHNDX: {
1014 ErrorOr<ArrayRef<Elf_Word>> TableOrErr = Obj->getSHNDXTable(Sec);
1015 error(TableOrErr.getError());
1016 ShndxTable = *TableOrErr;
1017 break;
1018 }
Michael J. Spencer37304f12016-02-11 04:59:26 +00001019 case ELF::SHT_GNU_versym:
1020 if (dot_gnu_version_sec != nullptr)
1021 reportError("Multiple SHT_GNU_versym");
1022 dot_gnu_version_sec = &Sec;
1023 break;
1024 case ELF::SHT_GNU_verdef:
1025 if (dot_gnu_version_d_sec != nullptr)
1026 reportError("Multiple SHT_GNU_verdef");
1027 dot_gnu_version_d_sec = &Sec;
1028 break;
1029 case ELF::SHT_GNU_verneed:
1030 if (dot_gnu_version_r_sec != nullptr)
1031 reportError("Multilpe SHT_GNU_verneed");
1032 dot_gnu_version_r_sec = &Sec;
1033 break;
Michael J. Spencer37304f12016-02-11 04:59:26 +00001034 }
1035 }
1036
Michael J. Spencer60d82b22016-02-11 04:59:37 +00001037 parseDynamicTable(LoadSegments);
1038
1039 if (opts::Output == opts::GNU)
1040 ELFDumperStyle.reset(new GNUStyle<ELFT>(Writer));
1041 else
1042 ELFDumperStyle.reset(new LLVMStyle<ELFT>(Writer));
1043}
1044
1045template <typename ELFT>
1046void ELFDumper<ELFT>::parseDynamicTable(
1047 ArrayRef<const Elf_Phdr *> LoadSegments) {
George Rimar47936762016-01-16 00:49:19 +00001048 auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * {
Michael J. Spencer60d82b22016-02-11 04:59:37 +00001049 const Elf_Phdr *const *I = std::upper_bound(
George Rimar47936762016-01-16 00:49:19 +00001050 LoadSegments.begin(), LoadSegments.end(), VAddr, compareAddr<ELFT>);
1051 if (I == LoadSegments.begin())
1052 report_fatal_error("Virtual address is not in any segment");
1053 --I;
1054 const Elf_Phdr &Phdr = **I;
1055 uint64_t Delta = VAddr - Phdr.p_vaddr;
1056 if (Delta >= Phdr.p_filesz)
1057 report_fatal_error("Virtual address is not in any segment");
1058 return Obj->base() + Phdr.p_offset + Delta;
1059 };
1060
1061 uint64_t SONameOffset = 0;
1062 const char *StringTableBegin = nullptr;
1063 uint64_t StringTableSize = 0;
1064 for (const Elf_Dyn &Dyn : dynamic_table()) {
1065 switch (Dyn.d_tag) {
1066 case ELF::DT_HASH:
1067 HashTable =
1068 reinterpret_cast<const Elf_Hash *>(toMappedAddr(Dyn.getPtr()));
1069 break;
1070 case ELF::DT_GNU_HASH:
1071 GnuHashTable =
1072 reinterpret_cast<const Elf_GnuHash *>(toMappedAddr(Dyn.getPtr()));
1073 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001074 case ELF::DT_STRTAB:
1075 StringTableBegin = (const char *)toMappedAddr(Dyn.getPtr());
Simon Atanasyan72155c32016-01-16 22:40:09 +00001076 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001077 case ELF::DT_STRSZ:
1078 StringTableSize = Dyn.getVal();
Simon Atanasyan72155c32016-01-16 22:40:09 +00001079 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001080 case ELF::DT_SYMTAB:
1081 DynSymStart =
1082 reinterpret_cast<const Elf_Sym *>(toMappedAddr(Dyn.getPtr()));
Simon Atanasyan72155c32016-01-16 22:40:09 +00001083 break;
George Rimar47936762016-01-16 00:49:19 +00001084 case ELF::DT_RELA:
1085 DynRelaRegion.Addr = toMappedAddr(Dyn.getPtr());
1086 break;
1087 case ELF::DT_RELASZ:
1088 DynRelaRegion.Size = Dyn.getVal();
1089 break;
1090 case ELF::DT_RELAENT:
1091 DynRelaRegion.EntSize = Dyn.getVal();
1092 break;
1093 case ELF::DT_SONAME:
1094 SONameOffset = Dyn.getVal();
1095 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001096 case ELF::DT_REL:
1097 DynRelRegion.Addr = toMappedAddr(Dyn.getPtr());
George Rimar47936762016-01-16 00:49:19 +00001098 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001099 case ELF::DT_RELSZ:
1100 DynRelRegion.Size = Dyn.getVal();
George Rimar47936762016-01-16 00:49:19 +00001101 break;
Michael J. Spencer94f060c2016-02-11 04:59:32 +00001102 case ELF::DT_RELENT:
1103 DynRelRegion.EntSize = Dyn.getVal();
George Rimar47936762016-01-16 00:49:19 +00001104 break;
1105 }
1106 }
1107 if (StringTableBegin)
1108 DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
1109 if (SONameOffset)
1110 SOName = getDynamicString(SONameOffset);
George Rimar47936762016-01-16 00:49:19 +00001111}
1112
1113template <typename ELFT>
Simon Atanasyane03126a2016-01-18 18:52:04 +00001114template <typename REL>
1115const REL *ELFDumper<ELFT>::dyn_rel_begin(const DynRegionInfo &Region) {
1116 if (Region.Size && Region.EntSize != sizeof(REL))
George Rimar47936762016-01-16 00:49:19 +00001117 report_fatal_error("Invalid relocation entry size");
Simon Atanasyane03126a2016-01-18 18:52:04 +00001118 return reinterpret_cast<const REL *>(Region.Addr);
George Rimar47936762016-01-16 00:49:19 +00001119}
1120
1121template <typename ELFT>
Simon Atanasyane03126a2016-01-18 18:52:04 +00001122template <typename REL>
1123const REL *ELFDumper<ELFT>::dyn_rel_end(const DynRegionInfo &Region) {
Simon Atanasyan72155c32016-01-16 22:40:09 +00001124 uint64_t Size = Region.Size;
Simon Atanasyane03126a2016-01-18 18:52:04 +00001125 if (Size % sizeof(REL))
George Rimar47936762016-01-16 00:49:19 +00001126 report_fatal_error("Invalid relocation table size");
Simon Atanasyane03126a2016-01-18 18:52:04 +00001127 return dyn_rel_begin<REL>(Region) + Size / sizeof(REL);
Simon Atanasyan72155c32016-01-16 22:40:09 +00001128}
1129
1130template <typename ELFT>
1131typename ELFDumper<ELFT>::Elf_Rel_Range ELFDumper<ELFT>::dyn_rels() const {
Simon Atanasyane03126a2016-01-18 18:52:04 +00001132 return make_range(dyn_rel_begin<Elf_Rel>(DynRelRegion),
1133 dyn_rel_end<Elf_Rel>(DynRelRegion));
George Rimar47936762016-01-16 00:49:19 +00001134}
1135
1136template <typename ELFT>
1137typename ELFDumper<ELFT>::Elf_Rela_Range ELFDumper<ELFT>::dyn_relas() const {
Simon Atanasyane03126a2016-01-18 18:52:04 +00001138 return make_range(dyn_rel_begin<Elf_Rela>(DynRelaRegion),
1139 dyn_rel_end<Elf_Rela>(DynRelaRegion));
George Rimar47936762016-01-16 00:49:19 +00001140}
1141
1142template<class ELFT>
1143void ELFDumper<ELFT>::printFileHeaders() {
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00001144 ELFDumperStyle->printFileHeaders(Obj);
George Rimar47936762016-01-16 00:49:19 +00001145}
1146
1147template<class ELFT>
1148void ELFDumper<ELFT>::printSections() {
1149 ListScope SectionsD(W, "Sections");
1150
1151 int SectionIndex = -1;
1152 for (const Elf_Shdr &Sec : Obj->sections()) {
1153 ++SectionIndex;
1154
1155 StringRef Name = errorOrDefault(Obj->getSectionName(&Sec));
1156
1157 DictScope SectionD(W, "Section");
1158 W.printNumber("Index", SectionIndex);
1159 W.printNumber("Name", Name, Sec.sh_name);
1160 W.printHex("Type",
1161 getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type),
1162 Sec.sh_type);
Simon Atanasyan2d0d8532016-01-20 19:15:18 +00001163 std::vector<EnumEntry<unsigned>> SectionFlags(std::begin(ElfSectionFlags),
1164 std::end(ElfSectionFlags));
1165 switch (Obj->getHeader()->e_machine) {
1166 case EM_AMDGPU:
1167 SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags),
1168 std::end(ElfAMDGPUSectionFlags));
1169 break;
1170 case EM_HEXAGON:
1171 SectionFlags.insert(SectionFlags.end(),
1172 std::begin(ElfHexagonSectionFlags),
1173 std::end(ElfHexagonSectionFlags));
1174 break;
1175 case EM_MIPS:
1176 SectionFlags.insert(SectionFlags.end(), std::begin(ElfMipsSectionFlags),
1177 std::end(ElfMipsSectionFlags));
1178 break;
1179 case EM_X86_64:
1180 SectionFlags.insert(SectionFlags.end(), std::begin(ElfX86_64SectionFlags),
1181 std::end(ElfX86_64SectionFlags));
1182 break;
1183 default:
1184 // Nothing to do.
1185 break;
1186 }
1187 W.printFlags("Flags", Sec.sh_flags, makeArrayRef(SectionFlags));
George Rimar47936762016-01-16 00:49:19 +00001188 W.printHex("Address", Sec.sh_addr);
1189 W.printHex("Offset", Sec.sh_offset);
1190 W.printNumber("Size", Sec.sh_size);
1191 W.printNumber("Link", Sec.sh_link);
1192 W.printNumber("Info", Sec.sh_info);
1193 W.printNumber("AddressAlignment", Sec.sh_addralign);
1194 W.printNumber("EntrySize", Sec.sh_entsize);
1195
1196 if (opts::SectionRelocations) {
1197 ListScope D(W, "Relocations");
1198 printRelocations(&Sec);
1199 }
1200
1201 if (opts::SectionSymbols) {
1202 ListScope D(W, "Symbols");
1203 const Elf_Shdr *Symtab = DotSymtabSec;
1204 ErrorOr<StringRef> StrTableOrErr = Obj->getStringTableForSymtab(*Symtab);
1205 error(StrTableOrErr.getError());
1206 StringRef StrTable = *StrTableOrErr;
1207
1208 for (const Elf_Sym &Sym : Obj->symbols(Symtab)) {
1209 ErrorOr<const Elf_Shdr *> SymSec =
1210 Obj->getSection(&Sym, Symtab, ShndxTable);
1211 if (!SymSec)
1212 continue;
1213 if (*SymSec == &Sec)
1214 printSymbol(&Sym, Symtab, StrTable, false);
1215 }
1216 }
1217
1218 if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) {
1219 ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(&Sec));
1220 W.printBinaryBlock("SectionData",
1221 StringRef((const char *)Data.data(), Data.size()));
1222 }
1223 }
1224}
1225
1226template<class ELFT>
1227void ELFDumper<ELFT>::printRelocations() {
1228 ListScope D(W, "Relocations");
1229
1230 int SectionNumber = -1;
1231 for (const Elf_Shdr &Sec : Obj->sections()) {
1232 ++SectionNumber;
1233
1234 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA)
1235 continue;
1236
1237 StringRef Name = errorOrDefault(Obj->getSectionName(&Sec));
1238
1239 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
1240 W.indent();
1241
1242 printRelocations(&Sec);
1243
1244 W.unindent();
1245 W.startLine() << "}\n";
1246 }
1247}
1248
Simon Atanasyan72155c32016-01-16 22:40:09 +00001249template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
1250 if (DynRelRegion.Size && DynRelaRegion.Size)
1251 report_fatal_error("There are both REL and RELA dynamic relocations");
George Rimar47936762016-01-16 00:49:19 +00001252 W.startLine() << "Dynamic Relocations {\n";
1253 W.indent();
Simon Atanasyan72155c32016-01-16 22:40:09 +00001254 if (DynRelaRegion.Size > 0)
1255 for (const Elf_Rela &Rela : dyn_relas())
1256 printDynamicRelocation(Rela);
1257 else
1258 for (const Elf_Rel &Rel : dyn_rels()) {
1259 Elf_Rela Rela;
1260 Rela.r_offset = Rel.r_offset;
1261 Rela.r_info = Rel.r_info;
1262 Rela.r_addend = 0;
1263 printDynamicRelocation(Rela);
George Rimar47936762016-01-16 00:49:19 +00001264 }
George Rimar47936762016-01-16 00:49:19 +00001265 W.unindent();
1266 W.startLine() << "}\n";
1267}
1268
1269template <class ELFT>
1270void ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) {
1271 ErrorOr<const Elf_Shdr *> SymTabOrErr = Obj->getSection(Sec->sh_link);
1272 error(SymTabOrErr.getError());
1273 const Elf_Shdr *SymTab = *SymTabOrErr;
1274
1275 switch (Sec->sh_type) {
1276 case ELF::SHT_REL:
1277 for (const Elf_Rel &R : Obj->rels(Sec)) {
1278 Elf_Rela Rela;
1279 Rela.r_offset = R.r_offset;
1280 Rela.r_info = R.r_info;
1281 Rela.r_addend = 0;
1282 printRelocation(Rela, SymTab);
1283 }
1284 break;
1285 case ELF::SHT_RELA:
1286 for (const Elf_Rela &R : Obj->relas(Sec))
1287 printRelocation(R, SymTab);
1288 break;
1289 }
1290}
1291
1292template <class ELFT>
1293void ELFDumper<ELFT>::printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab) {
1294 SmallString<32> RelocName;
1295 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
1296 StringRef TargetName;
1297 const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTab);
1298 if (Sym && Sym->getType() == ELF::STT_SECTION) {
1299 ErrorOr<const Elf_Shdr *> Sec = Obj->getSection(Sym, SymTab, ShndxTable);
1300 error(Sec.getError());
1301 ErrorOr<StringRef> SecName = Obj->getSectionName(*Sec);
1302 if (SecName)
1303 TargetName = SecName.get();
1304 } else if (Sym) {
1305 ErrorOr<StringRef> StrTableOrErr = Obj->getStringTableForSymtab(*SymTab);
1306 error(StrTableOrErr.getError());
1307 TargetName = errorOrDefault(Sym->getName(*StrTableOrErr));
1308 }
1309
1310 if (opts::ExpandRelocs) {
1311 DictScope Group(W, "Relocation");
1312 W.printHex("Offset", Rel.r_offset);
1313 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
1314 W.printNumber("Symbol", TargetName.size() > 0 ? TargetName : "-",
1315 Rel.getSymbol(Obj->isMips64EL()));
1316 W.printHex("Addend", Rel.r_addend);
1317 } else {
1318 raw_ostream& OS = W.startLine();
1319 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
1320 << (TargetName.size() > 0 ? TargetName : "-") << " "
1321 << W.hex(Rel.r_addend) << "\n";
1322 }
1323}
1324
Simon Atanasyan72155c32016-01-16 22:40:09 +00001325template <class ELFT>
1326void ELFDumper<ELFT>::printDynamicRelocation(Elf_Rela Rel) {
1327 SmallString<32> RelocName;
1328 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
1329 StringRef SymbolName;
1330 uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
1331 const Elf_Sym *Sym = DynSymStart + SymIndex;
1332 SymbolName = errorOrDefault(Sym->getName(DynamicStringTable));
1333 if (opts::ExpandRelocs) {
1334 DictScope Group(W, "Relocation");
1335 W.printHex("Offset", Rel.r_offset);
1336 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
1337 W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
1338 W.printHex("Addend", Rel.r_addend);
1339 } else {
1340 raw_ostream &OS = W.startLine();
1341 OS << W.hex(Rel.r_offset) << " " << RelocName << " "
1342 << (SymbolName.size() > 0 ? SymbolName : "-") << " "
1343 << W.hex(Rel.r_addend) << "\n";
1344 }
1345}
1346
George Rimar47936762016-01-16 00:49:19 +00001347template<class ELFT>
1348void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) {
1349 const Elf_Shdr *Symtab = (IsDynamic) ? DotDynSymSec : DotSymtabSec;
1350 if (!Symtab)
1351 return;
1352 ErrorOr<StringRef> StrTableOrErr = Obj->getStringTableForSymtab(*Symtab);
1353 error(StrTableOrErr.getError());
1354 StringRef StrTable = *StrTableOrErr;
1355 for (const Elf_Sym &Sym : Obj->symbols(Symtab))
1356 printSymbol(&Sym, Symtab, StrTable, IsDynamic);
1357}
1358
1359template<class ELFT>
1360void ELFDumper<ELFT>::printSymbols() {
1361 ListScope Group(W, "Symbols");
1362 printSymbolsHelper(false);
1363}
1364
1365template<class ELFT>
1366void ELFDumper<ELFT>::printDynamicSymbols() {
1367 ListScope Group(W, "DynamicSymbols");
1368 printSymbolsHelper(true);
1369}
1370
1371template <class ELFT>
1372void ELFDumper<ELFT>::printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
1373 StringRef StrTable, bool IsDynamic) {
1374 unsigned SectionIndex = 0;
1375 StringRef SectionName;
1376 getSectionNameIndex(*Obj, Symbol, SymTab, ShndxTable, SectionName,
1377 SectionIndex);
1378 std::string FullSymbolName = getFullSymbolName(Symbol, StrTable, IsDynamic);
1379 unsigned char SymbolType = Symbol->getType();
1380
1381 DictScope D(W, "Symbol");
1382 W.printNumber("Name", FullSymbolName, Symbol->st_name);
1383 W.printHex ("Value", Symbol->st_value);
1384 W.printNumber("Size", Symbol->st_size);
1385 W.printEnum ("Binding", Symbol->getBinding(),
1386 makeArrayRef(ElfSymbolBindings));
1387 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU &&
1388 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS)
1389 W.printEnum ("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
1390 else
1391 W.printEnum ("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
1392 W.printNumber("Other", Symbol->st_other);
1393 W.printHex("Section", SectionName, SectionIndex);
1394}
1395
1396#define LLVM_READOBJ_TYPE_CASE(name) \
1397 case DT_##name: return #name
1398
1399static const char *getTypeString(uint64_t Type) {
1400 switch (Type) {
1401 LLVM_READOBJ_TYPE_CASE(BIND_NOW);
1402 LLVM_READOBJ_TYPE_CASE(DEBUG);
1403 LLVM_READOBJ_TYPE_CASE(FINI);
1404 LLVM_READOBJ_TYPE_CASE(FINI_ARRAY);
1405 LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ);
1406 LLVM_READOBJ_TYPE_CASE(FLAGS);
1407 LLVM_READOBJ_TYPE_CASE(FLAGS_1);
1408 LLVM_READOBJ_TYPE_CASE(HASH);
1409 LLVM_READOBJ_TYPE_CASE(INIT);
1410 LLVM_READOBJ_TYPE_CASE(INIT_ARRAY);
1411 LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ);
1412 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY);
1413 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ);
1414 LLVM_READOBJ_TYPE_CASE(JMPREL);
1415 LLVM_READOBJ_TYPE_CASE(NEEDED);
1416 LLVM_READOBJ_TYPE_CASE(NULL);
1417 LLVM_READOBJ_TYPE_CASE(PLTGOT);
1418 LLVM_READOBJ_TYPE_CASE(PLTREL);
1419 LLVM_READOBJ_TYPE_CASE(PLTRELSZ);
1420 LLVM_READOBJ_TYPE_CASE(REL);
1421 LLVM_READOBJ_TYPE_CASE(RELA);
1422 LLVM_READOBJ_TYPE_CASE(RELENT);
1423 LLVM_READOBJ_TYPE_CASE(RELSZ);
1424 LLVM_READOBJ_TYPE_CASE(RELAENT);
1425 LLVM_READOBJ_TYPE_CASE(RELASZ);
1426 LLVM_READOBJ_TYPE_CASE(RPATH);
1427 LLVM_READOBJ_TYPE_CASE(RUNPATH);
1428 LLVM_READOBJ_TYPE_CASE(SONAME);
1429 LLVM_READOBJ_TYPE_CASE(STRSZ);
1430 LLVM_READOBJ_TYPE_CASE(STRTAB);
1431 LLVM_READOBJ_TYPE_CASE(SYMBOLIC);
1432 LLVM_READOBJ_TYPE_CASE(SYMENT);
1433 LLVM_READOBJ_TYPE_CASE(SYMTAB);
1434 LLVM_READOBJ_TYPE_CASE(TEXTREL);
1435 LLVM_READOBJ_TYPE_CASE(VERDEF);
1436 LLVM_READOBJ_TYPE_CASE(VERDEFNUM);
1437 LLVM_READOBJ_TYPE_CASE(VERNEED);
1438 LLVM_READOBJ_TYPE_CASE(VERNEEDNUM);
George Rimare05fcec2016-01-16 10:38:32 +00001439 LLVM_READOBJ_TYPE_CASE(VERSYM);
Davide Italiano8c503672016-01-16 06:06:36 +00001440 LLVM_READOBJ_TYPE_CASE(RELACOUNT);
George Rimare05fcec2016-01-16 10:38:32 +00001441 LLVM_READOBJ_TYPE_CASE(RELCOUNT);
1442 LLVM_READOBJ_TYPE_CASE(GNU_HASH);
1443 LLVM_READOBJ_TYPE_CASE(TLSDESC_PLT);
1444 LLVM_READOBJ_TYPE_CASE(TLSDESC_GOT);
1445 LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION);
1446 LLVM_READOBJ_TYPE_CASE(MIPS_RLD_MAP_REL);
1447 LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS);
George Rimar47936762016-01-16 00:49:19 +00001448 LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS);
1449 LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO);
1450 LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO);
1451 LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO);
1452 LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM);
1453 LLVM_READOBJ_TYPE_CASE(MIPS_RLD_MAP);
1454 LLVM_READOBJ_TYPE_CASE(MIPS_PLTGOT);
1455 LLVM_READOBJ_TYPE_CASE(MIPS_OPTIONS);
1456 default: return "unknown";
1457 }
1458}
1459
1460#undef LLVM_READOBJ_TYPE_CASE
1461
1462#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \
1463 { #enum, prefix##_##enum }
1464
1465static const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
1466 LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
1467 LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
1468 LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
1469 LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
1470 LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
1471};
1472
1473static const EnumEntry<unsigned> ElfDynamicDTFlags1[] = {
1474 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW),
1475 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL),
1476 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP),
1477 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE),
1478 LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR),
1479 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST),
1480 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN),
1481 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN),
1482 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT),
1483 LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS),
1484 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE),
1485 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB),
1486 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP),
1487 LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT),
1488 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE),
1489 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE),
1490 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT),
1491 LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF),
1492 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS),
1493 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR),
1494 LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED),
1495 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC),
1496 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE),
1497 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT),
1498 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON)
1499};
1500
1501static const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
1502 LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
1503 LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
1504 LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
1505 LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
1506 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
1507 LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
1508 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
1509 LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
1510 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
1511 LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
1512 LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
1513 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
1514 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
1515 LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
1516 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
1517 LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
1518};
1519
1520#undef LLVM_READOBJ_DT_FLAG_ENT
1521
1522template <typename T, typename TFlag>
1523void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
1524 typedef EnumEntry<TFlag> FlagEntry;
1525 typedef SmallVector<FlagEntry, 10> FlagVector;
1526 FlagVector SetFlags;
1527
1528 for (const auto &Flag : Flags) {
1529 if (Flag.Value == 0)
1530 continue;
1531
1532 if ((Value & Flag.Value) == Flag.Value)
1533 SetFlags.push_back(Flag);
1534 }
1535
1536 for (const auto &Flag : SetFlags) {
1537 OS << Flag.Name << " ";
1538 }
1539}
1540
1541template <class ELFT>
1542StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
1543 if (Value >= DynamicStringTable.size())
1544 reportError("Invalid dynamic string table reference");
1545 return StringRef(DynamicStringTable.data() + Value);
1546}
1547
1548template <class ELFT>
1549void ELFDumper<ELFT>::printValue(uint64_t Type, uint64_t Value) {
1550 raw_ostream &OS = W.getOStream();
1551 switch (Type) {
1552 case DT_PLTREL:
1553 if (Value == DT_REL) {
1554 OS << "REL";
1555 break;
1556 } else if (Value == DT_RELA) {
1557 OS << "RELA";
1558 break;
1559 }
1560 // Fallthrough.
1561 case DT_PLTGOT:
1562 case DT_HASH:
1563 case DT_STRTAB:
1564 case DT_SYMTAB:
1565 case DT_RELA:
1566 case DT_INIT:
1567 case DT_FINI:
1568 case DT_REL:
1569 case DT_JMPREL:
1570 case DT_INIT_ARRAY:
1571 case DT_FINI_ARRAY:
1572 case DT_PREINIT_ARRAY:
1573 case DT_DEBUG:
1574 case DT_VERDEF:
1575 case DT_VERNEED:
1576 case DT_VERSYM:
1577 case DT_GNU_HASH:
1578 case DT_NULL:
1579 case DT_MIPS_BASE_ADDRESS:
1580 case DT_MIPS_GOTSYM:
1581 case DT_MIPS_RLD_MAP:
1582 case DT_MIPS_RLD_MAP_REL:
1583 case DT_MIPS_PLTGOT:
1584 case DT_MIPS_OPTIONS:
1585 OS << format("0x%" PRIX64, Value);
1586 break;
Davide Italiano8c503672016-01-16 06:06:36 +00001587 case DT_RELACOUNT:
George Rimar47936762016-01-16 00:49:19 +00001588 case DT_RELCOUNT:
1589 case DT_VERDEFNUM:
1590 case DT_VERNEEDNUM:
1591 case DT_MIPS_RLD_VERSION:
1592 case DT_MIPS_LOCAL_GOTNO:
1593 case DT_MIPS_SYMTABNO:
1594 case DT_MIPS_UNREFEXTNO:
1595 OS << Value;
1596 break;
1597 case DT_PLTRELSZ:
1598 case DT_RELASZ:
1599 case DT_RELAENT:
1600 case DT_STRSZ:
1601 case DT_SYMENT:
1602 case DT_RELSZ:
1603 case DT_RELENT:
1604 case DT_INIT_ARRAYSZ:
1605 case DT_FINI_ARRAYSZ:
1606 case DT_PREINIT_ARRAYSZ:
1607 OS << Value << " (bytes)";
1608 break;
1609 case DT_NEEDED:
1610 OS << "SharedLibrary (" << getDynamicString(Value) << ")";
1611 break;
1612 case DT_SONAME:
1613 OS << "LibrarySoname (" << getDynamicString(Value) << ")";
1614 break;
1615 case DT_RPATH:
1616 case DT_RUNPATH:
1617 OS << getDynamicString(Value);
1618 break;
1619 case DT_MIPS_FLAGS:
1620 printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS);
1621 break;
1622 case DT_FLAGS:
1623 printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
1624 break;
1625 case DT_FLAGS_1:
1626 printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS);
1627 break;
1628 default:
1629 OS << format("0x%" PRIX64, Value);
1630 break;
1631 }
1632}
1633
1634template<class ELFT>
1635void ELFDumper<ELFT>::printUnwindInfo() {
1636 W.startLine() << "UnwindInfo not implemented.\n";
1637}
1638
1639namespace {
1640template <> void ELFDumper<ELFType<support::little, false>>::printUnwindInfo() {
1641 const unsigned Machine = Obj->getHeader()->e_machine;
1642 if (Machine == EM_ARM) {
1643 ARM::EHABI::PrinterContext<ELFType<support::little, false>> Ctx(
1644 W, Obj, DotSymtabSec);
1645 return Ctx.PrintUnwindInformation();
1646 }
1647 W.startLine() << "UnwindInfo not implemented.\n";
1648}
1649}
1650
1651template<class ELFT>
1652void ELFDumper<ELFT>::printDynamicTable() {
1653 auto I = dynamic_table_begin();
1654 auto E = dynamic_table_end();
1655
1656 if (I == E)
1657 return;
1658
1659 --E;
1660 while (I != E && E->getTag() == ELF::DT_NULL)
1661 --E;
1662 if (E->getTag() != ELF::DT_NULL)
1663 ++E;
1664 ++E;
1665
1666 ptrdiff_t Total = std::distance(I, E);
1667 if (Total == 0)
1668 return;
1669
1670 raw_ostream &OS = W.getOStream();
1671 W.startLine() << "DynamicSection [ (" << Total << " entries)\n";
1672
1673 bool Is64 = ELFT::Is64Bits;
1674
1675 W.startLine()
1676 << " Tag" << (Is64 ? " " : " ") << "Type"
1677 << " " << "Name/Value\n";
1678 while (I != E) {
1679 const Elf_Dyn &Entry = *I;
1680 uintX_t Tag = Entry.getTag();
1681 ++I;
1682 W.startLine() << " " << format_hex(Tag, Is64 ? 18 : 10, true) << " "
1683 << format("%-21s", getTypeString(Tag));
1684 printValue(Tag, Entry.getVal());
1685 OS << "\n";
1686 }
1687
1688 W.startLine() << "]\n";
1689}
1690
1691template<class ELFT>
1692void ELFDumper<ELFT>::printNeededLibraries() {
1693 ListScope D(W, "NeededLibraries");
1694
1695 typedef std::vector<StringRef> LibsTy;
1696 LibsTy Libs;
1697
1698 for (const auto &Entry : dynamic_table())
1699 if (Entry.d_tag == ELF::DT_NEEDED)
1700 Libs.push_back(getDynamicString(Entry.d_un.d_val));
1701
1702 std::stable_sort(Libs.begin(), Libs.end());
1703
1704 for (const auto &L : Libs) {
1705 outs() << " " << L << "\n";
1706 }
1707}
1708
1709template<class ELFT>
1710void ELFDumper<ELFT>::printProgramHeaders() {
1711 ListScope L(W, "ProgramHeaders");
1712
1713 for (const Elf_Phdr &Phdr : Obj->program_headers()) {
1714 DictScope P(W, "ProgramHeader");
1715 W.printHex("Type",
1716 getElfSegmentType(Obj->getHeader()->e_machine, Phdr.p_type),
1717 Phdr.p_type);
1718 W.printHex("Offset", Phdr.p_offset);
1719 W.printHex("VirtualAddress", Phdr.p_vaddr);
1720 W.printHex("PhysicalAddress", Phdr.p_paddr);
1721 W.printNumber("FileSize", Phdr.p_filesz);
1722 W.printNumber("MemSize", Phdr.p_memsz);
1723 W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags));
1724 W.printNumber("Alignment", Phdr.p_align);
1725 }
1726}
1727
1728template <typename ELFT>
1729void ELFDumper<ELFT>::printHashTable() {
1730 DictScope D(W, "HashTable");
1731 if (!HashTable)
1732 return;
1733 W.printNumber("Num Buckets", HashTable->nbucket);
1734 W.printNumber("Num Chains", HashTable->nchain);
1735 W.printList("Buckets", HashTable->buckets());
1736 W.printList("Chains", HashTable->chains());
1737}
1738
1739template <typename ELFT>
1740void ELFDumper<ELFT>::printGnuHashTable() {
1741 DictScope D(W, "GnuHashTable");
1742 if (!GnuHashTable)
1743 return;
1744 W.printNumber("Num Buckets", GnuHashTable->nbuckets);
1745 W.printNumber("First Hashed Symbol Index", GnuHashTable->symndx);
1746 W.printNumber("Num Mask Words", GnuHashTable->maskwords);
1747 W.printNumber("Shift Count", GnuHashTable->shift2);
1748 W.printHexList("Bloom Filter", GnuHashTable->filter());
1749 W.printList("Buckets", GnuHashTable->buckets());
1750 if (!DotDynSymSec)
1751 reportError("No dynamic symbol section");
1752 W.printHexList("Values",
1753 GnuHashTable->values(DotDynSymSec->getEntityCount()));
1754}
1755
1756template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {
1757 outs() << "LoadName: " << SOName << '\n';
1758}
1759
1760template <class ELFT>
1761void ELFDumper<ELFT>::printAttributes() {
1762 W.startLine() << "Attributes not implemented.\n";
1763}
1764
1765namespace {
1766template <> void ELFDumper<ELFType<support::little, false>>::printAttributes() {
1767 if (Obj->getHeader()->e_machine != EM_ARM) {
1768 W.startLine() << "Attributes not implemented.\n";
1769 return;
1770 }
1771
1772 DictScope BA(W, "BuildAttributes");
1773 for (const ELFO::Elf_Shdr &Sec : Obj->sections()) {
1774 if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES)
1775 continue;
1776
1777 ErrorOr<ArrayRef<uint8_t>> Contents = Obj->getSectionContents(&Sec);
1778 if (!Contents)
1779 continue;
1780
1781 if ((*Contents)[0] != ARMBuildAttrs::Format_Version) {
1782 errs() << "unrecognised FormatVersion: 0x" << utohexstr((*Contents)[0])
1783 << '\n';
1784 continue;
1785 }
1786
1787 W.printHex("FormatVersion", (*Contents)[0]);
1788 if (Contents->size() == 1)
1789 continue;
1790
1791 ARMAttributeParser(W).Parse(*Contents);
1792 }
1793}
1794}
1795
1796namespace {
1797template <class ELFT> class MipsGOTParser {
1798public:
1799 typedef object::ELFFile<ELFT> ELFO;
1800 typedef typename ELFO::Elf_Shdr Elf_Shdr;
1801 typedef typename ELFO::Elf_Sym Elf_Sym;
1802 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range;
1803 typedef typename ELFO::Elf_Addr GOTEntry;
1804 typedef typename ELFO::Elf_Rel Elf_Rel;
1805 typedef typename ELFO::Elf_Rela Elf_Rela;
1806
1807 MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
1808 Elf_Dyn_Range DynTable, StreamWriter &W);
1809
1810 void parseGOT();
1811 void parsePLT();
1812
1813private:
1814 ELFDumper<ELFT> *Dumper;
1815 const ELFO *Obj;
1816 StreamWriter &W;
1817 llvm::Optional<uint64_t> DtPltGot;
1818 llvm::Optional<uint64_t> DtLocalGotNum;
1819 llvm::Optional<uint64_t> DtGotSym;
1820 llvm::Optional<uint64_t> DtMipsPltGot;
1821 llvm::Optional<uint64_t> DtJmpRel;
1822
1823 std::size_t getGOTTotal(ArrayRef<uint8_t> GOT) const;
1824 const GOTEntry *makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum);
1825
1826 void printGotEntry(uint64_t GotAddr, const GOTEntry *BeginIt,
1827 const GOTEntry *It);
1828 void printGlobalGotEntry(uint64_t GotAddr, const GOTEntry *BeginIt,
1829 const GOTEntry *It, const Elf_Sym *Sym,
1830 StringRef StrTable, bool IsDynamic);
1831 void printPLTEntry(uint64_t PLTAddr, const GOTEntry *BeginIt,
1832 const GOTEntry *It, StringRef Purpose);
1833 void printPLTEntry(uint64_t PLTAddr, const GOTEntry *BeginIt,
1834 const GOTEntry *It, StringRef StrTable,
1835 const Elf_Sym *Sym);
1836};
1837}
1838
1839template <class ELFT>
1840MipsGOTParser<ELFT>::MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
1841 Elf_Dyn_Range DynTable, StreamWriter &W)
1842 : Dumper(Dumper), Obj(Obj), W(W) {
1843 for (const auto &Entry : DynTable) {
1844 switch (Entry.getTag()) {
1845 case ELF::DT_PLTGOT:
1846 DtPltGot = Entry.getVal();
1847 break;
1848 case ELF::DT_MIPS_LOCAL_GOTNO:
1849 DtLocalGotNum = Entry.getVal();
1850 break;
1851 case ELF::DT_MIPS_GOTSYM:
1852 DtGotSym = Entry.getVal();
1853 break;
1854 case ELF::DT_MIPS_PLTGOT:
1855 DtMipsPltGot = Entry.getVal();
1856 break;
1857 case ELF::DT_JMPREL:
1858 DtJmpRel = Entry.getVal();
1859 break;
1860 }
1861 }
1862}
1863
1864template <class ELFT> void MipsGOTParser<ELFT>::parseGOT() {
1865 // See "Global Offset Table" in Chapter 5 in the following document
1866 // for detailed GOT description.
1867 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1868 if (!DtPltGot) {
1869 W.startLine() << "Cannot find PLTGOT dynamic table tag.\n";
1870 return;
1871 }
1872 if (!DtLocalGotNum) {
1873 W.startLine() << "Cannot find MIPS_LOCAL_GOTNO dynamic table tag.\n";
1874 return;
1875 }
1876 if (!DtGotSym) {
1877 W.startLine() << "Cannot find MIPS_GOTSYM dynamic table tag.\n";
1878 return;
1879 }
1880
George Rimar47936762016-01-16 00:49:19 +00001881 const Elf_Shdr *DynSymSec = Dumper->getDotDynSymSec();
1882 ErrorOr<StringRef> StrTable = Obj->getStringTableForSymtab(*DynSymSec);
1883 error(StrTable.getError());
1884 const Elf_Sym *DynSymBegin = Obj->symbol_begin(DynSymSec);
1885 const Elf_Sym *DynSymEnd = Obj->symbol_end(DynSymSec);
1886 std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
1887
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001888 if (*DtGotSym > DynSymTotal)
1889 report_fatal_error("MIPS_GOTSYM exceeds a number of dynamic symbols");
George Rimar47936762016-01-16 00:49:19 +00001890
1891 std::size_t GlobalGotNum = DynSymTotal - *DtGotSym;
1892
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001893 if (*DtLocalGotNum + GlobalGotNum == 0) {
1894 W.startLine() << "GOT is empty.\n";
George Rimar47936762016-01-16 00:49:19 +00001895 return;
1896 }
1897
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001898 const Elf_Shdr *GOTShdr = findNotEmptySectionByAddress(Obj, *DtPltGot);
1899 if (!GOTShdr)
1900 report_fatal_error("There is no not empty GOT section at 0x" +
1901 Twine::utohexstr(*DtPltGot));
1902
1903 ErrorOr<ArrayRef<uint8_t>> GOT = Obj->getSectionContents(GOTShdr);
1904
1905 if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT))
1906 report_fatal_error("Number of GOT entries exceeds the size of GOT section");
1907
George Rimar47936762016-01-16 00:49:19 +00001908 const GOTEntry *GotBegin = makeGOTIter(*GOT, 0);
1909 const GOTEntry *GotLocalEnd = makeGOTIter(*GOT, *DtLocalGotNum);
1910 const GOTEntry *It = GotBegin;
1911
1912 DictScope GS(W, "Primary GOT");
1913
1914 W.printHex("Canonical gp value", GOTShdr->sh_addr + 0x7ff0);
1915 {
1916 ListScope RS(W, "Reserved entries");
1917
1918 {
1919 DictScope D(W, "Entry");
1920 printGotEntry(GOTShdr->sh_addr, GotBegin, It++);
1921 W.printString("Purpose", StringRef("Lazy resolver"));
1922 }
1923
1924 if (It != GotLocalEnd && (*It >> (sizeof(GOTEntry) * 8 - 1)) != 0) {
1925 DictScope D(W, "Entry");
1926 printGotEntry(GOTShdr->sh_addr, GotBegin, It++);
1927 W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
1928 }
1929 }
1930 {
1931 ListScope LS(W, "Local entries");
1932 for (; It != GotLocalEnd; ++It) {
1933 DictScope D(W, "Entry");
1934 printGotEntry(GOTShdr->sh_addr, GotBegin, It);
1935 }
1936 }
1937 {
1938 ListScope GS(W, "Global entries");
1939
1940 const GOTEntry *GotGlobalEnd =
1941 makeGOTIter(*GOT, *DtLocalGotNum + GlobalGotNum);
1942 const Elf_Sym *GotDynSym = DynSymBegin + *DtGotSym;
1943 for (; It != GotGlobalEnd; ++It) {
1944 DictScope D(W, "Entry");
1945 printGlobalGotEntry(GOTShdr->sh_addr, GotBegin, It, GotDynSym++,
1946 *StrTable, true);
1947 }
1948 }
1949
1950 std::size_t SpecGotNum = getGOTTotal(*GOT) - *DtLocalGotNum - GlobalGotNum;
1951 W.printNumber("Number of TLS and multi-GOT entries", uint64_t(SpecGotNum));
1952}
1953
1954template <class ELFT> void MipsGOTParser<ELFT>::parsePLT() {
1955 if (!DtMipsPltGot) {
1956 W.startLine() << "Cannot find MIPS_PLTGOT dynamic table tag.\n";
1957 return;
1958 }
1959 if (!DtJmpRel) {
1960 W.startLine() << "Cannot find JMPREL dynamic table tag.\n";
1961 return;
1962 }
1963
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001964 const Elf_Shdr *PLTShdr = findNotEmptySectionByAddress(Obj, *DtMipsPltGot);
1965 if (!PLTShdr)
1966 report_fatal_error("There is no not empty PLTGOT section at 0x " +
1967 Twine::utohexstr(*DtMipsPltGot));
George Rimar47936762016-01-16 00:49:19 +00001968 ErrorOr<ArrayRef<uint8_t>> PLT = Obj->getSectionContents(PLTShdr);
George Rimar47936762016-01-16 00:49:19 +00001969
Simon Atanasyancb1175c2016-02-09 18:45:35 +00001970 const Elf_Shdr *PLTRelShdr = findNotEmptySectionByAddress(Obj, *DtJmpRel);
1971 if (!PLTRelShdr)
1972 report_fatal_error("There is no not empty RELPLT section at 0x" +
1973 Twine::utohexstr(*DtJmpRel));
George Rimar47936762016-01-16 00:49:19 +00001974 ErrorOr<const Elf_Shdr *> SymTableOrErr =
1975 Obj->getSection(PLTRelShdr->sh_link);
1976 error(SymTableOrErr.getError());
1977 const Elf_Shdr *SymTable = *SymTableOrErr;
1978 ErrorOr<StringRef> StrTable = Obj->getStringTableForSymtab(*SymTable);
1979 error(StrTable.getError());
1980
1981 const GOTEntry *PLTBegin = makeGOTIter(*PLT, 0);
1982 const GOTEntry *PLTEnd = makeGOTIter(*PLT, getGOTTotal(*PLT));
1983 const GOTEntry *It = PLTBegin;
1984
1985 DictScope GS(W, "PLT GOT");
1986 {
1987 ListScope RS(W, "Reserved entries");
1988 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It++, "PLT lazy resolver");
1989 if (It != PLTEnd)
1990 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It++, "Module pointer");
1991 }
1992 {
1993 ListScope GS(W, "Entries");
1994
1995 switch (PLTRelShdr->sh_type) {
1996 case ELF::SHT_REL:
1997 for (const Elf_Rel *RI = Obj->rel_begin(PLTRelShdr),
1998 *RE = Obj->rel_end(PLTRelShdr);
1999 RI != RE && It != PLTEnd; ++RI, ++It) {
2000 const Elf_Sym *Sym = Obj->getRelocationSymbol(&*RI, SymTable);
2001 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, *StrTable, Sym);
2002 }
2003 break;
2004 case ELF::SHT_RELA:
2005 for (const Elf_Rela *RI = Obj->rela_begin(PLTRelShdr),
2006 *RE = Obj->rela_end(PLTRelShdr);
2007 RI != RE && It != PLTEnd; ++RI, ++It) {
2008 const Elf_Sym *Sym = Obj->getRelocationSymbol(&*RI, SymTable);
2009 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, *StrTable, Sym);
2010 }
2011 break;
2012 }
2013 }
2014}
2015
2016template <class ELFT>
2017std::size_t MipsGOTParser<ELFT>::getGOTTotal(ArrayRef<uint8_t> GOT) const {
2018 return GOT.size() / sizeof(GOTEntry);
2019}
2020
2021template <class ELFT>
2022const typename MipsGOTParser<ELFT>::GOTEntry *
2023MipsGOTParser<ELFT>::makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum) {
2024 const char *Data = reinterpret_cast<const char *>(GOT.data());
2025 return reinterpret_cast<const GOTEntry *>(Data + EntryNum * sizeof(GOTEntry));
2026}
2027
2028template <class ELFT>
2029void MipsGOTParser<ELFT>::printGotEntry(uint64_t GotAddr,
2030 const GOTEntry *BeginIt,
2031 const GOTEntry *It) {
2032 int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry);
2033 W.printHex("Address", GotAddr + Offset);
2034 W.printNumber("Access", Offset - 0x7ff0);
2035 W.printHex("Initial", *It);
2036}
2037
2038template <class ELFT>
2039void MipsGOTParser<ELFT>::printGlobalGotEntry(
2040 uint64_t GotAddr, const GOTEntry *BeginIt, const GOTEntry *It,
2041 const Elf_Sym *Sym, StringRef StrTable, bool IsDynamic) {
2042 printGotEntry(GotAddr, BeginIt, It);
2043
2044 W.printHex("Value", Sym->st_value);
2045 W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes));
2046
2047 unsigned SectionIndex = 0;
2048 StringRef SectionName;
2049 getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
2050 Dumper->getShndxTable(), SectionName, SectionIndex);
2051 W.printHex("Section", SectionName, SectionIndex);
2052
2053 std::string FullSymbolName =
2054 Dumper->getFullSymbolName(Sym, StrTable, IsDynamic);
2055 W.printNumber("Name", FullSymbolName, Sym->st_name);
2056}
2057
2058template <class ELFT>
2059void MipsGOTParser<ELFT>::printPLTEntry(uint64_t PLTAddr,
2060 const GOTEntry *BeginIt,
2061 const GOTEntry *It, StringRef Purpose) {
2062 DictScope D(W, "Entry");
2063 int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry);
2064 W.printHex("Address", PLTAddr + Offset);
2065 W.printHex("Initial", *It);
2066 W.printString("Purpose", Purpose);
2067}
2068
2069template <class ELFT>
2070void MipsGOTParser<ELFT>::printPLTEntry(uint64_t PLTAddr,
2071 const GOTEntry *BeginIt,
2072 const GOTEntry *It, StringRef StrTable,
2073 const Elf_Sym *Sym) {
2074 DictScope D(W, "Entry");
2075 int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry);
2076 W.printHex("Address", PLTAddr + Offset);
2077 W.printHex("Initial", *It);
2078 W.printHex("Value", Sym->st_value);
2079 W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes));
2080
2081 unsigned SectionIndex = 0;
2082 StringRef SectionName;
2083 getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
2084 Dumper->getShndxTable(), SectionName, SectionIndex);
2085 W.printHex("Section", SectionName, SectionIndex);
2086
2087 std::string FullSymbolName = Dumper->getFullSymbolName(Sym, StrTable, true);
2088 W.printNumber("Name", FullSymbolName, Sym->st_name);
2089}
2090
2091template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
2092 if (Obj->getHeader()->e_machine != EM_MIPS) {
2093 W.startLine() << "MIPS PLT GOT is available for MIPS targets only.\n";
2094 return;
2095 }
2096
2097 MipsGOTParser<ELFT> GOTParser(this, Obj, dynamic_table(), W);
2098 GOTParser.parseGOT();
2099 GOTParser.parsePLT();
2100}
2101
2102static const EnumEntry<unsigned> ElfMipsISAExtType[] = {
2103 {"None", Mips::AFL_EXT_NONE},
2104 {"Broadcom SB-1", Mips::AFL_EXT_SB1},
2105 {"Cavium Networks Octeon", Mips::AFL_EXT_OCTEON},
2106 {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2},
2107 {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP},
2108 {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3},
2109 {"LSI R4010", Mips::AFL_EXT_4010},
2110 {"Loongson 2E", Mips::AFL_EXT_LOONGSON_2E},
2111 {"Loongson 2F", Mips::AFL_EXT_LOONGSON_2F},
2112 {"Loongson 3A", Mips::AFL_EXT_LOONGSON_3A},
2113 {"MIPS R4650", Mips::AFL_EXT_4650},
2114 {"MIPS R5900", Mips::AFL_EXT_5900},
2115 {"MIPS R10000", Mips::AFL_EXT_10000},
2116 {"NEC VR4100", Mips::AFL_EXT_4100},
2117 {"NEC VR4111/VR4181", Mips::AFL_EXT_4111},
2118 {"NEC VR4120", Mips::AFL_EXT_4120},
2119 {"NEC VR5400", Mips::AFL_EXT_5400},
2120 {"NEC VR5500", Mips::AFL_EXT_5500},
2121 {"RMI Xlr", Mips::AFL_EXT_XLR},
2122 {"Toshiba R3900", Mips::AFL_EXT_3900}
2123};
2124
2125static const EnumEntry<unsigned> ElfMipsASEFlags[] = {
2126 {"DSP", Mips::AFL_ASE_DSP},
2127 {"DSPR2", Mips::AFL_ASE_DSPR2},
2128 {"Enhanced VA Scheme", Mips::AFL_ASE_EVA},
2129 {"MCU", Mips::AFL_ASE_MCU},
2130 {"MDMX", Mips::AFL_ASE_MDMX},
2131 {"MIPS-3D", Mips::AFL_ASE_MIPS3D},
2132 {"MT", Mips::AFL_ASE_MT},
2133 {"SmartMIPS", Mips::AFL_ASE_SMARTMIPS},
2134 {"VZ", Mips::AFL_ASE_VIRT},
2135 {"MSA", Mips::AFL_ASE_MSA},
2136 {"MIPS16", Mips::AFL_ASE_MIPS16},
2137 {"microMIPS", Mips::AFL_ASE_MICROMIPS},
2138 {"XPA", Mips::AFL_ASE_XPA}
2139};
2140
2141static const EnumEntry<unsigned> ElfMipsFpABIType[] = {
2142 {"Hard or soft float", Mips::Val_GNU_MIPS_ABI_FP_ANY},
2143 {"Hard float (double precision)", Mips::Val_GNU_MIPS_ABI_FP_DOUBLE},
2144 {"Hard float (single precision)", Mips::Val_GNU_MIPS_ABI_FP_SINGLE},
2145 {"Soft float", Mips::Val_GNU_MIPS_ABI_FP_SOFT},
2146 {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)",
2147 Mips::Val_GNU_MIPS_ABI_FP_OLD_64},
2148 {"Hard float (32-bit CPU, Any FPU)", Mips::Val_GNU_MIPS_ABI_FP_XX},
2149 {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64},
2150 {"Hard float compat (32-bit CPU, 64-bit FPU)",
2151 Mips::Val_GNU_MIPS_ABI_FP_64A}
2152};
2153
2154static const EnumEntry<unsigned> ElfMipsFlags1[] {
2155 {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG},
2156};
2157
2158static int getMipsRegisterSize(uint8_t Flag) {
2159 switch (Flag) {
2160 case Mips::AFL_REG_NONE:
2161 return 0;
2162 case Mips::AFL_REG_32:
2163 return 32;
2164 case Mips::AFL_REG_64:
2165 return 64;
2166 case Mips::AFL_REG_128:
2167 return 128;
2168 default:
2169 return -1;
2170 }
2171}
2172
2173template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() {
2174 const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.abiflags");
2175 if (!Shdr) {
2176 W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
2177 return;
2178 }
2179 ErrorOr<ArrayRef<uint8_t>> Sec = Obj->getSectionContents(Shdr);
2180 if (!Sec) {
2181 W.startLine() << "The .MIPS.abiflags section is empty.\n";
2182 return;
2183 }
2184 if (Sec->size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) {
2185 W.startLine() << "The .MIPS.abiflags section has a wrong size.\n";
2186 return;
2187 }
2188
2189 auto *Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(Sec->data());
2190
2191 raw_ostream &OS = W.getOStream();
2192 DictScope GS(W, "MIPS ABI Flags");
2193
2194 W.printNumber("Version", Flags->version);
2195 W.startLine() << "ISA: ";
2196 if (Flags->isa_rev <= 1)
2197 OS << format("MIPS%u", Flags->isa_level);
2198 else
2199 OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev);
2200 OS << "\n";
2201 W.printEnum("ISA Extension", Flags->isa_ext, makeArrayRef(ElfMipsISAExtType));
2202 W.printFlags("ASEs", Flags->ases, makeArrayRef(ElfMipsASEFlags));
2203 W.printEnum("FP ABI", Flags->fp_abi, makeArrayRef(ElfMipsFpABIType));
2204 W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size));
2205 W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size));
2206 W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size));
2207 W.printFlags("Flags 1", Flags->flags1, makeArrayRef(ElfMipsFlags1));
2208 W.printHex("Flags 2", Flags->flags2);
2209}
2210
2211template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
2212 const Elf_Shdr *Shdr = findSectionByName(*Obj, ".reginfo");
2213 if (!Shdr) {
2214 W.startLine() << "There is no .reginfo section in the file.\n";
2215 return;
2216 }
2217 ErrorOr<ArrayRef<uint8_t>> Sec = Obj->getSectionContents(Shdr);
2218 if (!Sec) {
2219 W.startLine() << "The .reginfo section is empty.\n";
2220 return;
2221 }
2222 if (Sec->size() != sizeof(Elf_Mips_RegInfo<ELFT>)) {
2223 W.startLine() << "The .reginfo section has a wrong size.\n";
2224 return;
2225 }
2226
2227 auto *Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(Sec->data());
2228
2229 DictScope GS(W, "MIPS RegInfo");
2230 W.printHex("GP", Reginfo->ri_gp_value);
2231 W.printHex("General Mask", Reginfo->ri_gprmask);
2232 W.printHex("Co-Proc Mask0", Reginfo->ri_cprmask[0]);
2233 W.printHex("Co-Proc Mask1", Reginfo->ri_cprmask[1]);
2234 W.printHex("Co-Proc Mask2", Reginfo->ri_cprmask[2]);
2235 W.printHex("Co-Proc Mask3", Reginfo->ri_cprmask[3]);
2236}
2237
2238template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
2239 const Elf_Shdr *StackMapSection = nullptr;
2240 for (const auto &Sec : Obj->sections()) {
2241 ErrorOr<StringRef> Name = Obj->getSectionName(&Sec);
2242 if (*Name == ".llvm_stackmaps") {
2243 StackMapSection = &Sec;
2244 break;
2245 }
2246 }
2247
2248 if (!StackMapSection)
2249 return;
2250
2251 StringRef StackMapContents;
2252 ErrorOr<ArrayRef<uint8_t>> StackMapContentsArray =
2253 Obj->getSectionContents(StackMapSection);
2254
2255 prettyPrintStackMap(
2256 llvm::outs(),
2257 StackMapV1Parser<ELFT::TargetEndianness>(*StackMapContentsArray));
2258}
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002259
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +00002260template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
2261 DictScope Lists(W, "Groups");
2262 uint32_t SectionIndex = 0;
2263 bool HasGroups = false;
2264 for (const Elf_Shdr &Sec : Obj->sections()) {
2265 if (Sec.sh_type == ELF::SHT_GROUP) {
2266 HasGroups = true;
2267 ErrorOr<const Elf_Shdr *> Symtab =
2268 errorOrDefault(Obj->getSection(Sec.sh_link));
2269 ErrorOr<StringRef> StrTableOrErr = Obj->getStringTableForSymtab(**Symtab);
2270 error(StrTableOrErr.getError());
2271 StringRef StrTable = *StrTableOrErr;
2272 const Elf_Sym *Sym =
2273 Obj->template getEntry<Elf_Sym>(*Symtab, Sec.sh_info);
2274 auto Data = errorOrDefault(
Hemant Kulkarniae1acb02016-01-26 20:28:15 +00002275 Obj->template getSectionContentsAsArray<Elf_Word>(&Sec));
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +00002276 DictScope D(W, "Group");
2277 StringRef Name = errorOrDefault(Obj->getSectionName(&Sec));
2278 W.printNumber("Name", Name, Sec.sh_name);
2279 W.printNumber("Index", SectionIndex);
2280 W.printHex("Type", getGroupType(Data[0]), Data[0]);
2281 W.startLine() << "Signature: " << StrTable.data() + Sym->st_name << "\n";
2282 {
2283 ListScope L(W, "Section(s) in group");
Hemant Kulkarni44476682016-01-26 20:38:15 +00002284 size_t Member = 1;
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +00002285 while (Member < Data.size()) {
2286 auto Sec = errorOrDefault(Obj->getSection(Data[Member]));
2287 const StringRef Name = errorOrDefault(Obj->getSectionName(Sec));
Benjamin Kramer73ae2492016-01-27 13:22:39 +00002288 W.startLine() << Name << " (" << Data[Member++] << ")\n";
Hemant Kulkarniab4a46f2016-01-26 19:46:39 +00002289 }
2290 }
2291 }
2292 ++SectionIndex;
2293 }
2294 if (!HasGroups)
2295 W.startLine() << "There are no group sections in the file.\n";
2296}
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002297
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002298static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
2299 StringRef Str2) {
2300 OS.PadToColumn(2u);
2301 OS << Str1;
2302 OS.PadToColumn(37u);
2303 OS << Str2 << "\n";
2304 OS.flush();
2305}
2306
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002307template <class ELFT>
2308void GNUStyle<ELFT>::printFileHeaders(const ELFFile<ELFT> *Obj) {
2309 const Elf_Ehdr *e = Obj->getHeader();
2310 OS << "ELF Header:\n";
2311 OS << " Magic: ";
2312 std::string Str;
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002313 for (int i = 0; i < ELF::EI_NIDENT; i++)
2314 OS << format(" %02x", static_cast<int>(e->e_ident[i]));
2315 OS << "\n";
2316 Str = printEnum(e->e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002317 printFields(OS, "Class:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002318 Str = printEnum(e->e_ident[ELF::EI_DATA], makeArrayRef(ElfDataEncoding));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002319 printFields(OS, "Data:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002320 OS.PadToColumn(2u);
2321 OS << "Version:";
2322 OS.PadToColumn(37u);
2323 OS << to_hexString(e->e_ident[ELF::EI_VERSION]);
2324 if (e->e_version == ELF::EV_CURRENT)
2325 OS << " (current)";
2326 OS << "\n";
2327 Str = printEnum(e->e_ident[ELF::EI_OSABI], makeArrayRef(ElfOSABI));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002328 printFields(OS, "OS/ABI:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002329 Str = "0x" + to_hexString(e->e_version);
2330 Str = to_hexString(e->e_ident[ELF::EI_ABIVERSION]);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002331 printFields(OS, "ABI Version:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002332 Str = printEnum(e->e_type, makeArrayRef(ElfObjectFileType));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002333 printFields(OS, "Type:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002334 Str = printEnum(e->e_machine, makeArrayRef(ElfMachineType));
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002335 printFields(OS, "Machine:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002336 Str = "0x" + to_hexString(e->e_version);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002337 printFields(OS, "Version:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002338 Str = "0x" + to_hexString(e->e_entry);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002339 printFields(OS, "Entry point address:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002340 Str = to_string(e->e_phoff) + " (bytes into file)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002341 printFields(OS, "Start of program headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002342 Str = to_string(e->e_shoff) + " (bytes into file)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002343 printFields(OS, "Start of section headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002344 Str = "0x" + to_hexString(e->e_flags);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002345 printFields(OS, "Flags:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002346 Str = to_string(e->e_ehsize) + " (bytes)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002347 printFields(OS, "Size of this header:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002348 Str = to_string(e->e_phentsize) + " (bytes)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002349 printFields(OS, "Size of program headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002350 Str = to_string(e->e_phnum);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002351 printFields(OS, "Number of program headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002352 Str = to_string(e->e_shentsize) + " (bytes)";
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002353 printFields(OS, "Size of section headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002354 Str = to_string(e->e_shnum);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002355 printFields(OS, "Number of section headers:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002356 Str = to_string(e->e_shstrndx);
Hemant Kulkarnif84cda72016-02-11 03:41:34 +00002357 printFields(OS, "Section header string table index:", Str);
Hemant Kulkarnid8a985e2016-02-10 20:40:55 +00002358}
2359
2360template <class ELFT>
2361void LLVMStyle<ELFT>::printFileHeaders(const ELFFile<ELFT> *Obj) {
2362 const Elf_Ehdr *e = Obj->getHeader();
2363 {
2364 DictScope D(W, "ElfHeader");
2365 {
2366 DictScope D(W, "Ident");
2367 W.printBinary("Magic", makeArrayRef(e->e_ident).slice(ELF::EI_MAG0, 4));
2368 W.printEnum("Class", e->e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass));
2369 W.printEnum("DataEncoding", e->e_ident[ELF::EI_DATA],
2370 makeArrayRef(ElfDataEncoding));
2371 W.printNumber("FileVersion", e->e_ident[ELF::EI_VERSION]);
2372
2373 // Handle architecture specific OS/ABI values.
2374 if (e->e_machine == ELF::EM_AMDGPU &&
2375 e->e_ident[ELF::EI_OSABI] == ELF::ELFOSABI_AMDGPU_HSA)
2376 W.printHex("OS/ABI", "AMDGPU_HSA", ELF::ELFOSABI_AMDGPU_HSA);
2377 else
2378 W.printEnum("OS/ABI", e->e_ident[ELF::EI_OSABI],
2379 makeArrayRef(ElfOSABI));
2380 W.printNumber("ABIVersion", e->e_ident[ELF::EI_ABIVERSION]);
2381 W.printBinary("Unused", makeArrayRef(e->e_ident).slice(ELF::EI_PAD));
2382 }
2383
2384 W.printEnum("Type", e->e_type, makeArrayRef(ElfObjectFileType));
2385 W.printEnum("Machine", e->e_machine, makeArrayRef(ElfMachineType));
2386 W.printNumber("Version", e->e_version);
2387 W.printHex("Entry", e->e_entry);
2388 W.printHex("ProgramHeaderOffset", e->e_phoff);
2389 W.printHex("SectionHeaderOffset", e->e_shoff);
2390 if (e->e_machine == EM_MIPS)
2391 W.printFlags("Flags", e->e_flags, makeArrayRef(ElfHeaderMipsFlags),
2392 unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
2393 unsigned(ELF::EF_MIPS_MACH));
2394 else
2395 W.printFlags("Flags", e->e_flags);
2396 W.printNumber("HeaderSize", e->e_ehsize);
2397 W.printNumber("ProgramHeaderEntrySize", e->e_phentsize);
2398 W.printNumber("ProgramHeaderCount", e->e_phnum);
2399 W.printNumber("SectionHeaderEntrySize", e->e_shentsize);
2400 W.printNumber("SectionHeaderCount", e->e_shnum);
2401 W.printNumber("StringTableSectionIndex", e->e_shstrndx);
2402 }
2403}