1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

[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
This commit is contained in:
Xing GUO 2019-02-26 13:06:16 +00:00
parent 4ca8c7b7fa
commit ab7e1b886f
2 changed files with 85 additions and 3 deletions

View File

@ -0,0 +1,41 @@
# RUN: yaml2obj %s > %t
# RUN: llvm-objdump -p %t | FileCheck --strict-whitespace %s
# CHECK: Version definitions:
# CHECK-NEXT: 1 0x01 0x075bcd15 foo
# CHECK-NEXT: 2 0x02 0x3ade68b1 VERSION_1
# CHECK-NEXT: VERSION_2
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Entry: 0x0000000000001000
Sections:
- Name: .gnu.version_d
Type: SHT_GNU_verdef
Flags: [ SHF_ALLOC ]
Address: 0x0000000000000230
Link: .dynstr
AddressAlign: 0x0000000000000004
Info: 0x0000000000000003
Entries:
- Version: 1
Flags: 1
VersionNdx: 1
Hash: 123456789
Names:
- foo
- Version: 1
Flags: 2
VersionNdx: 2
Hash: 987654321
Names:
- VERSION_1
- VERSION_2
DynamicSymbols:
Global:
- Name: bar
...

View File

@ -297,6 +297,43 @@ void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
}
}
template <class ELFT>
void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
ArrayRef<uint8_t> Contents,
StringRef StrTab) {
typedef ELFFile<ELFT> ELFO;
typedef typename ELFO::Elf_Verdef Elf_Verdef;
typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
outs() << "Version definitions:\n";
const uint8_t *Buf = Contents.data();
uint32_t VerdefIndex = 1;
// sh_info contains the number of entries in the SHT_GNU_verdef section. To
// make the index column have consistent width, we should insert blank spaces
// according to sh_info.
uint16_t VerdefIndexWidth = std::to_string(Shdr.sh_info).size();
while (Buf) {
const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
outs() << format_decimal(VerdefIndex++, VerdefIndexWidth) << " "
<< format("0x%02" PRIx16 " ", (uint16_t)Verdef->vd_flags)
<< format("0x%08" PRIx32 " ", (uint32_t)Verdef->vd_hash);
const uint8_t *BufAux = Buf + Verdef->vd_aux;
uint16_t VerdauxIndex = 0;
while (BufAux) {
const Elf_Verdaux *Verdaux =
reinterpret_cast<const Elf_Verdaux *>(BufAux);
if (VerdauxIndex)
outs() << std::string(VerdefIndexWidth + 17, ' ');
outs() << StringRef(StrTab.drop_front(Verdaux->vda_name).data()) << '\n';
BufAux = Verdaux->vda_next ? BufAux + Verdaux->vda_next : nullptr;
++VerdauxIndex;
}
Buf = Verdef->vd_next ? Buf + Verdef->vd_next : nullptr;
}
}
template <class ELFT>
void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
typedef typename ELFT::Shdr Elf_Shdr;
@ -306,7 +343,8 @@ void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
report_error(FileName, SectionsOrError.takeError());
for (const Elf_Shdr &Shdr : *SectionsOrError) {
if (Shdr.sh_type != ELF::SHT_GNU_verneed)
if (Shdr.sh_type != ELF::SHT_GNU_verneed &&
Shdr.sh_type != ELF::SHT_GNU_verdef)
continue;
auto ContentsOrError = Elf->getSectionContents(&Shdr);
@ -321,8 +359,11 @@ void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
if (!StrTabOrError)
report_error(FileName, StrTabOrError.takeError());
printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
// TODO: Implement symbol version definitions dumper.
if (Shdr.sh_type == ELF::SHT_GNU_verneed)
printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
else
printSymbolVersionDefinition<ELFT>(Shdr, *ContentsOrError,
*StrTabOrError);
}
}