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