CHECK-NEXT: ]
CHECK-NEXT: }
-CHECK: Version definition {
-CHECK-NEXT: Section Name: .gnu.version_d (70)
-CHECK-NEXT: Address: 0x25C
-CHECK-NEXT: Offset: 0x25C
-CHECK-NEXT: Link: 2
-CHECK-NEXT: Entries [
-CHECK-NEXT: Entry {
-CHECK-NEXT: Offset: 0x0
-CHECK-NEXT: Rev: 1
-CHECK-NEXT: Flags: 1
-CHECK-NEXT: Index: 1
-CHECK-NEXT: Cnt: 1
-CHECK-NEXT: Hash: 430712
-CHECK-NEXT: Name: blah
-CHECK-NEXT: }
-CHECK-NEXT: Entry {
-CHECK-NEXT: Offset: 0x1C
-CHECK-NEXT: Rev: 1
-CHECK-NEXT: Flags: 0
-CHECK-NEXT: Index: 2
-CHECK-NEXT: Cnt: 1
-CHECK-NEXT: Hash: 175630257
-CHECK-NEXT: Name: VERSION1
-CHECK-NEXT: }
-CHECK-NEXT: Entry {
-CHECK-NEXT: Offset: 0x38
-CHECK-NEXT: Rev: 1
-CHECK-NEXT: Flags: 0
-CHECK-NEXT: Index: 3
-CHECK-NEXT: Cnt: 2
-CHECK-NEXT: Hash: 175630258
-CHECK-NEXT: Name: VERSION2
-CHECK-NEXT: }
-CHECK-NEXT: ]
+CHECK: SHT_GNU_verdef {
+CHECK-NEXT: Definition {
+CHECK-NEXT: Version: 1
+CHECK-NEXT: Flags: Base (0x1)
+CHECK-NEXT: Index: 1
+CHECK-NEXT: Hash: 430712
+CHECK-NEXT: Name: blah
+CHECK-NEXT: }
+CHECK-NEXT: Definition {
+CHECK-NEXT: Version: 1
+CHECK-NEXT: Flags: 0x0
+CHECK-NEXT: Index: 2
+CHECK-NEXT: Hash: 175630257
+CHECK-NEXT: Name: VERSION1
+CHECK-NEXT: }
+CHECK-NEXT: Definition {
+CHECK-NEXT: Version: 1
+CHECK-NEXT: Flags: 0x0
+CHECK-NEXT: Index: 3
+CHECK-NEXT: Hash: 175630258
+CHECK-NEXT: Name: VERSION2
+CHECK-NEXT: Predecessor: VERSION1
+CHECK-NEXT: }
CHECK-NEXT: }
RUN: llvm-readobj -V %p/Inputs/verneed.elf-x86-64 | FileCheck %s --check-prefix=VERNEED
const ELFO *Obj,
const typename ELFO::Elf_Shdr *Sec,
ScopedPrinter &W) {
- DictScope SD(W, "Version definition");
+ typedef typename ELFO::Elf_Verdef VerDef;
+ typedef typename ELFO::Elf_Verdaux VerdAux;
+
+ DictScope SD(W, "SHT_GNU_verdef");
if (!Sec)
return;
- StringRef Name = unwrapOrError(Obj->getSectionName(Sec));
- W.printNumber("Section Name", Name, Sec->sh_name);
- W.printHex("Address", Sec->sh_addr);
- W.printHex("Offset", Sec->sh_offset);
- W.printNumber("Link", Sec->sh_link);
- unsigned verdef_entries = 0;
// The number of entries in the section SHT_GNU_verdef
// is determined by DT_VERDEFNUM tag.
+ unsigned VerDefsNum = 0;
for (const typename ELFO::Elf_Dyn &Dyn : Dumper->dynamic_table()) {
if (Dyn.d_tag == DT_VERDEFNUM)
- verdef_entries = Dyn.d_un.d_val;
+ VerDefsNum = Dyn.d_un.d_val;
}
const uint8_t *SecStartAddress =
(const uint8_t *)Obj->base() + Sec->sh_offset;
const typename ELFO::Elf_Shdr *StrTab =
unwrapOrError(Obj->getSection(Sec->sh_link));
- ListScope Entries(W, "Entries");
- for (unsigned i = 0; i < verdef_entries; ++i) {
- if (P + sizeof(typename ELFO::Elf_Verdef) > SecEndAddress)
+ while (VerDefsNum--) {
+ if (P + sizeof(VerDef) > SecEndAddress)
report_fatal_error("invalid offset in the section");
- auto *VD = reinterpret_cast<const typename ELFO::Elf_Verdef *>(P);
- DictScope Entry(W, "Entry");
- W.printHex("Offset", (uintptr_t)P - (uintptr_t)SecStartAddress);
- W.printNumber("Rev", VD->vd_version);
- // FIXME: print something more readable.
- W.printNumber("Flags", VD->vd_flags);
+
+ auto *VD = reinterpret_cast<const VerDef *>(P);
+ DictScope Def(W, "Definition");
+ W.printNumber("Version", VD->vd_version);
+ W.printEnum("Flags", VD->vd_flags, makeArrayRef(SymVersionFlags));
W.printNumber("Index", VD->vd_ndx);
- W.printNumber("Cnt", VD->vd_cnt);
W.printNumber("Hash", VD->vd_hash);
W.printString("Name",
StringRef((const char *)(Obj->base() + StrTab->sh_offset +
VD->getAux()->vda_name)));
+ if (!VD->vd_cnt)
+ report_fatal_error("at least one definition string must exist");
+ if (VD->vd_cnt > 2)
+ report_fatal_error("more than one predecessor is not expected");
+
+ if (VD->vd_cnt == 2) {
+ const uint8_t *PAux = P + VD->vd_aux + VD->getAux()->vda_next;
+ const VerdAux *Aux = reinterpret_cast<const VerdAux *>(PAux);
+ W.printString("Predecessor",
+ StringRef((const char *)(Obj->base() + StrTab->sh_offset +
+ Aux->vda_name)));
+ }
+
P += VD->vd_next;
}
}