1 //===- llvm-readobj/ELF.cpp - ELF Specific Dumper -------------------------===//
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 #include "llvm-readobj.h"
11
12 #include "llvm/Object/ELF.h"
13 #include "llvm/Support/Casting.h"
14 #include "llvm/Support/Format.h"
15
16 namespace llvm {
17 using namespace object;
18 using namespace ELF;
19
getTypeString(uint64_t Type)20 const char *getTypeString(uint64_t Type) {
21 switch (Type) {
22 case DT_BIND_NOW:
23 return "(BIND_NOW)";
24 case DT_DEBUG:
25 return "(DEBUG)";
26 case DT_FINI:
27 return "(FINI)";
28 case DT_FINI_ARRAY:
29 return "(FINI_ARRAY)";
30 case DT_FINI_ARRAYSZ:
31 return "(FINI_ARRAYSZ)";
32 case DT_FLAGS:
33 return "(FLAGS)";
34 case DT_HASH:
35 return "(HASH)";
36 case DT_INIT:
37 return "(INIT)";
38 case DT_INIT_ARRAY:
39 return "(INIT_ARRAY)";
40 case DT_INIT_ARRAYSZ:
41 return "(INIT_ARRAYSZ)";
42 case DT_PREINIT_ARRAY:
43 return "(PREINIT_ARRAY)";
44 case DT_PREINIT_ARRAYSZ:
45 return "(PREINIT_ARRAYSZ)";
46 case DT_JMPREL:
47 return "(JMPREL)";
48 case DT_NEEDED:
49 return "(NEEDED)";
50 case DT_NULL:
51 return "(NULL)";
52 case DT_PLTGOT:
53 return "(PLTGOT)";
54 case DT_PLTREL:
55 return "(PLTREL)";
56 case DT_PLTRELSZ:
57 return "(PLTRELSZ)";
58 case DT_REL:
59 return "(REL)";
60 case DT_RELA:
61 return "(RELA)";
62 case DT_RELENT:
63 return "(RELENT)";
64 case DT_RELSZ:
65 return "(RELSZ)";
66 case DT_RELAENT:
67 return "(RELAENT)";
68 case DT_RELASZ:
69 return "(RELASZ)";
70 case DT_RPATH:
71 return "(RPATH)";
72 case DT_RUNPATH:
73 return "(RUNPATH)";
74 case DT_SONAME:
75 return "(SONAME)";
76 case DT_STRSZ:
77 return "(STRSZ)";
78 case DT_STRTAB:
79 return "(STRTAB)";
80 case DT_SYMBOLIC:
81 return "(SYMBOLIC)";
82 case DT_SYMENT:
83 return "(SYMENT)";
84 case DT_SYMTAB:
85 return "(SYMTAB)";
86 case DT_TEXTREL:
87 return "(TEXTREL)";
88 default:
89 return "unknown";
90 }
91 }
92
93 template <class ELFT>
printValue(const ELFObjectFile<ELFT> * O,uint64_t Type,uint64_t Value,bool Is64,raw_ostream & OS)94 void printValue(const ELFObjectFile<ELFT> *O, uint64_t Type, uint64_t Value,
95 bool Is64, raw_ostream &OS) {
96 switch (Type) {
97 case DT_PLTREL:
98 if (Value == DT_REL) {
99 OS << "REL";
100 break;
101 } else if (Value == DT_RELA) {
102 OS << "RELA";
103 break;
104 }
105 // Fallthrough.
106 case DT_PLTGOT:
107 case DT_HASH:
108 case DT_STRTAB:
109 case DT_SYMTAB:
110 case DT_RELA:
111 case DT_INIT:
112 case DT_FINI:
113 case DT_REL:
114 case DT_JMPREL:
115 case DT_INIT_ARRAY:
116 case DT_FINI_ARRAY:
117 case DT_PREINIT_ARRAY:
118 case DT_DEBUG:
119 case DT_NULL:
120 OS << format("0x%" PRIx64, Value);
121 break;
122 case DT_PLTRELSZ:
123 case DT_RELASZ:
124 case DT_RELAENT:
125 case DT_STRSZ:
126 case DT_SYMENT:
127 case DT_RELSZ:
128 case DT_RELENT:
129 case DT_INIT_ARRAYSZ:
130 case DT_FINI_ARRAYSZ:
131 case DT_PREINIT_ARRAYSZ:
132 OS << Value << " (bytes)";
133 break;
134 case DT_NEEDED:
135 OS << "Shared library: ["
136 << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]";
137 break;
138 case DT_SONAME:
139 OS << "Library soname: ["
140 << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]";
141 break;
142 }
143 }
144
145 template <class ELFT>
dumpDynamicTable(const ELFObjectFile<ELFT> * O,raw_ostream & OS)146 ErrorOr<void> dumpDynamicTable(const ELFObjectFile<ELFT> *O, raw_ostream &OS) {
147 typedef ELFObjectFile<ELFT> ELFO;
148 typedef typename ELFO::Elf_Dyn_iterator EDI;
149 EDI Start = O->begin_dynamic_table(),
150 End = O->end_dynamic_table(true);
151
152 if (Start == End)
153 return error_code::success();
154
155 ptrdiff_t Total = std::distance(Start, End);
156 OS << "Dynamic section contains " << Total << " entries\n";
157
158 bool Is64 = O->getBytesInAddress() == 8;
159
160 OS << " Tag" << (Is64 ? " " : " ") << "Type"
161 << " " << "Name/Value\n";
162 for (; Start != End; ++Start) {
163 OS << " "
164 << format(Is64 ? "0x%016" PRIx64 : "0x%08" PRIx64, Start->getTag())
165 << " " << format("%-21s", getTypeString(Start->getTag()));
166 printValue(O, Start->getTag(), Start->getVal(), Is64, OS);
167 OS << "\n";
168 }
169
170 OS << " Total: " << Total << "\n\n";
171 return error_code::success();
172 }
173
dumpELFDynamicTable(ObjectFile * O,raw_ostream & OS)174 ErrorOr<void> dumpELFDynamicTable(ObjectFile *O, raw_ostream &OS) {
175 // Little-endian 32-bit
176 if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj =
177 dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(O))
178 return dumpDynamicTable(ELFObj, OS);
179
180 // Big-endian 32-bit
181 if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj =
182 dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(O))
183 return dumpDynamicTable(ELFObj, OS);
184
185 // Little-endian 64-bit
186 if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj =
187 dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(O))
188 return dumpDynamicTable(ELFObj, OS);
189
190 // Big-endian 64-bit
191 if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj =
192 dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(O))
193 return dumpDynamicTable(ELFObj, OS);
194 return error_code(object_error::invalid_file_type);
195 }
196 } // end namespace llvm
197