blob: 0ca0e0d44b35d86a15d0b317741bfd4842a3c49c [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
179 StringRef Str = StringRef(Elf->getDynamicTagAsString(Dyn.d_tag));
180
181 if (Str.empty()) {
182 std::string HexStr = utohexstr(static_cast<uint64_t>(Dyn.d_tag), true);
183 outs() << format(" 0x%-19s", HexStr.c_str());
184 } else {
185 // We use "-21" in order to match GNU objdump's output.
186 outs() << format(" %-21s", Str.data());
187 }
188
189 const char *Fmt =
190 ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n";
191 if (Dyn.d_tag == ELF::DT_NEEDED) {
192 Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
193 if (StrTabOrErr) {
194 const char *Data = StrTabOrErr.get().data();
195 outs() << (Data + Dyn.d_un.d_val) << "\n";
196 continue;
197 }
198 warn(errorToErrorCode(StrTabOrErr.takeError()).message());
199 consumeError(StrTabOrErr.takeError());
200 }
201 outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val);
202 }
203}
204
Michael J. Spencer126973b2013-08-08 22:27:13 +0000205template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
206 typedef ELFFile<ELFT> ELFO;
Michael J. Spencer209565db2013-01-06 03:56:49 +0000207 outs() << "Program Header:\n";
Rafael Espindola6a494972016-11-03 17:28:33 +0000208 auto ProgramHeaderOrError = o->program_headers();
Davide Italiano6cf09262016-11-16 05:10:28 +0000209 if (!ProgramHeaderOrError)
210 report_fatal_error(
211 errorToErrorCode(ProgramHeaderOrError.takeError()).message());
Rafael Espindola6a494972016-11-03 17:28:33 +0000212 for (const typename ELFO::Elf_Phdr &Phdr : *ProgramHeaderOrError) {
Rafael Espindola073624b2015-07-20 13:35:33 +0000213 switch (Phdr.p_type) {
Ed Maste178a4e52016-12-24 14:53:45 +0000214 case ELF::PT_DYNAMIC:
215 outs() << " DYNAMIC ";
Michael J. Spencer209565db2013-01-06 03:56:49 +0000216 break;
217 case ELF::PT_GNU_EH_FRAME:
218 outs() << "EH_FRAME ";
219 break;
Davide Italianocad19272017-01-16 22:58:26 +0000220 case ELF::PT_GNU_RELRO:
221 outs() << " RELRO ";
222 break;
Ed Maste178a4e52016-12-24 14:53:45 +0000223 case ELF::PT_GNU_STACK:
224 outs() << " STACK ";
225 break;
Michael J. Spencer1366a612013-02-20 20:18:10 +0000226 case ELF::PT_INTERP:
227 outs() << " INTERP ";
228 break;
Ed Maste178a4e52016-12-24 14:53:45 +0000229 case ELF::PT_LOAD:
230 outs() << " LOAD ";
Michael J. Spencer1366a612013-02-20 20:18:10 +0000231 break;
Davide Italianoeb9ad982017-01-16 23:13:46 +0000232 case ELF::PT_NOTE:
233 outs() << " NOTE ";
234 break;
Davide Italiano6cc726e2017-01-16 22:01:41 +0000235 case ELF::PT_OPENBSD_BOOTDATA:
236 outs() << " OPENBSD_BOOTDATA ";
237 break;
238 case ELF::PT_OPENBSD_RANDOMIZE:
239 outs() << " OPENBSD_RANDOMIZE ";
240 break;
241 case ELF::PT_OPENBSD_WXNEEDED:
242 outs() << " OPENBSD_WXNEEDED ";
243 break;
Michael J. Spencered820952013-02-21 02:21:29 +0000244 case ELF::PT_PHDR:
245 outs() << " PHDR ";
246 break;
Shankar Easwarane0bdc942013-02-27 17:57:17 +0000247 case ELF::PT_TLS:
248 outs() << " TLS ";
249 break;
Michael J. Spencer209565db2013-01-06 03:56:49 +0000250 default:
251 outs() << " UNKNOWN ";
252 }
253
Michael J. Spencer1a791612013-01-15 07:44:25 +0000254 const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " ";
Michael J. Spencer6acf8142013-01-06 05:23:59 +0000255
Rafael Espindola073624b2015-07-20 13:35:33 +0000256 outs() << "off " << format(Fmt, (uint64_t)Phdr.p_offset) << "vaddr "
257 << format(Fmt, (uint64_t)Phdr.p_vaddr) << "paddr "
258 << format(Fmt, (uint64_t)Phdr.p_paddr)
259 << format("align 2**%u\n",
260 countTrailingZeros<uint64_t>(Phdr.p_align))
261 << " filesz " << format(Fmt, (uint64_t)Phdr.p_filesz)
262 << "memsz " << format(Fmt, (uint64_t)Phdr.p_memsz) << "flags "
263 << ((Phdr.p_flags & ELF::PF_R) ? "r" : "-")
264 << ((Phdr.p_flags & ELF::PF_W) ? "w" : "-")
265 << ((Phdr.p_flags & ELF::PF_X) ? "x" : "-") << "\n";
Michael J. Spencer209565db2013-01-06 03:56:49 +0000266 }
267 outs() << "\n";
268}
269
Xing GUO56d651d2019-02-25 13:13:19 +0000270template <class ELFT>
271void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
272 StringRef StrTab) {
273 typedef ELFFile<ELFT> ELFO;
274 typedef typename ELFO::Elf_Verneed Elf_Verneed;
275 typedef typename ELFO::Elf_Vernaux Elf_Vernaux;
276
277 outs() << "Version References:\n";
278
279 const uint8_t *Buf = Contents.data();
280 while (Buf) {
281 const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
282 outs() << " required from "
283 << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n";
284
285 const uint8_t *BufAux = Buf + Verneed->vn_aux;
286 while (BufAux) {
287 const Elf_Vernaux *Vernaux =
288 reinterpret_cast<const Elf_Vernaux *>(BufAux);
289 outs() << " "
290 << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash)
291 << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags)
292 << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other)
293 << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n';
294 BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
295 }
296 Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
297 }
298}
299
300template <class ELFT>
301void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
302 typedef typename ELFT::Shdr Elf_Shdr;
303
304 auto SectionsOrError = Elf->sections();
305 if (!SectionsOrError)
306 report_error(FileName, SectionsOrError.takeError());
307
308 for (const Elf_Shdr &Shdr : *SectionsOrError) {
309 if (Shdr.sh_type != ELF::SHT_GNU_verneed)
310 continue;
311
312 auto ContentsOrError = Elf->getSectionContents(&Shdr);
313 if (!ContentsOrError)
314 report_error(FileName, ContentsOrError.takeError());
315
316 auto StrTabSecOrError = Elf->getSection(Shdr.sh_link);
317 if (!StrTabSecOrError)
318 report_error(FileName, StrTabSecOrError.takeError());
319
320 auto StrTabOrError = Elf->getStringTable(*StrTabSecOrError);
321 if (!StrTabOrError)
322 report_error(FileName, StrTabOrError.takeError());
323
324 printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
325 // TODO: Implement symbol version definitions dumper.
326 }
327}
328
Michael J. Spencer209565db2013-01-06 03:56:49 +0000329void llvm::printELFFileHeader(const object::ObjectFile *Obj) {
Xing GUOcc0829f2018-11-15 11:51:13 +0000330 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000331 printProgramHeaders(ELFObj->getELFFile());
Xing GUOcc0829f2018-11-15 11:51:13 +0000332 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000333 printProgramHeaders(ELFObj->getELFFile());
Xing GUOcc0829f2018-11-15 11:51:13 +0000334 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000335 printProgramHeaders(ELFObj->getELFFile());
Xing GUOcc0829f2018-11-15 11:51:13 +0000336 else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
Michael J. Spencer126973b2013-08-08 22:27:13 +0000337 printProgramHeaders(ELFObj->getELFFile());
Michael J. Spencer209565db2013-01-06 03:56:49 +0000338}
Paul Semel0913dcd2018-07-25 11:09:20 +0000339
340void llvm::printELFDynamicSection(const object::ObjectFile *Obj) {
Xing GUOcc0829f2018-11-15 11:51:13 +0000341 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000342 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
Xing GUOcc0829f2018-11-15 11:51:13 +0000343 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000344 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
Xing GUOcc0829f2018-11-15 11:51:13 +0000345 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000346 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
Xing GUOcc0829f2018-11-15 11:51:13 +0000347 else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
Paul Semel0913dcd2018-07-25 11:09:20 +0000348 printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
349}
Xing GUO56d651d2019-02-25 13:13:19 +0000350
351void llvm::printELFSymbolVersionInfo(const object::ObjectFile *Obj) {
352 if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
353 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
354 else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
355 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
356 else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
357 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
358 else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
359 printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
360}