summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2016-06-07 11:04:49 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2016-06-07 11:04:49 +0000
commitcd36e182d2f408fd2949e809b3d20889a5bfa2e9 (patch)
tree42a902225bb22d986ae2024243bd6d26ae427add
parent353a2286e2325f28718501c64ac9139d1fdedd85 (diff)
downloadbcm5719-llvm-cd36e182d2f408fd2949e809b3d20889a5bfa2e9.tar.gz
bcm5719-llvm-cd36e182d2f408fd2949e809b3d20889a5bfa2e9.zip
[llvm-readobj] - Teach llvm-readobj to dump .gnu.version_r sections
SHT_GNU_verneed (.gnu.version_r) is a version dependency section. It was the last symbol versioning relative section that was not dumped, now it is. Differential revision: http://reviews.llvm.org/D21024 llvm-svn: 271998
-rw-r--r--llvm/test/tools/llvm-readobj/Inputs/verneed.elf-x86-64bin0 -> 13520 bytes
-rw-r--r--llvm/test/tools/llvm-readobj/elf-versioninfo.test33
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp55
3 files changed, 88 insertions, 0 deletions
diff --git a/llvm/test/tools/llvm-readobj/Inputs/verneed.elf-x86-64 b/llvm/test/tools/llvm-readobj/Inputs/verneed.elf-x86-64
new file mode 100644
index 00000000000..3a9c8d8df8d
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/Inputs/verneed.elf-x86-64
Binary files differ
diff --git a/llvm/test/tools/llvm-readobj/elf-versioninfo.test b/llvm/test/tools/llvm-readobj/elf-versioninfo.test
index e43d373e92f..c7c97b94344 100644
--- a/llvm/test/tools/llvm-readobj/elf-versioninfo.test
+++ b/llvm/test/tools/llvm-readobj/elf-versioninfo.test
@@ -82,3 +82,36 @@ CHECK-NEXT: Name: VERSION2
CHECK-NEXT: }
CHECK-NEXT: ]
CHECK-NEXT: }
+
+RUN: llvm-readobj -V %p/Inputs/verneed.elf-x86-64 | FileCheck %s --check-prefix=VERNEED
+
+VERNEED: SHT_GNU_verneed {
+VERNEED-NEXT: Dependency {
+VERNEED-NEXT: Version: 1
+VERNEED-NEXT: Count: 2
+VERNEED-NEXT: FileName: verneed1.so.0
+VERNEED-NEXT: Entry {
+VERNEED-NEXT: Hash: 1938
+VERNEED-NEXT: Flags: 0x0
+VERNEED-NEXT: Index: 3
+VERNEED-NEXT: Name: v2
+VERNEED-NEXT: }
+VERNEED-NEXT: Entry {
+VERNEED-NEXT: Hash: 1939
+VERNEED-NEXT: Flags: 0x0
+VERNEED-NEXT: Index: 2
+VERNEED-NEXT: Name: v3
+VERNEED-NEXT: }
+VERNEED-NEXT: }
+VERNEED-NEXT: Dependency {
+VERNEED-NEXT: Version: 1
+VERNEED-NEXT: Count: 1
+VERNEED-NEXT: FileName: verneed2.so.0
+VERNEED-NEXT: Entry {
+VERNEED-NEXT: Hash: 1937
+VERNEED-NEXT: Flags: 0x0
+VERNEED-NEXT: Index: 4
+VERNEED-NEXT: Name: v1
+VERNEED-NEXT: }
+VERNEED-NEXT: }
+VERNEED-NEXT: }
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index dfdd029a7f9..1f45b7986a6 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -520,6 +520,11 @@ static void printVersionSymbolSection(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
}
}
+static const EnumEntry<unsigned> SymVersionFlags[] = {
+ {"Base", "BASE", VER_FLG_BASE},
+ {"Weak", "WEAK", VER_FLG_WEAK},
+ {"Info", "INFO", VER_FLG_INFO}};
+
template <typename ELFO, class ELFT>
static void printVersionDefinitionSection(ELFDumper<ELFT> *Dumper,
const ELFO *Obj,
@@ -568,12 +573,62 @@ static void printVersionDefinitionSection(ELFDumper<ELFT> *Dumper,
}
}
+template <typename ELFO, class ELFT>
+static void printVersionDependencySection(ELFDumper<ELFT> *Dumper,
+ const ELFO *Obj,
+ const typename ELFO::Elf_Shdr *Sec,
+ ScopedPrinter &W) {
+ typedef typename ELFO::Elf_Verneed VerNeed;
+ typedef typename ELFO::Elf_Vernaux VernAux;
+
+ DictScope SD(W, "SHT_GNU_verneed");
+ if (!Sec)
+ return;
+
+ unsigned VerNeedNum = 0;
+ for (const typename ELFO::Elf_Dyn &Dyn : Dumper->dynamic_table())
+ if (Dyn.d_tag == DT_VERNEEDNUM)
+ VerNeedNum = Dyn.d_un.d_val;
+
+ const uint8_t *SecData = (const uint8_t *)Obj->base() + Sec->sh_offset;
+ const typename ELFO::Elf_Shdr *StrTab =
+ unwrapOrError(Obj->getSection(Sec->sh_link));
+
+ const uint8_t *P = SecData;
+ for (unsigned I = 0; I < VerNeedNum; ++I) {
+ const VerNeed *Need = reinterpret_cast<const VerNeed *>(P);
+ DictScope Entry(W, "Dependency");
+ W.printNumber("Version", Need->vn_version);
+ W.printNumber("Count", Need->vn_cnt);
+ W.printString("FileName",
+ StringRef((const char *)(Obj->base() + StrTab->sh_offset +
+ Need->vn_file)));
+
+ const uint8_t *PAux = P + Need->vn_aux;
+ for (unsigned J = 0; J < Need->vn_cnt; ++J) {
+ const VernAux *Aux = reinterpret_cast<const VernAux *>(PAux);
+ DictScope Entry(W, "Entry");
+ W.printNumber("Hash", Aux->vna_hash);
+ W.printEnum("Flags", Aux->vna_flags, makeArrayRef(SymVersionFlags));
+ W.printNumber("Index", Aux->vna_other);
+ W.printString("Name",
+ StringRef((const char *)(Obj->base() + StrTab->sh_offset +
+ Aux->vna_name)));
+ PAux += Aux->vna_next;
+ }
+ P += Need->vn_next;
+ }
+}
+
template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
// Dump version symbol section.
printVersionSymbolSection(this, Obj, dot_gnu_version_sec, W);
// Dump version definition section.
printVersionDefinitionSection(this, Obj, dot_gnu_version_d_sec, W);
+
+ // Dump version dependency section.
+ printVersionDependencySection(this, Obj, dot_gnu_version_r_sec, W);
}
template <typename ELFT>
OpenPOWER on IntegriCloud