mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-13 22:58:50 +00:00
[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
This commit is contained in:
parent
d64bc3ec0b
commit
37a7f50a87
BIN
test/tools/llvm-readobj/Inputs/verneed.elf-x86-64
Normal file
BIN
test/tools/llvm-readobj/Inputs/verneed.elf-x86-64
Normal file
Binary file not shown.
@ -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: }
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user