• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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