diff options
| author | George Rimar <grimar@accesssoftek.com> | 2019-02-21 12:21:43 +0000 |
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2019-02-21 12:21:43 +0000 |
| commit | 623ae72ad46d378d6a2e40abf67d3c5e627bef7c (patch) | |
| tree | 4baa8da9fe68fe64a574bc6f6c3d4f0e702c40ed /llvm/tools/obj2yaml | |
| parent | b173d75c49afdc9a41507a2018d71476a9c0d198 (diff) | |
| download | bcm5719-llvm-623ae72ad46d378d6a2e40abf67d3c5e627bef7c.tar.gz bcm5719-llvm-623ae72ad46d378d6a2e40abf67d3c5e627bef7c.zip | |
[yaml2obj][obj2yaml] - Support SHT_GNU_verdef (.gnu.version_d) section.
This patch adds support for parsing/dumping the .gnu.version section.
Description of the section is: https://refspecs.linuxfoundation.org/LSB_1.3.0/gLSB/gLSB/symverdefs.html
Differential revision: https://reviews.llvm.org/D58437
llvm-svn: 354574
Diffstat (limited to 'llvm/tools/obj2yaml')
| -rw-r--r-- | llvm/tools/obj2yaml/elf2yaml.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index d593ef03acc..b02c25ad153 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::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr); @@ -186,6 +187,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_verdef: { + ErrorOr<ELFYAML::VerdefSection *> S = dumpVerdefSection(&Sec); + if (std::error_code EC = S.getError()) + return EC; + Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get())); + break; + } case ELF::SHT_GNU_versym: { ErrorOr<ELFYAML::SymverSection *> S = dumpSymverSection(&Sec); if (std::error_code EC = S.getError()) @@ -460,6 +468,56 @@ ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) { } template <class ELFT> +ErrorOr<ELFYAML::VerdefSection *> +ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) { + typedef typename ELFT::Verdef Elf_Verdef; + typedef typename ELFT::Verdaux Elf_Verdaux; + + auto S = make_unique<ELFYAML::VerdefSection>(); + if (std::error_code EC = dumpCommonSection(Shdr, *S)) + return EC; + + S->Info = Shdr->sh_info; + + auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link); + if (!StringTableShdrOrErr) + return errorToErrorCode(StringTableShdrOrErr.takeError()); + + auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr); + if (!StringTableOrErr) + return errorToErrorCode(StringTableOrErr.takeError()); + + auto Contents = Obj.getSectionContents(Shdr); + if (!Contents) + return errorToErrorCode(Contents.takeError()); + + llvm::ArrayRef<uint8_t> Data = *Contents; + const uint8_t *Buf = Data.data(); + while (Buf) { + const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf); + ELFYAML::VerdefEntry Entry; + Entry.Version = Verdef->vd_version; + Entry.Flags = Verdef->vd_flags; + Entry.VersionNdx = Verdef->vd_ndx; + Entry.Hash = Verdef->vd_hash; + + const uint8_t *BufAux = Buf + Verdef->vd_aux; + while (BufAux) { + const Elf_Verdaux *Verdaux = + reinterpret_cast<const Elf_Verdaux *>(BufAux); + Entry.VerNames.push_back( + StringTableOrErr->drop_front(Verdaux->vda_name).data()); + BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr; + } + + S->Entries.push_back(Entry); + Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr; + } + + return S.release(); +} + +template <class ELFT> ErrorOr<ELFYAML::SymverSection *> ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) { typedef typename ELFT::Half Elf_Half; |

