blob: 90a99c971ee741f3d0c37b91b5347143ac41d982 [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) {
Fangrui Songe7834bd2019-04-07 08:19:55 +0000166 ArrayRef<typename ELFT::Dyn> DynamicEntries =
167 unwrapOrError(Elf->dynamicEntries(), Filename);
Paul Semel0913dcd2018-07-25 11:09:20 +0000168 outs() << "Dynamic Section:\n";
Fangrui Songe7834bd2019-04-07 08:19:55 +0000169 for (const typename ELFT::Dyn &Dyn : DynamicEntries) {
Paul Semel0913dcd2018-07-25 11:09:20 +0000170 if (Dyn.d_tag == ELF::DT_NULL)
171 continue;
172
Xing GUOb2858782019-03-02 04:20:28 +0000173 std::string Str = Elf->getDynamicTagAsString(Dyn.d_tag);
174 outs() << format(" %-21s", Str.c_str());
Paul Semel0913dcd2018-07-25 11:09:20 +0000175
176 const char *Fmt =
177 ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n";
Xing GUOd78164a2019-02-27 16:37:15 +0000178 if (Dyn.d_tag == ELF::DT_NEEDED || Dyn.d_tag == ELF::DT_RPATH ||
179 Dyn.d_tag == ELF::DT_RUNPATH || Dyn.d_tag == ELF::DT_SONAME ||
180 Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER) {
Paul Semel0913dcd2018-07-25 11:09:20 +0000181 Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
182 if (StrTabOrErr) {
183 const char *Data = StrTabOrErr.get().data();
184 outs() << (Data + Dyn.d_un.d_val) << "\n";
185 continue;
186 }
187 warn(errorToErrorCode(StrTabOrErr.takeError()).message());
188 consumeError(StrTabOrErr.takeError());
189 }
190 outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val);
191 }
192}
193
Michael J. Spencer126973b2013-08-08 22:27:13 +0000194template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
195 typedef ELFFile<ELFT> ELFO;
Michael J. Spencer209565db2013-01-06 03:56:49 +0000196 outs() << "Program Header:\n";
Rafael Espindola6a494972016-11-03 17:28:33 +0000197 auto ProgramHeaderOrError = o->program_headers();
Davide Italiano6cf09262016-11-16 05:10:28 +0000198 if (!ProgramHeaderOrError)
199 report_fatal_error(
200 errorToErrorCode(ProgramHeaderOrError.takeError()).message());
Rafael Espindola6a494972016-11-03 17:28:33 +0000201 for (const typename ELFO::Elf_Phdr &Phdr : *ProgramHeaderOrError) {
Rafael Espindola073624b2015-07-20 13:35:33 +0000202 switch (Phdr.p_type) {
Ed Maste178a4e52016-12-24 14:53:45 +0000203 case ELF::PT_DYNAMIC:
204 outs() << " DYNAMIC ";
Michael J. Spencer209565db2013-01-06 03:56:49 +0000205 break;
206 case ELF::PT_GNU_EH_FRAME:
207 outs() << "EH_FRAME ";
208 break;
Davide Italianocad19272017-01-16 22:58:26 +0000209 case ELF::PT_GNU_RELRO:
210 outs() << " RELRO ";
211 break;
Ed Maste178a4e52016-12-24 14:53:45 +0000212 case ELF::PT_GNU_STACK:
213 outs() << " STACK ";
214 break;
Michael J. Spencer1366a612013-02-20 20:18:10 +0000215 case ELF::PT_INTERP:
216 outs() << " INTERP ";
217 break;
Ed Maste178a4e52016-12-24 14:53:45 +0000218 case ELF::PT_LOAD:
219 outs() << " LOAD ";
Michael J. Spencer1366a612013-02-20 20:18:10 +0000220 break;
Davide Italianoeb9ad982017-01-16 23:13:46 +0000221 case ELF::PT_NOTE:
222 outs() << " NOTE ";
223 break;
Davide Italiano6cc726e2017-01-16 22:01:41 +0000224 case ELF::PT_OPENBSD_BOOTDATA:
225 outs() << " OPENBSD_BOOTDATA ";
226 break;
227 case ELF::PT_OPENBSD_RANDOMIZE:
228 outs() << " OPENBSD_RANDOMIZE ";
229 break;
230 case ELF::PT_OPENBSD_WXNEEDED:
231 outs() << " OPENBSD_WXNEEDED ";
232 break;
Michael J. Spencered820952013-02-21 02:21:29 +0000233 case ELF::PT_PHDR:
234 outs() << " PHDR ";
235 break;
Shankar Easwarane0bdc942013-02-27 17:57:17 +0000236 case ELF::PT_TLS:
237 outs() << " TLS ";
238 break;
Michael J. Spencer209565db2013-01-06 03:56:49 +0000239 default:
240 outs() << " UNKNOWN ";
241 }
242
Michael J. Spencer1a791612013-01-15 07:44:25 +0000243 const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " ";
Michael J. Spencer6acf8142013-01-06 05:23:59 +0000244
Rafael Espindola073624b2015-07-20 13:35:33 +0000245 outs() << "off " << format(Fmt, (uint64_t)Phdr.p_offset) << "vaddr "
246 << format(Fmt, (uint64_t)Phdr.p_vaddr) << "paddr "
247 << format(Fmt, (uint64_t)Phdr.p_paddr)
248 << format("align 2**%u\n",
249 countTrailingZeros<uint64_t>(Phdr.p_align))
250 << " filesz " << format(Fmt, (uint64_t)Phdr.p_filesz)
251 << "memsz " << format(Fmt, (uint64_t)Phdr.p_memsz) << "flags "
252 << ((Phdr.p_flags & ELF::PF_R) ? "r" : "-")
253 << ((Phdr.p_flags & ELF::PF_W) ? "w" : "-")
254 << ((Phdr.p_flags & ELF::PF_X) ? "x" : "-") << "\n";
Michael J. Spencer209565db2013-01-06 03:56:49 +0000255 }
256 outs() << "\n";
257}
258
Xing GUO56d651d2019-02-25 13:13:19 +0000259template <class ELFT>
260void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
261 StringRef StrTab) {
262 typedef ELFFile<ELFT> ELFO;
263 typedef typename ELFO::Elf_Verneed Elf_Verneed;
264 typedef typename ELFO::Elf_Vernaux Elf_Vernaux;
265
266 outs() << "Version References:\n";
267
268 const uint8_t *Buf = Contents.data();
269 while (Buf) {
270 const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
271 outs() << " required from "
272 << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n";
273
274 const uint8_t *BufAux = Buf + Verneed->vn_aux;
275 while (BufAux) {
276 const Elf_Vernaux *Vernaux =
277 reinterpret_cast<const Elf_Vernaux *>(BufAux);
278 outs() << " "
279 << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash)
280 << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags)
281 << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other)
282 << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n';
283 BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
284 }
285 Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
286 }
287}
288
289template <class ELFT>
Xing GUO85b50a72019-02-26 13:06:16 +0000290void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
291 ArrayRef<uint8_t> Contents,
292 StringRef StrTab) {
293 typedef ELFFile<ELFT> ELFO;
294 typedef typename ELFO::Elf_Verdef Elf_Verdef;
295 typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
296
297 outs() << "Version definitions:\n";
298
299 const uint8_t *Buf = Contents.data();
300 uint32_t VerdefIndex = 1;
301 // sh_info contains the number of entries in the SHT_GNU_verdef section. To
302 // make the index column have consistent width, we should insert blank spaces
303 // according to sh_info.
304 uint16_t VerdefIndexWidth = std::to_string(Shdr.sh_info).size();
305 while (Buf) {
306 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
307 outs() << format_decimal(VerdefIndex++, VerdefIndexWidth) << " "
308 << format("0x%02" PRIx16 " ", (uint16_t)Verdef->vd_flags)
309 << format("0x%08" PRIx32 " ", (uint32_t)Verdef->vd_hash);
310
311 const uint8_t *BufAux = Buf + Verdef->vd_aux;
312 uint16_t VerdauxIndex = 0;
313 while (BufAux) {
314 const Elf_Verdaux *Verdaux =
315 reinterpret_cast<const Elf_Verdaux *>(BufAux);
316 if (VerdauxIndex)
317 outs() << std::string(VerdefIndexWidth + 17, ' ');
318 outs() << StringRef(StrTab.drop_front(Verdaux->vda_name).data()) << '\n';
319 BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
320 ++VerdauxIndex;
321 }
322 Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
323 }
324}
325
326template <class ELFT>
Xing GUO56d651d2019-02-25 13:13:19 +0000327void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
Fangrui Songe7834bd2019-04-07 08:19:55 +0000328 ArrayRef<typename ELFT::Shdr> Sections =
329 unwrapOrError(Elf->sections(), FileName);
330 for (const typename ELFT::Shdr &Shdr : Sections) {
Xing GUO85b50a72019-02-26 13:06:16 +0000331 if (Shdr.sh_type != ELF::SHT_GNU_verneed &&
332 Shdr.sh_type != ELF::SHT_GNU_verdef)
Xing GUO56d651d2019-02-25 13:13:19 +0000333 continue;
334
Fangrui Songe7834bd2019-04-07 08:19:55 +0000335 ArrayRef<uint8_t> Contents =
336 unwrapOrError(Elf->getSectionContents(&Shdr), FileName);
337 const typename ELFT::Shdr *StrTabSec =
338 unwrapOrError(Elf->getSection(Shdr.sh_link), FileName);
339 StringRef StrTab = unwrapOrError(Elf->getStringTable(StrTabSec), FileName);
Xing GUO56d651d2019-02-25 13:13:19 +0000340
Xing GUO85b50a72019-02-26 13:06:16 +0000341 if (Shdr.sh_type == ELF::SHT_GNU_verneed)
Fangrui Songe7834bd2019-04-07 08:19:55 +0000342 printSymbolVersionDependency<ELFT>(Contents, StrTab);
Xing GUO85b50a72019-02-26 13:06:16 +0000343 else
Fangrui Songe7834bd2019-04-07 08:19:55 +0000344 printSymbolVersionDefinition<ELFT>(Shdr, Contents, StrTab);
Xing GUO56d651d2019-02-25 13:13:19 +0000345 }
346}
347
Michael J. Spencer209565db2013-01-06 03:56:49 +0000348void llvm::printELFFileHeader(const object::ObjectFile *Obj) {
Xing GUOcc0829f2018-11-15 11:51:13 +0000349 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000350 printProgramHeaders(ELFObj->getELFFile());
Xing GUOcc0829f2018-11-15 11:51:13 +0000351 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000352 printProgramHeaders(ELFObj->getELFFile());
Xing GUOcc0829f2018-11-15 11:51:13 +0000353 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000354 printProgramHeaders(ELFObj->getELFFile());
Xing GUOcc0829f2018-11-15 11:51:13 +0000355 else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000356 printProgramHeaders(ELFObj->getELFFile());
Michael J. Spencer209565db2013-01-06 03:56:49 +0000357}
Paul Semel0913dcd2018-07-25 11:09:20 +0000358
359void llvm::printELFDynamicSection(const object::ObjectFile *Obj) {
Xing GUOcc0829f2018-11-15 11:51:13 +0000360 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000361 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
Xing GUOcc0829f2018-11-15 11:51:13 +0000362 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000363 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
Xing GUOcc0829f2018-11-15 11:51:13 +0000364 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000365 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
Xing GUOcc0829f2018-11-15 11:51:13 +0000366 else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000367 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
368}
Xing GUO56d651d2019-02-25 13:13:19 +0000369
370void llvm::printELFSymbolVersionInfo(const object::ObjectFile *Obj) {
371 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
372 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
373 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
374 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
375 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
376 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
377 else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
378 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
379}