Skip to content

Commit 85b50a7

Browse files
committed
[llvm-objdump] Add Version Definitions dumper
Summary: `llvm-objdump` needs a `Version Definitions` dumper. Reviewers: grimar, jhenderson Reviewed By: grimar, jhenderson Subscribers: rupprecht, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58615 llvm-svn: 354871
1 parent 2d3faad commit 85b50a7

File tree

2 files changed

+85
-3
lines changed

2 files changed

+85
-3
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# RUN: yaml2obj %s > %t
2+
# RUN: llvm-objdump -p %t | FileCheck --strict-whitespace %s
3+
4+
# CHECK: Version definitions:
5+
# CHECK-NEXT: 1 0x01 0x075bcd15 foo
6+
# CHECK-NEXT: 2 0x02 0x3ade68b1 VERSION_1
7+
# CHECK-NEXT: VERSION_2
8+
9+
--- !ELF
10+
FileHeader:
11+
Class: ELFCLASS64
12+
Data: ELFDATA2LSB
13+
Type: ET_DYN
14+
Machine: EM_X86_64
15+
Entry: 0x0000000000001000
16+
Sections:
17+
- Name: .gnu.version_d
18+
Type: SHT_GNU_verdef
19+
Flags: [ SHF_ALLOC ]
20+
Address: 0x0000000000000230
21+
Link: .dynstr
22+
AddressAlign: 0x0000000000000004
23+
Info: 0x0000000000000003
24+
Entries:
25+
- Version: 1
26+
Flags: 1
27+
VersionNdx: 1
28+
Hash: 123456789
29+
Names:
30+
- foo
31+
- Version: 1
32+
Flags: 2
33+
VersionNdx: 2
34+
Hash: 987654321
35+
Names:
36+
- VERSION_1
37+
- VERSION_2
38+
DynamicSymbols:
39+
Global:
40+
- Name: bar
41+
...

llvm/tools/llvm-objdump/ELFDump.cpp

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,43 @@ void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
297297
}
298298
}
299299

300+
template <class ELFT>
301+
void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
302+
ArrayRef<uint8_t> Contents,
303+
StringRef StrTab) {
304+
typedef ELFFile<ELFT> ELFO;
305+
typedef typename ELFO::Elf_Verdef Elf_Verdef;
306+
typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
307+
308+
outs() << "Version definitions:\n";
309+
310+
const uint8_t *Buf = Contents.data();
311+
uint32_t VerdefIndex = 1;
312+
// sh_info contains the number of entries in the SHT_GNU_verdef section. To
313+
// make the index column have consistent width, we should insert blank spaces
314+
// according to sh_info.
315+
uint16_t VerdefIndexWidth = std::to_string(Shdr.sh_info).size();
316+
while (Buf) {
317+
const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
318+
outs() << format_decimal(VerdefIndex++, VerdefIndexWidth) << " "
319+
<< format("0x%02" PRIx16 " ", (uint16_t)Verdef->vd_flags)
320+
<< format("0x%08" PRIx32 " ", (uint32_t)Verdef->vd_hash);
321+
322+
const uint8_t *BufAux = Buf + Verdef->vd_aux;
323+
uint16_t VerdauxIndex = 0;
324+
while (BufAux) {
325+
const Elf_Verdaux *Verdaux =
326+
reinterpret_cast<const Elf_Verdaux *>(BufAux);
327+
if (VerdauxIndex)
328+
outs() << std::string(VerdefIndexWidth + 17, ' ');
329+
outs() << StringRef(StrTab.drop_front(Verdaux->vda_name).data()) << '\n';
330+
BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
331+
++VerdauxIndex;
332+
}
333+
Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
334+
}
335+
}
336+
300337
template <class ELFT>
301338
void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
302339
typedef typename ELFT::Shdr Elf_Shdr;
@@ -306,7 +343,8 @@ void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
306343
report_error(FileName, SectionsOrError.takeError());
307344

308345
for (const Elf_Shdr &Shdr : *SectionsOrError) {
309-
if (Shdr.sh_type != ELF::SHT_GNU_verneed)
346+
if (Shdr.sh_type != ELF::SHT_GNU_verneed &&
347+
Shdr.sh_type != ELF::SHT_GNU_verdef)
310348
continue;
311349

312350
auto ContentsOrError = Elf->getSectionContents(&Shdr);
@@ -321,8 +359,11 @@ void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
321359
if (!StrTabOrError)
322360
report_error(FileName, StrTabOrError.takeError());
323361

324-
printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
325-
// TODO: Implement symbol version definitions dumper.
362+
if (Shdr.sh_type == ELF::SHT_GNU_verneed)
363+
printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
364+
else
365+
printSymbolVersionDefinition<ELFT>(Shdr, *ContentsOrError,
366+
*StrTabOrError);
326367
}
327368
}
328369

0 commit comments

Comments
 (0)