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