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_STRTAB:
180     case ELF::SHT_SYMTAB:
181     case ELF::SHT_DYNSYM:
182       // Do not dump these sections.
183       break;
184     case ELF::SHT_SYMTAB_SHNDX: {
185       auto TableOrErr = Obj.getSHNDXTable(Sec);
186       if (!TableOrErr)
187         return TableOrErr.takeError();
188       ShndxTable = *TableOrErr;
189       break;
190     }
191     case ELF::SHT_REL:
192     case ELF::SHT_RELA: {
193       Expected<ELFYAML::RelocationSection *> SecOrErr = dumpRelocSection(&Sec);
194       if (!SecOrErr)
195         return SecOrErr.takeError();
196       Y->Sections.emplace_back(*SecOrErr);
197       break;
198     }
199     case ELF::SHT_GROUP: {
200       Expected<ELFYAML::Group *> GroupOrErr = dumpGroup(&Sec);
201       if (!GroupOrErr)
202         return GroupOrErr.takeError();
203       Y->Sections.emplace_back(*GroupOrErr);
204       break;
205     }
206     case ELF::SHT_MIPS_ABIFLAGS: {
207       Expected<ELFYAML::MipsABIFlags *> SecOrErr = dumpMipsABIFlags(&Sec);
208       if (!SecOrErr)
209         return SecOrErr.takeError();
210       Y->Sections.emplace_back(*SecOrErr);
211       break;
212     }
213     case ELF::SHT_NOBITS: {
214       Expected<ELFYAML::NoBitsSection *> SecOrErr = dumpNoBitsSection(&Sec);
215       if (!SecOrErr)
216         return SecOrErr.takeError();
217       Y->Sections.emplace_back(*SecOrErr);
218       break;
219     }
220     case ELF::SHT_GNU_verdef: {
221       Expected<ELFYAML::VerdefSection *> SecOrErr = dumpVerdefSection(&Sec);
222       if (!SecOrErr)
223         return SecOrErr.takeError();
224       Y->Sections.emplace_back(*SecOrErr);
225       break;
226     }
227     case ELF::SHT_GNU_versym: {
228       Expected<ELFYAML::SymverSection *> SecOrErr = dumpSymverSection(&Sec);
229       if (!SecOrErr)
230         return SecOrErr.takeError();
231       Y->Sections.emplace_back(*SecOrErr);
232       break;
233     }
234     case ELF::SHT_GNU_verneed: {
235       Expected<ELFYAML::VerneedSection *> SecOrErr = dumpVerneedSection(&Sec);
236       if (!SecOrErr)
237         return SecOrErr.takeError();
238       Y->Sections.emplace_back(*SecOrErr);
239       break;
240     }
241     case ELF::SHT_NULL: {
242       // We only dump the SHT_NULL section at index 0 when it
243       // has at least one non-null field, because yaml2obj
244       // normally creates the zero section at index 0 implicitly.
245       if (&Sec == &Sections[0]) {
246         const uint8_t *Begin = reinterpret_cast<const uint8_t *>(&Sec);
247         const uint8_t *End = Begin + sizeof(Elf_Shdr);
248         if (std::find_if(Begin, End, [](uint8_t V) { return V != 0; }) == End)
249           break;
250       }
251       LLVM_FALLTHROUGH;
252     }
253     default: {
254       Expected<ELFYAML::RawContentSection *> SecOrErr =
255           dumpContentSection(&Sec);
256       if (!SecOrErr)
257         return SecOrErr.takeError();
258       Y->Sections.emplace_back(*SecOrErr);
259     }
260     }
261   }
262 
263   return Y.release();
264 }
265 
266 template <class ELFT>
267 Error ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
268                              std::vector<ELFYAML::Symbol> &Symbols) {
269   if (!Symtab)
270     return Error::success();
271 
272   auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
273   if (!StrTableOrErr)
274     return StrTableOrErr.takeError();
275   StringRef StrTable = *StrTableOrErr;
276 
277   auto SymtabOrErr = Obj.symbols(Symtab);
278   if (!SymtabOrErr)
279     return SymtabOrErr.takeError();
280 
281   if (Symtab->sh_type == ELF::SHT_SYMTAB) {
282     SymTable = *SymtabOrErr;
283     SymbolNames.resize(SymTable.size());
284   }
285 
286   for (const auto &Sym : (*SymtabOrErr).drop_front()) {
287     ELFYAML::Symbol S;
288     if (auto EC = dumpSymbol(&Sym, Symtab, StrTable, S))
289       return EC;
290     Symbols.push_back(S);
291   }
292 
293   return Error::success();
294 }
295 
296 template <class ELFT>
297 Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
298                                   StringRef StrTable, ELFYAML::Symbol &S) {
299   S.Type = Sym->getType();
300   S.Value = Sym->st_value;
301   S.Size = Sym->st_size;
302   S.Other = Sym->st_other;
303   S.Binding = Sym->getBinding();
304 
305   Expected<StringRef> SymbolNameOrErr =
306       getUniquedSymbolName(Sym, StrTable, SymTab);
307   if (!SymbolNameOrErr)
308     return SymbolNameOrErr.takeError();
309   S.Name = SymbolNameOrErr.get();
310 
311   if (Sym->st_shndx >= ELF::SHN_LORESERVE) {
312     if (Sym->st_shndx == ELF::SHN_XINDEX)
313       return createStringError(obj2yaml_error::not_implemented,
314                                "SHN_XINDEX symbols are not supported");
315     S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx;
316     return Error::success();
317   }
318 
319   auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
320   if (!ShdrOrErr)
321     return ShdrOrErr.takeError();
322   const Elf_Shdr *Shdr = *ShdrOrErr;
323   if (!Shdr)
324     return Error::success();
325 
326   auto NameOrErr = getUniquedSectionName(Shdr);
327   if (!NameOrErr)
328     return NameOrErr.takeError();
329   S.Section = NameOrErr.get();
330 
331   return Error::success();
332 }
333 
334 template <class ELFT>
335 template <class RelT>
336 Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
337                                       ELFYAML::Relocation &R) {
338   R.Type = Rel->getType(Obj.isMips64EL());
339   R.Offset = Rel->r_offset;
340   R.Addend = 0;
341 
342   auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
343   if (!SymOrErr)
344     return SymOrErr.takeError();
345   const Elf_Sym *Sym = *SymOrErr;
346   auto StrTabSec = Obj.getSection(SymTab->sh_link);
347   if (!StrTabSec)
348     return StrTabSec.takeError();
349   auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
350   if (!StrTabOrErr)
351     return StrTabOrErr.takeError();
352   StringRef StrTab = *StrTabOrErr;
353 
354   if (Sym) {
355     Expected<StringRef> NameOrErr = getUniquedSymbolName(Sym, StrTab, SymTab);
356     if (!NameOrErr)
357       return NameOrErr.takeError();
358     R.Symbol = NameOrErr.get();
359   } else {
360     // We have some edge cases of relocations without a symbol associated,
361     // e.g. an object containing the invalid (according to the System V
362     // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
363     // of crashing.
364     R.Symbol = "";
365   }
366 
367   return Error::success();
368 }
369 
370 template <class ELFT>
371 Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
372                                          ELFYAML::Section &S) {
373   // Dump fields. We do not dump the ShOffset field. When not explicitly
374   // set, the value is set by yaml2obj automatically.
375   S.Type = Shdr->sh_type;
376   if (Shdr->sh_flags)
377     S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags);
378   S.Address = Shdr->sh_addr;
379   S.AddressAlign = Shdr->sh_addralign;
380   if (Shdr->sh_entsize)
381     S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);
382 
383   auto NameOrErr = getUniquedSectionName(Shdr);
384   if (!NameOrErr)
385     return NameOrErr.takeError();
386   S.Name = NameOrErr.get();
387 
388   if (Shdr->sh_link != ELF::SHN_UNDEF) {
389     auto LinkSection = Obj.getSection(Shdr->sh_link);
390     if (!LinkSection)
391       return make_error<StringError>(
392           "unable to resolve sh_link reference in section '" + S.Name +
393               "': " + toString(LinkSection.takeError()),
394           inconvertibleErrorCode());
395 
396     NameOrErr = getUniquedSectionName(*LinkSection);
397     if (!NameOrErr)
398       return NameOrErr.takeError();
399     S.Link = NameOrErr.get();
400   }
401 
402   return Error::success();
403 }
404 
405 template <class ELFT>
406 Error ELFDumper<ELFT>::dumpCommonRelocationSection(
407     const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S) {
408   if (Error E = dumpCommonSection(Shdr, S))
409     return E;
410 
411   auto InfoSection = Obj.getSection(Shdr->sh_info);
412   if (!InfoSection)
413     return InfoSection.takeError();
414 
415   auto NameOrErr = getUniquedSectionName(*InfoSection);
416   if (!NameOrErr)
417     return NameOrErr.takeError();
418   S.RelocatableSec = NameOrErr.get();
419 
420   return Error::success();
421 }
422 
423 template <class ELFT>
424 Expected<ELFYAML::DynamicSection *>
425 ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
426   auto S = make_unique<ELFYAML::DynamicSection>();
427   if (Error E = dumpCommonSection(Shdr, *S))
428     return std::move(E);
429 
430   auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(Shdr);
431   if (!DynTagsOrErr)
432     return DynTagsOrErr.takeError();
433 
434   for (const Elf_Dyn &Dyn : *DynTagsOrErr)
435     S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
436 
437   return S.release();
438 }
439 
440 template <class ELFT>
441 Expected<ELFYAML::RelocationSection *>
442 ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
443   auto S = make_unique<ELFYAML::RelocationSection>();
444   if (auto E = dumpCommonRelocationSection(Shdr, *S))
445     return std::move(E);
446 
447   auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
448   if (!SymTabOrErr)
449     return SymTabOrErr.takeError();
450   const Elf_Shdr *SymTab = *SymTabOrErr;
451 
452   if (Shdr->sh_type == ELF::SHT_REL) {
453     auto Rels = Obj.rels(Shdr);
454     if (!Rels)
455       return Rels.takeError();
456     for (const Elf_Rel &Rel : *Rels) {
457       ELFYAML::Relocation R;
458       if (Error E = dumpRelocation(&Rel, SymTab, R))
459         return std::move(E);
460       S->Relocations.push_back(R);
461     }
462   } else {
463     auto Rels = Obj.relas(Shdr);
464     if (!Rels)
465       return Rels.takeError();
466     for (const Elf_Rela &Rel : *Rels) {
467       ELFYAML::Relocation R;
468       if (Error E = dumpRelocation(&Rel, SymTab, R))
469         return std::move(E);
470       R.Addend = Rel.r_addend;
471       S->Relocations.push_back(R);
472     }
473   }
474 
475   return S.release();
476 }
477 
478 template <class ELFT>
479 Expected<ELFYAML::RawContentSection *>
480 ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
481   auto S = make_unique<ELFYAML::RawContentSection>();
482   if (Error E = dumpCommonSection(Shdr, *S))
483     return std::move(E);
484 
485   unsigned SecIndex = Shdr - &Sections[0];
486   if (SecIndex != 0 || Shdr->sh_type != ELF::SHT_NULL) {
487     auto ContentOrErr = Obj.getSectionContents(Shdr);
488     if (!ContentOrErr)
489       return ContentOrErr.takeError();
490     ArrayRef<uint8_t> Content = *ContentOrErr;
491     if (!Content.empty())
492       S->Content = yaml::BinaryRef(Content);
493   } else {
494     S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);
495   }
496 
497   if (Shdr->sh_info)
498     S->Info = static_cast<llvm::yaml::Hex64>(Shdr->sh_info);
499   return S.release();
500 }
501 
502 template <class ELFT>
503 Expected<ELFYAML::NoBitsSection *>
504 ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
505   auto S = make_unique<ELFYAML::NoBitsSection>();
506   if (Error E = dumpCommonSection(Shdr, *S))
507     return std::move(E);
508   S->Size = Shdr->sh_size;
509 
510   return S.release();
511 }
512 
513 template <class ELFT>
514 Expected<ELFYAML::VerdefSection *>
515 ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
516   typedef typename ELFT::Verdef Elf_Verdef;
517   typedef typename ELFT::Verdaux Elf_Verdaux;
518 
519   auto S = make_unique<ELFYAML::VerdefSection>();
520   if (Error E = dumpCommonSection(Shdr, *S))
521     return std::move(E);
522 
523   S->Info = Shdr->sh_info;
524 
525   auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
526   if (!StringTableShdrOrErr)
527     return StringTableShdrOrErr.takeError();
528 
529   auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
530   if (!StringTableOrErr)
531     return StringTableOrErr.takeError();
532 
533   auto Contents = Obj.getSectionContents(Shdr);
534   if (!Contents)
535     return Contents.takeError();
536 
537   llvm::ArrayRef<uint8_t> Data = *Contents;
538   const uint8_t *Buf = Data.data();
539   while (Buf) {
540     const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
541     ELFYAML::VerdefEntry Entry;
542     Entry.Version = Verdef->vd_version;
543     Entry.Flags = Verdef->vd_flags;
544     Entry.VersionNdx = Verdef->vd_ndx;
545     Entry.Hash = Verdef->vd_hash;
546 
547     const uint8_t *BufAux = Buf + Verdef->vd_aux;
548     while (BufAux) {
549       const Elf_Verdaux *Verdaux =
550           reinterpret_cast<const Elf_Verdaux *>(BufAux);
551       Entry.VerNames.push_back(
552           StringTableOrErr->drop_front(Verdaux->vda_name).data());
553       BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
554     }
555 
556     S->Entries.push_back(Entry);
557     Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
558   }
559 
560   return S.release();
561 }
562 
563 template <class ELFT>
564 Expected<ELFYAML::SymverSection *>
565 ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
566   typedef typename ELFT::Half Elf_Half;
567 
568   auto S = make_unique<ELFYAML::SymverSection>();
569   if (Error E = dumpCommonSection(Shdr, *S))
570     return std::move(E);
571 
572   auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(Shdr);
573   if (!VersionsOrErr)
574     return VersionsOrErr.takeError();
575   for (const Elf_Half &E : *VersionsOrErr)
576     S->Entries.push_back(E);
577 
578   return S.release();
579 }
580 
581 template <class ELFT>
582 Expected<ELFYAML::VerneedSection *>
583 ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
584   typedef typename ELFT::Verneed Elf_Verneed;
585   typedef typename ELFT::Vernaux Elf_Vernaux;
586 
587   auto S = make_unique<ELFYAML::VerneedSection>();
588   if (Error E = dumpCommonSection(Shdr, *S))
589     return std::move(E);
590 
591   S->Info = Shdr->sh_info;
592 
593   auto Contents = Obj.getSectionContents(Shdr);
594   if (!Contents)
595     return Contents.takeError();
596 
597   auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
598   if (!StringTableShdrOrErr)
599     return StringTableShdrOrErr.takeError();
600 
601   auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
602   if (!StringTableOrErr)
603     return StringTableOrErr.takeError();
604 
605   llvm::ArrayRef<uint8_t> Data = *Contents;
606   const uint8_t *Buf = Data.data();
607   while (Buf) {
608     const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
609 
610     ELFYAML::VerneedEntry Entry;
611     Entry.Version = Verneed->vn_version;
612     Entry.File =
613         StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data());
614 
615     const uint8_t *BufAux = Buf + Verneed->vn_aux;
616     while (BufAux) {
617       const Elf_Vernaux *Vernaux =
618           reinterpret_cast<const Elf_Vernaux *>(BufAux);
619 
620       ELFYAML::VernauxEntry Aux;
621       Aux.Hash = Vernaux->vna_hash;
622       Aux.Flags = Vernaux->vna_flags;
623       Aux.Other = Vernaux->vna_other;
624       Aux.Name =
625           StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data());
626 
627       Entry.AuxV.push_back(Aux);
628       BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
629     }
630 
631     S->VerneedV.push_back(Entry);
632     Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
633   }
634 
635   return S.release();
636 }
637 
638 template <class ELFT>
639 Expected<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
640   auto S = make_unique<ELFYAML::Group>();
641   if (Error E = dumpCommonSection(Shdr, *S))
642     return std::move(E);
643 
644   auto SymtabOrErr = Obj.getSection(Shdr->sh_link);
645   if (!SymtabOrErr)
646     return SymtabOrErr.takeError();
647   // Get symbol with index sh_info which name is the signature of the group.
648   const Elf_Shdr *Symtab = *SymtabOrErr;
649   auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
650   if (!SymOrErr)
651     return SymOrErr.takeError();
652   auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
653   if (!StrTabOrErr)
654     return StrTabOrErr.takeError();
655 
656   Expected<StringRef> SymbolName =
657       getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
658   if (!SymbolName)
659     return SymbolName.takeError();
660   S->Signature = *SymbolName;
661 
662   auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(Shdr);
663   if (!MembersOrErr)
664     return MembersOrErr.takeError();
665 
666   for (Elf_Word Member : *MembersOrErr) {
667     if (Member == llvm::ELF::GRP_COMDAT) {
668       S->Members.push_back({"GRP_COMDAT"});
669       continue;
670     }
671 
672     auto SHdrOrErr = Obj.getSection(Member);
673     if (!SHdrOrErr)
674       return SHdrOrErr.takeError();
675     auto NameOrErr = getUniquedSectionName(*SHdrOrErr);
676     if (!NameOrErr)
677       return NameOrErr.takeError();
678     S->Members.push_back({*NameOrErr});
679   }
680   return S.release();
681 }
682 
683 template <class ELFT>
684 Expected<ELFYAML::MipsABIFlags *>
685 ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
686   assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&
687          "Section type is not SHT_MIPS_ABIFLAGS");
688   auto S = make_unique<ELFYAML::MipsABIFlags>();
689   if (Error E = dumpCommonSection(Shdr, *S))
690     return std::move(E);
691 
692   auto ContentOrErr = Obj.getSectionContents(Shdr);
693   if (!ContentOrErr)
694     return ContentOrErr.takeError();
695 
696   auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
697       ContentOrErr.get().data());
698   S->Version = Flags->version;
699   S->ISALevel = Flags->isa_level;
700   S->ISARevision = Flags->isa_rev;
701   S->GPRSize = Flags->gpr_size;
702   S->CPR1Size = Flags->cpr1_size;
703   S->CPR2Size = Flags->cpr2_size;
704   S->FpABI = Flags->fp_abi;
705   S->ISAExtension = Flags->isa_ext;
706   S->ASEs = Flags->ases;
707   S->Flags1 = Flags->flags1;
708   S->Flags2 = Flags->flags2;
709   return S.release();
710 }
711 
712 template <class ELFT>
713 static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj) {
714   ELFDumper<ELFT> Dumper(Obj);
715   Expected<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
716   if (!YAMLOrErr)
717     return YAMLOrErr.takeError();
718 
719   std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
720   yaml::Output Yout(Out);
721   Yout << *YAML;
722 
723   return Error::success();
724 }
725 
726 Error elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
727   if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
728     return elf2yaml(Out, *ELFObj->getELFFile());
729 
730   if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
731     return elf2yaml(Out, *ELFObj->getELFFile());
732 
733   if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
734     return elf2yaml(Out, *ELFObj->getELFFile());
735 
736   if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
737     return elf2yaml(Out, *ELFObj->getELFFile());
738 
739   llvm_unreachable("unknown ELF file format");
740 }
741