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 //===----------------------------------------------------------------------===//
8 
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"
16 
17 using namespace llvm;
18 
19 namespace {
20 
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;
29 
30   ArrayRef<Elf_Shdr> Sections;
31   ArrayRef<Elf_Sym> SymTable;
32 
33   DenseMap<StringRef, uint32_t> UsedSectionNames;
34   std::vector<std::string> SectionNames;
35 
36   DenseMap<StringRef, uint32_t> UsedSymbolNames;
37   std::vector<std::string> SymbolNames;
38 
39   Expected<StringRef> getUniquedSectionName(const Elf_Shdr *Sec);
40   Expected<StringRef> getUniquedSymbolName(const Elf_Sym *Sym,
41                                            StringRef StrTable,
42                                            const Elf_Shdr *SymTab);
43 
44   const object::ELFFile<ELFT> &Obj;
45   ArrayRef<Elf_Word> ShndxTable;
46 
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);
57 
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::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
63   Expected<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr);
64   Expected<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
65   Expected<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
66   Expected<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
67   Expected<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
68 
69 public:
70   ELFDumper(const object::ELFFile<ELFT> &O);
71   Expected<ELFYAML::Object *> dump();
72 };
73 
74 }
75 
76 template <class ELFT>
77 ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O)
78     : Obj(O) {}
79 
80 template <class ELFT>
81 Expected<StringRef>
82 ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr *Sec) {
83   unsigned SecIndex = Sec - &Sections[0];
84   assert(&Sections[SecIndex] == Sec);
85   if (!SectionNames[SecIndex].empty())
86     return SectionNames[SecIndex];
87 
88   auto NameOrErr = Obj.getSectionName(Sec);
89   if (!NameOrErr)
90     return NameOrErr;
91   StringRef Name = *NameOrErr;
92   std::string &Ret = SectionNames[SecIndex];
93 
94   auto It = UsedSectionNames.insert({Name, 0});
95   if (!It.second)
96     Ret = (Name + " [" + Twine(++It.first->second) + "]").str();
97   else
98     Ret = Name;
99   return Ret;
100 }
101 
102 template <class ELFT>
103 Expected<StringRef>
104 ELFDumper<ELFT>::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable,
105                                       const Elf_Shdr *SymTab) {
106   Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
107   if (!SymbolNameOrErr)
108     return SymbolNameOrErr;
109   StringRef Name = *SymbolNameOrErr;
110   if (Name.empty() && Sym->getType() == ELF::STT_SECTION) {
111     auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
112     if (!ShdrOrErr)
113       return ShdrOrErr.takeError();
114     return getUniquedSectionName(*ShdrOrErr);
115   }
116 
117   // Symbols in .symtab can have duplicate names. For example, it is a common
118   // situation for local symbols in a relocatable object. Here we assign unique
119   // suffixes for such symbols so that we can differentiate them.
120   if (SymTab->sh_type == ELF::SHT_SYMTAB) {
121     unsigned Index = Sym - SymTable.data();
122     if (!SymbolNames[Index].empty())
123       return SymbolNames[Index];
124 
125     auto It = UsedSymbolNames.insert({Name, 0});
126     if (!It.second)
127       SymbolNames[Index] =
128           (Name + " [" + Twine(++It.first->second) + "]").str();
129     else
130       SymbolNames[Index] = Name;
131     return SymbolNames[Index];
132   }
133 
134   return Name;
135 }
136 
137 template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
138   auto Y = make_unique<ELFYAML::Object>();
139 
140   // Dump header. We do not dump SHEntSize, SHOffset, SHNum and SHStrNdx field.
141   // When not explicitly set, the values are set by yaml2obj automatically
142   // and there is no need to dump them here.
143   Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass());
144   Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding());
145   Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI];
146   Y->Header.ABIVersion = Obj.getHeader()->e_ident[ELF::EI_ABIVERSION];
147   Y->Header.Type = Obj.getHeader()->e_type;
148   Y->Header.Machine = Obj.getHeader()->e_machine;
149   Y->Header.Flags = Obj.getHeader()->e_flags;
150   Y->Header.Entry = Obj.getHeader()->e_entry;
151 
152   // Dump sections
153   auto SectionsOrErr = Obj.sections();
154   if (!SectionsOrErr)
155     return SectionsOrErr.takeError();
156   Sections = *SectionsOrErr;
157   SectionNames.resize(Sections.size());
158 
159   // Dump symbols. We need to do this early because other sections might want
160   // to access the deduplicated symbol names that we also create here.
161   for (const Elf_Shdr &Sec : Sections) {
162     if (Sec.sh_type == ELF::SHT_SYMTAB)
163       if (Error E = dumpSymbols(&Sec, Y->Symbols))
164         return std::move(E);
165     if (Sec.sh_type == ELF::SHT_DYNSYM)
166       if (Error E = dumpSymbols(&Sec, Y->DynamicSymbols))
167         return std::move(E);
168   }
169 
170   for (const Elf_Shdr &Sec : Sections) {
171     switch (Sec.sh_type) {
172     case ELF::SHT_DYNAMIC: {
173       Expected<ELFYAML::DynamicSection *> SecOrErr = dumpDynamicSection(&Sec);
174       if (!SecOrErr)
175         return SecOrErr.takeError();
176       Y->Sections.emplace_back(*SecOrErr);
177       break;
178     }
179     case ELF::SHT_NULL:
180     case ELF::SHT_STRTAB:
181     case ELF::SHT_SYMTAB:
182     case ELF::SHT_DYNSYM:
183       // Do not dump these sections.
184       break;
185     case ELF::SHT_SYMTAB_SHNDX: {
186       auto TableOrErr = Obj.getSHNDXTable(Sec);
187       if (!TableOrErr)
188         return TableOrErr.takeError();
189       ShndxTable = *TableOrErr;
190       break;
191     }
192     case ELF::SHT_REL:
193     case ELF::SHT_RELA: {
194       Expected<ELFYAML::RelocationSection *> SecOrErr = dumpRelocSection(&Sec);
195       if (!SecOrErr)
196         return SecOrErr.takeError();
197       Y->Sections.emplace_back(*SecOrErr);
198       break;
199     }
200     case ELF::SHT_GROUP: {
201       Expected<ELFYAML::Group *> GroupOrErr = dumpGroup(&Sec);
202       if (!GroupOrErr)
203         return GroupOrErr.takeError();
204       Y->Sections.emplace_back(*GroupOrErr);
205       break;
206     }
207     case ELF::SHT_MIPS_ABIFLAGS: {
208       Expected<ELFYAML::MipsABIFlags *> SecOrErr = dumpMipsABIFlags(&Sec);
209       if (!SecOrErr)
210         return SecOrErr.takeError();
211       Y->Sections.emplace_back(*SecOrErr);
212       break;
213     }
214     case ELF::SHT_NOBITS: {
215       Expected<ELFYAML::NoBitsSection *> SecOrErr = dumpNoBitsSection(&Sec);
216       if (!SecOrErr)
217         return SecOrErr.takeError();
218       Y->Sections.emplace_back(*SecOrErr);
219       break;
220     }
221     case ELF::SHT_GNU_verdef: {
222       Expected<ELFYAML::VerdefSection *> SecOrErr = dumpVerdefSection(&Sec);
223       if (!SecOrErr)
224         return SecOrErr.takeError();
225       Y->Sections.emplace_back(*SecOrErr);
226       break;
227     }
228     case ELF::SHT_GNU_versym: {
229       Expected<ELFYAML::SymverSection *> SecOrErr = dumpSymverSection(&Sec);
230       if (!SecOrErr)
231         return SecOrErr.takeError();
232       Y->Sections.emplace_back(*SecOrErr);
233       break;
234     }
235     case ELF::SHT_GNU_verneed: {
236       Expected<ELFYAML::VerneedSection *> SecOrErr = dumpVerneedSection(&Sec);
237       if (!SecOrErr)
238         return SecOrErr.takeError();
239       Y->Sections.emplace_back(*SecOrErr);
240       break;
241     }
242     default: {
243       Expected<ELFYAML::RawContentSection *> SecOrErr =
244           dumpContentSection(&Sec);
245       if (!SecOrErr)
246         return SecOrErr.takeError();
247       Y->Sections.emplace_back(*SecOrErr);
248     }
249     }
250   }
251 
252   return Y.release();
253 }
254 
255 template <class ELFT>
256 Error ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
257                              std::vector<ELFYAML::Symbol> &Symbols) {
258   if (!Symtab)
259     return Error::success();
260 
261   auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
262   if (!StrTableOrErr)
263     return StrTableOrErr.takeError();
264   StringRef StrTable = *StrTableOrErr;
265 
266   auto SymtabOrErr = Obj.symbols(Symtab);
267   if (!SymtabOrErr)
268     return SymtabOrErr.takeError();
269 
270   if (Symtab->sh_type == ELF::SHT_SYMTAB) {
271     SymTable = *SymtabOrErr;
272     SymbolNames.resize(SymTable.size());
273   }
274 
275   for (const auto &Sym : (*SymtabOrErr).drop_front()) {
276     ELFYAML::Symbol S;
277     if (auto EC = dumpSymbol(&Sym, Symtab, StrTable, S))
278       return EC;
279     Symbols.push_back(S);
280   }
281 
282   return Error::success();
283 }
284 
285 template <class ELFT>
286 Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
287                                   StringRef StrTable, ELFYAML::Symbol &S) {
288   S.Type = Sym->getType();
289   S.Value = Sym->st_value;
290   S.Size = Sym->st_size;
291   S.Other = Sym->st_other;
292   S.Binding = Sym->getBinding();
293 
294   Expected<StringRef> SymbolNameOrErr =
295       getUniquedSymbolName(Sym, StrTable, SymTab);
296   if (!SymbolNameOrErr)
297     return SymbolNameOrErr.takeError();
298   S.Name = SymbolNameOrErr.get();
299 
300   if (Sym->st_shndx >= ELF::SHN_LORESERVE) {
301     if (Sym->st_shndx == ELF::SHN_XINDEX)
302       return createStringError(obj2yaml_error::not_implemented,
303                                "SHN_XINDEX symbols are not supported");
304     S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx;
305     return Error::success();
306   }
307 
308   auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
309   if (!ShdrOrErr)
310     return ShdrOrErr.takeError();
311   const Elf_Shdr *Shdr = *ShdrOrErr;
312   if (!Shdr)
313     return Error::success();
314 
315   auto NameOrErr = getUniquedSectionName(Shdr);
316   if (!NameOrErr)
317     return NameOrErr.takeError();
318   S.Section = NameOrErr.get();
319 
320   return Error::success();
321 }
322 
323 template <class ELFT>
324 template <class RelT>
325 Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
326                                       ELFYAML::Relocation &R) {
327   R.Type = Rel->getType(Obj.isMips64EL());
328   R.Offset = Rel->r_offset;
329   R.Addend = 0;
330 
331   auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
332   if (!SymOrErr)
333     return SymOrErr.takeError();
334   const Elf_Sym *Sym = *SymOrErr;
335   auto StrTabSec = Obj.getSection(SymTab->sh_link);
336   if (!StrTabSec)
337     return StrTabSec.takeError();
338   auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
339   if (!StrTabOrErr)
340     return StrTabOrErr.takeError();
341   StringRef StrTab = *StrTabOrErr;
342 
343   if (Sym) {
344     Expected<StringRef> NameOrErr = getUniquedSymbolName(Sym, StrTab, SymTab);
345     if (!NameOrErr)
346       return NameOrErr.takeError();
347     R.Symbol = NameOrErr.get();
348   } else {
349     // We have some edge cases of relocations without a symbol associated,
350     // e.g. an object containing the invalid (according to the System V
351     // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
352     // of crashing.
353     R.Symbol = "";
354   }
355 
356   return Error::success();
357 }
358 
359 template <class ELFT>
360 Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
361                                          ELFYAML::Section &S) {
362   // Dump fields. We do not dump the ShOffset field. When not explicitly
363   // set, the value is set by yaml2obj automatically.
364   S.Type = Shdr->sh_type;
365   if (Shdr->sh_flags)
366     S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags);
367   S.Address = Shdr->sh_addr;
368   S.AddressAlign = Shdr->sh_addralign;
369   if (Shdr->sh_entsize)
370     S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);
371 
372   auto NameOrErr = getUniquedSectionName(Shdr);
373   if (!NameOrErr)
374     return NameOrErr.takeError();
375   S.Name = NameOrErr.get();
376 
377   if (Shdr->sh_link != ELF::SHN_UNDEF) {
378     auto LinkSection = Obj.getSection(Shdr->sh_link);
379     if (!LinkSection)
380       return make_error<StringError>(
381           "unable to resolve sh_link reference in section '" + S.Name +
382               "': " + toString(LinkSection.takeError()),
383           inconvertibleErrorCode());
384 
385     NameOrErr = getUniquedSectionName(*LinkSection);
386     if (!NameOrErr)
387       return NameOrErr.takeError();
388     S.Link = NameOrErr.get();
389   }
390 
391   return Error::success();
392 }
393 
394 template <class ELFT>
395 Error ELFDumper<ELFT>::dumpCommonRelocationSection(
396     const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S) {
397   if (Error E = dumpCommonSection(Shdr, S))
398     return E;
399 
400   auto InfoSection = Obj.getSection(Shdr->sh_info);
401   if (!InfoSection)
402     return InfoSection.takeError();
403 
404   auto NameOrErr = getUniquedSectionName(*InfoSection);
405   if (!NameOrErr)
406     return NameOrErr.takeError();
407   S.RelocatableSec = NameOrErr.get();
408 
409   return Error::success();
410 }
411 
412 template <class ELFT>
413 Expected<ELFYAML::DynamicSection *>
414 ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
415   auto S = make_unique<ELFYAML::DynamicSection>();
416   if (Error E = dumpCommonSection(Shdr, *S))
417     return std::move(E);
418 
419   auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(Shdr);
420   if (!DynTagsOrErr)
421     return DynTagsOrErr.takeError();
422 
423   for (const Elf_Dyn &Dyn : *DynTagsOrErr)
424     S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
425 
426   return S.release();
427 }
428 
429 template <class ELFT>
430 Expected<ELFYAML::RelocationSection *>
431 ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
432   auto S = make_unique<ELFYAML::RelocationSection>();
433   if (auto E = dumpCommonRelocationSection(Shdr, *S))
434     return std::move(E);
435 
436   auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
437   if (!SymTabOrErr)
438     return SymTabOrErr.takeError();
439   const Elf_Shdr *SymTab = *SymTabOrErr;
440 
441   if (Shdr->sh_type == ELF::SHT_REL) {
442     auto Rels = Obj.rels(Shdr);
443     if (!Rels)
444       return Rels.takeError();
445     for (const Elf_Rel &Rel : *Rels) {
446       ELFYAML::Relocation R;
447       if (Error E = dumpRelocation(&Rel, SymTab, R))
448         return std::move(E);
449       S->Relocations.push_back(R);
450     }
451   } else {
452     auto Rels = Obj.relas(Shdr);
453     if (!Rels)
454       return Rels.takeError();
455     for (const Elf_Rela &Rel : *Rels) {
456       ELFYAML::Relocation R;
457       if (Error E = dumpRelocation(&Rel, SymTab, R))
458         return std::move(E);
459       R.Addend = Rel.r_addend;
460       S->Relocations.push_back(R);
461     }
462   }
463 
464   return S.release();
465 }
466 
467 template <class ELFT>
468 Expected<ELFYAML::RawContentSection *>
469 ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
470   auto S = make_unique<ELFYAML::RawContentSection>();
471   if (Error E = dumpCommonSection(Shdr, *S))
472     return std::move(E);
473 
474   auto ContentOrErr = Obj.getSectionContents(Shdr);
475   if (!ContentOrErr)
476     return ContentOrErr.takeError();
477   ArrayRef<uint8_t> Content = *ContentOrErr;
478   if (!Content.empty())
479     S->Content = yaml::BinaryRef(Content);
480   if (Shdr->sh_info)
481     S->Info = static_cast<llvm::yaml::Hex64>(Shdr->sh_info);
482   return S.release();
483 }
484 
485 template <class ELFT>
486 Expected<ELFYAML::NoBitsSection *>
487 ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
488   auto S = make_unique<ELFYAML::NoBitsSection>();
489   if (Error E = dumpCommonSection(Shdr, *S))
490     return std::move(E);
491   S->Size = Shdr->sh_size;
492 
493   return S.release();
494 }
495 
496 template <class ELFT>
497 Expected<ELFYAML::VerdefSection *>
498 ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
499   typedef typename ELFT::Verdef Elf_Verdef;
500   typedef typename ELFT::Verdaux Elf_Verdaux;
501 
502   auto S = make_unique<ELFYAML::VerdefSection>();
503   if (Error E = dumpCommonSection(Shdr, *S))
504     return std::move(E);
505 
506   S->Info = Shdr->sh_info;
507 
508   auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
509   if (!StringTableShdrOrErr)
510     return StringTableShdrOrErr.takeError();
511 
512   auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
513   if (!StringTableOrErr)
514     return StringTableOrErr.takeError();
515 
516   auto Contents = Obj.getSectionContents(Shdr);
517   if (!Contents)
518     return Contents.takeError();
519 
520   llvm::ArrayRef<uint8_t> Data = *Contents;
521   const uint8_t *Buf = Data.data();
522   while (Buf) {
523     const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
524     ELFYAML::VerdefEntry Entry;
525     Entry.Version = Verdef->vd_version;
526     Entry.Flags = Verdef->vd_flags;
527     Entry.VersionNdx = Verdef->vd_ndx;
528     Entry.Hash = Verdef->vd_hash;
529 
530     const uint8_t *BufAux = Buf + Verdef->vd_aux;
531     while (BufAux) {
532       const Elf_Verdaux *Verdaux =
533           reinterpret_cast<const Elf_Verdaux *>(BufAux);
534       Entry.VerNames.push_back(
535           StringTableOrErr->drop_front(Verdaux->vda_name).data());
536       BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
537     }
538 
539     S->Entries.push_back(Entry);
540     Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
541   }
542 
543   return S.release();
544 }
545 
546 template <class ELFT>
547 Expected<ELFYAML::SymverSection *>
548 ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
549   typedef typename ELFT::Half Elf_Half;
550 
551   auto S = make_unique<ELFYAML::SymverSection>();
552   if (Error E = dumpCommonSection(Shdr, *S))
553     return std::move(E);
554 
555   auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(Shdr);
556   if (!VersionsOrErr)
557     return VersionsOrErr.takeError();
558   for (const Elf_Half &E : *VersionsOrErr)
559     S->Entries.push_back(E);
560 
561   return S.release();
562 }
563 
564 template <class ELFT>
565 Expected<ELFYAML::VerneedSection *>
566 ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
567   typedef typename ELFT::Verneed Elf_Verneed;
568   typedef typename ELFT::Vernaux Elf_Vernaux;
569 
570   auto S = make_unique<ELFYAML::VerneedSection>();
571   if (Error E = dumpCommonSection(Shdr, *S))
572     return std::move(E);
573 
574   S->Info = Shdr->sh_info;
575 
576   auto Contents = Obj.getSectionContents(Shdr);
577   if (!Contents)
578     return Contents.takeError();
579 
580   auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
581   if (!StringTableShdrOrErr)
582     return StringTableShdrOrErr.takeError();
583 
584   auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
585   if (!StringTableOrErr)
586     return StringTableOrErr.takeError();
587 
588   llvm::ArrayRef<uint8_t> Data = *Contents;
589   const uint8_t *Buf = Data.data();
590   while (Buf) {
591     const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
592 
593     ELFYAML::VerneedEntry Entry;
594     Entry.Version = Verneed->vn_version;
595     Entry.File =
596         StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data());
597 
598     const uint8_t *BufAux = Buf + Verneed->vn_aux;
599     while (BufAux) {
600       const Elf_Vernaux *Vernaux =
601           reinterpret_cast<const Elf_Vernaux *>(BufAux);
602 
603       ELFYAML::VernauxEntry Aux;
604       Aux.Hash = Vernaux->vna_hash;
605       Aux.Flags = Vernaux->vna_flags;
606       Aux.Other = Vernaux->vna_other;
607       Aux.Name =
608           StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data());
609 
610       Entry.AuxV.push_back(Aux);
611       BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
612     }
613 
614     S->VerneedV.push_back(Entry);
615     Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
616   }
617 
618   return S.release();
619 }
620 
621 template <class ELFT>
622 Expected<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
623   auto S = make_unique<ELFYAML::Group>();
624   if (Error E = dumpCommonSection(Shdr, *S))
625     return std::move(E);
626 
627   auto SymtabOrErr = Obj.getSection(Shdr->sh_link);
628   if (!SymtabOrErr)
629     return SymtabOrErr.takeError();
630   // Get symbol with index sh_info which name is the signature of the group.
631   const Elf_Shdr *Symtab = *SymtabOrErr;
632   auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
633   if (!SymOrErr)
634     return SymOrErr.takeError();
635   auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
636   if (!StrTabOrErr)
637     return StrTabOrErr.takeError();
638 
639   Expected<StringRef> SymbolName =
640       getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
641   if (!SymbolName)
642     return SymbolName.takeError();
643   S->Signature = *SymbolName;
644 
645   auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(Shdr);
646   if (!MembersOrErr)
647     return MembersOrErr.takeError();
648 
649   for (Elf_Word Member : *MembersOrErr) {
650     if (Member == llvm::ELF::GRP_COMDAT) {
651       S->Members.push_back({"GRP_COMDAT"});
652       continue;
653     }
654 
655     auto SHdrOrErr = Obj.getSection(Member);
656     if (!SHdrOrErr)
657       return SHdrOrErr.takeError();
658     auto NameOrErr = getUniquedSectionName(*SHdrOrErr);
659     if (!NameOrErr)
660       return NameOrErr.takeError();
661     S->Members.push_back({*NameOrErr});
662   }
663   return S.release();
664 }
665 
666 template <class ELFT>
667 Expected<ELFYAML::MipsABIFlags *>
668 ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
669   assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&
670          "Section type is not SHT_MIPS_ABIFLAGS");
671   auto S = make_unique<ELFYAML::MipsABIFlags>();
672   if (Error E = dumpCommonSection(Shdr, *S))
673     return std::move(E);
674 
675   auto ContentOrErr = Obj.getSectionContents(Shdr);
676   if (!ContentOrErr)
677     return ContentOrErr.takeError();
678 
679   auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
680       ContentOrErr.get().data());
681   S->Version = Flags->version;
682   S->ISALevel = Flags->isa_level;
683   S->ISARevision = Flags->isa_rev;
684   S->GPRSize = Flags->gpr_size;
685   S->CPR1Size = Flags->cpr1_size;
686   S->CPR2Size = Flags->cpr2_size;
687   S->FpABI = Flags->fp_abi;
688   S->ISAExtension = Flags->isa_ext;
689   S->ASEs = Flags->ases;
690   S->Flags1 = Flags->flags1;
691   S->Flags2 = Flags->flags2;
692   return S.release();
693 }
694 
695 template <class ELFT>
696 static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj) {
697   ELFDumper<ELFT> Dumper(Obj);
698   Expected<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
699   if (!YAMLOrErr)
700     return YAMLOrErr.takeError();
701 
702   std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
703   yaml::Output Yout(Out);
704   Yout << *YAML;
705 
706   return Error::success();
707 }
708 
709 Error elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
710   if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
711     return elf2yaml(Out, *ELFObj->getELFFile());
712 
713   if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
714     return elf2yaml(Out, *ELFObj->getELFFile());
715 
716   if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
717     return elf2yaml(Out, *ELFObj->getELFFile());
718 
719   if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
720     return elf2yaml(Out, *ELFObj->getELFFile());
721 
722   llvm_unreachable("unknown ELF file format");
723 }
724