summaryrefslogtreecommitdiffstats
path: root/llvm/tools/obj2yaml
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2019-02-21 12:21:43 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2019-02-21 12:21:43 +0000
commit623ae72ad46d378d6a2e40abf67d3c5e627bef7c (patch)
tree4baa8da9fe68fe64a574bc6f6c3d4f0e702c40ed /llvm/tools/obj2yaml
parentb173d75c49afdc9a41507a2018d71476a9c0d198 (diff)
downloadbcm5719-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.cpp58
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;
OpenPOWER on IntegriCloud