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 "obj2yaml.h"
10 #include "llvm/ADT/DenseSet.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
14 #include "llvm/Object/ELFObjectFile.h"
15 #include "llvm/ObjectYAML/DWARFYAML.h"
16 #include "llvm/ObjectYAML/ELFYAML.h"
17 #include "llvm/Support/DataExtractor.h"
18 #include "llvm/Support/Errc.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/YAMLTraits.h"
21 
22 using namespace llvm;
23 
24 namespace {
25 
26 template <class ELFT>
27 class ELFDumper {
28   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
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   Optional<uint32_t> ShStrTabIndex;
36 
37   DenseMap<StringRef, uint32_t> UsedSymbolNames;
38   std::vector<std::string> SymbolNames;
39 
40   BumpPtrAllocator StringAllocator;
41 
42   Expected<StringRef> getUniquedSectionName(const Elf_Shdr &Sec);
43   Expected<StringRef> getUniquedSymbolName(const Elf_Sym *Sym,
44                                            StringRef StrTable,
45                                            const Elf_Shdr *SymTab);
46   Expected<StringRef> getSymbolName(uint32_t SymtabNdx, uint32_t SymbolNdx);
47 
48   const object::ELFFile<ELFT> &Obj;
49   std::unique_ptr<DWARFContext> DWARFCtx;
50 
51   DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
52 
53   Expected<std::vector<ELFYAML::ProgramHeader>>
54   dumpProgramHeaders(ArrayRef<std::unique_ptr<ELFYAML::Chunk>> Sections);
55 
56   Optional<DWARFYAML::Data>
57   dumpDWARFSections(std::vector<std::unique_ptr<ELFYAML::Chunk>> &Sections);
58 
59   Error dumpSymbols(const Elf_Shdr *Symtab,
60                     Optional<std::vector<ELFYAML::Symbol>> &Symbols);
61   Error dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
62                    StringRef StrTable, ELFYAML::Symbol &S);
63   Expected<std::vector<std::unique_ptr<ELFYAML::Chunk>>> dumpSections();
64   Error dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
65   Error dumpCommonRelocationSection(const Elf_Shdr *Shdr,
66                                     ELFYAML::RelocationSection &S);
67   template <class RelT>
68   Error dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
69                        ELFYAML::Relocation &R);
70 
71   Expected<ELFYAML::AddrsigSection *> dumpAddrsigSection(const Elf_Shdr *Shdr);
72   Expected<ELFYAML::LinkerOptionsSection *>
73   dumpLinkerOptionsSection(const Elf_Shdr *Shdr);
74   Expected<ELFYAML::DependentLibrariesSection *>
75   dumpDependentLibrariesSection(const Elf_Shdr *Shdr);
76   Expected<ELFYAML::CallGraphProfileSection *>
77   dumpCallGraphProfileSection(const Elf_Shdr *Shdr);
78   Expected<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr);
79   Expected<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
80   Expected<ELFYAML::RelrSection *> dumpRelrSection(const Elf_Shdr *Shdr);
81   Expected<ELFYAML::RawContentSection *>
82   dumpContentSection(const Elf_Shdr *Shdr);
83   Expected<ELFYAML::SymtabShndxSection *>
84   dumpSymtabShndxSection(const Elf_Shdr *Shdr);
85   Expected<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
86   Expected<ELFYAML::HashSection *> dumpHashSection(const Elf_Shdr *Shdr);
87   Expected<ELFYAML::NoteSection *> dumpNoteSection(const Elf_Shdr *Shdr);
88   Expected<ELFYAML::GnuHashSection *> dumpGnuHashSection(const Elf_Shdr *Shdr);
89   Expected<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr);
90   Expected<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
91   Expected<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
92   Expected<ELFYAML::GroupSection *> dumpGroupSection(const Elf_Shdr *Shdr);
93   Expected<ELFYAML::ARMIndexTableSection *>
94   dumpARMIndexTableSection(const Elf_Shdr *Shdr);
95   Expected<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
96   Expected<ELFYAML::StackSizesSection *>
97   dumpStackSizesSection(const Elf_Shdr *Shdr);
98   Expected<ELFYAML::BBAddrMapSection *>
99   dumpBBAddrMapSection(const Elf_Shdr *Shdr);
100   Expected<ELFYAML::RawContentSection *>
101   dumpPlaceholderSection(const Elf_Shdr *Shdr);
102 
103   bool shouldPrintSection(const ELFYAML::Section &S, const Elf_Shdr &SHdr,
104                           Optional<DWARFYAML::Data> DWARF);
105 
106 public:
107   ELFDumper(const object::ELFFile<ELFT> &O, std::unique_ptr<DWARFContext> DCtx);
108   Expected<ELFYAML::Object *> dump();
109 };
110 
111 }
112 
113 template <class ELFT>
ELFDumper(const object::ELFFile<ELFT> & O,std::unique_ptr<DWARFContext> DCtx)114 ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O,
115                            std::unique_ptr<DWARFContext> DCtx)
116     : Obj(O), DWARFCtx(std::move(DCtx)) {}
117 
118 template <class ELFT>
119 Expected<StringRef>
getUniquedSectionName(const Elf_Shdr & Sec)120 ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr &Sec) {
121   unsigned SecIndex = &Sec - &Sections[0];
122   if (!SectionNames[SecIndex].empty())
123     return SectionNames[SecIndex];
124 
125   auto NameOrErr = Obj.getSectionName(Sec);
126   if (!NameOrErr)
127     return NameOrErr;
128   StringRef Name = *NameOrErr;
129   // In some specific cases we might have more than one section without a
130   // name (sh_name == 0). It normally doesn't happen, but when we have this case
131   // it doesn't make sense to uniquify their names and add noise to the output.
132   if (Name.empty())
133     return "";
134 
135   std::string &Ret = SectionNames[SecIndex];
136 
137   auto It = UsedSectionNames.insert({Name, 0});
138   if (!It.second)
139     Ret = ELFYAML::appendUniqueSuffix(Name, Twine(++It.first->second));
140   else
141     Ret = std::string(Name);
142   return Ret;
143 }
144 
145 template <class ELFT>
146 Expected<StringRef>
getUniquedSymbolName(const Elf_Sym * Sym,StringRef StrTable,const Elf_Shdr * SymTab)147 ELFDumper<ELFT>::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable,
148                                       const Elf_Shdr *SymTab) {
149   Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
150   if (!SymbolNameOrErr)
151     return SymbolNameOrErr;
152   StringRef Name = *SymbolNameOrErr;
153   if (Name.empty() && Sym->getType() == ELF::STT_SECTION) {
154     Expected<const Elf_Shdr *> ShdrOrErr =
155         Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab));
156     if (!ShdrOrErr)
157       return ShdrOrErr.takeError();
158     // The null section has no name.
159     return (*ShdrOrErr == nullptr) ? "" : getUniquedSectionName(**ShdrOrErr);
160   }
161 
162   // Symbols in .symtab can have duplicate names. For example, it is a common
163   // situation for local symbols in a relocatable object. Here we assign unique
164   // suffixes for such symbols so that we can differentiate them.
165   if (SymTab->sh_type == ELF::SHT_SYMTAB) {
166     unsigned Index = Sym - SymTable.data();
167     if (!SymbolNames[Index].empty())
168       return SymbolNames[Index];
169 
170     auto It = UsedSymbolNames.insert({Name, 0});
171     if (!It.second)
172       SymbolNames[Index] =
173           ELFYAML::appendUniqueSuffix(Name, Twine(++It.first->second));
174     else
175       SymbolNames[Index] = std::string(Name);
176     return SymbolNames[Index];
177   }
178 
179   return Name;
180 }
181 
182 template <class ELFT>
shouldPrintSection(const ELFYAML::Section & S,const Elf_Shdr & SHdr,Optional<DWARFYAML::Data> DWARF)183 bool ELFDumper<ELFT>::shouldPrintSection(const ELFYAML::Section &S,
184                                          const Elf_Shdr &SHdr,
185                                          Optional<DWARFYAML::Data> DWARF) {
186   // We only print the SHT_NULL section at index 0 when it
187   // has at least one non-null field, because yaml2obj
188   // normally creates the zero section at index 0 implicitly.
189   if (S.Type == ELF::SHT_NULL && (&SHdr == &Sections[0])) {
190     const uint8_t *Begin = reinterpret_cast<const uint8_t *>(&SHdr);
191     const uint8_t *End = Begin + sizeof(Elf_Shdr);
192     return std::any_of(Begin, End, [](uint8_t V) { return V != 0; });
193   }
194 
195   // Normally we use "DWARF:" to describe contents of DWARF sections. Sometimes
196   // the content of DWARF sections can be successfully parsed into the "DWARF:"
197   // entry but their section headers may have special flags, entry size, address
198   // alignment, etc. We will preserve the header for them under such
199   // circumstances.
200   StringRef SecName = S.Name.substr(1);
201   if (DWARF && DWARF->getNonEmptySectionNames().count(SecName)) {
202     if (const ELFYAML::RawContentSection *RawSec =
203             dyn_cast<const ELFYAML::RawContentSection>(&S)) {
204       if (RawSec->Type != ELF::SHT_PROGBITS || RawSec->Link || RawSec->Info ||
205           RawSec->AddressAlign != yaml::Hex64{1} || RawSec->Address ||
206           RawSec->EntSize)
207         return true;
208 
209       ELFYAML::ELF_SHF ShFlags = RawSec->Flags.value_or(ELFYAML::ELF_SHF(0));
210 
211       if (SecName == "debug_str")
212         return ShFlags != ELFYAML::ELF_SHF(ELF::SHF_MERGE | ELF::SHF_STRINGS);
213 
214       return ShFlags != ELFYAML::ELF_SHF{0};
215     }
216   }
217 
218   // Normally we use "Symbols:" and "DynamicSymbols:" to describe contents of
219   // symbol tables. We also build and emit corresponding string tables
220   // implicitly. But sometimes it is important to preserve positions and virtual
221   // addresses of allocatable sections, e.g. for creating program headers.
222   // Generally we are trying to reduce noise in the YAML output. Because
223   // of that we do not print non-allocatable versions of such sections and
224   // assume they are placed at the end.
225   // We also dump symbol tables when the Size field is set. It happens when they
226   // are empty, which should not normally happen.
227   if (S.Type == ELF::SHT_STRTAB || S.Type == ELF::SHT_SYMTAB ||
228       S.Type == ELF::SHT_DYNSYM) {
229     return S.Size || S.Flags.value_or(ELFYAML::ELF_SHF(0)) & ELF::SHF_ALLOC;
230   }
231 
232   return true;
233 }
234 
235 template <class ELFT>
dumpSectionOffsets(const typename ELFT::Ehdr & Header,ArrayRef<ELFYAML::ProgramHeader> Phdrs,std::vector<std::unique_ptr<ELFYAML::Chunk>> & V,ArrayRef<typename ELFT::Shdr> S)236 static void dumpSectionOffsets(const typename ELFT::Ehdr &Header,
237                                ArrayRef<ELFYAML::ProgramHeader> Phdrs,
238                                std::vector<std::unique_ptr<ELFYAML::Chunk>> &V,
239                                ArrayRef<typename ELFT::Shdr> S) {
240   if (V.empty())
241     return;
242 
243   uint64_t ExpectedOffset;
244   if (Header.e_phoff > 0)
245     ExpectedOffset = Header.e_phoff + Header.e_phentsize * Header.e_phnum;
246   else
247     ExpectedOffset = sizeof(typename ELFT::Ehdr);
248 
249   for (const std::unique_ptr<ELFYAML::Chunk> &C :
250        makeArrayRef(V).drop_front()) {
251     ELFYAML::Section &Sec = *cast<ELFYAML::Section>(C.get());
252     const typename ELFT::Shdr &SecHdr = S[Sec.OriginalSecNdx];
253 
254     ExpectedOffset = alignTo(ExpectedOffset,
255                              SecHdr.sh_addralign ? SecHdr.sh_addralign : 1uLL);
256 
257     // We only set the "Offset" field when it can't be naturally derived
258     // from the offset and size of the previous section. This reduces
259     // the noise in the YAML output.
260     if (SecHdr.sh_offset != ExpectedOffset)
261       Sec.Offset = (yaml::Hex64)SecHdr.sh_offset;
262 
263     if (Sec.Type == ELF::SHT_NOBITS &&
264         !ELFYAML::shouldAllocateFileSpace(Phdrs,
265                                           *cast<ELFYAML::NoBitsSection>(&Sec)))
266       ExpectedOffset = SecHdr.sh_offset;
267     else
268       ExpectedOffset = SecHdr.sh_offset + SecHdr.sh_size;
269   }
270 }
271 
dump()272 template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
273   auto Y = std::make_unique<ELFYAML::Object>();
274 
275   // Dump header. We do not dump EPh* and ESh* fields. When not explicitly set,
276   // the values are set by yaml2obj automatically and there is no need to dump
277   // them here.
278   Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader().getFileClass());
279   Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader().getDataEncoding());
280   Y->Header.OSABI = Obj.getHeader().e_ident[ELF::EI_OSABI];
281   Y->Header.ABIVersion = Obj.getHeader().e_ident[ELF::EI_ABIVERSION];
282   Y->Header.Type = Obj.getHeader().e_type;
283   if (Obj.getHeader().e_machine != 0)
284     Y->Header.Machine = ELFYAML::ELF_EM(Obj.getHeader().e_machine);
285   Y->Header.Flags = Obj.getHeader().e_flags;
286   Y->Header.Entry = Obj.getHeader().e_entry;
287 
288   // Dump sections
289   auto SectionsOrErr = Obj.sections();
290   if (!SectionsOrErr)
291     return SectionsOrErr.takeError();
292   Sections = *SectionsOrErr;
293   SectionNames.resize(Sections.size());
294 
295   if (Sections.size() > 0) {
296     ShStrTabIndex = Obj.getHeader().e_shstrndx;
297     if (*ShStrTabIndex == ELF::SHN_XINDEX)
298       ShStrTabIndex = Sections[0].sh_link;
299     // TODO: Set EShStrndx if the value doesn't represent a real section.
300   }
301 
302   // Normally an object that does not have sections has e_shnum == 0.
303   // Also, e_shnum might be 0, when the the number of entries in the section
304   // header table is larger than or equal to SHN_LORESERVE (0xff00). In this
305   // case the real number of entries is held in the sh_size member of the
306   // initial entry. We have a section header table when `e_shoff` is not 0.
307   if (Obj.getHeader().e_shoff != 0 && Obj.getHeader().e_shnum == 0)
308     Y->Header.EShNum = 0;
309 
310   // Dump symbols. We need to do this early because other sections might want
311   // to access the deduplicated symbol names that we also create here.
312   const Elf_Shdr *SymTab = nullptr;
313   const Elf_Shdr *DynSymTab = nullptr;
314 
315   for (const Elf_Shdr &Sec : Sections) {
316     if (Sec.sh_type == ELF::SHT_SYMTAB) {
317       SymTab = &Sec;
318     } else if (Sec.sh_type == ELF::SHT_DYNSYM) {
319       DynSymTab = &Sec;
320     } else if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
321       // We need to locate SHT_SYMTAB_SHNDX sections early, because they
322       // might be needed for dumping symbols.
323       if (Expected<ArrayRef<Elf_Word>> TableOrErr = Obj.getSHNDXTable(Sec)) {
324         // The `getSHNDXTable` calls the `getSection` internally when validates
325         // the symbol table section linked to the SHT_SYMTAB_SHNDX section.
326         const Elf_Shdr *LinkedSymTab = cantFail(Obj.getSection(Sec.sh_link));
327         if (!ShndxTables.insert({LinkedSymTab, *TableOrErr}).second)
328           return createStringError(
329               errc::invalid_argument,
330               "multiple SHT_SYMTAB_SHNDX sections are "
331               "linked to the same symbol table with index " +
332                   Twine(Sec.sh_link));
333       } else {
334         return createStringError(errc::invalid_argument,
335                                  "unable to read extended section indexes: " +
336                                      toString(TableOrErr.takeError()));
337       }
338     }
339   }
340 
341   if (SymTab)
342     if (Error E = dumpSymbols(SymTab, Y->Symbols))
343       return std::move(E);
344 
345   if (DynSymTab)
346     if (Error E = dumpSymbols(DynSymTab, Y->DynamicSymbols))
347       return std::move(E);
348 
349   // We dump all sections first. It is simple and allows us to verify that all
350   // sections are valid and also to generalize the code. But we are not going to
351   // keep all of them in the final output (see comments for
352   // 'shouldPrintSection()'). Undesired chunks will be removed later.
353   Expected<std::vector<std::unique_ptr<ELFYAML::Chunk>>> ChunksOrErr =
354       dumpSections();
355   if (!ChunksOrErr)
356     return ChunksOrErr.takeError();
357   std::vector<std::unique_ptr<ELFYAML::Chunk>> Chunks = std::move(*ChunksOrErr);
358 
359   std::vector<ELFYAML::Section *> OriginalOrder;
360   if (!Chunks.empty())
361     for (const std::unique_ptr<ELFYAML::Chunk> &C :
362          makeArrayRef(Chunks).drop_front())
363       OriginalOrder.push_back(cast<ELFYAML::Section>(C.get()));
364 
365   // Sometimes the order of sections in the section header table does not match
366   // their actual order. Here we sort sections by the file offset.
367   llvm::stable_sort(Chunks, [&](const std::unique_ptr<ELFYAML::Chunk> &A,
368                                 const std::unique_ptr<ELFYAML::Chunk> &B) {
369     return Sections[cast<ELFYAML::Section>(A.get())->OriginalSecNdx].sh_offset <
370            Sections[cast<ELFYAML::Section>(B.get())->OriginalSecNdx].sh_offset;
371   });
372 
373   // Dump program headers.
374   Expected<std::vector<ELFYAML::ProgramHeader>> PhdrsOrErr =
375       dumpProgramHeaders(Chunks);
376   if (!PhdrsOrErr)
377     return PhdrsOrErr.takeError();
378   Y->ProgramHeaders = std::move(*PhdrsOrErr);
379 
380   dumpSectionOffsets<ELFT>(Obj.getHeader(), Y->ProgramHeaders, Chunks,
381                            Sections);
382 
383   // Dump DWARF sections.
384   Y->DWARF = dumpDWARFSections(Chunks);
385 
386   // We emit the "SectionHeaderTable" key when the order of sections in the
387   // sections header table doesn't match the file order.
388   const bool SectionsSorted =
389       llvm::is_sorted(Chunks, [&](const std::unique_ptr<ELFYAML::Chunk> &A,
390                                   const std::unique_ptr<ELFYAML::Chunk> &B) {
391         return cast<ELFYAML::Section>(A.get())->OriginalSecNdx <
392                cast<ELFYAML::Section>(B.get())->OriginalSecNdx;
393       });
394   if (!SectionsSorted) {
395     std::unique_ptr<ELFYAML::SectionHeaderTable> SHT =
396         std::make_unique<ELFYAML::SectionHeaderTable>(/*IsImplicit=*/false);
397     SHT->Sections.emplace();
398     for (ELFYAML::Section *S : OriginalOrder)
399       SHT->Sections->push_back({S->Name});
400     Chunks.push_back(std::move(SHT));
401   }
402 
403   llvm::erase_if(Chunks, [this, &Y](const std::unique_ptr<ELFYAML::Chunk> &C) {
404     if (isa<ELFYAML::SectionHeaderTable>(*C.get()))
405       return false;
406 
407     const ELFYAML::Section &S = cast<ELFYAML::Section>(*C.get());
408     return !shouldPrintSection(S, Sections[S.OriginalSecNdx], Y->DWARF);
409   });
410 
411   // The section header string table by default is assumed to be called
412   // ".shstrtab" and be in its own unique section. However, it's possible for it
413   // to be called something else and shared with another section. If the name
414   // isn't the default, provide this in the YAML.
415   if (ShStrTabIndex && *ShStrTabIndex != ELF::SHN_UNDEF &&
416       *ShStrTabIndex < Sections.size()) {
417     StringRef ShStrtabName;
418     if (SymTab && SymTab->sh_link == *ShStrTabIndex) {
419       // Section header string table is shared with the symbol table. Use that
420       // section's name (usually .strtab).
421       ShStrtabName = cantFail(Obj.getSectionName(Sections[SymTab->sh_link]));
422     } else if (DynSymTab && DynSymTab->sh_link == *ShStrTabIndex) {
423       // Section header string table is shared with the dynamic symbol table.
424       // Use that section's name (usually .dynstr).
425       ShStrtabName = cantFail(Obj.getSectionName(Sections[DynSymTab->sh_link]));
426     } else {
427       // Otherwise, the section name potentially needs uniquifying.
428       ShStrtabName = cantFail(getUniquedSectionName(Sections[*ShStrTabIndex]));
429     }
430     if (ShStrtabName != ".shstrtab")
431       Y->Header.SectionHeaderStringTable = ShStrtabName;
432   }
433 
434   Y->Chunks = std::move(Chunks);
435   return Y.release();
436 }
437 
438 template <class ELFT>
isInSegment(const ELFYAML::Section & Sec,const typename ELFT::Shdr & SHdr,const typename ELFT::Phdr & Phdr)439 static bool isInSegment(const ELFYAML::Section &Sec,
440                         const typename ELFT::Shdr &SHdr,
441                         const typename ELFT::Phdr &Phdr) {
442   if (Sec.Type == ELF::SHT_NULL)
443     return false;
444 
445   // A section is within a segment when its location in a file is within the
446   // [p_offset, p_offset + p_filesz] region.
447   bool FileOffsetsMatch =
448       SHdr.sh_offset >= Phdr.p_offset &&
449       (SHdr.sh_offset + SHdr.sh_size <= Phdr.p_offset + Phdr.p_filesz);
450 
451   bool VirtualAddressesMatch = SHdr.sh_addr >= Phdr.p_vaddr &&
452                                SHdr.sh_addr <= Phdr.p_vaddr + Phdr.p_memsz;
453 
454   if (FileOffsetsMatch) {
455     // An empty section on the edges of a program header can be outside of the
456     // virtual address space of the segment. This means it is not included in
457     // the segment and we should ignore it.
458     if (SHdr.sh_size == 0 && (SHdr.sh_offset == Phdr.p_offset ||
459                               SHdr.sh_offset == Phdr.p_offset + Phdr.p_filesz))
460       return VirtualAddressesMatch;
461     return true;
462   }
463 
464   // SHT_NOBITS sections usually occupy no physical space in a file. Such
465   // sections belong to a segment when they reside in the segment's virtual
466   // address space.
467   if (Sec.Type != ELF::SHT_NOBITS)
468     return false;
469   return VirtualAddressesMatch;
470 }
471 
472 template <class ELFT>
473 Expected<std::vector<ELFYAML::ProgramHeader>>
dumpProgramHeaders(ArrayRef<std::unique_ptr<ELFYAML::Chunk>> Chunks)474 ELFDumper<ELFT>::dumpProgramHeaders(
475     ArrayRef<std::unique_ptr<ELFYAML::Chunk>> Chunks) {
476   std::vector<ELFYAML::ProgramHeader> Ret;
477   Expected<typename ELFT::PhdrRange> PhdrsOrErr = Obj.program_headers();
478   if (!PhdrsOrErr)
479     return PhdrsOrErr.takeError();
480 
481   for (const typename ELFT::Phdr &Phdr : *PhdrsOrErr) {
482     ELFYAML::ProgramHeader PH;
483     PH.Type = Phdr.p_type;
484     PH.Flags = Phdr.p_flags;
485     PH.VAddr = Phdr.p_vaddr;
486     PH.PAddr = Phdr.p_paddr;
487 
488     // yaml2obj sets the alignment of a segment to 1 by default.
489     // We do not print the default alignment to reduce noise in the output.
490     if (Phdr.p_align != 1)
491       PH.Align = static_cast<llvm::yaml::Hex64>(Phdr.p_align);
492 
493     // Here we match sections with segments.
494     // It is not possible to have a non-Section chunk, because
495     // obj2yaml does not create Fill chunks.
496     for (const std::unique_ptr<ELFYAML::Chunk> &C : Chunks) {
497       ELFYAML::Section &S = cast<ELFYAML::Section>(*C.get());
498       if (isInSegment<ELFT>(S, Sections[S.OriginalSecNdx], Phdr)) {
499         if (!PH.FirstSec)
500           PH.FirstSec = S.Name;
501         PH.LastSec = S.Name;
502         PH.Chunks.push_back(C.get());
503       }
504     }
505 
506     Ret.push_back(PH);
507   }
508 
509   return Ret;
510 }
511 
512 template <class ELFT>
dumpDWARFSections(std::vector<std::unique_ptr<ELFYAML::Chunk>> & Sections)513 Optional<DWARFYAML::Data> ELFDumper<ELFT>::dumpDWARFSections(
514     std::vector<std::unique_ptr<ELFYAML::Chunk>> &Sections) {
515   DWARFYAML::Data DWARF;
516   for (std::unique_ptr<ELFYAML::Chunk> &C : Sections) {
517     if (!C->Name.startswith(".debug_"))
518       continue;
519 
520     if (ELFYAML::RawContentSection *RawSec =
521             dyn_cast<ELFYAML::RawContentSection>(C.get())) {
522       // FIXME: The dumpDebug* functions should take the content as stored in
523       // RawSec. Currently, they just use the last section with the matching
524       // name, which defeats this attempt to skip reading a section header
525       // string table with the same name as a DWARF section.
526       if (ShStrTabIndex && RawSec->OriginalSecNdx == *ShStrTabIndex)
527         continue;
528       Error Err = Error::success();
529       cantFail(std::move(Err));
530 
531       if (RawSec->Name == ".debug_aranges")
532         Err = dumpDebugARanges(*DWARFCtx.get(), DWARF);
533       else if (RawSec->Name == ".debug_str")
534         Err = dumpDebugStrings(*DWARFCtx.get(), DWARF);
535       else if (RawSec->Name == ".debug_ranges")
536         Err = dumpDebugRanges(*DWARFCtx.get(), DWARF);
537       else if (RawSec->Name == ".debug_addr")
538         Err = dumpDebugAddr(*DWARFCtx.get(), DWARF);
539       else
540         continue;
541 
542       // If the DWARF section cannot be successfully parsed, emit raw content
543       // instead of an entry in the DWARF section of the YAML.
544       if (Err)
545         consumeError(std::move(Err));
546       else
547         RawSec->Content.reset();
548     }
549   }
550 
551   if (DWARF.getNonEmptySectionNames().empty())
552     return None;
553   return DWARF;
554 }
555 
556 template <class ELFT>
557 Expected<ELFYAML::RawContentSection *>
dumpPlaceholderSection(const Elf_Shdr * Shdr)558 ELFDumper<ELFT>::dumpPlaceholderSection(const Elf_Shdr *Shdr) {
559   auto S = std::make_unique<ELFYAML::RawContentSection>();
560   if (Error E = dumpCommonSection(Shdr, *S.get()))
561     return std::move(E);
562 
563   // Normally symbol tables should not be empty. We dump the "Size"
564   // key when they are.
565   if ((Shdr->sh_type == ELF::SHT_SYMTAB || Shdr->sh_type == ELF::SHT_DYNSYM) &&
566       !Shdr->sh_size)
567     S->Size.emplace();
568 
569   return S.release();
570 }
571 
572 template <class ELFT>
573 Expected<std::vector<std::unique_ptr<ELFYAML::Chunk>>>
dumpSections()574 ELFDumper<ELFT>::dumpSections() {
575   std::vector<std::unique_ptr<ELFYAML::Chunk>> Ret;
576   auto Add = [&](Expected<ELFYAML::Chunk *> SecOrErr) -> Error {
577     if (!SecOrErr)
578       return SecOrErr.takeError();
579     Ret.emplace_back(*SecOrErr);
580     return Error::success();
581   };
582 
583   auto GetDumper = [this](unsigned Type)
584       -> std::function<Expected<ELFYAML::Chunk *>(const Elf_Shdr *)> {
585     if (Obj.getHeader().e_machine == ELF::EM_ARM && Type == ELF::SHT_ARM_EXIDX)
586       return [this](const Elf_Shdr *S) { return dumpARMIndexTableSection(S); };
587 
588     if (Obj.getHeader().e_machine == ELF::EM_MIPS &&
589         Type == ELF::SHT_MIPS_ABIFLAGS)
590       return [this](const Elf_Shdr *S) { return dumpMipsABIFlags(S); };
591 
592     switch (Type) {
593     case ELF::SHT_DYNAMIC:
594       return [this](const Elf_Shdr *S) { return dumpDynamicSection(S); };
595     case ELF::SHT_SYMTAB_SHNDX:
596       return [this](const Elf_Shdr *S) { return dumpSymtabShndxSection(S); };
597     case ELF::SHT_REL:
598     case ELF::SHT_RELA:
599       return [this](const Elf_Shdr *S) { return dumpRelocSection(S); };
600     case ELF::SHT_RELR:
601       return [this](const Elf_Shdr *S) { return dumpRelrSection(S); };
602     case ELF::SHT_GROUP:
603       return [this](const Elf_Shdr *S) { return dumpGroupSection(S); };
604     case ELF::SHT_NOBITS:
605       return [this](const Elf_Shdr *S) { return dumpNoBitsSection(S); };
606     case ELF::SHT_NOTE:
607       return [this](const Elf_Shdr *S) { return dumpNoteSection(S); };
608     case ELF::SHT_HASH:
609       return [this](const Elf_Shdr *S) { return dumpHashSection(S); };
610     case ELF::SHT_GNU_HASH:
611       return [this](const Elf_Shdr *S) { return dumpGnuHashSection(S); };
612     case ELF::SHT_GNU_verdef:
613       return [this](const Elf_Shdr *S) { return dumpVerdefSection(S); };
614     case ELF::SHT_GNU_versym:
615       return [this](const Elf_Shdr *S) { return dumpSymverSection(S); };
616     case ELF::SHT_GNU_verneed:
617       return [this](const Elf_Shdr *S) { return dumpVerneedSection(S); };
618     case ELF::SHT_LLVM_ADDRSIG:
619       return [this](const Elf_Shdr *S) { return dumpAddrsigSection(S); };
620     case ELF::SHT_LLVM_LINKER_OPTIONS:
621       return [this](const Elf_Shdr *S) { return dumpLinkerOptionsSection(S); };
622     case ELF::SHT_LLVM_DEPENDENT_LIBRARIES:
623       return [this](const Elf_Shdr *S) {
624         return dumpDependentLibrariesSection(S);
625       };
626     case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
627       return
628           [this](const Elf_Shdr *S) { return dumpCallGraphProfileSection(S); };
629     case ELF::SHT_LLVM_BB_ADDR_MAP_V0:
630     case ELF::SHT_LLVM_BB_ADDR_MAP:
631       return [this](const Elf_Shdr *S) { return dumpBBAddrMapSection(S); };
632     case ELF::SHT_STRTAB:
633     case ELF::SHT_SYMTAB:
634     case ELF::SHT_DYNSYM:
635       // The contents of these sections are described by other parts of the YAML
636       // file. But we still want to dump them, because their properties can be
637       // important. See comments for 'shouldPrintSection()' for more details.
638       return [this](const Elf_Shdr *S) { return dumpPlaceholderSection(S); };
639     default:
640       return nullptr;
641     }
642   };
643 
644   for (const Elf_Shdr &Sec : Sections) {
645     // We have dedicated dumping functions for most of the section types.
646     // Try to use one of them first.
647     if (std::function<Expected<ELFYAML::Chunk *>(const Elf_Shdr *)> DumpFn =
648             GetDumper(Sec.sh_type)) {
649       if (Error E = Add(DumpFn(&Sec)))
650         return std::move(E);
651       continue;
652     }
653 
654     // Recognize some special SHT_PROGBITS sections by name.
655     if (Sec.sh_type == ELF::SHT_PROGBITS) {
656       auto NameOrErr = Obj.getSectionName(Sec);
657       if (!NameOrErr)
658         return NameOrErr.takeError();
659 
660       if (ELFYAML::StackSizesSection::nameMatches(*NameOrErr)) {
661         if (Error E = Add(dumpStackSizesSection(&Sec)))
662           return std::move(E);
663         continue;
664       }
665     }
666 
667     if (Error E = Add(dumpContentSection(&Sec)))
668       return std::move(E);
669   }
670 
671   return std::move(Ret);
672 }
673 
674 template <class ELFT>
dumpSymbols(const Elf_Shdr * Symtab,Optional<std::vector<ELFYAML::Symbol>> & Symbols)675 Error ELFDumper<ELFT>::dumpSymbols(
676     const Elf_Shdr *Symtab, Optional<std::vector<ELFYAML::Symbol>> &Symbols) {
677   if (!Symtab)
678     return Error::success();
679 
680   auto SymtabOrErr = Obj.symbols(Symtab);
681   if (!SymtabOrErr)
682     return SymtabOrErr.takeError();
683 
684   if (SymtabOrErr->empty())
685     return Error::success();
686 
687   auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
688   if (!StrTableOrErr)
689     return StrTableOrErr.takeError();
690 
691   if (Symtab->sh_type == ELF::SHT_SYMTAB) {
692     SymTable = *SymtabOrErr;
693     SymbolNames.resize(SymTable.size());
694   }
695 
696   Symbols.emplace();
697   for (const auto &Sym : (*SymtabOrErr).drop_front()) {
698     ELFYAML::Symbol S;
699     if (auto EC = dumpSymbol(&Sym, Symtab, *StrTableOrErr, S))
700       return EC;
701     Symbols->push_back(S);
702   }
703 
704   return Error::success();
705 }
706 
707 template <class ELFT>
dumpSymbol(const Elf_Sym * Sym,const Elf_Shdr * SymTab,StringRef StrTable,ELFYAML::Symbol & S)708 Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
709                                   StringRef StrTable, ELFYAML::Symbol &S) {
710   S.Type = Sym->getType();
711   if (Sym->st_value)
712     S.Value = (yaml::Hex64)Sym->st_value;
713   if (Sym->st_size)
714     S.Size = (yaml::Hex64)Sym->st_size;
715   S.Other = Sym->st_other;
716   S.Binding = Sym->getBinding();
717 
718   Expected<StringRef> SymbolNameOrErr =
719       getUniquedSymbolName(Sym, StrTable, SymTab);
720   if (!SymbolNameOrErr)
721     return SymbolNameOrErr.takeError();
722   S.Name = SymbolNameOrErr.get();
723 
724   if (Sym->st_shndx >= ELF::SHN_LORESERVE) {
725     S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx;
726     return Error::success();
727   }
728 
729   auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab));
730   if (!ShdrOrErr)
731     return ShdrOrErr.takeError();
732   const Elf_Shdr *Shdr = *ShdrOrErr;
733   if (!Shdr)
734     return Error::success();
735 
736   auto NameOrErr = getUniquedSectionName(*Shdr);
737   if (!NameOrErr)
738     return NameOrErr.takeError();
739   S.Section = NameOrErr.get();
740 
741   return Error::success();
742 }
743 
744 template <class ELFT>
745 template <class RelT>
dumpRelocation(const RelT * Rel,const Elf_Shdr * SymTab,ELFYAML::Relocation & R)746 Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
747                                       ELFYAML::Relocation &R) {
748   R.Type = Rel->getType(Obj.isMips64EL());
749   R.Offset = Rel->r_offset;
750   R.Addend = 0;
751 
752   auto SymOrErr = Obj.getRelocationSymbol(*Rel, SymTab);
753   if (!SymOrErr)
754     return SymOrErr.takeError();
755 
756   // We have might have a relocation with symbol index 0,
757   // e.g. R_X86_64_NONE or R_X86_64_GOTPC32.
758   const Elf_Sym *Sym = *SymOrErr;
759   if (!Sym)
760     return Error::success();
761 
762   auto StrTabSec = Obj.getSection(SymTab->sh_link);
763   if (!StrTabSec)
764     return StrTabSec.takeError();
765   auto StrTabOrErr = Obj.getStringTable(**StrTabSec);
766   if (!StrTabOrErr)
767     return StrTabOrErr.takeError();
768 
769   Expected<StringRef> NameOrErr =
770       getUniquedSymbolName(Sym, *StrTabOrErr, SymTab);
771   if (!NameOrErr)
772     return NameOrErr.takeError();
773   R.Symbol = NameOrErr.get();
774 
775   return Error::success();
776 }
777 
778 template <class ELFT>
dumpCommonSection(const Elf_Shdr * Shdr,ELFYAML::Section & S)779 Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
780                                          ELFYAML::Section &S) {
781   // Dump fields. We do not dump the ShOffset field. When not explicitly
782   // set, the value is set by yaml2obj automatically.
783   S.Type = Shdr->sh_type;
784   if (Shdr->sh_flags)
785     S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags);
786   if (Shdr->sh_addr)
787     S.Address = static_cast<uint64_t>(Shdr->sh_addr);
788   S.AddressAlign = Shdr->sh_addralign;
789 
790   S.OriginalSecNdx = Shdr - &Sections[0];
791 
792   Expected<StringRef> NameOrErr = getUniquedSectionName(*Shdr);
793   if (!NameOrErr)
794     return NameOrErr.takeError();
795   S.Name = NameOrErr.get();
796 
797   if (Shdr->sh_entsize != ELFYAML::getDefaultShEntSize<ELFT>(
798                               Obj.getHeader().e_machine, S.Type, S.Name))
799     S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);
800 
801   if (Shdr->sh_link != ELF::SHN_UNDEF) {
802     Expected<const Elf_Shdr *> LinkSection = Obj.getSection(Shdr->sh_link);
803     if (!LinkSection)
804       return make_error<StringError>(
805           "unable to resolve sh_link reference in section '" + S.Name +
806               "': " + toString(LinkSection.takeError()),
807           inconvertibleErrorCode());
808 
809     NameOrErr = getUniquedSectionName(**LinkSection);
810     if (!NameOrErr)
811       return NameOrErr.takeError();
812     S.Link = NameOrErr.get();
813   }
814 
815   return Error::success();
816 }
817 
818 template <class ELFT>
dumpCommonRelocationSection(const Elf_Shdr * Shdr,ELFYAML::RelocationSection & S)819 Error ELFDumper<ELFT>::dumpCommonRelocationSection(
820     const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S) {
821   if (Error E = dumpCommonSection(Shdr, S))
822     return E;
823 
824   // Having a zero sh_info field is normal: .rela.dyn is a dynamic
825   // relocation section that normally has no value in this field.
826   if (!Shdr->sh_info)
827     return Error::success();
828 
829   auto InfoSection = Obj.getSection(Shdr->sh_info);
830   if (!InfoSection)
831     return InfoSection.takeError();
832 
833   Expected<StringRef> NameOrErr = getUniquedSectionName(**InfoSection);
834   if (!NameOrErr)
835     return NameOrErr.takeError();
836   S.RelocatableSec = NameOrErr.get();
837 
838   return Error::success();
839 }
840 
841 template <class ELFT>
842 Expected<ELFYAML::StackSizesSection *>
dumpStackSizesSection(const Elf_Shdr * Shdr)843 ELFDumper<ELFT>::dumpStackSizesSection(const Elf_Shdr *Shdr) {
844   auto S = std::make_unique<ELFYAML::StackSizesSection>();
845   if (Error E = dumpCommonSection(Shdr, *S))
846     return std::move(E);
847 
848   auto ContentOrErr = Obj.getSectionContents(*Shdr);
849   if (!ContentOrErr)
850     return ContentOrErr.takeError();
851 
852   ArrayRef<uint8_t> Content = *ContentOrErr;
853   DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4);
854 
855   std::vector<ELFYAML::StackSizeEntry> Entries;
856   DataExtractor::Cursor Cur(0);
857   while (Cur && Cur.tell() < Content.size()) {
858     uint64_t Address = Data.getAddress(Cur);
859     uint64_t Size = Data.getULEB128(Cur);
860     Entries.push_back({Address, Size});
861   }
862 
863   if (Content.empty() || !Cur) {
864     // If .stack_sizes cannot be decoded, we dump it as an array of bytes.
865     consumeError(Cur.takeError());
866     S->Content = yaml::BinaryRef(Content);
867   } else {
868     S->Entries = std::move(Entries);
869   }
870 
871   return S.release();
872 }
873 
874 template <class ELFT>
875 Expected<ELFYAML::BBAddrMapSection *>
dumpBBAddrMapSection(const Elf_Shdr * Shdr)876 ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {
877   auto S = std::make_unique<ELFYAML::BBAddrMapSection>();
878   if (Error E = dumpCommonSection(Shdr, *S))
879     return std::move(E);
880 
881   auto ContentOrErr = Obj.getSectionContents(*Shdr);
882   if (!ContentOrErr)
883     return ContentOrErr.takeError();
884 
885   ArrayRef<uint8_t> Content = *ContentOrErr;
886   if (Content.empty())
887     return S.release();
888 
889   DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4);
890 
891   std::vector<ELFYAML::BBAddrMapEntry> Entries;
892   DataExtractor::Cursor Cur(0);
893   uint8_t Version = 0;
894   uint8_t Feature = 0;
895   while (Cur && Cur.tell() < Content.size()) {
896     if (Shdr->sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
897       Version = Data.getU8(Cur);
898       if (Cur && Version > 1)
899         return createStringError(
900             errc::invalid_argument,
901             "invalid SHT_LLVM_BB_ADDR_MAP section version: " +
902                 Twine(static_cast<int>(Version)));
903       Feature = Data.getU8(Cur);
904     }
905     uint64_t Address = Data.getAddress(Cur);
906     uint64_t NumBlocks = Data.getULEB128(Cur);
907     std::vector<ELFYAML::BBAddrMapEntry::BBEntry> BBEntries;
908     // Read the specified number of BB entries, or until decoding fails.
909     for (uint64_t BlockID = 0; Cur && BlockID < NumBlocks; ++BlockID) {
910       uint64_t Offset = Data.getULEB128(Cur);
911       uint64_t Size = Data.getULEB128(Cur);
912       uint64_t Metadata = Data.getULEB128(Cur);
913       BBEntries.push_back({Offset, Size, Metadata});
914     }
915     Entries.push_back(
916         {Version, Feature, Address, /*NumBlocks=*/{}, std::move(BBEntries)});
917   }
918 
919   if (!Cur) {
920     // If the section cannot be decoded, we dump it as an array of bytes.
921     consumeError(Cur.takeError());
922     S->Content = yaml::BinaryRef(Content);
923   } else {
924     S->Entries = std::move(Entries);
925   }
926 
927   return S.release();
928 }
929 
930 template <class ELFT>
931 Expected<ELFYAML::AddrsigSection *>
dumpAddrsigSection(const Elf_Shdr * Shdr)932 ELFDumper<ELFT>::dumpAddrsigSection(const Elf_Shdr *Shdr) {
933   auto S = std::make_unique<ELFYAML::AddrsigSection>();
934   if (Error E = dumpCommonSection(Shdr, *S))
935     return std::move(E);
936 
937   auto ContentOrErr = Obj.getSectionContents(*Shdr);
938   if (!ContentOrErr)
939     return ContentOrErr.takeError();
940 
941   ArrayRef<uint8_t> Content = *ContentOrErr;
942   DataExtractor::Cursor Cur(0);
943   DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);
944   std::vector<ELFYAML::YAMLFlowString> Symbols;
945   while (Cur && Cur.tell() < Content.size()) {
946     uint64_t SymNdx = Data.getULEB128(Cur);
947     if (!Cur)
948       break;
949 
950     Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, SymNdx);
951     if (!SymbolName || SymbolName->empty()) {
952       consumeError(SymbolName.takeError());
953       Symbols.emplace_back(
954           StringRef(std::to_string(SymNdx)).copy(StringAllocator));
955       continue;
956     }
957 
958     Symbols.emplace_back(*SymbolName);
959   }
960 
961   if (Cur) {
962     S->Symbols = std::move(Symbols);
963     return S.release();
964   }
965 
966   consumeError(Cur.takeError());
967   S->Content = yaml::BinaryRef(Content);
968   return S.release();
969 }
970 
971 template <class ELFT>
972 Expected<ELFYAML::LinkerOptionsSection *>
dumpLinkerOptionsSection(const Elf_Shdr * Shdr)973 ELFDumper<ELFT>::dumpLinkerOptionsSection(const Elf_Shdr *Shdr) {
974   auto S = std::make_unique<ELFYAML::LinkerOptionsSection>();
975   if (Error E = dumpCommonSection(Shdr, *S))
976     return std::move(E);
977 
978   auto ContentOrErr = Obj.getSectionContents(*Shdr);
979   if (!ContentOrErr)
980     return ContentOrErr.takeError();
981 
982   ArrayRef<uint8_t> Content = *ContentOrErr;
983   if (Content.empty() || Content.back() != 0) {
984     S->Content = Content;
985     return S.release();
986   }
987 
988   SmallVector<StringRef, 16> Strings;
989   toStringRef(Content.drop_back()).split(Strings, '\0');
990   if (Strings.size() % 2 != 0) {
991     S->Content = Content;
992     return S.release();
993   }
994 
995   S->Options.emplace();
996   for (size_t I = 0, E = Strings.size(); I != E; I += 2)
997     S->Options->push_back({Strings[I], Strings[I + 1]});
998 
999   return S.release();
1000 }
1001 
1002 template <class ELFT>
1003 Expected<ELFYAML::DependentLibrariesSection *>
dumpDependentLibrariesSection(const Elf_Shdr * Shdr)1004 ELFDumper<ELFT>::dumpDependentLibrariesSection(const Elf_Shdr *Shdr) {
1005   auto DL = std::make_unique<ELFYAML::DependentLibrariesSection>();
1006   if (Error E = dumpCommonSection(Shdr, *DL))
1007     return std::move(E);
1008 
1009   Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1010   if (!ContentOrErr)
1011     return ContentOrErr.takeError();
1012 
1013   ArrayRef<uint8_t> Content = *ContentOrErr;
1014   if (!Content.empty() && Content.back() != 0) {
1015     DL->Content = Content;
1016     return DL.release();
1017   }
1018 
1019   DL->Libs.emplace();
1020   for (const uint8_t *I = Content.begin(), *E = Content.end(); I < E;) {
1021     StringRef Lib((const char *)I);
1022     DL->Libs->emplace_back(Lib);
1023     I += Lib.size() + 1;
1024   }
1025 
1026   return DL.release();
1027 }
1028 
1029 template <class ELFT>
1030 Expected<ELFYAML::CallGraphProfileSection *>
dumpCallGraphProfileSection(const Elf_Shdr * Shdr)1031 ELFDumper<ELFT>::dumpCallGraphProfileSection(const Elf_Shdr *Shdr) {
1032   auto S = std::make_unique<ELFYAML::CallGraphProfileSection>();
1033   if (Error E = dumpCommonSection(Shdr, *S))
1034     return std::move(E);
1035 
1036   Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1037   if (!ContentOrErr)
1038     return ContentOrErr.takeError();
1039   ArrayRef<uint8_t> Content = *ContentOrErr;
1040   const uint32_t SizeOfEntry = ELFYAML::getDefaultShEntSize<ELFT>(
1041       Obj.getHeader().e_machine, S->Type, S->Name);
1042   // Dump the section by using the Content key when it is truncated.
1043   // There is no need to create either "Content" or "Entries" fields when the
1044   // section is empty.
1045   if (Content.empty() || Content.size() % SizeOfEntry != 0) {
1046     if (!Content.empty())
1047       S->Content = yaml::BinaryRef(Content);
1048     return S.release();
1049   }
1050 
1051   std::vector<ELFYAML::CallGraphEntryWeight> Entries(Content.size() /
1052                                                      SizeOfEntry);
1053   DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);
1054   DataExtractor::Cursor Cur(0);
1055   auto ReadEntry = [&](ELFYAML::CallGraphEntryWeight &E) {
1056     E.Weight = Data.getU64(Cur);
1057     if (!Cur) {
1058       consumeError(Cur.takeError());
1059       return false;
1060     }
1061     return true;
1062   };
1063 
1064   for (ELFYAML::CallGraphEntryWeight &E : Entries) {
1065     if (ReadEntry(E))
1066       continue;
1067     S->Content = yaml::BinaryRef(Content);
1068     return S.release();
1069   }
1070 
1071   S->Entries = std::move(Entries);
1072   return S.release();
1073 }
1074 
1075 template <class ELFT>
1076 Expected<ELFYAML::DynamicSection *>
dumpDynamicSection(const Elf_Shdr * Shdr)1077 ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
1078   auto S = std::make_unique<ELFYAML::DynamicSection>();
1079   if (Error E = dumpCommonSection(Shdr, *S))
1080     return std::move(E);
1081 
1082   auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(*Shdr);
1083   if (!DynTagsOrErr)
1084     return DynTagsOrErr.takeError();
1085 
1086   S->Entries.emplace();
1087   for (const Elf_Dyn &Dyn : *DynTagsOrErr)
1088     S->Entries->push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
1089 
1090   return S.release();
1091 }
1092 
1093 template <class ELFT>
1094 Expected<ELFYAML::RelocationSection *>
dumpRelocSection(const Elf_Shdr * Shdr)1095 ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
1096   auto S = std::make_unique<ELFYAML::RelocationSection>();
1097   if (auto E = dumpCommonRelocationSection(Shdr, *S))
1098     return std::move(E);
1099 
1100   auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
1101   if (!SymTabOrErr)
1102     return SymTabOrErr.takeError();
1103 
1104   if (Shdr->sh_size != 0)
1105     S->Relocations.emplace();
1106 
1107   if (Shdr->sh_type == ELF::SHT_REL) {
1108     auto Rels = Obj.rels(*Shdr);
1109     if (!Rels)
1110       return Rels.takeError();
1111     for (const Elf_Rel &Rel : *Rels) {
1112       ELFYAML::Relocation R;
1113       if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
1114         return std::move(E);
1115       S->Relocations->push_back(R);
1116     }
1117   } else {
1118     auto Rels = Obj.relas(*Shdr);
1119     if (!Rels)
1120       return Rels.takeError();
1121     for (const Elf_Rela &Rel : *Rels) {
1122       ELFYAML::Relocation R;
1123       if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
1124         return std::move(E);
1125       R.Addend = Rel.r_addend;
1126       S->Relocations->push_back(R);
1127     }
1128   }
1129 
1130   return S.release();
1131 }
1132 
1133 template <class ELFT>
1134 Expected<ELFYAML::RelrSection *>
dumpRelrSection(const Elf_Shdr * Shdr)1135 ELFDumper<ELFT>::dumpRelrSection(const Elf_Shdr *Shdr) {
1136   auto S = std::make_unique<ELFYAML::RelrSection>();
1137   if (auto E = dumpCommonSection(Shdr, *S))
1138     return std::move(E);
1139 
1140   if (Expected<ArrayRef<Elf_Relr>> Relrs = Obj.relrs(*Shdr)) {
1141     S->Entries.emplace();
1142     for (Elf_Relr Rel : *Relrs)
1143       S->Entries->emplace_back(Rel);
1144     return S.release();
1145   } else {
1146     // Ignore. We are going to dump the data as raw content below.
1147     consumeError(Relrs.takeError());
1148   }
1149 
1150   Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1151   if (!ContentOrErr)
1152     return ContentOrErr.takeError();
1153   S->Content = *ContentOrErr;
1154   return S.release();
1155 }
1156 
1157 template <class ELFT>
1158 Expected<ELFYAML::RawContentSection *>
dumpContentSection(const Elf_Shdr * Shdr)1159 ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
1160   auto S = std::make_unique<ELFYAML::RawContentSection>();
1161   if (Error E = dumpCommonSection(Shdr, *S))
1162     return std::move(E);
1163 
1164   unsigned SecIndex = Shdr - &Sections[0];
1165   if (SecIndex != 0 || Shdr->sh_type != ELF::SHT_NULL) {
1166     auto ContentOrErr = Obj.getSectionContents(*Shdr);
1167     if (!ContentOrErr)
1168       return ContentOrErr.takeError();
1169     ArrayRef<uint8_t> Content = *ContentOrErr;
1170     if (!Content.empty())
1171       S->Content = yaml::BinaryRef(Content);
1172   } else {
1173     S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);
1174   }
1175 
1176   if (Shdr->sh_info)
1177     S->Info = static_cast<llvm::yaml::Hex64>(Shdr->sh_info);
1178   return S.release();
1179 }
1180 
1181 template <class ELFT>
1182 Expected<ELFYAML::SymtabShndxSection *>
dumpSymtabShndxSection(const Elf_Shdr * Shdr)1183 ELFDumper<ELFT>::dumpSymtabShndxSection(const Elf_Shdr *Shdr) {
1184   auto S = std::make_unique<ELFYAML::SymtabShndxSection>();
1185   if (Error E = dumpCommonSection(Shdr, *S))
1186     return std::move(E);
1187 
1188   auto EntriesOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(*Shdr);
1189   if (!EntriesOrErr)
1190     return EntriesOrErr.takeError();
1191 
1192   S->Entries.emplace();
1193   for (const Elf_Word &E : *EntriesOrErr)
1194     S->Entries->push_back(E);
1195   return S.release();
1196 }
1197 
1198 template <class ELFT>
1199 Expected<ELFYAML::NoBitsSection *>
dumpNoBitsSection(const Elf_Shdr * Shdr)1200 ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
1201   auto S = std::make_unique<ELFYAML::NoBitsSection>();
1202   if (Error E = dumpCommonSection(Shdr, *S))
1203     return std::move(E);
1204   if (Shdr->sh_size)
1205     S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);
1206   return S.release();
1207 }
1208 
1209 template <class ELFT>
1210 Expected<ELFYAML::NoteSection *>
dumpNoteSection(const Elf_Shdr * Shdr)1211 ELFDumper<ELFT>::dumpNoteSection(const Elf_Shdr *Shdr) {
1212   auto S = std::make_unique<ELFYAML::NoteSection>();
1213   if (Error E = dumpCommonSection(Shdr, *S))
1214     return std::move(E);
1215 
1216   auto ContentOrErr = Obj.getSectionContents(*Shdr);
1217   if (!ContentOrErr)
1218     return ContentOrErr.takeError();
1219 
1220   std::vector<ELFYAML::NoteEntry> Entries;
1221   ArrayRef<uint8_t> Content = *ContentOrErr;
1222   while (!Content.empty()) {
1223     if (Content.size() < sizeof(Elf_Nhdr)) {
1224       S->Content = yaml::BinaryRef(*ContentOrErr);
1225       return S.release();
1226     }
1227 
1228     const Elf_Nhdr *Header = reinterpret_cast<const Elf_Nhdr *>(Content.data());
1229     if (Content.size() < Header->getSize()) {
1230       S->Content = yaml::BinaryRef(*ContentOrErr);
1231       return S.release();
1232     }
1233 
1234     Elf_Note Note(*Header);
1235     Entries.push_back(
1236         {Note.getName(), Note.getDesc(), (ELFYAML::ELF_NT)Note.getType()});
1237 
1238     Content = Content.drop_front(Header->getSize());
1239   }
1240 
1241   S->Notes = std::move(Entries);
1242   return S.release();
1243 }
1244 
1245 template <class ELFT>
1246 Expected<ELFYAML::HashSection *>
dumpHashSection(const Elf_Shdr * Shdr)1247 ELFDumper<ELFT>::dumpHashSection(const Elf_Shdr *Shdr) {
1248   auto S = std::make_unique<ELFYAML::HashSection>();
1249   if (Error E = dumpCommonSection(Shdr, *S))
1250     return std::move(E);
1251 
1252   auto ContentOrErr = Obj.getSectionContents(*Shdr);
1253   if (!ContentOrErr)
1254     return ContentOrErr.takeError();
1255 
1256   ArrayRef<uint8_t> Content = *ContentOrErr;
1257   if (Content.size() % 4 != 0 || Content.size() < 8) {
1258     S->Content = yaml::BinaryRef(Content);
1259     return S.release();
1260   }
1261 
1262   DataExtractor::Cursor Cur(0);
1263   DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);
1264   uint64_t NBucket = Data.getU32(Cur);
1265   uint64_t NChain = Data.getU32(Cur);
1266   if (Content.size() != (2 + NBucket + NChain) * 4) {
1267     S->Content = yaml::BinaryRef(Content);
1268     if (Cur)
1269       return S.release();
1270     llvm_unreachable("entries were not read correctly");
1271   }
1272 
1273   S->Bucket.emplace(NBucket);
1274   for (uint32_t &V : *S->Bucket)
1275     V = Data.getU32(Cur);
1276 
1277   S->Chain.emplace(NChain);
1278   for (uint32_t &V : *S->Chain)
1279     V = Data.getU32(Cur);
1280 
1281   if (Cur)
1282     return S.release();
1283   llvm_unreachable("entries were not read correctly");
1284 }
1285 
1286 template <class ELFT>
1287 Expected<ELFYAML::GnuHashSection *>
dumpGnuHashSection(const Elf_Shdr * Shdr)1288 ELFDumper<ELFT>::dumpGnuHashSection(const Elf_Shdr *Shdr) {
1289   auto S = std::make_unique<ELFYAML::GnuHashSection>();
1290   if (Error E = dumpCommonSection(Shdr, *S))
1291     return std::move(E);
1292 
1293   auto ContentOrErr = Obj.getSectionContents(*Shdr);
1294   if (!ContentOrErr)
1295     return ContentOrErr.takeError();
1296 
1297   unsigned AddrSize = ELFT::Is64Bits ? 8 : 4;
1298   ArrayRef<uint8_t> Content = *ContentOrErr;
1299   DataExtractor Data(Content, Obj.isLE(), AddrSize);
1300 
1301   ELFYAML::GnuHashHeader Header;
1302   DataExtractor::Cursor Cur(0);
1303   uint64_t NBuckets = Data.getU32(Cur);
1304   Header.SymNdx = Data.getU32(Cur);
1305   uint64_t MaskWords = Data.getU32(Cur);
1306   Header.Shift2 = Data.getU32(Cur);
1307 
1308   // Set just the raw binary content if we were unable to read the header
1309   // or when the section data is truncated or malformed.
1310   uint64_t Size = Data.getData().size() - Cur.tell();
1311   if (!Cur || (Size < MaskWords * AddrSize + NBuckets * 4) ||
1312       (Size % 4 != 0)) {
1313     consumeError(Cur.takeError());
1314     S->Content = yaml::BinaryRef(Content);
1315     return S.release();
1316   }
1317 
1318   S->Header = Header;
1319 
1320   S->BloomFilter.emplace(MaskWords);
1321   for (llvm::yaml::Hex64 &Val : *S->BloomFilter)
1322     Val = Data.getAddress(Cur);
1323 
1324   S->HashBuckets.emplace(NBuckets);
1325   for (llvm::yaml::Hex32 &Val : *S->HashBuckets)
1326     Val = Data.getU32(Cur);
1327 
1328   S->HashValues.emplace((Data.getData().size() - Cur.tell()) / 4);
1329   for (llvm::yaml::Hex32 &Val : *S->HashValues)
1330     Val = Data.getU32(Cur);
1331 
1332   if (Cur)
1333     return S.release();
1334   llvm_unreachable("GnuHashSection was not read correctly");
1335 }
1336 
1337 template <class ELFT>
1338 Expected<ELFYAML::VerdefSection *>
dumpVerdefSection(const Elf_Shdr * Shdr)1339 ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
1340   auto S = std::make_unique<ELFYAML::VerdefSection>();
1341   if (Error E = dumpCommonSection(Shdr, *S))
1342     return std::move(E);
1343 
1344   auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
1345   if (!StringTableShdrOrErr)
1346     return StringTableShdrOrErr.takeError();
1347 
1348   auto StringTableOrErr = Obj.getStringTable(**StringTableShdrOrErr);
1349   if (!StringTableOrErr)
1350     return StringTableOrErr.takeError();
1351 
1352   auto Contents = Obj.getSectionContents(*Shdr);
1353   if (!Contents)
1354     return Contents.takeError();
1355 
1356   S->Entries.emplace();
1357 
1358   llvm::ArrayRef<uint8_t> Data = *Contents;
1359   const uint8_t *Buf = Data.data();
1360   while (Buf) {
1361     const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
1362     ELFYAML::VerdefEntry Entry;
1363     if (Verdef->vd_version != 1)
1364       return createStringError(errc::invalid_argument,
1365                                "invalid SHT_GNU_verdef section version: " +
1366                                    Twine(Verdef->vd_version));
1367 
1368     if (Verdef->vd_flags != 0)
1369       Entry.Flags = Verdef->vd_flags;
1370 
1371     if (Verdef->vd_ndx != 0)
1372       Entry.VersionNdx = Verdef->vd_ndx;
1373 
1374     if (Verdef->vd_hash != 0)
1375       Entry.Hash = Verdef->vd_hash;
1376 
1377     const uint8_t *BufAux = Buf + Verdef->vd_aux;
1378     while (BufAux) {
1379       const Elf_Verdaux *Verdaux =
1380           reinterpret_cast<const Elf_Verdaux *>(BufAux);
1381       Entry.VerNames.push_back(
1382           StringTableOrErr->drop_front(Verdaux->vda_name).data());
1383       BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
1384     }
1385 
1386     S->Entries->push_back(Entry);
1387     Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
1388   }
1389 
1390   if (Shdr->sh_info != S->Entries->size())
1391     S->Info = (llvm::yaml::Hex64)Shdr->sh_info;
1392 
1393   return S.release();
1394 }
1395 
1396 template <class ELFT>
1397 Expected<ELFYAML::SymverSection *>
dumpSymverSection(const Elf_Shdr * Shdr)1398 ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
1399   auto S = std::make_unique<ELFYAML::SymverSection>();
1400   if (Error E = dumpCommonSection(Shdr, *S))
1401     return std::move(E);
1402 
1403   auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(*Shdr);
1404   if (!VersionsOrErr)
1405     return VersionsOrErr.takeError();
1406 
1407   S->Entries.emplace();
1408   for (const Elf_Half &E : *VersionsOrErr)
1409     S->Entries->push_back(E);
1410 
1411   return S.release();
1412 }
1413 
1414 template <class ELFT>
1415 Expected<ELFYAML::VerneedSection *>
dumpVerneedSection(const Elf_Shdr * Shdr)1416 ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
1417   auto S = std::make_unique<ELFYAML::VerneedSection>();
1418   if (Error E = dumpCommonSection(Shdr, *S))
1419     return std::move(E);
1420 
1421   auto Contents = Obj.getSectionContents(*Shdr);
1422   if (!Contents)
1423     return Contents.takeError();
1424 
1425   auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
1426   if (!StringTableShdrOrErr)
1427     return StringTableShdrOrErr.takeError();
1428 
1429   auto StringTableOrErr = Obj.getStringTable(**StringTableShdrOrErr);
1430   if (!StringTableOrErr)
1431     return StringTableOrErr.takeError();
1432 
1433   S->VerneedV.emplace();
1434 
1435   llvm::ArrayRef<uint8_t> Data = *Contents;
1436   const uint8_t *Buf = Data.data();
1437   while (Buf) {
1438     const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
1439 
1440     ELFYAML::VerneedEntry Entry;
1441     Entry.Version = Verneed->vn_version;
1442     Entry.File =
1443         StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data());
1444 
1445     const uint8_t *BufAux = Buf + Verneed->vn_aux;
1446     while (BufAux) {
1447       const Elf_Vernaux *Vernaux =
1448           reinterpret_cast<const Elf_Vernaux *>(BufAux);
1449 
1450       ELFYAML::VernauxEntry Aux;
1451       Aux.Hash = Vernaux->vna_hash;
1452       Aux.Flags = Vernaux->vna_flags;
1453       Aux.Other = Vernaux->vna_other;
1454       Aux.Name =
1455           StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data());
1456 
1457       Entry.AuxV.push_back(Aux);
1458       BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
1459     }
1460 
1461     S->VerneedV->push_back(Entry);
1462     Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
1463   }
1464 
1465   if (Shdr->sh_info != S->VerneedV->size())
1466     S->Info = (llvm::yaml::Hex64)Shdr->sh_info;
1467 
1468   return S.release();
1469 }
1470 
1471 template <class ELFT>
getSymbolName(uint32_t SymtabNdx,uint32_t SymbolNdx)1472 Expected<StringRef> ELFDumper<ELFT>::getSymbolName(uint32_t SymtabNdx,
1473                                                    uint32_t SymbolNdx) {
1474   auto SymtabOrErr = Obj.getSection(SymtabNdx);
1475   if (!SymtabOrErr)
1476     return SymtabOrErr.takeError();
1477 
1478   const Elf_Shdr *Symtab = *SymtabOrErr;
1479   auto SymOrErr = Obj.getSymbol(Symtab, SymbolNdx);
1480   if (!SymOrErr)
1481     return SymOrErr.takeError();
1482 
1483   auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
1484   if (!StrTabOrErr)
1485     return StrTabOrErr.takeError();
1486   return getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
1487 }
1488 
1489 template <class ELFT>
1490 Expected<ELFYAML::GroupSection *>
dumpGroupSection(const Elf_Shdr * Shdr)1491 ELFDumper<ELFT>::dumpGroupSection(const Elf_Shdr *Shdr) {
1492   auto S = std::make_unique<ELFYAML::GroupSection>();
1493   if (Error E = dumpCommonSection(Shdr, *S))
1494     return std::move(E);
1495 
1496   // Get symbol with index sh_info. This symbol's name is the signature of the group.
1497   Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, Shdr->sh_info);
1498   if (!SymbolName)
1499     return SymbolName.takeError();
1500   S->Signature = *SymbolName;
1501 
1502   auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(*Shdr);
1503   if (!MembersOrErr)
1504     return MembersOrErr.takeError();
1505 
1506   S->Members.emplace();
1507   for (Elf_Word Member : *MembersOrErr) {
1508     if (Member == llvm::ELF::GRP_COMDAT) {
1509       S->Members->push_back({"GRP_COMDAT"});
1510       continue;
1511     }
1512 
1513     Expected<const Elf_Shdr *> SHdrOrErr = Obj.getSection(Member);
1514     if (!SHdrOrErr)
1515       return SHdrOrErr.takeError();
1516     Expected<StringRef> NameOrErr = getUniquedSectionName(**SHdrOrErr);
1517     if (!NameOrErr)
1518       return NameOrErr.takeError();
1519     S->Members->push_back({*NameOrErr});
1520   }
1521   return S.release();
1522 }
1523 
1524 template <class ELFT>
1525 Expected<ELFYAML::ARMIndexTableSection *>
dumpARMIndexTableSection(const Elf_Shdr * Shdr)1526 ELFDumper<ELFT>::dumpARMIndexTableSection(const Elf_Shdr *Shdr) {
1527   auto S = std::make_unique<ELFYAML::ARMIndexTableSection>();
1528   if (Error E = dumpCommonSection(Shdr, *S))
1529     return std::move(E);
1530 
1531   Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
1532   if (!ContentOrErr)
1533     return ContentOrErr.takeError();
1534 
1535   if (ContentOrErr->size() % (sizeof(Elf_Word) * 2) != 0) {
1536     S->Content = yaml::BinaryRef(*ContentOrErr);
1537     return S.release();
1538   }
1539 
1540   ArrayRef<Elf_Word> Words(
1541       reinterpret_cast<const Elf_Word *>(ContentOrErr->data()),
1542       ContentOrErr->size() / sizeof(Elf_Word));
1543 
1544   S->Entries.emplace();
1545   for (size_t I = 0, E = Words.size(); I != E; I += 2)
1546     S->Entries->push_back({(yaml::Hex32)Words[I], (yaml::Hex32)Words[I + 1]});
1547 
1548   return S.release();
1549 }
1550 
1551 template <class ELFT>
1552 Expected<ELFYAML::MipsABIFlags *>
dumpMipsABIFlags(const Elf_Shdr * Shdr)1553 ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
1554   assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&
1555          "Section type is not SHT_MIPS_ABIFLAGS");
1556   auto S = std::make_unique<ELFYAML::MipsABIFlags>();
1557   if (Error E = dumpCommonSection(Shdr, *S))
1558     return std::move(E);
1559 
1560   auto ContentOrErr = Obj.getSectionContents(*Shdr);
1561   if (!ContentOrErr)
1562     return ContentOrErr.takeError();
1563 
1564   auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
1565       ContentOrErr.get().data());
1566   S->Version = Flags->version;
1567   S->ISALevel = Flags->isa_level;
1568   S->ISARevision = Flags->isa_rev;
1569   S->GPRSize = Flags->gpr_size;
1570   S->CPR1Size = Flags->cpr1_size;
1571   S->CPR2Size = Flags->cpr2_size;
1572   S->FpABI = Flags->fp_abi;
1573   S->ISAExtension = Flags->isa_ext;
1574   S->ASEs = Flags->ases;
1575   S->Flags1 = Flags->flags1;
1576   S->Flags2 = Flags->flags2;
1577   return S.release();
1578 }
1579 
1580 template <class ELFT>
elf2yaml(raw_ostream & Out,const object::ELFFile<ELFT> & Obj,std::unique_ptr<DWARFContext> DWARFCtx)1581 static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj,
1582                       std::unique_ptr<DWARFContext> DWARFCtx) {
1583   ELFDumper<ELFT> Dumper(Obj, std::move(DWARFCtx));
1584   Expected<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
1585   if (!YAMLOrErr)
1586     return YAMLOrErr.takeError();
1587 
1588   std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
1589   yaml::Output Yout(Out);
1590   Yout << *YAML;
1591 
1592   return Error::success();
1593 }
1594 
elf2yaml(raw_ostream & Out,const object::ObjectFile & Obj)1595 Error elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
1596   std::unique_ptr<DWARFContext> DWARFCtx = DWARFContext::create(Obj);
1597   if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
1598     return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1599 
1600   if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
1601     return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1602 
1603   if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
1604     return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1605 
1606   if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
1607     return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));
1608 
1609   llvm_unreachable("unknown ELF file format");
1610 }
1611