[llvm-readelf] - Allow dumping dynamic symbols when there is no program headers.
[llvm-complete.git] / tools / obj2yaml / elf2yaml.cpp
blobbaa1b863273e2df847b1f3d070977147dbcba747
1 //===------ utils/elf2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "Error.h"
10 #include "llvm/ADT/DenseSet.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/Object/ELFObjectFile.h"
13 #include "llvm/ObjectYAML/ELFYAML.h"
14 #include "llvm/Support/ErrorHandling.h"
15 #include "llvm/Support/YAMLTraits.h"
17 using namespace llvm;
19 namespace {
21 template <class ELFT>
22 class ELFDumper {
23 typedef object::Elf_Sym_Impl<ELFT> Elf_Sym;
24 typedef typename ELFT::Dyn Elf_Dyn;
25 typedef typename ELFT::Shdr Elf_Shdr;
26 typedef typename ELFT::Word Elf_Word;
27 typedef typename ELFT::Rel Elf_Rel;
28 typedef typename ELFT::Rela Elf_Rela;
30 ArrayRef<Elf_Shdr> Sections;
31 ArrayRef<Elf_Sym> SymTable;
33 DenseMap<StringRef, uint32_t> UsedSectionNames;
34 std::vector<std::string> SectionNames;
36 DenseMap<StringRef, uint32_t> UsedSymbolNames;
37 std::vector<std::string> SymbolNames;
39 Expected<StringRef> getUniquedSectionName(const Elf_Shdr *Sec);
40 Expected<StringRef> getUniquedSymbolName(const Elf_Sym *Sym,
41 StringRef StrTable,
42 const Elf_Shdr *SymTab);
44 const object::ELFFile<ELFT> &Obj;
45 ArrayRef<Elf_Word> ShndxTable;
47 Error dumpSymbols(const Elf_Shdr *Symtab,
48 std::vector<ELFYAML::Symbol> &Symbols);
49 Error dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
50 StringRef StrTable, ELFYAML::Symbol &S);
51 Error dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
52 Error dumpCommonRelocationSection(const Elf_Shdr *Shdr,
53 ELFYAML::RelocationSection &S);
54 template <class RelT>
55 Error dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
56 ELFYAML::Relocation &R);
58 Expected<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr);
59 Expected<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
60 Expected<ELFYAML::RawContentSection *>
61 dumpContentSection(const Elf_Shdr *Shdr);
62 Expected<ELFYAML::SymtabShndxSection *>
63 dumpSymtabShndxSection(const Elf_Shdr *Shdr);
64 Expected<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
65 Expected<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr);
66 Expected<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
67 Expected<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
68 Expected<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
69 Expected<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
71 public:
72 ELFDumper(const object::ELFFile<ELFT> &O);
73 Expected<ELFYAML::Object *> dump();
78 template <class ELFT>
79 ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O)
80 : Obj(O) {}
82 template <class ELFT>
83 Expected<StringRef>
84 ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr *Sec) {
85 unsigned SecIndex = Sec - &Sections[0];
86 assert(&Sections[SecIndex] == Sec);
87 if (!SectionNames[SecIndex].empty())
88 return SectionNames[SecIndex];
90 auto NameOrErr = Obj.getSectionName(Sec);
91 if (!NameOrErr)
92 return NameOrErr;
93 StringRef Name = *NameOrErr;
94 std::string &Ret = SectionNames[SecIndex];
96 auto It = UsedSectionNames.insert({Name, 0});
97 if (!It.second)
98 Ret = (Name + " [" + Twine(++It.first->second) + "]").str();
99 else
100 Ret = Name;
101 return Ret;
104 template <class ELFT>
105 Expected<StringRef>
106 ELFDumper<ELFT>::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable,
107 const Elf_Shdr *SymTab) {
108 Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
109 if (!SymbolNameOrErr)
110 return SymbolNameOrErr;
111 StringRef Name = *SymbolNameOrErr;
112 if (Name.empty() && Sym->getType() == ELF::STT_SECTION) {
113 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
114 if (!ShdrOrErr)
115 return ShdrOrErr.takeError();
116 return getUniquedSectionName(*ShdrOrErr);
119 // Symbols in .symtab can have duplicate names. For example, it is a common
120 // situation for local symbols in a relocatable object. Here we assign unique
121 // suffixes for such symbols so that we can differentiate them.
122 if (SymTab->sh_type == ELF::SHT_SYMTAB) {
123 unsigned Index = Sym - SymTable.data();
124 if (!SymbolNames[Index].empty())
125 return SymbolNames[Index];
127 auto It = UsedSymbolNames.insert({Name, 0});
128 if (!It.second)
129 SymbolNames[Index] =
130 (Name + " [" + Twine(++It.first->second) + "]").str();
131 else
132 SymbolNames[Index] = Name;
133 return SymbolNames[Index];
136 return Name;
139 template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
140 auto Y = std::make_unique<ELFYAML::Object>();
142 // Dump header. We do not dump SHEntSize, SHOffset, SHNum and SHStrNdx field.
143 // When not explicitly set, the values are set by yaml2obj automatically
144 // and there is no need to dump them here.
145 Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass());
146 Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding());
147 Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI];
148 Y->Header.ABIVersion = Obj.getHeader()->e_ident[ELF::EI_ABIVERSION];
149 Y->Header.Type = Obj.getHeader()->e_type;
150 Y->Header.Machine = Obj.getHeader()->e_machine;
151 Y->Header.Flags = Obj.getHeader()->e_flags;
152 Y->Header.Entry = Obj.getHeader()->e_entry;
154 // Dump sections
155 auto SectionsOrErr = Obj.sections();
156 if (!SectionsOrErr)
157 return SectionsOrErr.takeError();
158 Sections = *SectionsOrErr;
159 SectionNames.resize(Sections.size());
161 // Dump symbols. We need to do this early because other sections might want
162 // to access the deduplicated symbol names that we also create here.
163 const Elf_Shdr *SymTab = nullptr;
164 const Elf_Shdr *SymTabShndx = nullptr;
165 const Elf_Shdr *DynSymTab = nullptr;
167 for (const Elf_Shdr &Sec : Sections) {
168 if (Sec.sh_type == ELF::SHT_SYMTAB) {
169 SymTab = &Sec;
170 } else if (Sec.sh_type == ELF::SHT_DYNSYM) {
171 DynSymTab = &Sec;
172 } else if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
173 // ABI allows us to have one SHT_SYMTAB_SHNDX for each symbol table.
174 // We only support having the SHT_SYMTAB_SHNDX for SHT_SYMTAB now.
175 if (SymTabShndx)
176 return createStringError(obj2yaml_error::not_implemented,
177 "multiple SHT_SYMTAB_SHNDX sections are not supported");
178 SymTabShndx = &Sec;
182 // We need to locate the SHT_SYMTAB_SHNDX section early, because it might be
183 // needed for dumping symbols.
184 if (SymTabShndx) {
185 if (!SymTab || SymTabShndx->sh_link != SymTab - Sections.begin())
186 return createStringError(
187 obj2yaml_error::not_implemented,
188 "only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported");
190 auto TableOrErr = Obj.getSHNDXTable(*SymTabShndx);
191 if (!TableOrErr)
192 return TableOrErr.takeError();
193 ShndxTable = *TableOrErr;
195 if (SymTab)
196 if (Error E = dumpSymbols(SymTab, Y->Symbols))
197 return std::move(E);
198 if (DynSymTab)
199 if (Error E = dumpSymbols(DynSymTab, Y->DynamicSymbols))
200 return std::move(E);
202 for (const Elf_Shdr &Sec : Sections) {
203 switch (Sec.sh_type) {
204 case ELF::SHT_DYNAMIC: {
205 Expected<ELFYAML::DynamicSection *> SecOrErr = dumpDynamicSection(&Sec);
206 if (!SecOrErr)
207 return SecOrErr.takeError();
208 Y->Sections.emplace_back(*SecOrErr);
209 break;
211 case ELF::SHT_STRTAB:
212 case ELF::SHT_SYMTAB:
213 case ELF::SHT_DYNSYM:
214 // Do not dump these sections.
215 break;
216 case ELF::SHT_SYMTAB_SHNDX: {
217 Expected<ELFYAML::SymtabShndxSection *> SecOrErr =
218 dumpSymtabShndxSection(&Sec);
219 if (!SecOrErr)
220 return SecOrErr.takeError();
221 Y->Sections.emplace_back(*SecOrErr);
222 break;
224 case ELF::SHT_REL:
225 case ELF::SHT_RELA: {
226 Expected<ELFYAML::RelocationSection *> SecOrErr = dumpRelocSection(&Sec);
227 if (!SecOrErr)
228 return SecOrErr.takeError();
229 Y->Sections.emplace_back(*SecOrErr);
230 break;
232 case ELF::SHT_GROUP: {
233 Expected<ELFYAML::Group *> GroupOrErr = dumpGroup(&Sec);
234 if (!GroupOrErr)
235 return GroupOrErr.takeError();
236 Y->Sections.emplace_back(*GroupOrErr);
237 break;
239 case ELF::SHT_MIPS_ABIFLAGS: {
240 Expected<ELFYAML::MipsABIFlags *> SecOrErr = dumpMipsABIFlags(&Sec);
241 if (!SecOrErr)
242 return SecOrErr.takeError();
243 Y->Sections.emplace_back(*SecOrErr);
244 break;
246 case ELF::SHT_NOBITS: {
247 Expected<ELFYAML::NoBitsSection *> SecOrErr = dumpNoBitsSection(&Sec);
248 if (!SecOrErr)
249 return SecOrErr.takeError();
250 Y->Sections.emplace_back(*SecOrErr);
251 break;
253 case ELF::SHT_GNU_verdef: {
254 Expected<ELFYAML::VerdefSection *> SecOrErr = dumpVerdefSection(&Sec);
255 if (!SecOrErr)
256 return SecOrErr.takeError();
257 Y->Sections.emplace_back(*SecOrErr);
258 break;
260 case ELF::SHT_GNU_versym: {
261 Expected<ELFYAML::SymverSection *> SecOrErr = dumpSymverSection(&Sec);
262 if (!SecOrErr)
263 return SecOrErr.takeError();
264 Y->Sections.emplace_back(*SecOrErr);
265 break;
267 case ELF::SHT_GNU_verneed: {
268 Expected<ELFYAML::VerneedSection *> SecOrErr = dumpVerneedSection(&Sec);
269 if (!SecOrErr)
270 return SecOrErr.takeError();
271 Y->Sections.emplace_back(*SecOrErr);
272 break;
274 case ELF::SHT_NULL: {
275 // We only dump the SHT_NULL section at index 0 when it
276 // has at least one non-null field, because yaml2obj
277 // normally creates the zero section at index 0 implicitly.
278 if (&Sec == &Sections[0]) {
279 const uint8_t *Begin = reinterpret_cast<const uint8_t *>(&Sec);
280 const uint8_t *End = Begin + sizeof(Elf_Shdr);
281 if (std::find_if(Begin, End, [](uint8_t V) { return V != 0; }) == End)
282 break;
284 LLVM_FALLTHROUGH;
286 default: {
287 Expected<ELFYAML::RawContentSection *> SecOrErr =
288 dumpContentSection(&Sec);
289 if (!SecOrErr)
290 return SecOrErr.takeError();
291 Y->Sections.emplace_back(*SecOrErr);
296 return Y.release();
299 template <class ELFT>
300 Error ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
301 std::vector<ELFYAML::Symbol> &Symbols) {
302 if (!Symtab)
303 return Error::success();
305 auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
306 if (!StrTableOrErr)
307 return StrTableOrErr.takeError();
308 StringRef StrTable = *StrTableOrErr;
310 auto SymtabOrErr = Obj.symbols(Symtab);
311 if (!SymtabOrErr)
312 return SymtabOrErr.takeError();
314 if (Symtab->sh_type == ELF::SHT_SYMTAB) {
315 SymTable = *SymtabOrErr;
316 SymbolNames.resize(SymTable.size());
319 for (const auto &Sym : (*SymtabOrErr).drop_front()) {
320 ELFYAML::Symbol S;
321 if (auto EC = dumpSymbol(&Sym, Symtab, StrTable, S))
322 return EC;
323 Symbols.push_back(S);
326 return Error::success();
329 template <class ELFT>
330 Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
331 StringRef StrTable, ELFYAML::Symbol &S) {
332 S.Type = Sym->getType();
333 S.Value = Sym->st_value;
334 S.Size = Sym->st_size;
335 S.Other = Sym->st_other;
336 S.Binding = Sym->getBinding();
338 Expected<StringRef> SymbolNameOrErr =
339 getUniquedSymbolName(Sym, StrTable, SymTab);
340 if (!SymbolNameOrErr)
341 return SymbolNameOrErr.takeError();
342 S.Name = SymbolNameOrErr.get();
344 if (Sym->st_shndx >= ELF::SHN_LORESERVE) {
345 S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx;
346 return Error::success();
349 auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
350 if (!ShdrOrErr)
351 return ShdrOrErr.takeError();
352 const Elf_Shdr *Shdr = *ShdrOrErr;
353 if (!Shdr)
354 return Error::success();
356 auto NameOrErr = getUniquedSectionName(Shdr);
357 if (!NameOrErr)
358 return NameOrErr.takeError();
359 S.Section = NameOrErr.get();
361 return Error::success();
364 template <class ELFT>
365 template <class RelT>
366 Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
367 ELFYAML::Relocation &R) {
368 R.Type = Rel->getType(Obj.isMips64EL());
369 R.Offset = Rel->r_offset;
370 R.Addend = 0;
372 auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
373 if (!SymOrErr)
374 return SymOrErr.takeError();
375 const Elf_Sym *Sym = *SymOrErr;
376 auto StrTabSec = Obj.getSection(SymTab->sh_link);
377 if (!StrTabSec)
378 return StrTabSec.takeError();
379 auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
380 if (!StrTabOrErr)
381 return StrTabOrErr.takeError();
382 StringRef StrTab = *StrTabOrErr;
384 if (Sym) {
385 Expected<StringRef> NameOrErr = getUniquedSymbolName(Sym, StrTab, SymTab);
386 if (!NameOrErr)
387 return NameOrErr.takeError();
388 R.Symbol = NameOrErr.get();
389 } else {
390 // We have some edge cases of relocations without a symbol associated,
391 // e.g. an object containing the invalid (according to the System V
392 // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
393 // of crashing.
394 R.Symbol = "";
397 return Error::success();
400 template <class ELFT>
401 Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
402 ELFYAML::Section &S) {
403 // Dump fields. We do not dump the ShOffset field. When not explicitly
404 // set, the value is set by yaml2obj automatically.
405 S.Type = Shdr->sh_type;
406 if (Shdr->sh_flags)
407 S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags);
408 S.Address = Shdr->sh_addr;
409 S.AddressAlign = Shdr->sh_addralign;
410 if (Shdr->sh_entsize)
411 S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);
413 auto NameOrErr = getUniquedSectionName(Shdr);
414 if (!NameOrErr)
415 return NameOrErr.takeError();
416 S.Name = NameOrErr.get();
418 if (Shdr->sh_link != ELF::SHN_UNDEF) {
419 auto LinkSection = Obj.getSection(Shdr->sh_link);
420 if (!LinkSection)
421 return make_error<StringError>(
422 "unable to resolve sh_link reference in section '" + S.Name +
423 "': " + toString(LinkSection.takeError()),
424 inconvertibleErrorCode());
426 NameOrErr = getUniquedSectionName(*LinkSection);
427 if (!NameOrErr)
428 return NameOrErr.takeError();
429 S.Link = NameOrErr.get();
432 return Error::success();
435 template <class ELFT>
436 Error ELFDumper<ELFT>::dumpCommonRelocationSection(
437 const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S) {
438 if (Error E = dumpCommonSection(Shdr, S))
439 return E;
441 auto InfoSection = Obj.getSection(Shdr->sh_info);
442 if (!InfoSection)
443 return InfoSection.takeError();
445 auto NameOrErr = getUniquedSectionName(*InfoSection);
446 if (!NameOrErr)
447 return NameOrErr.takeError();
448 S.RelocatableSec = NameOrErr.get();
450 return Error::success();
453 template <class ELFT>
454 Expected<ELFYAML::DynamicSection *>
455 ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
456 auto S = std::make_unique<ELFYAML::DynamicSection>();
457 if (Error E = dumpCommonSection(Shdr, *S))
458 return std::move(E);
460 auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(Shdr);
461 if (!DynTagsOrErr)
462 return DynTagsOrErr.takeError();
464 for (const Elf_Dyn &Dyn : *DynTagsOrErr)
465 S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
467 return S.release();
470 template <class ELFT>
471 Expected<ELFYAML::RelocationSection *>
472 ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
473 auto S = std::make_unique<ELFYAML::RelocationSection>();
474 if (auto E = dumpCommonRelocationSection(Shdr, *S))
475 return std::move(E);
477 auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
478 if (!SymTabOrErr)
479 return SymTabOrErr.takeError();
480 const Elf_Shdr *SymTab = *SymTabOrErr;
482 if (Shdr->sh_type == ELF::SHT_REL) {
483 auto Rels = Obj.rels(Shdr);
484 if (!Rels)
485 return Rels.takeError();
486 for (const Elf_Rel &Rel : *Rels) {
487 ELFYAML::Relocation R;
488 if (Error E = dumpRelocation(&Rel, SymTab, R))
489 return std::move(E);
490 S->Relocations.push_back(R);
492 } else {
493 auto Rels = Obj.relas(Shdr);
494 if (!Rels)
495 return Rels.takeError();
496 for (const Elf_Rela &Rel : *Rels) {
497 ELFYAML::Relocation R;
498 if (Error E = dumpRelocation(&Rel, SymTab, R))
499 return std::move(E);
500 R.Addend = Rel.r_addend;
501 S->Relocations.push_back(R);
505 return S.release();
508 template <class ELFT>
509 Expected<ELFYAML::RawContentSection *>
510 ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
511 auto S = std::make_unique<ELFYAML::RawContentSection>();
512 if (Error E = dumpCommonSection(Shdr, *S))
513 return std::move(E);
515 unsigned SecIndex = Shdr - &Sections[0];
516 if (SecIndex != 0 || Shdr->sh_type != ELF::SHT_NULL) {
517 auto ContentOrErr = Obj.getSectionContents(Shdr);
518 if (!ContentOrErr)
519 return ContentOrErr.takeError();
520 ArrayRef<uint8_t> Content = *ContentOrErr;
521 if (!Content.empty())
522 S->Content = yaml::BinaryRef(Content);
523 } else {
524 S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);
527 if (Shdr->sh_info)
528 S->Info = static_cast<llvm::yaml::Hex64>(Shdr->sh_info);
529 return S.release();
532 template <class ELFT>
533 Expected<ELFYAML::SymtabShndxSection *>
534 ELFDumper<ELFT>::dumpSymtabShndxSection(const Elf_Shdr *Shdr) {
535 auto S = std::make_unique<ELFYAML::SymtabShndxSection>();
536 if (Error E = dumpCommonSection(Shdr, *S))
537 return std::move(E);
539 auto EntriesOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(Shdr);
540 if (!EntriesOrErr)
541 return EntriesOrErr.takeError();
542 for (const Elf_Word &E : *EntriesOrErr)
543 S->Entries.push_back(E);
544 return S.release();
547 template <class ELFT>
548 Expected<ELFYAML::NoBitsSection *>
549 ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
550 auto S = std::make_unique<ELFYAML::NoBitsSection>();
551 if (Error E = dumpCommonSection(Shdr, *S))
552 return std::move(E);
553 S->Size = Shdr->sh_size;
555 return S.release();
558 template <class ELFT>
559 Expected<ELFYAML::VerdefSection *>
560 ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
561 typedef typename ELFT::Verdef Elf_Verdef;
562 typedef typename ELFT::Verdaux Elf_Verdaux;
564 auto S = std::make_unique<ELFYAML::VerdefSection>();
565 if (Error E = dumpCommonSection(Shdr, *S))
566 return std::move(E);
568 S->Info = Shdr->sh_info;
570 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
571 if (!StringTableShdrOrErr)
572 return StringTableShdrOrErr.takeError();
574 auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
575 if (!StringTableOrErr)
576 return StringTableOrErr.takeError();
578 auto Contents = Obj.getSectionContents(Shdr);
579 if (!Contents)
580 return Contents.takeError();
582 llvm::ArrayRef<uint8_t> Data = *Contents;
583 const uint8_t *Buf = Data.data();
584 while (Buf) {
585 const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
586 ELFYAML::VerdefEntry Entry;
587 Entry.Version = Verdef->vd_version;
588 Entry.Flags = Verdef->vd_flags;
589 Entry.VersionNdx = Verdef->vd_ndx;
590 Entry.Hash = Verdef->vd_hash;
592 const uint8_t *BufAux = Buf + Verdef->vd_aux;
593 while (BufAux) {
594 const Elf_Verdaux *Verdaux =
595 reinterpret_cast<const Elf_Verdaux *>(BufAux);
596 Entry.VerNames.push_back(
597 StringTableOrErr->drop_front(Verdaux->vda_name).data());
598 BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
601 S->Entries.push_back(Entry);
602 Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
605 return S.release();
608 template <class ELFT>
609 Expected<ELFYAML::SymverSection *>
610 ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
611 typedef typename ELFT::Half Elf_Half;
613 auto S = std::make_unique<ELFYAML::SymverSection>();
614 if (Error E = dumpCommonSection(Shdr, *S))
615 return std::move(E);
617 auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(Shdr);
618 if (!VersionsOrErr)
619 return VersionsOrErr.takeError();
620 for (const Elf_Half &E : *VersionsOrErr)
621 S->Entries.push_back(E);
623 return S.release();
626 template <class ELFT>
627 Expected<ELFYAML::VerneedSection *>
628 ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
629 typedef typename ELFT::Verneed Elf_Verneed;
630 typedef typename ELFT::Vernaux Elf_Vernaux;
632 auto S = std::make_unique<ELFYAML::VerneedSection>();
633 if (Error E = dumpCommonSection(Shdr, *S))
634 return std::move(E);
636 S->Info = Shdr->sh_info;
638 auto Contents = Obj.getSectionContents(Shdr);
639 if (!Contents)
640 return Contents.takeError();
642 auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
643 if (!StringTableShdrOrErr)
644 return StringTableShdrOrErr.takeError();
646 auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
647 if (!StringTableOrErr)
648 return StringTableOrErr.takeError();
650 llvm::ArrayRef<uint8_t> Data = *Contents;
651 const uint8_t *Buf = Data.data();
652 while (Buf) {
653 const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
655 ELFYAML::VerneedEntry Entry;
656 Entry.Version = Verneed->vn_version;
657 Entry.File =
658 StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data());
660 const uint8_t *BufAux = Buf + Verneed->vn_aux;
661 while (BufAux) {
662 const Elf_Vernaux *Vernaux =
663 reinterpret_cast<const Elf_Vernaux *>(BufAux);
665 ELFYAML::VernauxEntry Aux;
666 Aux.Hash = Vernaux->vna_hash;
667 Aux.Flags = Vernaux->vna_flags;
668 Aux.Other = Vernaux->vna_other;
669 Aux.Name =
670 StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data());
672 Entry.AuxV.push_back(Aux);
673 BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
676 S->VerneedV.push_back(Entry);
677 Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
680 return S.release();
683 template <class ELFT>
684 Expected<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
685 auto S = std::make_unique<ELFYAML::Group>();
686 if (Error E = dumpCommonSection(Shdr, *S))
687 return std::move(E);
689 auto SymtabOrErr = Obj.getSection(Shdr->sh_link);
690 if (!SymtabOrErr)
691 return SymtabOrErr.takeError();
692 // Get symbol with index sh_info which name is the signature of the group.
693 const Elf_Shdr *Symtab = *SymtabOrErr;
694 auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
695 if (!SymOrErr)
696 return SymOrErr.takeError();
697 auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
698 if (!StrTabOrErr)
699 return StrTabOrErr.takeError();
701 Expected<StringRef> SymbolName =
702 getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
703 if (!SymbolName)
704 return SymbolName.takeError();
705 S->Signature = *SymbolName;
707 auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(Shdr);
708 if (!MembersOrErr)
709 return MembersOrErr.takeError();
711 for (Elf_Word Member : *MembersOrErr) {
712 if (Member == llvm::ELF::GRP_COMDAT) {
713 S->Members.push_back({"GRP_COMDAT"});
714 continue;
717 auto SHdrOrErr = Obj.getSection(Member);
718 if (!SHdrOrErr)
719 return SHdrOrErr.takeError();
720 auto NameOrErr = getUniquedSectionName(*SHdrOrErr);
721 if (!NameOrErr)
722 return NameOrErr.takeError();
723 S->Members.push_back({*NameOrErr});
725 return S.release();
728 template <class ELFT>
729 Expected<ELFYAML::MipsABIFlags *>
730 ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
731 assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&
732 "Section type is not SHT_MIPS_ABIFLAGS");
733 auto S = std::make_unique<ELFYAML::MipsABIFlags>();
734 if (Error E = dumpCommonSection(Shdr, *S))
735 return std::move(E);
737 auto ContentOrErr = Obj.getSectionContents(Shdr);
738 if (!ContentOrErr)
739 return ContentOrErr.takeError();
741 auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
742 ContentOrErr.get().data());
743 S->Version = Flags->version;
744 S->ISALevel = Flags->isa_level;
745 S->ISARevision = Flags->isa_rev;
746 S->GPRSize = Flags->gpr_size;
747 S->CPR1Size = Flags->cpr1_size;
748 S->CPR2Size = Flags->cpr2_size;
749 S->FpABI = Flags->fp_abi;
750 S->ISAExtension = Flags->isa_ext;
751 S->ASEs = Flags->ases;
752 S->Flags1 = Flags->flags1;
753 S->Flags2 = Flags->flags2;
754 return S.release();
757 template <class ELFT>
758 static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj) {
759 ELFDumper<ELFT> Dumper(Obj);
760 Expected<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
761 if (!YAMLOrErr)
762 return YAMLOrErr.takeError();
764 std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
765 yaml::Output Yout(Out);
766 Yout << *YAML;
768 return Error::success();
771 Error elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
772 if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
773 return elf2yaml(Out, *ELFObj->getELFFile());
775 if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
776 return elf2yaml(Out, *ELFObj->getELFFile());
778 if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
779 return elf2yaml(Out, *ELFObj->getELFFile());
781 if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
782 return elf2yaml(Out, *ELFObj->getELFFile());
784 llvm_unreachable("unknown ELF file format");