[llvm-objdump] Add `Version References` dumper
Summary: Add symbol version dumper for [#30241](https://bugs.llvm.org/show_bug.cgi?id=30241)
Reviewers: jhenderson, MaskRay, kristina, emaste, grimar
Reviewed By: jhenderson, grimar
Subscribers: grimar, rupprecht, jakehehrlich, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D54697
llvm-svn: 354782
diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp
index 7157469..0ca0e0d 100644
--- a/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -267,6 +267,65 @@
outs() << "\n";
}
+template <class ELFT>
+void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
+ StringRef StrTab) {
+ typedef ELFFile<ELFT> ELFO;
+ typedef typename ELFO::Elf_Verneed Elf_Verneed;
+ typedef typename ELFO::Elf_Vernaux Elf_Vernaux;
+
+ outs() << "Version References:\n";
+
+ const uint8_t *Buf = Contents.data();
+ while (Buf) {
+ const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
+ outs() << " required from "
+ << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n";
+
+ const uint8_t *BufAux = Buf + Verneed->vn_aux;
+ while (BufAux) {
+ const Elf_Vernaux *Vernaux =
+ reinterpret_cast<const Elf_Vernaux *>(BufAux);
+ outs() << " "
+ << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash)
+ << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags)
+ << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other)
+ << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n';
+ BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
+ }
+ Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
+ }
+}
+
+template <class ELFT>
+void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
+ typedef typename ELFT::Shdr Elf_Shdr;
+
+ auto SectionsOrError = Elf->sections();
+ if (!SectionsOrError)
+ report_error(FileName, SectionsOrError.takeError());
+
+ for (const Elf_Shdr &Shdr : *SectionsOrError) {
+ if (Shdr.sh_type != ELF::SHT_GNU_verneed)
+ continue;
+
+ auto ContentsOrError = Elf->getSectionContents(&Shdr);
+ if (!ContentsOrError)
+ report_error(FileName, ContentsOrError.takeError());
+
+ auto StrTabSecOrError = Elf->getSection(Shdr.sh_link);
+ if (!StrTabSecOrError)
+ report_error(FileName, StrTabSecOrError.takeError());
+
+ auto StrTabOrError = Elf->getStringTable(*StrTabSecOrError);
+ if (!StrTabOrError)
+ report_error(FileName, StrTabOrError.takeError());
+
+ printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
+ // TODO: Implement symbol version definitions dumper.
+ }
+}
+
void llvm::printELFFileHeader(const object::ObjectFile *Obj) {
if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
printProgramHeaders(ELFObj->getELFFile());
@@ -288,3 +347,14 @@
else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
}
+
+void llvm::printELFSymbolVersionInfo(const object::ObjectFile *Obj) {
+ if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
+ printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
+ else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
+ printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
+ else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
+ printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
+ else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
+ printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
+}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index e75db92..e9d1545 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1887,7 +1887,9 @@
static void printPrivateFileHeaders(const ObjectFile *O, bool OnlyFirst) {
if (O->isELF()) {
printELFFileHeader(O);
- return printELFDynamicSection(O);
+ printELFDynamicSection(O);
+ printELFSymbolVersionInfo(O);
+ return;
}
if (O->isCOFF())
return printCOFFFileHeader(O);
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index e559b72..e4c51e6 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -153,6 +153,7 @@
void printMachOWeakBindTable(object::MachOObjectFile *O);
void printELFFileHeader(const object::ObjectFile *O);
void printELFDynamicSection(const object::ObjectFile *Obj);
+void printELFSymbolVersionInfo(const object::ObjectFile *Obj);
void printCOFFFileHeader(const object::ObjectFile *O);
void printCOFFSymbolTable(const object::COFFImportFile *I);
void printCOFFSymbolTable(const object::COFFObjectFile *O);