diff options
Diffstat (limited to 'llvm/tools/obj2yaml/elf2yaml.cpp')
-rw-r--r-- | llvm/tools/obj2yaml/elf2yaml.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index a3fe811b9d5..cb18e1820df 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -57,6 +57,7 @@ class ELFDumper { ErrorOr<ELFYAML::RawContentSection *> dumpContentSection(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr); + ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr); @@ -184,6 +185,13 @@ template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() { Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); break; } + case ELF::SHT_GNU_verneed: { + ErrorOr<ELFYAML::VerneedSection *> S = dumpVerneedSection(&Sec); + if (std::error_code EC = S.getError()) + return EC; + Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); + break; + } default: { ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec); if (std::error_code EC = S.getError()) @@ -444,6 +452,63 @@ ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) { } template <class ELFT> +ErrorOr<ELFYAML::VerneedSection *> +ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) { + typedef typename ELFT::Verneed Elf_Verneed; + typedef typename ELFT::Vernaux Elf_Vernaux; + + auto S = make_unique<ELFYAML::VerneedSection>(); + if (std::error_code EC = dumpCommonSection(Shdr, *S)) + return EC; + + S->Info = Shdr->sh_info; + + auto Contents = Obj.getSectionContents(Shdr); + if (!Contents) + return errorToErrorCode(Contents.takeError()); + + auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link); + if (!StringTableShdrOrErr) + return errorToErrorCode(StringTableShdrOrErr.takeError()); + + auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr); + if (!StringTableOrErr) + return errorToErrorCode(StringTableOrErr.takeError()); + + llvm::ArrayRef<uint8_t> Data = *Contents; + const uint8_t *Buf = Data.data(); + while (Buf) { + const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf); + + ELFYAML::VerneedEntry Entry; + Entry.Version = Verneed->vn_version; + Entry.File = + StringRef(StringTableOrErr->drop_front(Verneed->vn_file).data()); + + const uint8_t *BufAux = Buf + Verneed->vn_aux; + while (BufAux) { + const Elf_Vernaux *Vernaux = + reinterpret_cast<const Elf_Vernaux *>(BufAux); + + ELFYAML::VernauxEntry Aux; + Aux.Hash = Vernaux->vna_hash; + Aux.Flags = Vernaux->vna_flags; + Aux.Other = Vernaux->vna_other; + Aux.Name = + StringRef(StringTableOrErr->drop_front(Vernaux->vna_name).data()); + + Entry.AuxV.push_back(Aux); + BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr; + } + + S->VerneedV.push_back(Entry); + Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr; + } + + return S.release(); +} + +template <class ELFT> ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { auto S = make_unique<ELFYAML::Group>(); |