brintos

brintos / llvm-project-archived public Read only

0
0
Text · 58.4 KiB · 4364d15 Raw
1713 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "obj2yaml.h"10#include "llvm/ADT/STLExtras.h"11#include "llvm/ADT/Twine.h"12#include "llvm/DebugInfo/DWARF/DWARFContext.h"13#include "llvm/Object/ELFObjectFile.h"14#include "llvm/ObjectYAML/DWARFYAML.h"15#include "llvm/ObjectYAML/ELFYAML.h"16#include "llvm/Support/DataExtractor.h"17#include "llvm/Support/Errc.h"18#include "llvm/Support/ErrorHandling.h"19#include "llvm/Support/YAMLTraits.h"20#include <optional>21 22using namespace llvm;23 24namespace {25 26template <class ELFT>27class 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  std::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  std::optional<DWARFYAML::Data>57  dumpDWARFSections(std::vector<std::unique_ptr<ELFYAML::Chunk>> &Sections);58 59  Error dumpSymbols(const Elf_Shdr *Symtab,60                    std::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                          std::optional<DWARFYAML::Data> DWARF);105 106public:107  ELFDumper(const object::ELFFile<ELFT> &O, std::unique_ptr<DWARFContext> DCtx);108  Expected<ELFYAML::Object *> dump();109};110 111}112 113template <class ELFT>114ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O,115                           std::unique_ptr<DWARFContext> DCtx)116    : Obj(O), DWARFCtx(std::move(DCtx)) {}117 118template <class ELFT>119Expected<StringRef>120ELFDumper<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 a130  // name (sh_name == 0). It normally doesn't happen, but when we have this case131  // 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  else141    Ret = std::string(Name);142  return Ret;143}144 145template <class ELFT>146Expected<StringRef>147ELFDumper<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 common163  // situation for local symbols in a relocatable object. Here we assign unique164  // 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    else175      SymbolNames[Index] = std::string(Name);176    return SymbolNames[Index];177  }178 179  return Name;180}181 182template <class ELFT>183bool ELFDumper<ELFT>::shouldPrintSection(const ELFYAML::Section &S,184                                         const Elf_Shdr &SHdr,185                                         std::optional<DWARFYAML::Data> DWARF) {186  // We only print the SHT_NULL section at index 0 when it187  // has at least one non-null field, because yaml2obj188  // 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. Sometimes196  // the content of DWARF sections can be successfully parsed into the "DWARF:"197  // entry but their section headers may have special flags, entry size, address198  // alignment, etc. We will preserve the header for them under such199  // 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 of219  // symbol tables. We also build and emit corresponding string tables220  // implicitly. But sometimes it is important to preserve positions and virtual221  // addresses of allocatable sections, e.g. for creating program headers.222  // Generally we are trying to reduce noise in the YAML output. Because223  // of that we do not print non-allocatable versions of such sections and224  // assume they are placed at the end.225  // We also dump symbol tables when the Size field is set. It happens when they226  // 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 235template <class ELFT>236static 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  else247    ExpectedOffset = sizeof(typename ELFT::Ehdr);248 249  for (const std::unique_ptr<ELFYAML::Chunk> &C : ArrayRef(V).drop_front()) {250    ELFYAML::Section &Sec = *cast<ELFYAML::Section>(C.get());251    const typename ELFT::Shdr &SecHdr = S[Sec.OriginalSecNdx];252 253    ExpectedOffset = alignTo(ExpectedOffset,254                             SecHdr.sh_addralign ? SecHdr.sh_addralign : 1uLL);255 256    // We only set the "Offset" field when it can't be naturally derived257    // from the offset and size of the previous section. This reduces258    // the noise in the YAML output.259    if (SecHdr.sh_offset != ExpectedOffset)260      Sec.Offset = (yaml::Hex64)SecHdr.sh_offset;261 262    if (Sec.Type == ELF::SHT_NOBITS &&263        !ELFYAML::shouldAllocateFileSpace(Phdrs,264                                          *cast<ELFYAML::NoBitsSection>(&Sec)))265      ExpectedOffset = SecHdr.sh_offset;266    else267      ExpectedOffset = SecHdr.sh_offset + SecHdr.sh_size;268  }269}270 271template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {272  auto Y = std::make_unique<ELFYAML::Object>();273 274  // Dump header. We do not dump EPh* and ESh* fields. When not explicitly set,275  // the values are set by yaml2obj automatically and there is no need to dump276  // them here.277  Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader().getFileClass());278  Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader().getDataEncoding());279  Y->Header.OSABI = Obj.getHeader().e_ident[ELF::EI_OSABI];280  Y->Header.ABIVersion = Obj.getHeader().e_ident[ELF::EI_ABIVERSION];281  Y->Header.Type = Obj.getHeader().e_type;282  if (Obj.getHeader().e_machine != 0)283    Y->Header.Machine = ELFYAML::ELF_EM(Obj.getHeader().e_machine);284  if (Obj.getHeader().e_flags != 0)285    Y->Header.Flags = ELFYAML::ELF_EF(Obj.getHeader().e_flags);286  Y->Header.Entry = Obj.getHeader().e_entry;287 288  // Dump sections289  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 number of entries in the section304  // header table is larger than or equal to SHN_LORESERVE (0xff00). In this305  // case the real number of entries is held in the sh_size member of the306  // 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 want311  // 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 they322      // might be needed for dumping symbols.323      if (Expected<ArrayRef<Elf_Word>> TableOrErr = Obj.getSHNDXTable(Sec)) {324        // The `getSHNDXTable` calls the `getSection` internally when validates325        // 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 all350  // sections are valid and also to generalize the code. But we are not going to351  // keep all of them in the final output (see comments for352  // '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         ArrayRef(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 match366  // 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 the387  // 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))405      return false;406 407    const ELFYAML::Section &S = cast<ELFYAML::Section>(*C);408    return !shouldPrintSection(S, Sections[S.OriginalSecNdx], Y->DWARF);409  });410 411  // The section header string table by default is assumed to be called412  // ".shstrtab" and be in its own unique section. However, it's possible for it413  // to be called something else and shared with another section. If the name414  // 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 that420      // 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 438template <class ELFT>439static 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 the446  // [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 the456    // virtual address space of the segment. This means it is not included in457    // 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. Such465  // sections belong to a segment when they reside in the segment's virtual466  // address space.467  if (Sec.Type != ELF::SHT_NOBITS)468    return false;469  return VirtualAddressesMatch;470}471 472template <class ELFT>473Expected<std::vector<ELFYAML::ProgramHeader>>474ELFDumper<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    PH.Offset = Phdr.p_offset;488 489    // yaml2obj sets the alignment of a segment to 1 by default.490    // We do not print the default alignment to reduce noise in the output.491    if (Phdr.p_align != 1)492      PH.Align = static_cast<llvm::yaml::Hex64>(Phdr.p_align);493 494    // Here we match sections with segments.495    // It is not possible to have a non-Section chunk, because496    // obj2yaml does not create Fill chunks.497    for (const std::unique_ptr<ELFYAML::Chunk> &C : Chunks) {498      ELFYAML::Section &S = cast<ELFYAML::Section>(*C);499      if (isInSegment<ELFT>(S, Sections[S.OriginalSecNdx], Phdr)) {500        if (!PH.FirstSec)501          PH.FirstSec = S.Name;502        PH.LastSec = S.Name;503        PH.Chunks.push_back(C.get());504      }505    }506 507    Ret.push_back(PH);508  }509 510  return Ret;511}512 513template <class ELFT>514std::optional<DWARFYAML::Data> ELFDumper<ELFT>::dumpDWARFSections(515    std::vector<std::unique_ptr<ELFYAML::Chunk>> &Sections) {516  DWARFYAML::Data DWARF;517  for (std::unique_ptr<ELFYAML::Chunk> &C : Sections) {518    if (!C->Name.starts_with(".debug_"))519      continue;520 521    if (ELFYAML::RawContentSection *RawSec =522            dyn_cast<ELFYAML::RawContentSection>(C.get())) {523      // FIXME: The dumpDebug* functions should take the content as stored in524      // RawSec. Currently, they just use the last section with the matching525      // name, which defeats this attempt to skip reading a section header526      // string table with the same name as a DWARF section.527      if (ShStrTabIndex && RawSec->OriginalSecNdx == *ShStrTabIndex)528        continue;529      Error Err = Error::success();530      cantFail(std::move(Err));531 532      if (RawSec->Name == ".debug_aranges")533        Err = dumpDebugARanges(*DWARFCtx, DWARF);534      else if (RawSec->Name == ".debug_str")535        Err = dumpDebugStrings(*DWARFCtx, DWARF);536      else if (RawSec->Name == ".debug_ranges")537        Err = dumpDebugRanges(*DWARFCtx, DWARF);538      else if (RawSec->Name == ".debug_addr")539        Err = dumpDebugAddr(*DWARFCtx, DWARF);540      else541        continue;542 543      // If the DWARF section cannot be successfully parsed, emit raw content544      // instead of an entry in the DWARF section of the YAML.545      if (Err)546        consumeError(std::move(Err));547      else548        RawSec->Content.reset();549    }550  }551 552  if (DWARF.getNonEmptySectionNames().empty())553    return std::nullopt;554  return DWARF;555}556 557template <class ELFT>558Expected<ELFYAML::RawContentSection *>559ELFDumper<ELFT>::dumpPlaceholderSection(const Elf_Shdr *Shdr) {560  auto S = std::make_unique<ELFYAML::RawContentSection>();561  if (Error E = dumpCommonSection(Shdr, *S.get()))562    return std::move(E);563 564  // Normally symbol tables should not be empty. We dump the "Size"565  // key when they are.566  if ((Shdr->sh_type == ELF::SHT_SYMTAB || Shdr->sh_type == ELF::SHT_DYNSYM) &&567      !Shdr->sh_size)568    S->Size.emplace();569 570  return S.release();571}572 573template <class ELFT>574Expected<std::vector<std::unique_ptr<ELFYAML::Chunk>>>575ELFDumper<ELFT>::dumpSections() {576  std::vector<std::unique_ptr<ELFYAML::Chunk>> Ret;577  auto Add = [&](Expected<ELFYAML::Chunk *> SecOrErr) -> Error {578    if (!SecOrErr)579      return SecOrErr.takeError();580    Ret.emplace_back(*SecOrErr);581    return Error::success();582  };583 584  auto GetDumper = [this](unsigned Type)585      -> std::function<Expected<ELFYAML::Chunk *>(const Elf_Shdr *)> {586    if (Obj.getHeader().e_machine == ELF::EM_ARM && Type == ELF::SHT_ARM_EXIDX)587      return [this](const Elf_Shdr *S) { return dumpARMIndexTableSection(S); };588 589    if (Obj.getHeader().e_machine == ELF::EM_MIPS &&590        Type == ELF::SHT_MIPS_ABIFLAGS)591      return [this](const Elf_Shdr *S) { return dumpMipsABIFlags(S); };592 593    switch (Type) {594    case ELF::SHT_DYNAMIC:595      return [this](const Elf_Shdr *S) { return dumpDynamicSection(S); };596    case ELF::SHT_SYMTAB_SHNDX:597      return [this](const Elf_Shdr *S) { return dumpSymtabShndxSection(S); };598    case ELF::SHT_REL:599    case ELF::SHT_RELA:600    case ELF::SHT_CREL:601      return [this](const Elf_Shdr *S) { return dumpRelocSection(S); };602    case ELF::SHT_RELR:603      return [this](const Elf_Shdr *S) { return dumpRelrSection(S); };604    case ELF::SHT_GROUP:605      return [this](const Elf_Shdr *S) { return dumpGroupSection(S); };606    case ELF::SHT_NOBITS:607      return [this](const Elf_Shdr *S) { return dumpNoBitsSection(S); };608    case ELF::SHT_NOTE:609      return [this](const Elf_Shdr *S) { return dumpNoteSection(S); };610    case ELF::SHT_HASH:611      return [this](const Elf_Shdr *S) { return dumpHashSection(S); };612    case ELF::SHT_GNU_HASH:613      return [this](const Elf_Shdr *S) { return dumpGnuHashSection(S); };614    case ELF::SHT_GNU_verdef:615      return [this](const Elf_Shdr *S) { return dumpVerdefSection(S); };616    case ELF::SHT_GNU_versym:617      return [this](const Elf_Shdr *S) { return dumpSymverSection(S); };618    case ELF::SHT_GNU_verneed:619      return [this](const Elf_Shdr *S) { return dumpVerneedSection(S); };620    case ELF::SHT_LLVM_ADDRSIG:621      return [this](const Elf_Shdr *S) { return dumpAddrsigSection(S); };622    case ELF::SHT_LLVM_LINKER_OPTIONS:623      return [this](const Elf_Shdr *S) { return dumpLinkerOptionsSection(S); };624    case ELF::SHT_LLVM_DEPENDENT_LIBRARIES:625      return [this](const Elf_Shdr *S) {626        return dumpDependentLibrariesSection(S);627      };628    case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:629      return630          [this](const Elf_Shdr *S) { return dumpCallGraphProfileSection(S); };631    case ELF::SHT_LLVM_BB_ADDR_MAP:632      return [this](const Elf_Shdr *S) { return dumpBBAddrMapSection(S); };633    case ELF::SHT_STRTAB:634    case ELF::SHT_SYMTAB:635    case ELF::SHT_DYNSYM:636      // The contents of these sections are described by other parts of the YAML637      // file. But we still want to dump them, because their properties can be638      // important. See comments for 'shouldPrintSection()' for more details.639      return [this](const Elf_Shdr *S) { return dumpPlaceholderSection(S); };640    default:641      return nullptr;642    }643  };644 645  for (const Elf_Shdr &Sec : Sections) {646    // We have dedicated dumping functions for most of the section types.647    // Try to use one of them first.648    if (std::function<Expected<ELFYAML::Chunk *>(const Elf_Shdr *)> DumpFn =649            GetDumper(Sec.sh_type)) {650      if (Error E = Add(DumpFn(&Sec)))651        return std::move(E);652      continue;653    }654 655    // Recognize some special SHT_PROGBITS sections by name.656    if (Sec.sh_type == ELF::SHT_PROGBITS) {657      auto NameOrErr = Obj.getSectionName(Sec);658      if (!NameOrErr)659        return NameOrErr.takeError();660 661      if (ELFYAML::StackSizesSection::nameMatches(*NameOrErr)) {662        if (Error E = Add(dumpStackSizesSection(&Sec)))663          return std::move(E);664        continue;665      }666    }667 668    if (Error E = Add(dumpContentSection(&Sec)))669      return std::move(E);670  }671 672  return std::move(Ret);673}674 675template <class ELFT>676Error ELFDumper<ELFT>::dumpSymbols(677    const Elf_Shdr *Symtab,678    std::optional<std::vector<ELFYAML::Symbol>> &Symbols) {679  if (!Symtab)680    return Error::success();681 682  auto SymtabOrErr = Obj.symbols(Symtab);683  if (!SymtabOrErr)684    return SymtabOrErr.takeError();685 686  if (SymtabOrErr->empty())687    return Error::success();688 689  auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);690  if (!StrTableOrErr)691    return StrTableOrErr.takeError();692 693  if (Symtab->sh_type == ELF::SHT_SYMTAB) {694    SymTable = *SymtabOrErr;695    SymbolNames.resize(SymTable.size());696  }697 698  Symbols.emplace();699  for (const auto &Sym : (*SymtabOrErr).drop_front()) {700    ELFYAML::Symbol S;701    if (auto EC = dumpSymbol(&Sym, Symtab, *StrTableOrErr, S))702      return EC;703    Symbols->push_back(S);704  }705 706  return Error::success();707}708 709template <class ELFT>710Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,711                                  StringRef StrTable, ELFYAML::Symbol &S) {712  S.Type = Sym->getType();713  if (Sym->st_value)714    S.Value = (yaml::Hex64)Sym->st_value;715  if (Sym->st_size)716    S.Size = (yaml::Hex64)Sym->st_size;717  S.Other = Sym->st_other;718  S.Binding = Sym->getBinding();719 720  Expected<StringRef> SymbolNameOrErr =721      getUniquedSymbolName(Sym, StrTable, SymTab);722  if (!SymbolNameOrErr)723    return SymbolNameOrErr.takeError();724  S.Name = SymbolNameOrErr.get();725 726  if (Sym->st_shndx >= ELF::SHN_LORESERVE) {727    S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx;728    return Error::success();729  }730 731  auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab));732  if (!ShdrOrErr)733    return ShdrOrErr.takeError();734  const Elf_Shdr *Shdr = *ShdrOrErr;735  if (!Shdr)736    return Error::success();737 738  auto NameOrErr = getUniquedSectionName(*Shdr);739  if (!NameOrErr)740    return NameOrErr.takeError();741  S.Section = NameOrErr.get();742 743  return Error::success();744}745 746template <class ELFT>747template <class RelT>748Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,749                                      ELFYAML::Relocation &R) {750  R.Type = Rel->getType(Obj.isMips64EL());751  R.Offset = Rel->r_offset;752  R.Addend = 0;753 754  auto SymOrErr = Obj.getRelocationSymbol(*Rel, SymTab);755  if (!SymOrErr)756    return SymOrErr.takeError();757 758  // We have might have a relocation with symbol index 0,759  // e.g. R_X86_64_NONE or R_X86_64_GOTPC32.760  const Elf_Sym *Sym = *SymOrErr;761  if (!Sym)762    return Error::success();763 764  auto StrTabSec = Obj.getSection(SymTab->sh_link);765  if (!StrTabSec)766    return StrTabSec.takeError();767  auto StrTabOrErr = Obj.getStringTable(**StrTabSec);768  if (!StrTabOrErr)769    return StrTabOrErr.takeError();770 771  Expected<StringRef> NameOrErr =772      getUniquedSymbolName(Sym, *StrTabOrErr, SymTab);773  if (!NameOrErr)774    return NameOrErr.takeError();775  R.Symbol = NameOrErr.get();776 777  return Error::success();778}779 780template <class ELFT>781Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,782                                         ELFYAML::Section &S) {783  // Dump fields. We do not dump the ShOffset field. When not explicitly784  // set, the value is set by yaml2obj automatically.785  S.Type = Shdr->sh_type;786  if (Shdr->sh_flags)787    S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags);788  if (Shdr->sh_addr)789    S.Address = static_cast<uint64_t>(Shdr->sh_addr);790  S.AddressAlign = Shdr->sh_addralign;791 792  S.OriginalSecNdx = Shdr - &Sections[0];793 794  Expected<StringRef> NameOrErr = getUniquedSectionName(*Shdr);795  if (!NameOrErr)796    return NameOrErr.takeError();797  S.Name = NameOrErr.get();798 799  if (Shdr->sh_entsize != ELFYAML::getDefaultShEntSize<ELFT>(800                              Obj.getHeader().e_machine, S.Type, S.Name))801    S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);802 803  if (Shdr->sh_link != ELF::SHN_UNDEF) {804    Expected<const Elf_Shdr *> LinkSection = Obj.getSection(Shdr->sh_link);805    if (!LinkSection)806      return make_error<StringError>(807          "unable to resolve sh_link reference in section '" + S.Name +808              "': " + toString(LinkSection.takeError()),809          inconvertibleErrorCode());810 811    NameOrErr = getUniquedSectionName(**LinkSection);812    if (!NameOrErr)813      return NameOrErr.takeError();814    S.Link = NameOrErr.get();815  }816 817  return Error::success();818}819 820template <class ELFT>821Error ELFDumper<ELFT>::dumpCommonRelocationSection(822    const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S) {823  if (Error E = dumpCommonSection(Shdr, S))824    return E;825 826  // Having a zero sh_info field is normal: .rela.dyn is a dynamic827  // relocation section that normally has no value in this field.828  if (!Shdr->sh_info)829    return Error::success();830 831  auto InfoSection = Obj.getSection(Shdr->sh_info);832  if (!InfoSection)833    return InfoSection.takeError();834 835  Expected<StringRef> NameOrErr = getUniquedSectionName(**InfoSection);836  if (!NameOrErr)837    return NameOrErr.takeError();838  S.RelocatableSec = NameOrErr.get();839 840  return Error::success();841}842 843template <class ELFT>844Expected<ELFYAML::StackSizesSection *>845ELFDumper<ELFT>::dumpStackSizesSection(const Elf_Shdr *Shdr) {846  auto S = std::make_unique<ELFYAML::StackSizesSection>();847  if (Error E = dumpCommonSection(Shdr, *S))848    return std::move(E);849 850  auto ContentOrErr = Obj.getSectionContents(*Shdr);851  if (!ContentOrErr)852    return ContentOrErr.takeError();853 854  ArrayRef<uint8_t> Content = *ContentOrErr;855  DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4);856 857  std::vector<ELFYAML::StackSizeEntry> Entries;858  DataExtractor::Cursor Cur(0);859  while (Cur && Cur.tell() < Content.size()) {860    uint64_t Address = Data.getAddress(Cur);861    uint64_t Size = Data.getULEB128(Cur);862    Entries.push_back({Address, Size});863  }864 865  if (Content.empty() || !Cur) {866    // If .stack_sizes cannot be decoded, we dump it as an array of bytes.867    consumeError(Cur.takeError());868    S->Content = yaml::BinaryRef(Content);869  } else {870    S->Entries = std::move(Entries);871  }872 873  return S.release();874}875 876template <class ELFT>877Expected<ELFYAML::BBAddrMapSection *>878ELFDumper<ELFT>::dumpBBAddrMapSection(const Elf_Shdr *Shdr) {879  auto S = std::make_unique<ELFYAML::BBAddrMapSection>();880  if (Error E = dumpCommonSection(Shdr, *S))881    return std::move(E);882 883  auto ContentOrErr = Obj.getSectionContents(*Shdr);884  if (!ContentOrErr)885    return ContentOrErr.takeError();886 887  ArrayRef<uint8_t> Content = *ContentOrErr;888  if (Content.empty())889    return S.release();890 891  DataExtractor Data(Content, Obj.isLE(), ELFT::Is64Bits ? 8 : 4);892 893  std::vector<ELFYAML::BBAddrMapEntry> Entries;894  bool HasAnyPGOAnalysisMapEntry = false;895  std::vector<ELFYAML::PGOAnalysisMapEntry> PGOAnalyses;896  DataExtractor::Cursor Cur(0);897  uint8_t Version = 0;898  uint16_t Feature = 0;899  uint64_t Address = 0;900  while (Cur && Cur.tell() < Content.size()) {901    if (Shdr->sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {902      Version = Data.getU8(Cur);903      if (Cur && Version > 4)904        return createStringError(905            errc::invalid_argument,906            "invalid SHT_LLVM_BB_ADDR_MAP section version: " +907                Twine(static_cast<int>(Version)));908      Feature = Version < 5 ? Data.getU8(Cur) : Data.getU16(Cur);909    }910    uint64_t NumBBRanges = 1;911    uint64_t NumBlocks = 0;912    uint32_t TotalNumBlocks = 0;913    auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(Feature);914    if (!FeatureOrErr)915      return FeatureOrErr.takeError();916    if (FeatureOrErr->MultiBBRange) {917      NumBBRanges = Data.getULEB128(Cur);918    } else {919      Address = Data.getAddress(Cur);920      NumBlocks = Data.getULEB128(Cur);921    }922    std::vector<ELFYAML::BBAddrMapEntry::BBRangeEntry> BBRanges;923    uint64_t BaseAddress = 0;924    for (uint64_t BBRangeN = 0; Cur && BBRangeN != NumBBRanges; ++BBRangeN) {925      if (FeatureOrErr->MultiBBRange) {926        BaseAddress = Data.getAddress(Cur);927        NumBlocks = Data.getULEB128(Cur);928      } else {929        BaseAddress = Address;930      }931 932      std::vector<ELFYAML::BBAddrMapEntry::BBEntry> BBEntries;933      // Read the specified number of BB entries, or until decoding fails.934      for (uint64_t BlockIndex = 0; Cur && BlockIndex < NumBlocks;935           ++BlockIndex) {936        uint32_t ID = Version >= 2 ? Data.getULEB128(Cur) : BlockIndex;937        uint64_t Offset = Data.getULEB128(Cur);938        std::optional<std::vector<llvm::yaml::Hex64>> CallsiteEndOffsets;939        if (FeatureOrErr->CallsiteEndOffsets) {940          uint32_t NumCallsites = Data.getULEB128(Cur);941          CallsiteEndOffsets = std::vector<llvm::yaml::Hex64>(NumCallsites, 0);942          for (uint32_t CallsiteIndex = 0; Cur && CallsiteIndex < NumCallsites;943               ++CallsiteIndex) {944            (*CallsiteEndOffsets)[CallsiteIndex] = Data.getULEB128(Cur);945          }946        }947        uint64_t Size = Data.getULEB128(Cur);948        uint64_t Metadata = Data.getULEB128(Cur);949        std::optional<llvm::yaml::Hex64> Hash;950        if (FeatureOrErr->BBHash)951          Hash = Data.getU64(Cur);952        BBEntries.push_back(953            {ID, Offset, Size, Metadata, std::move(CallsiteEndOffsets), Hash});954      }955      TotalNumBlocks += BBEntries.size();956      BBRanges.push_back({BaseAddress, /*NumBlocks=*/{}, BBEntries});957    }958    Entries.push_back(959        {Version, Feature, /*NumBBRanges=*/{}, std::move(BBRanges)});960 961    ELFYAML::PGOAnalysisMapEntry &PGOAnalysis = PGOAnalyses.emplace_back();962    if (FeatureOrErr->hasPGOAnalysis()) {963      HasAnyPGOAnalysisMapEntry = true;964 965      if (FeatureOrErr->FuncEntryCount)966        PGOAnalysis.FuncEntryCount = Data.getULEB128(Cur);967 968      if (FeatureOrErr->hasPGOAnalysisBBData()) {969        auto &PGOBBEntries = PGOAnalysis.PGOBBEntries.emplace();970        for (uint64_t BlockIndex = 0; Cur && BlockIndex < TotalNumBlocks;971             ++BlockIndex) {972          auto &PGOBBEntry = PGOBBEntries.emplace_back();973          if (FeatureOrErr->BBFreq) {974            PGOBBEntry.BBFreq = Data.getULEB128(Cur);975            if (FeatureOrErr->PostLinkCfg)976              PGOBBEntry.PostLinkBBFreq = Data.getULEB128(Cur);977            if (!Cur)978              break;979          }980 981          if (FeatureOrErr->BrProb) {982            auto &SuccEntries = PGOBBEntry.Successors.emplace();983            uint64_t SuccCount = Data.getULEB128(Cur);984            for (uint64_t SuccIdx = 0; Cur && SuccIdx < SuccCount; ++SuccIdx) {985              uint32_t ID = Data.getULEB128(Cur);986              uint32_t BrProb = Data.getULEB128(Cur);987              std::optional<uint32_t> PostLinkBrFreq;988              if (FeatureOrErr->PostLinkCfg)989                PostLinkBrFreq = Data.getULEB128(Cur);990              SuccEntries.push_back({ID, BrProb, PostLinkBrFreq});991            }992          }993        }994      }995    }996  }997 998  if (!Cur) {999    // If the section cannot be decoded, we dump it as an array of bytes.1000    consumeError(Cur.takeError());1001    S->Content = yaml::BinaryRef(Content);1002  } else {1003    S->Entries = std::move(Entries);1004    if (HasAnyPGOAnalysisMapEntry)1005      S->PGOAnalyses = std::move(PGOAnalyses);1006  }1007 1008  return S.release();1009}1010 1011template <class ELFT>1012Expected<ELFYAML::AddrsigSection *>1013ELFDumper<ELFT>::dumpAddrsigSection(const Elf_Shdr *Shdr) {1014  auto S = std::make_unique<ELFYAML::AddrsigSection>();1015  if (Error E = dumpCommonSection(Shdr, *S))1016    return std::move(E);1017 1018  auto ContentOrErr = Obj.getSectionContents(*Shdr);1019  if (!ContentOrErr)1020    return ContentOrErr.takeError();1021 1022  ArrayRef<uint8_t> Content = *ContentOrErr;1023  DataExtractor::Cursor Cur(0);1024  DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);1025  std::vector<ELFYAML::YAMLFlowString> Symbols;1026  while (Cur && Cur.tell() < Content.size()) {1027    uint64_t SymNdx = Data.getULEB128(Cur);1028    if (!Cur)1029      break;1030 1031    Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, SymNdx);1032    if (!SymbolName || SymbolName->empty()) {1033      consumeError(SymbolName.takeError());1034      Symbols.emplace_back(1035          StringRef(std::to_string(SymNdx)).copy(StringAllocator));1036      continue;1037    }1038 1039    Symbols.emplace_back(*SymbolName);1040  }1041 1042  if (Cur) {1043    S->Symbols = std::move(Symbols);1044    return S.release();1045  }1046 1047  consumeError(Cur.takeError());1048  S->Content = yaml::BinaryRef(Content);1049  return S.release();1050}1051 1052template <class ELFT>1053Expected<ELFYAML::LinkerOptionsSection *>1054ELFDumper<ELFT>::dumpLinkerOptionsSection(const Elf_Shdr *Shdr) {1055  auto S = std::make_unique<ELFYAML::LinkerOptionsSection>();1056  if (Error E = dumpCommonSection(Shdr, *S))1057    return std::move(E);1058 1059  auto ContentOrErr = Obj.getSectionContents(*Shdr);1060  if (!ContentOrErr)1061    return ContentOrErr.takeError();1062 1063  ArrayRef<uint8_t> Content = *ContentOrErr;1064  if (Content.empty() || Content.back() != 0) {1065    S->Content = Content;1066    return S.release();1067  }1068 1069  SmallVector<StringRef, 16> Strings;1070  toStringRef(Content.drop_back()).split(Strings, '\0');1071  if (Strings.size() % 2 != 0) {1072    S->Content = Content;1073    return S.release();1074  }1075 1076  S->Options.emplace();1077  for (size_t I = 0, E = Strings.size(); I != E; I += 2)1078    S->Options->push_back({Strings[I], Strings[I + 1]});1079 1080  return S.release();1081}1082 1083template <class ELFT>1084Expected<ELFYAML::DependentLibrariesSection *>1085ELFDumper<ELFT>::dumpDependentLibrariesSection(const Elf_Shdr *Shdr) {1086  auto DL = std::make_unique<ELFYAML::DependentLibrariesSection>();1087  if (Error E = dumpCommonSection(Shdr, *DL))1088    return std::move(E);1089 1090  Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);1091  if (!ContentOrErr)1092    return ContentOrErr.takeError();1093 1094  ArrayRef<uint8_t> Content = *ContentOrErr;1095  if (!Content.empty() && Content.back() != 0) {1096    DL->Content = Content;1097    return DL.release();1098  }1099 1100  DL->Libs.emplace();1101  for (const uint8_t *I = Content.begin(), *E = Content.end(); I < E;) {1102    StringRef Lib((const char *)I);1103    DL->Libs->emplace_back(Lib);1104    I += Lib.size() + 1;1105  }1106 1107  return DL.release();1108}1109 1110template <class ELFT>1111Expected<ELFYAML::CallGraphProfileSection *>1112ELFDumper<ELFT>::dumpCallGraphProfileSection(const Elf_Shdr *Shdr) {1113  auto S = std::make_unique<ELFYAML::CallGraphProfileSection>();1114  if (Error E = dumpCommonSection(Shdr, *S))1115    return std::move(E);1116 1117  Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);1118  if (!ContentOrErr)1119    return ContentOrErr.takeError();1120  ArrayRef<uint8_t> Content = *ContentOrErr;1121  const uint32_t SizeOfEntry = ELFYAML::getDefaultShEntSize<ELFT>(1122      Obj.getHeader().e_machine, S->Type, S->Name);1123  // Dump the section by using the Content key when it is truncated.1124  // There is no need to create either "Content" or "Entries" fields when the1125  // section is empty.1126  if (Content.empty() || Content.size() % SizeOfEntry != 0) {1127    if (!Content.empty())1128      S->Content = yaml::BinaryRef(Content);1129    return S.release();1130  }1131 1132  std::vector<ELFYAML::CallGraphEntryWeight> Entries(Content.size() /1133                                                     SizeOfEntry);1134  DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);1135  DataExtractor::Cursor Cur(0);1136  auto ReadEntry = [&](ELFYAML::CallGraphEntryWeight &E) {1137    E.Weight = Data.getU64(Cur);1138    if (!Cur) {1139      consumeError(Cur.takeError());1140      return false;1141    }1142    return true;1143  };1144 1145  for (ELFYAML::CallGraphEntryWeight &E : Entries) {1146    if (ReadEntry(E))1147      continue;1148    S->Content = yaml::BinaryRef(Content);1149    return S.release();1150  }1151 1152  S->Entries = std::move(Entries);1153  return S.release();1154}1155 1156template <class ELFT>1157Expected<ELFYAML::DynamicSection *>1158ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {1159  auto S = std::make_unique<ELFYAML::DynamicSection>();1160  if (Error E = dumpCommonSection(Shdr, *S))1161    return std::move(E);1162 1163  auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(*Shdr);1164  if (!DynTagsOrErr)1165    return DynTagsOrErr.takeError();1166 1167  S->Entries.emplace();1168  for (const Elf_Dyn &Dyn : *DynTagsOrErr)1169    S->Entries->push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});1170 1171  return S.release();1172}1173 1174template <class ELFT>1175Expected<ELFYAML::RelocationSection *>1176ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {1177  auto S = std::make_unique<ELFYAML::RelocationSection>();1178  if (auto E = dumpCommonRelocationSection(Shdr, *S))1179    return std::move(E);1180 1181  auto SymTabOrErr = Obj.getSection(Shdr->sh_link);1182  if (!SymTabOrErr)1183    return SymTabOrErr.takeError();1184 1185  if (Shdr->sh_size != 0)1186    S->Relocations.emplace();1187 1188  std::vector<Elf_Rel> Rels;1189  std::vector<Elf_Rela> Relas;1190  if (Shdr->sh_type == ELF::SHT_CREL) {1191    Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);1192    if (!ContentOrErr)1193      return ContentOrErr.takeError();1194    auto Crel = Obj.decodeCrel(*ContentOrErr);1195    if (!Crel)1196      return Crel.takeError();1197    Rels = std::move(Crel->first);1198    Relas = std::move(Crel->second);1199  } else if (Shdr->sh_type == ELF::SHT_REL) {1200    auto R = Obj.rels(*Shdr);1201    if (!R)1202      return R.takeError();1203    Rels = std::move(*R);1204  } else {1205    auto R = Obj.relas(*Shdr);1206    if (!R)1207      return R.takeError();1208    Relas = std::move(*R);1209  }1210 1211  for (const Elf_Rel &Rel : Rels) {1212    ELFYAML::Relocation R;1213    if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))1214      return std::move(E);1215    S->Relocations->push_back(R);1216  }1217  for (const Elf_Rela &Rel : Relas) {1218    ELFYAML::Relocation R;1219    if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))1220      return std::move(E);1221    R.Addend = Rel.r_addend;1222    S->Relocations->push_back(R);1223  }1224 1225  return S.release();1226}1227 1228template <class ELFT>1229Expected<ELFYAML::RelrSection *>1230ELFDumper<ELFT>::dumpRelrSection(const Elf_Shdr *Shdr) {1231  auto S = std::make_unique<ELFYAML::RelrSection>();1232  if (auto E = dumpCommonSection(Shdr, *S))1233    return std::move(E);1234 1235  if (Expected<ArrayRef<Elf_Relr>> Relrs = Obj.relrs(*Shdr)) {1236    S->Entries.emplace();1237    for (Elf_Relr Rel : *Relrs)1238      S->Entries->emplace_back(Rel);1239    return S.release();1240  } else {1241    // Ignore. We are going to dump the data as raw content below.1242    consumeError(Relrs.takeError());1243  }1244 1245  Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);1246  if (!ContentOrErr)1247    return ContentOrErr.takeError();1248  S->Content = *ContentOrErr;1249  return S.release();1250}1251 1252template <class ELFT>1253Expected<ELFYAML::RawContentSection *>1254ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {1255  auto S = std::make_unique<ELFYAML::RawContentSection>();1256  if (Error E = dumpCommonSection(Shdr, *S))1257    return std::move(E);1258 1259  unsigned SecIndex = Shdr - &Sections[0];1260  if (SecIndex != 0 || Shdr->sh_type != ELF::SHT_NULL) {1261    auto ContentOrErr = Obj.getSectionContents(*Shdr);1262    if (!ContentOrErr)1263      return ContentOrErr.takeError();1264    ArrayRef<uint8_t> Content = *ContentOrErr;1265    if (!Content.empty())1266      S->Content = yaml::BinaryRef(Content);1267  } else {1268    S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);1269  }1270 1271  if (Shdr->sh_info)1272    S->Info = static_cast<llvm::yaml::Hex64>(Shdr->sh_info);1273  return S.release();1274}1275 1276template <class ELFT>1277Expected<ELFYAML::SymtabShndxSection *>1278ELFDumper<ELFT>::dumpSymtabShndxSection(const Elf_Shdr *Shdr) {1279  auto S = std::make_unique<ELFYAML::SymtabShndxSection>();1280  if (Error E = dumpCommonSection(Shdr, *S))1281    return std::move(E);1282 1283  auto EntriesOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(*Shdr);1284  if (!EntriesOrErr)1285    return EntriesOrErr.takeError();1286 1287  S->Entries.emplace();1288  llvm::append_range(*S->Entries, *EntriesOrErr);1289  return S.release();1290}1291 1292template <class ELFT>1293Expected<ELFYAML::NoBitsSection *>1294ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {1295  auto S = std::make_unique<ELFYAML::NoBitsSection>();1296  if (Error E = dumpCommonSection(Shdr, *S))1297    return std::move(E);1298  if (Shdr->sh_size)1299    S->Size = static_cast<llvm::yaml::Hex64>(Shdr->sh_size);1300  return S.release();1301}1302 1303template <class ELFT>1304Expected<ELFYAML::NoteSection *>1305ELFDumper<ELFT>::dumpNoteSection(const Elf_Shdr *Shdr) {1306  auto S = std::make_unique<ELFYAML::NoteSection>();1307  if (Error E = dumpCommonSection(Shdr, *S))1308    return std::move(E);1309 1310  auto ContentOrErr = Obj.getSectionContents(*Shdr);1311  if (!ContentOrErr)1312    return ContentOrErr.takeError();1313 1314  std::vector<ELFYAML::NoteEntry> Entries;1315  ArrayRef<uint8_t> Content = *ContentOrErr;1316  size_t Align = std::max<size_t>(Shdr->sh_addralign, 4);1317  while (!Content.empty()) {1318    if (Content.size() < sizeof(Elf_Nhdr)) {1319      S->Content = yaml::BinaryRef(*ContentOrErr);1320      return S.release();1321    }1322 1323    const Elf_Nhdr *Header = reinterpret_cast<const Elf_Nhdr *>(Content.data());1324    if (Content.size() < Header->getSize(Align)) {1325      S->Content = yaml::BinaryRef(*ContentOrErr);1326      return S.release();1327    }1328 1329    Elf_Note Note(*Header);1330    Entries.push_back(1331        {Note.getName(), Note.getDesc(Align), (ELFYAML::ELF_NT)Note.getType()});1332 1333    Content = Content.drop_front(Header->getSize(Align));1334  }1335 1336  S->Notes = std::move(Entries);1337  return S.release();1338}1339 1340template <class ELFT>1341Expected<ELFYAML::HashSection *>1342ELFDumper<ELFT>::dumpHashSection(const Elf_Shdr *Shdr) {1343  auto S = std::make_unique<ELFYAML::HashSection>();1344  if (Error E = dumpCommonSection(Shdr, *S))1345    return std::move(E);1346 1347  auto ContentOrErr = Obj.getSectionContents(*Shdr);1348  if (!ContentOrErr)1349    return ContentOrErr.takeError();1350 1351  ArrayRef<uint8_t> Content = *ContentOrErr;1352  if (Content.size() % 4 != 0 || Content.size() < 8) {1353    S->Content = yaml::BinaryRef(Content);1354    return S.release();1355  }1356 1357  DataExtractor::Cursor Cur(0);1358  DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0);1359  uint64_t NBucket = Data.getU32(Cur);1360  uint64_t NChain = Data.getU32(Cur);1361  if (Content.size() != (2 + NBucket + NChain) * 4) {1362    S->Content = yaml::BinaryRef(Content);1363    if (Cur)1364      return S.release();1365    llvm_unreachable("entries were not read correctly");1366  }1367 1368  S->Bucket.emplace(NBucket);1369  for (uint32_t &V : *S->Bucket)1370    V = Data.getU32(Cur);1371 1372  S->Chain.emplace(NChain);1373  for (uint32_t &V : *S->Chain)1374    V = Data.getU32(Cur);1375 1376  if (Cur)1377    return S.release();1378  llvm_unreachable("entries were not read correctly");1379}1380 1381template <class ELFT>1382Expected<ELFYAML::GnuHashSection *>1383ELFDumper<ELFT>::dumpGnuHashSection(const Elf_Shdr *Shdr) {1384  auto S = std::make_unique<ELFYAML::GnuHashSection>();1385  if (Error E = dumpCommonSection(Shdr, *S))1386    return std::move(E);1387 1388  auto ContentOrErr = Obj.getSectionContents(*Shdr);1389  if (!ContentOrErr)1390    return ContentOrErr.takeError();1391 1392  unsigned AddrSize = ELFT::Is64Bits ? 8 : 4;1393  ArrayRef<uint8_t> Content = *ContentOrErr;1394  DataExtractor Data(Content, Obj.isLE(), AddrSize);1395 1396  ELFYAML::GnuHashHeader Header;1397  DataExtractor::Cursor Cur(0);1398  uint64_t NBuckets = Data.getU32(Cur);1399  Header.SymNdx = Data.getU32(Cur);1400  uint64_t MaskWords = Data.getU32(Cur);1401  Header.Shift2 = Data.getU32(Cur);1402 1403  // Set just the raw binary content if we were unable to read the header1404  // or when the section data is truncated or malformed.1405  uint64_t Size = Data.getData().size() - Cur.tell();1406  if (!Cur || (Size < MaskWords * AddrSize + NBuckets * 4) ||1407      (Size % 4 != 0)) {1408    consumeError(Cur.takeError());1409    S->Content = yaml::BinaryRef(Content);1410    return S.release();1411  }1412 1413  S->Header = Header;1414 1415  S->BloomFilter.emplace(MaskWords);1416  for (llvm::yaml::Hex64 &Val : *S->BloomFilter)1417    Val = Data.getAddress(Cur);1418 1419  S->HashBuckets.emplace(NBuckets);1420  for (llvm::yaml::Hex32 &Val : *S->HashBuckets)1421    Val = Data.getU32(Cur);1422 1423  S->HashValues.emplace((Data.getData().size() - Cur.tell()) / 4);1424  for (llvm::yaml::Hex32 &Val : *S->HashValues)1425    Val = Data.getU32(Cur);1426 1427  if (Cur)1428    return S.release();1429  llvm_unreachable("GnuHashSection was not read correctly");1430}1431 1432template <class ELFT>1433Expected<ELFYAML::VerdefSection *>1434ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {1435  auto S = std::make_unique<ELFYAML::VerdefSection>();1436  if (Error E = dumpCommonSection(Shdr, *S))1437    return std::move(E);1438 1439  auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);1440  if (!StringTableShdrOrErr)1441    return StringTableShdrOrErr.takeError();1442 1443  auto StringTableOrErr = Obj.getStringTable(**StringTableShdrOrErr);1444  if (!StringTableOrErr)1445    return StringTableOrErr.takeError();1446 1447  auto Contents = Obj.getSectionContents(*Shdr);1448  if (!Contents)1449    return Contents.takeError();1450 1451  S->Entries.emplace();1452 1453  llvm::ArrayRef<uint8_t> Data = *Contents;1454  const uint8_t *Buf = Data.data();1455  while (Buf) {1456    const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);1457    ELFYAML::VerdefEntry Entry;1458    if (Verdef->vd_version != 1)1459      return createStringError(errc::invalid_argument,1460                               "invalid SHT_GNU_verdef section version: " +1461                                   Twine(Verdef->vd_version));1462 1463    if (Verdef->vd_flags != 0)1464      Entry.Flags = Verdef->vd_flags;1465 1466    if (Verdef->vd_ndx != 0)1467      Entry.VersionNdx = Verdef->vd_ndx;1468 1469    if (Verdef->vd_hash != 0)1470      Entry.Hash = Verdef->vd_hash;1471 1472    if (Verdef->vd_aux != sizeof(Elf_Verdef))1473      Entry.VDAux = Verdef->vd_aux;1474 1475    const uint8_t *BufAux = Buf + Verdef->vd_aux;1476    if (BufAux > Data.end())1477      return createStringError(1478          errc::invalid_argument,1479          "corrupted section: vd_aux value " + Twine(Verdef->vd_aux) +1480              " in section verdef points past end of the section");1481    while (BufAux) {1482      const Elf_Verdaux *Verdaux =1483          reinterpret_cast<const Elf_Verdaux *>(BufAux);1484      Entry.VerNames.push_back(1485          StringTableOrErr->drop_front(Verdaux->vda_name).data());1486      BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;1487    }1488 1489    S->Entries->push_back(Entry);1490    Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;1491  }1492 1493  if (Shdr->sh_info != S->Entries->size())1494    S->Info = (llvm::yaml::Hex64)Shdr->sh_info;1495 1496  return S.release();1497}1498 1499template <class ELFT>1500Expected<ELFYAML::SymverSection *>1501ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {1502  auto S = std::make_unique<ELFYAML::SymverSection>();1503  if (Error E = dumpCommonSection(Shdr, *S))1504    return std::move(E);1505 1506  auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(*Shdr);1507  if (!VersionsOrErr)1508    return VersionsOrErr.takeError();1509 1510  S->Entries.emplace();1511  llvm::append_range(*S->Entries, *VersionsOrErr);1512 1513  return S.release();1514}1515 1516template <class ELFT>1517Expected<ELFYAML::VerneedSection *>1518ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {1519  auto S = std::make_unique<ELFYAML::VerneedSection>();1520  if (Error E = dumpCommonSection(Shdr, *S))1521    return std::move(E);1522 1523  auto Contents = Obj.getSectionContents(*Shdr);1524  if (!Contents)1525    return Contents.takeError();1526 1527  auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);1528  if (!StringTableShdrOrErr)1529    return StringTableShdrOrErr.takeError();1530 1531  auto StringTableOrErr = Obj.getStringTable(**StringTableShdrOrErr);1532  if (!StringTableOrErr)1533    return StringTableOrErr.takeError();1534 1535  S->VerneedV.emplace();1536 1537  llvm::ArrayRef<uint8_t> Data = *Contents;1538  const uint8_t *Buf = Data.data();1539  while (Buf) {1540    const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);1541 1542    ELFYAML::VerneedEntry Entry;1543    Entry.Version = Verneed->vn_version;1544    Entry.File =1545        StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data());1546 1547    const uint8_t *BufAux = Buf + Verneed->vn_aux;1548    while (BufAux) {1549      const Elf_Vernaux *Vernaux =1550          reinterpret_cast<const Elf_Vernaux *>(BufAux);1551 1552      ELFYAML::VernauxEntry Aux;1553      Aux.Hash = Vernaux->vna_hash;1554      Aux.Flags = Vernaux->vna_flags;1555      Aux.Other = Vernaux->vna_other;1556      Aux.Name =1557          StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data());1558 1559      Entry.AuxV.push_back(Aux);1560      BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;1561    }1562 1563    S->VerneedV->push_back(Entry);1564    Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;1565  }1566 1567  if (Shdr->sh_info != S->VerneedV->size())1568    S->Info = (llvm::yaml::Hex64)Shdr->sh_info;1569 1570  return S.release();1571}1572 1573template <class ELFT>1574Expected<StringRef> ELFDumper<ELFT>::getSymbolName(uint32_t SymtabNdx,1575                                                   uint32_t SymbolNdx) {1576  auto SymtabOrErr = Obj.getSection(SymtabNdx);1577  if (!SymtabOrErr)1578    return SymtabOrErr.takeError();1579 1580  const Elf_Shdr *Symtab = *SymtabOrErr;1581  auto SymOrErr = Obj.getSymbol(Symtab, SymbolNdx);1582  if (!SymOrErr)1583    return SymOrErr.takeError();1584 1585  auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);1586  if (!StrTabOrErr)1587    return StrTabOrErr.takeError();1588  return getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);1589}1590 1591template <class ELFT>1592Expected<ELFYAML::GroupSection *>1593ELFDumper<ELFT>::dumpGroupSection(const Elf_Shdr *Shdr) {1594  auto S = std::make_unique<ELFYAML::GroupSection>();1595  if (Error E = dumpCommonSection(Shdr, *S))1596    return std::move(E);1597 1598  // Get symbol with index sh_info. This symbol's name is the signature of the group.1599  Expected<StringRef> SymbolName = getSymbolName(Shdr->sh_link, Shdr->sh_info);1600  if (!SymbolName)1601    return SymbolName.takeError();1602  S->Signature = *SymbolName;1603 1604  auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(*Shdr);1605  if (!MembersOrErr)1606    return MembersOrErr.takeError();1607 1608  S->Members.emplace();1609  for (Elf_Word Member : *MembersOrErr) {1610    if (Member == llvm::ELF::GRP_COMDAT) {1611      S->Members->push_back({"GRP_COMDAT"});1612      continue;1613    }1614 1615    Expected<const Elf_Shdr *> SHdrOrErr = Obj.getSection(Member);1616    if (!SHdrOrErr)1617      return SHdrOrErr.takeError();1618    Expected<StringRef> NameOrErr = getUniquedSectionName(**SHdrOrErr);1619    if (!NameOrErr)1620      return NameOrErr.takeError();1621    S->Members->push_back({*NameOrErr});1622  }1623  return S.release();1624}1625 1626template <class ELFT>1627Expected<ELFYAML::ARMIndexTableSection *>1628ELFDumper<ELFT>::dumpARMIndexTableSection(const Elf_Shdr *Shdr) {1629  auto S = std::make_unique<ELFYAML::ARMIndexTableSection>();1630  if (Error E = dumpCommonSection(Shdr, *S))1631    return std::move(E);1632 1633  Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);1634  if (!ContentOrErr)1635    return ContentOrErr.takeError();1636 1637  if (ContentOrErr->size() % (sizeof(Elf_Word) * 2) != 0) {1638    S->Content = yaml::BinaryRef(*ContentOrErr);1639    return S.release();1640  }1641 1642  ArrayRef<Elf_Word> Words(1643      reinterpret_cast<const Elf_Word *>(ContentOrErr->data()),1644      ContentOrErr->size() / sizeof(Elf_Word));1645 1646  S->Entries.emplace();1647  for (size_t I = 0, E = Words.size(); I != E; I += 2)1648    S->Entries->push_back({(yaml::Hex32)Words[I], (yaml::Hex32)Words[I + 1]});1649 1650  return S.release();1651}1652 1653template <class ELFT>1654Expected<ELFYAML::MipsABIFlags *>1655ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {1656  assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&1657         "Section type is not SHT_MIPS_ABIFLAGS");1658  auto S = std::make_unique<ELFYAML::MipsABIFlags>();1659  if (Error E = dumpCommonSection(Shdr, *S))1660    return std::move(E);1661 1662  auto ContentOrErr = Obj.getSectionContents(*Shdr);1663  if (!ContentOrErr)1664    return ContentOrErr.takeError();1665 1666  auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(1667      ContentOrErr.get().data());1668  S->Version = Flags->version;1669  S->ISALevel = Flags->isa_level;1670  S->ISARevision = Flags->isa_rev;1671  S->GPRSize = Flags->gpr_size;1672  S->CPR1Size = Flags->cpr1_size;1673  S->CPR2Size = Flags->cpr2_size;1674  S->FpABI = Flags->fp_abi;1675  S->ISAExtension = Flags->isa_ext;1676  S->ASEs = Flags->ases;1677  S->Flags1 = Flags->flags1;1678  S->Flags2 = Flags->flags2;1679  return S.release();1680}1681 1682template <class ELFT>1683static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj,1684                      std::unique_ptr<DWARFContext> DWARFCtx) {1685  ELFDumper<ELFT> Dumper(Obj, std::move(DWARFCtx));1686  Expected<ELFYAML::Object *> YAMLOrErr = Dumper.dump();1687  if (!YAMLOrErr)1688    return YAMLOrErr.takeError();1689 1690  std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());1691  yaml::Output Yout(Out);1692  Yout << *YAML;1693 1694  return Error::success();1695}1696 1697Error elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {1698  std::unique_ptr<DWARFContext> DWARFCtx = DWARFContext::create(Obj);1699  if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))1700    return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));1701 1702  if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))1703    return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));1704 1705  if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))1706    return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));1707 1708  if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))1709    return elf2yaml(Out, ELFObj->getELFFile(), std::move(DWARFCtx));1710 1711  llvm_unreachable("unknown ELF file format");1712}1713