blob: c358b428e47081ed282c8f249bd7a348e5357c0b [file] [log] [blame]
Michael J. Spencer209565db2013-01-06 03:56:49 +00001//===-- ELFDump.cpp - ELF-specific dumper -----------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Michael J. Spencer209565db2013-01-06 03:56:49 +00006//
7//===----------------------------------------------------------------------===//
8///
9/// \file
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000010/// This file implements the ELF-specific dumper for llvm-objdump.
Michael J. Spencer209565db2013-01-06 03:56:49 +000011///
12//===----------------------------------------------------------------------===//
13
14#include "llvm-objdump.h"
George Rimarc1964882019-01-18 11:33:26 +000015#include "llvm/Demangle/Demangle.h"
Michael J. Spencer126973b2013-08-08 22:27:13 +000016#include "llvm/Object/ELFObjectFile.h"
Michael J. Spencer209565db2013-01-06 03:56:49 +000017#include "llvm/Support/Format.h"
18#include "llvm/Support/MathExtras.h"
19#include "llvm/Support/raw_ostream.h"
20
21using namespace llvm;
22using namespace llvm::object;
23
Paul Semel0913dcd2018-07-25 11:09:20 +000024template <class ELFT>
25Expected<StringRef> getDynamicStrTab(const ELFFile<ELFT> *Elf) {
26 typedef ELFFile<ELFT> ELFO;
27
28 auto DynamicEntriesOrError = Elf->dynamicEntries();
29 if (!DynamicEntriesOrError)
30 return DynamicEntriesOrError.takeError();
31
32 for (const typename ELFO::Elf_Dyn &Dyn : *DynamicEntriesOrError) {
33 if (Dyn.d_tag == ELF::DT_STRTAB) {
34 auto MappedAddrOrError = Elf->toMappedAddr(Dyn.getPtr());
35 if (!MappedAddrOrError)
36 consumeError(MappedAddrOrError.takeError());
37 return StringRef(reinterpret_cast<const char *>(*MappedAddrOrError));
38 }
39 }
40
41 // If the dynamic segment is not present, we fall back on the sections.
42 auto SectionsOrError = Elf->sections();
43 if (!SectionsOrError)
44 return SectionsOrError.takeError();
45
46 for (const typename ELFO::Elf_Shdr &Sec : *SectionsOrError) {
47 if (Sec.sh_type == ELF::SHT_DYNSYM)
48 return Elf->getStringTableForSymtab(Sec);
49 }
50
51 return createError("dynamic string table not found");
52}
53
54template <class ELFT>
George Rimarc1964882019-01-18 11:33:26 +000055static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
56 const RelocationRef &RelRef,
57 SmallVectorImpl<char> &Result) {
58 typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
59 typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
60 typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
61
62 const ELFFile<ELFT> &EF = *Obj->getELFFile();
63 DataRefImpl Rel = RelRef.getRawDataRefImpl();
64 auto SecOrErr = EF.getSection(Rel.d.a);
65 if (!SecOrErr)
66 return errorToErrorCode(SecOrErr.takeError());
67
68 int64_t Addend = 0;
69 // If there is no Symbol associated with the relocation, we set the undef
70 // boolean value to 'true'. This will prevent us from calling functions that
71 // requires the relocation to be associated with a symbol.
72 //
73 // In SHT_REL case we would need to read the addend from section data.
74 // GNU objdump does not do that and we just follow for simplicity atm.
75 bool Undef = false;
76 if ((*SecOrErr)->sh_type == ELF::SHT_RELA) {
77 const Elf_Rela *ERela = Obj->getRela(Rel);
78 Addend = ERela->r_addend;
79 Undef = ERela->getSymbol(false) == 0;
80 } else if ((*SecOrErr)->sh_type != ELF::SHT_REL) {
81 return object_error::parse_failed;
82 }
83
84 // Default scheme is to print Target, as well as "+ <addend>" for nonzero
85 // addend. Should be acceptable for all normal purposes.
86 std::string FmtBuf;
87 raw_string_ostream Fmt(FmtBuf);
88
89 if (!Undef) {
90 symbol_iterator SI = RelRef.getSymbol();
91 const Elf_Sym *Sym = Obj->getSymbol(SI->getRawDataRefImpl());
92 if (Sym->getType() == ELF::STT_SECTION) {
93 Expected<section_iterator> SymSI = SI->getSection();
94 if (!SymSI)
95 return errorToErrorCode(SymSI.takeError());
96 const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
97 auto SecName = EF.getSectionName(SymSec);
98 if (!SecName)
99 return errorToErrorCode(SecName.takeError());
100 Fmt << *SecName;
101 } else {
102 Expected<StringRef> SymName = SI->getName();
103 if (!SymName)
104 return errorToErrorCode(SymName.takeError());
105 if (Demangle)
106 Fmt << demangle(*SymName);
107 else
108 Fmt << *SymName;
109 }
110 } else {
111 Fmt << "*ABS*";
112 }
113
114 if (Addend != 0)
115 Fmt << (Addend < 0 ? "" : "+") << Addend;
116 Fmt.flush();
117 Result.append(FmtBuf.begin(), FmtBuf.end());
118 return std::error_code();
119}
120
121std::error_code
122llvm::getELFRelocationValueString(const ELFObjectFileBase *Obj,
123 const RelocationRef &Rel,
124 SmallVectorImpl<char> &Result) {
125 if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
126 return getRelocationValueString(ELF32LE, Rel, Result);
127 if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
128 return getRelocationValueString(ELF64LE, Rel, Result);
129 if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
130 return getRelocationValueString(ELF32BE, Rel, Result);
131 auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
132 return getRelocationValueString(ELF64BE, Rel, Result);
133}
134
135template <class ELFT>
George Rimar87fa2e62019-01-28 14:11:35 +0000136static uint64_t getSectionLMA(const ELFFile<ELFT> *Obj,
137 const object::ELFSectionRef &Sec) {
138 auto PhdrRangeOrErr = Obj->program_headers();
139 if (!PhdrRangeOrErr)
140 report_fatal_error(errorToErrorCode(PhdrRangeOrErr.takeError()).message());
141
142 // Search for a PT_LOAD segment containing the requested section. Use this
143 // segment's p_addr to calculate the section's LMA.
144 for (const typename ELFFile<ELFT>::Elf_Phdr &Phdr : *PhdrRangeOrErr)
145 if ((Phdr.p_type == ELF::PT_LOAD) && (Phdr.p_vaddr <= Sec.getAddress()) &&
146 (Phdr.p_vaddr + Phdr.p_memsz > Sec.getAddress()))
147 return Sec.getAddress() - Phdr.p_vaddr + Phdr.p_paddr;
148
149 // Return section's VMA if it isn't in a PT_LOAD segment.
150 return Sec.getAddress();
151}
152
153uint64_t llvm::getELFSectionLMA(const object::ELFSectionRef &Sec) {
154 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Sec.getObject()))
155 return getSectionLMA(ELFObj->getELFFile(), Sec);
156 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Sec.getObject()))
157 return getSectionLMA(ELFObj->getELFFile(), Sec);
158 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Sec.getObject()))
159 return getSectionLMA(ELFObj->getELFFile(), Sec);
160 const auto *ELFObj = cast<ELF64BEObjectFile>(Sec.getObject());
161 return getSectionLMA(ELFObj->getELFFile(), Sec);
162}
163
164template <class ELFT>
Paul Semel0913dcd2018-07-25 11:09:20 +0000165void printDynamicSection(const ELFFile<ELFT> *Elf, StringRef Filename) {
166 auto ProgramHeaderOrError = Elf->program_headers();
167 if (!ProgramHeaderOrError)
168 report_error(Filename, ProgramHeaderOrError.takeError());
169
170 auto DynamicEntriesOrError = Elf->dynamicEntries();
171 if (!DynamicEntriesOrError)
172 report_error(Filename, DynamicEntriesOrError.takeError());
173
174 outs() << "Dynamic Section:\n";
175 for (const auto &Dyn : *DynamicEntriesOrError) {
176 if (Dyn.d_tag == ELF::DT_NULL)
177 continue;
178
Xing GUOb2858782019-03-02 04:20:28 +0000179 std::string Str = Elf->getDynamicTagAsString(Dyn.d_tag);
180 outs() << format(" %-21s", Str.c_str());
Paul Semel0913dcd2018-07-25 11:09:20 +0000181
182 const char *Fmt =
183 ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n";
Xing GUOd78164a2019-02-27 16:37:15 +0000184 if (Dyn.d_tag == ELF::DT_NEEDED || Dyn.d_tag == ELF::DT_RPATH ||
185 Dyn.d_tag == ELF::DT_RUNPATH || Dyn.d_tag == ELF::DT_SONAME ||
186 Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER) {
Paul Semel0913dcd2018-07-25 11:09:20 +0000187 Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
188 if (StrTabOrErr) {
189 const char *Data = StrTabOrErr.get().data();
190 outs() << (Data + Dyn.d_un.d_val) << "\n";
191 continue;
192 }
193 warn(errorToErrorCode(StrTabOrErr.takeError()).message());
194 consumeError(StrTabOrErr.takeError());
195 }
196 outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val);
197 }
198}
199
Michael J. Spencer126973b2013-08-08 22:27:13 +0000200template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
201 typedef ELFFile<ELFT> ELFO;
Michael J. Spencer209565db2013-01-06 03:56:49 +0000202 outs() << "Program Header:\n";
Rafael Espindola6a494972016-11-03 17:28:33 +0000203 auto ProgramHeaderOrError = o->program_headers();
Davide Italiano6cf09262016-11-16 05:10:28 +0000204 if (!ProgramHeaderOrError)
205 report_fatal_error(
206 errorToErrorCode(ProgramHeaderOrError.takeError()).message());
Rafael Espindola6a494972016-11-03 17:28:33 +0000207 for (const typename ELFO::Elf_Phdr &Phdr : *ProgramHeaderOrError) {
Rafael Espindola073624b2015-07-20 13:35:33 +0000208 switch (Phdr.p_type) {
Ed Maste178a4e52016-12-24 14:53:45 +0000209 case ELF::PT_DYNAMIC:
210 outs() << " DYNAMIC ";
Michael J. Spencer209565db2013-01-06 03:56:49 +0000211 break;
212 case ELF::PT_GNU_EH_FRAME:
213 outs() << "EH_FRAME ";
214 break;
Davide Italianocad19272017-01-16 22:58:26 +0000215 case ELF::PT_GNU_RELRO:
216 outs() << " RELRO ";
217 break;
Ed Maste178a4e52016-12-24 14:53:45 +0000218 case ELF::PT_GNU_STACK:
219 outs() << " STACK ";
220 break;
Michael J. Spencer1366a612013-02-20 20:18:10 +0000221 case ELF::PT_INTERP:
222 outs() << " INTERP ";
223 break;
Ed Maste178a4e52016-12-24 14:53:45 +0000224 case ELF::PT_LOAD:
225 outs() << " LOAD ";
Michael J. Spencer1366a612013-02-20 20:18:10 +0000226 break;
Davide Italianoeb9ad982017-01-16 23:13:46 +0000227 case ELF::PT_NOTE:
228 outs() << " NOTE ";
229 break;
Davide Italiano6cc726e2017-01-16 22:01:41 +0000230 case ELF::PT_OPENBSD_BOOTDATA:
231 outs() << " OPENBSD_BOOTDATA ";
232 break;
233 case ELF::PT_OPENBSD_RANDOMIZE:
234 outs() << " OPENBSD_RANDOMIZE ";
235 break;
236 case ELF::PT_OPENBSD_WXNEEDED:
237 outs() << " OPENBSD_WXNEEDED ";
238 break;
Michael J. Spencered820952013-02-21 02:21:29 +0000239 case ELF::PT_PHDR:
240 outs() << " PHDR ";
241 break;
Shankar Easwarane0bdc942013-02-27 17:57:17 +0000242 case ELF::PT_TLS:
243 outs() << " TLS ";
244 break;
Michael J. Spencer209565db2013-01-06 03:56:49 +0000245 default:
246 outs() << " UNKNOWN ";
247 }
248
Michael J. Spencer1a791612013-01-15 07:44:25 +0000249 const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " ";
Michael J. Spencer6acf8142013-01-06 05:23:59 +0000250
Rafael Espindola073624b2015-07-20 13:35:33 +0000251 outs() << "off " << format(Fmt, (uint64_t)Phdr.p_offset) << "vaddr "
252 << format(Fmt, (uint64_t)Phdr.p_vaddr) << "paddr "
253 << format(Fmt, (uint64_t)Phdr.p_paddr)
254 << format("align 2**%u\n",
255 countTrailingZeros<uint64_t>(Phdr.p_align))
256 << " filesz " << format(Fmt, (uint64_t)Phdr.p_filesz)
257 << "memsz " << format(Fmt, (uint64_t)Phdr.p_memsz) << "flags "
258 << ((Phdr.p_flags & ELF::PF_R) ? "r" : "-")
259 << ((Phdr.p_flags & ELF::PF_W) ? "w" : "-")
260 << ((Phdr.p_flags & ELF::PF_X) ? "x" : "-") << "\n";
Michael J. Spencer209565db2013-01-06 03:56:49 +0000261 }
262 outs() << "\n";
263}
264
Xing GUO56d651d2019-02-25 13:13:19 +0000265template <class ELFT>
266void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
267 StringRef StrTab) {
268 typedef ELFFile<ELFT> ELFO;
269 typedef typename ELFO::Elf_Verneed Elf_Verneed;
270 typedef typename ELFO::Elf_Vernaux Elf_Vernaux;
271
272 outs() << "Version References:\n";
273
274 const uint8_t *Buf = Contents.data();
275 while (Buf) {
276 const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
277 outs() << " required from "
278 << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n";
279
280 const uint8_t *BufAux = Buf + Verneed->vn_aux;
281 while (BufAux) {
282 const Elf_Vernaux *Vernaux =
283 reinterpret_cast<const Elf_Vernaux *>(BufAux);
284 outs() << " "
285 << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash)
286 << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags)
287 << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other)
288 << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n';
289 BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
290 }
291 Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
292 }
293}
294
295template <class ELFT>
Xing GUO85b50a72019-02-26 13:06:16 +0000296void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
297 ArrayRef<uint8_t> Contents,
298 StringRef StrTab) {
299 typedef ELFFile<ELFT> ELFO;
300 typedef typename ELFO::Elf_Verdef Elf_Verdef;
301 typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
302
303 outs() << "Version definitions:\n";
304
305 const uint8_t *Buf = Contents.data();
306 uint32_t VerdefIndex = 1;
307 // sh_info contains the number of entries in the SHT_GNU_verdef section. To
308 // make the index column have consistent width, we should insert blank spaces
309 // according to sh_info.
310 uint16_t VerdefIndexWidth = std::to_string(Shdr.sh_info).size();
311 while (Buf) {
312 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
313 outs() << format_decimal(VerdefIndex++, VerdefIndexWidth) << " "
314 << format("0x%02" PRIx16 " ", (uint16_t)Verdef->vd_flags)
315 << format("0x%08" PRIx32 " ", (uint32_t)Verdef->vd_hash);
316
317 const uint8_t *BufAux = Buf + Verdef->vd_aux;
318 uint16_t VerdauxIndex = 0;
319 while (BufAux) {
320 const Elf_Verdaux *Verdaux =
321 reinterpret_cast<const Elf_Verdaux *>(BufAux);
322 if (VerdauxIndex)
323 outs() << std::string(VerdefIndexWidth + 17, ' ');
324 outs() << StringRef(StrTab.drop_front(Verdaux->vda_name).data()) << '\n';
325 BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
326 ++VerdauxIndex;
327 }
328 Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
329 }
330}
331
332template <class ELFT>
Xing GUO56d651d2019-02-25 13:13:19 +0000333void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
334 typedef typename ELFT::Shdr Elf_Shdr;
335
336 auto SectionsOrError = Elf->sections();
337 if (!SectionsOrError)
338 report_error(FileName, SectionsOrError.takeError());
339
340 for (const Elf_Shdr &Shdr : *SectionsOrError) {
Xing GUO85b50a72019-02-26 13:06:16 +0000341 if (Shdr.sh_type != ELF::SHT_GNU_verneed &&
342 Shdr.sh_type != ELF::SHT_GNU_verdef)
Xing GUO56d651d2019-02-25 13:13:19 +0000343 continue;
344
345 auto ContentsOrError = Elf->getSectionContents(&Shdr);
346 if (!ContentsOrError)
347 report_error(FileName, ContentsOrError.takeError());
348
349 auto StrTabSecOrError = Elf->getSection(Shdr.sh_link);
350 if (!StrTabSecOrError)
351 report_error(FileName, StrTabSecOrError.takeError());
352
353 auto StrTabOrError = Elf->getStringTable(*StrTabSecOrError);
354 if (!StrTabOrError)
355 report_error(FileName, StrTabOrError.takeError());
356
Xing GUO85b50a72019-02-26 13:06:16 +0000357 if (Shdr.sh_type == ELF::SHT_GNU_verneed)
358 printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
359 else
360 printSymbolVersionDefinition<ELFT>(Shdr, *ContentsOrError,
361 *StrTabOrError);
Xing GUO56d651d2019-02-25 13:13:19 +0000362 }
363}
364
Michael J. Spencer209565db2013-01-06 03:56:49 +0000365void llvm::printELFFileHeader(const object::ObjectFile *Obj) {
Xing GUOcc0829f2018-11-15 11:51:13 +0000366 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000367 printProgramHeaders(ELFObj->getELFFile());
Xing GUOcc0829f2018-11-15 11:51:13 +0000368 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000369 printProgramHeaders(ELFObj->getELFFile());
Xing GUOcc0829f2018-11-15 11:51:13 +0000370 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000371 printProgramHeaders(ELFObj->getELFFile());
Xing GUOcc0829f2018-11-15 11:51:13 +0000372 else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000373 printProgramHeaders(ELFObj->getELFFile());
Michael J. Spencer209565db2013-01-06 03:56:49 +0000374}
Paul Semel0913dcd2018-07-25 11:09:20 +0000375
376void llvm::printELFDynamicSection(const object::ObjectFile *Obj) {
Xing GUOcc0829f2018-11-15 11:51:13 +0000377 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000378 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
Xing GUOcc0829f2018-11-15 11:51:13 +0000379 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000380 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
Xing GUOcc0829f2018-11-15 11:51:13 +0000381 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000382 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
Xing GUOcc0829f2018-11-15 11:51:13 +0000383 else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000384 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
385}
Xing GUO56d651d2019-02-25 13:13:19 +0000386
387void llvm::printELFSymbolVersionInfo(const object::ObjectFile *Obj) {
388 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
389 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
390 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
391 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
392 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
393 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
394 else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
395 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
396}