[llvm-readobj] Add GNU style dumper for .gnu.version section
Summary: Currently, `llvm-readobj` do not support GNU style dumper for symbol versioning sections. In this patch, I would like to implement dumper for `.gnu.version` section Reviewers: jhenderson, rupprecht, grimar Reviewed By: jhenderson, rupprecht Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59877 llvm-svn: 357578
This commit is contained in:
parent
884c29e9ae
commit
8f6166a72e
|
@ -0,0 +1,42 @@
|
||||||
|
# RUN: yaml2obj %s -o %t
|
||||||
|
# RUN: llvm-readelf -V %t | FileCheck %s --check-prefix=HIDDEN
|
||||||
|
|
||||||
|
# HIDDEN: Version symbols section '.gnu.version' contains 2 entries:
|
||||||
|
# HIDDEN-NEXT: Addr: 0000000000200210 Offset: 0x000240 Link: 6 (.dynsym)
|
||||||
|
# HIDDEN-NEXT: 000: 0 (*local*) 3h(hiddensym)
|
||||||
|
|
||||||
|
--- !ELF
|
||||||
|
FileHeader:
|
||||||
|
Class: ELFCLASS64
|
||||||
|
Data: ELFDATA2LSB
|
||||||
|
Type: ET_EXEC
|
||||||
|
Machine: EM_X86_64
|
||||||
|
Entry: 0x0000000000201000
|
||||||
|
Sections:
|
||||||
|
- Name: .gnu.version
|
||||||
|
Type: SHT_GNU_versym
|
||||||
|
Flags: [ SHF_ALLOC ]
|
||||||
|
Address: 0x0000000000200210
|
||||||
|
Link: .dynsym
|
||||||
|
AddressAlign: 0x0000000000000002
|
||||||
|
EntSize: 0x0000000000000002
|
||||||
|
Entries: [ 0, 0x8003 ]
|
||||||
|
- Name: .gnu.version_r
|
||||||
|
Type: SHT_GNU_verneed
|
||||||
|
Flags: [ SHF_ALLOC ]
|
||||||
|
Address: 0x0000000000200250
|
||||||
|
Link: .dynstr
|
||||||
|
AddressAlign: 0x0000000000000004
|
||||||
|
Info: 0x0000000000000001
|
||||||
|
Dependencies:
|
||||||
|
- Version: 1
|
||||||
|
File: somefile
|
||||||
|
Entries:
|
||||||
|
- Name: hiddensym
|
||||||
|
Hash: 1234
|
||||||
|
Flags: 0
|
||||||
|
Other: 3
|
||||||
|
DynamicSymbols:
|
||||||
|
Global:
|
||||||
|
- Name: h
|
||||||
|
...
|
|
@ -0,0 +1,42 @@
|
||||||
|
# RUN: yaml2obj %s -o %t
|
||||||
|
# RUN: llvm-readelf -V %t | FileCheck %s --check-prefix=INVALID
|
||||||
|
|
||||||
|
# INVALID: Version symbols section '.gnu.version' contains 2 entries:
|
||||||
|
# INVALID-NEXT: Addr: 0000000000200210 Offset: 0x000240 Link: 6 (.dynsym)
|
||||||
|
# INVALID-NEXT: 000: 0 (*local*) 3 (*invalid*)
|
||||||
|
|
||||||
|
--- !ELF
|
||||||
|
FileHeader:
|
||||||
|
Class: ELFCLASS64
|
||||||
|
Data: ELFDATA2LSB
|
||||||
|
Type: ET_EXEC
|
||||||
|
Machine: EM_X86_64
|
||||||
|
Entry: 0x0000000000201000
|
||||||
|
Sections:
|
||||||
|
- Name: .gnu.version
|
||||||
|
Type: SHT_GNU_versym
|
||||||
|
Flags: [ SHF_ALLOC ]
|
||||||
|
Address: 0x0000000000200210
|
||||||
|
Link: .dynsym
|
||||||
|
AddressAlign: 0x0000000000000002
|
||||||
|
EntSize: 0x0000000000000002
|
||||||
|
Entries: [ 0, 3 ]
|
||||||
|
- Name: .gnu.version_r
|
||||||
|
Type: SHT_GNU_verneed
|
||||||
|
Flags: [ SHF_ALLOC ]
|
||||||
|
Address: 0x0000000000200250
|
||||||
|
Link: .dynstr
|
||||||
|
AddressAlign: 0x0000000000000004
|
||||||
|
Info: 0x0000000000000001
|
||||||
|
Dependencies:
|
||||||
|
- Version: 1
|
||||||
|
File: somefile
|
||||||
|
Entries:
|
||||||
|
- Name: '' # invalid name
|
||||||
|
Hash: 1937
|
||||||
|
Flags: 233
|
||||||
|
Other: 3
|
||||||
|
DynamicSymbols:
|
||||||
|
Global:
|
||||||
|
- Name: f
|
||||||
|
...
|
|
@ -77,7 +77,11 @@ GNU-VERDEF: 0x000000006ffffff0 VERSYM 0x24c
|
||||||
GNU-VERDEF: 0x000000006ffffffc VERDEF 0x25c
|
GNU-VERDEF: 0x000000006ffffffc VERDEF 0x25c
|
||||||
GNU-VERDEF: 0x000000006ffffffd VERDEFNUM 3
|
GNU-VERDEF: 0x000000006ffffffd VERDEFNUM 3
|
||||||
|
|
||||||
GNU-VERDEF: Dumper for .gnu.version is not implemented
|
GNU-VERDEF: Version symbols section '.gnu.version' contains 8 entries:
|
||||||
|
GNU-VERDEF-NEXT: Addr: 000000000000024c Offset: 0x00024c Link: 1 (.dynsym)
|
||||||
|
GNU-VERDEF-NEXT: 000: 0 (*local*) 1 (*global*) 1 (*global*) 3 (VERSION2)
|
||||||
|
GNU-VERDEF-NEXT: 004: 1 (*global*) 2 (VERSION1) 2 (VERSION1) 3 (VERSION2)
|
||||||
|
|
||||||
GNU-VERDEF: Dumper for .gnu.version_d is not implemented
|
GNU-VERDEF: Dumper for .gnu.version_d is not implemented
|
||||||
|
|
||||||
RUN: llvm-readobj -V %p/Inputs/verneed.elf-x86-64 | FileCheck %s --check-prefix=LLVM-VERNEED
|
RUN: llvm-readobj -V %p/Inputs/verneed.elf-x86-64 | FileCheck %s --check-prefix=LLVM-VERNEED
|
||||||
|
@ -114,6 +118,9 @@ LLVM-VERNEED-NEXT: }
|
||||||
LLVM-VERNEED-NEXT: }
|
LLVM-VERNEED-NEXT: }
|
||||||
LLVM-VERNEED-NEXT: }
|
LLVM-VERNEED-NEXT: }
|
||||||
|
|
||||||
GNU-VERNEED: Dumper for .gnu.version is not implemented
|
GNU-VERNEED: Version symbols section '.gnu.version' contains 4 entries:
|
||||||
|
GNU-VERNEED-NEXT: Addr: 0000000000010228 Offset: 0x000228 Link: 1 (.dynsym)
|
||||||
|
GNU-VERNEED-NEXT: 000: 0 (*local*) 2 (v3) 3 (v2) 4 (v1)
|
||||||
|
|
||||||
GNU-VERNEED: Dumper for .gnu.version_r is not implemented
|
GNU-VERNEED: Dumper for .gnu.version_r is not implemented
|
||||||
|
|
||||||
|
|
|
@ -3355,7 +3355,57 @@ void GNUStyle<ELFT>::printVersionSymbolSection(const ELFFile<ELFT> *Obj,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
|
StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
|
||||||
OS << "Dumper for " << SecName << " is not implemented\n";
|
uint64_t Entries = Sec->sh_size / sizeof(Elf_Versym);
|
||||||
|
|
||||||
|
OS << "Version symbols section '" << SecName << "' "
|
||||||
|
<< "contains " << Entries << " entries:\n";
|
||||||
|
|
||||||
|
const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link));
|
||||||
|
StringRef SymTabName = unwrapOrError(Obj->getSectionName(SymTab));
|
||||||
|
OS << " Addr: " << format_hex_no_prefix(Sec->sh_addr, 16)
|
||||||
|
<< " Offset: " << format_hex(Sec->sh_offset, 8)
|
||||||
|
<< " Link: " << Sec->sh_link << " (" << SymTabName << ")\n";
|
||||||
|
|
||||||
|
const uint8_t *VersymBuf =
|
||||||
|
reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset);
|
||||||
|
const ELFDumper<ELFT> *Dumper = this->dumper();
|
||||||
|
StringRef StrTable = Dumper->getDynamicStringTable();
|
||||||
|
|
||||||
|
// readelf prints 4 entries per line.
|
||||||
|
for (uint64_t VersymRow = 0; VersymRow < Entries; VersymRow += 4) {
|
||||||
|
OS << " " << format_hex_no_prefix(VersymRow, 3) << ":";
|
||||||
|
|
||||||
|
for (uint64_t VersymIndex = 0;
|
||||||
|
(VersymIndex < 4) && (VersymIndex + VersymRow) < Entries;
|
||||||
|
++VersymIndex) {
|
||||||
|
const Elf_Versym *Versym =
|
||||||
|
reinterpret_cast<const Elf_Versym *>(VersymBuf);
|
||||||
|
switch (Versym->vs_index) {
|
||||||
|
case 0:
|
||||||
|
OS << " 0 (*local*) ";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
OS << " 1 (*global*) ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OS << format("%4x%c", Versym->vs_index & VERSYM_VERSION,
|
||||||
|
Versym->vs_index & VERSYM_HIDDEN ? 'h' : ' ');
|
||||||
|
|
||||||
|
bool IsDefault = true;
|
||||||
|
std::string VersionName = Dumper->getSymbolVersionByIndex(
|
||||||
|
StrTable, Versym->vs_index, IsDefault);
|
||||||
|
|
||||||
|
if (!VersionName.empty())
|
||||||
|
VersionName = "(" + VersionName + ")";
|
||||||
|
else
|
||||||
|
VersionName = "(*invalid*)";
|
||||||
|
OS << left_justify(VersionName, 13);
|
||||||
|
}
|
||||||
|
VersymBuf += sizeof(Elf_Versym);
|
||||||
|
}
|
||||||
|
OS << '\n';
|
||||||
|
}
|
||||||
|
OS << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
|
|
Loading…
Reference in New Issue