summaryrefslogtreecommitdiffstats
path: root/llvm/tools/obj2yaml/elf2yaml.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/obj2yaml/elf2yaml.cpp')
-rw-r--r--llvm/tools/obj2yaml/elf2yaml.cpp65
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>();
OpenPOWER on IntegriCloud