diff options
Diffstat (limited to 'llvm/tools/obj2yaml/elf2yaml.cpp')
-rw-r--r-- | llvm/tools/obj2yaml/elf2yaml.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 7d05252a162..b70a5dd0784 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -63,6 +63,7 @@ class ELFDumper { Expected<ELFYAML::SymtabShndxSection *> dumpSymtabShndxSection(const Elf_Shdr *Shdr); Expected<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr); + Expected<ELFYAML::HashSection *> dumpHashSection(const Elf_Shdr *Shdr); Expected<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr); Expected<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr); Expected<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr); @@ -255,6 +256,13 @@ template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() { Y->Sections.emplace_back(*SecOrErr); break; } + case ELF::SHT_HASH: { + Expected<ELFYAML::HashSection *> SecOrErr = dumpHashSection(&Sec); + if (!SecOrErr) + return SecOrErr.takeError(); + Y->Sections.emplace_back(*SecOrErr); + break; + } case ELF::SHT_GNU_verdef: { Expected<ELFYAML::VerdefSection *> SecOrErr = dumpVerdefSection(&Sec); if (!SecOrErr) @@ -617,6 +625,45 @@ ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) { } template <class ELFT> +Expected<ELFYAML::HashSection *> +ELFDumper<ELFT>::dumpHashSection(const Elf_Shdr *Shdr) { + auto S = std::make_unique<ELFYAML::HashSection>(); + if (Error E = dumpCommonSection(Shdr, *S)) + return std::move(E); + + auto ContentOrErr = Obj.getSectionContents(Shdr); + if (!ContentOrErr) + return ContentOrErr.takeError(); + + ArrayRef<uint8_t> Content = *ContentOrErr; + if (Content.size() % 4 != 0 || Content.size() < 8) { + S->Content = yaml::BinaryRef(Content); + return S.release(); + } + + DataExtractor::Cursor Cur(0); + DataExtractor Data(Content, Obj.isLE(), /*AddressSize=*/0); + uint32_t NBucket = Data.getU32(Cur); + uint32_t NChain = Data.getU32(Cur); + if (Content.size() != (2 + NBucket + NChain) * 4) { + S->Content = yaml::BinaryRef(Content); + return S.release(); + } + + S->Bucket.emplace(NBucket); + for (uint32_t &V : *S->Bucket) + V = Data.getU32(Cur); + + S->Chain.emplace(NChain); + for (uint32_t &V : *S->Chain) + V = Data.getU32(Cur); + + if (!Cur) + llvm_unreachable("entries were not read correctly"); + return S.release(); +} + +template <class ELFT> Expected<ELFYAML::VerdefSection *> ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) { typedef typename ELFT::Verdef Elf_Verdef; |