Index: test/tools/llvm-readobj/elf-versioninfo.test =================================================================== --- test/tools/llvm-readobj/elf-versioninfo.test +++ test/tools/llvm-readobj/elf-versioninfo.test @@ -47,40 +47,38 @@ 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: SHT_GNU_verdef { +CHECK-NEXT: Definition { +CHECK-NEXT: Version: 1 +CHECK-NEXT: Flags: Base (0x1) +CHECK-NEXT: Index: 1 +CHECK-NEXT: Count: 1 +CHECK-NEXT: Hash: 430712 +CHECK-NEXT: Name: blah +CHECK-NEXT: Dependencies { +CHECK-NEXT: } +CHECK-NEXT: } +CHECK-NEXT: Definition { +CHECK-NEXT: Version: 1 +CHECK-NEXT: Flags: 0x0 +CHECK-NEXT: Index: 2 +CHECK-NEXT: Count: 1 +CHECK-NEXT: Hash: 175630257 +CHECK-NEXT: Name: VERSION1 +CHECK-NEXT: Dependencies { +CHECK-NEXT: } +CHECK-NEXT: } +CHECK-NEXT: Definition { +CHECK-NEXT: Version: 1 +CHECK-NEXT: Flags: 0x0 +CHECK-NEXT: Index: 3 +CHECK-NEXT: Count: 2 +CHECK-NEXT: Hash: 175630258 +CHECK-NEXT: Name: VERSION2 +CHECK-NEXT: Dependencies { +CHECK-NEXT: VERSION1 CHECK-NEXT: } -CHECK-NEXT: ] +CHECK-NEXT: } CHECK-NEXT: } RUN: llvm-readobj -V %p/Inputs/verneed.elf-x86-64 | FileCheck %s --check-prefix=VERNEED Index: tools/llvm-readobj/ELFDumper.cpp =================================================================== --- tools/llvm-readobj/ELFDumper.cpp +++ tools/llvm-readobj/ELFDumper.cpp @@ -530,21 +530,19 @@ 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; @@ -553,22 +551,31 @@ 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(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(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("Count", 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"); + + DictScope Dep(W, "Dependencies"); + const uint8_t *PAux = P + VD->vd_aux + VD->getAux()->vda_next; + for (unsigned J = 0; J < (unsigned)VD->vd_cnt - 1; ++J) { + const VerdAux *Aux = reinterpret_cast(PAux); + W.printString(StringRef( + (const char *)(Obj->base() + StrTab->sh_offset + Aux->vda_name))); + PAux += Aux->vda_next; + } + P += VD->vd_next; } }