[llvm-readobj] Print section type values for unknown sections.

Summary:
This patch displays a hexadecimal section value (Elf_Shdr::sh_type) or section-relative offset when printing unknown sections.

Here is a subset of the output (ignoring the fields following "Type" when dumping an ELF's GNU `--section-headers` table).
Section Headers:
```
  [Nr] Name              Type
  [16] android_rel       LOOS+0x1
  [17] android_rela      LOOS+0x2
  [27] unknown           0x1000: <unknown>
  [28] loos              LOOS+0
  [30] hios              VERSYM
  [31] loproc            LOPROC+0
  [33] hiproc            LOPROC+0xFFFFFFF
  [34] louser            LOUSER+0
  [36] hiuser            LOUSER+0x7FFFFFFF
```

As a comparison, the previous output looked something like the above, but with a blank "Type" field:
```
  [Nr] Name              Type
  [27] unknown
  [28] loos
  [30] hios              VERSYM
  [31] loproc
  [33] hiproc
  [34] louser
  [36] hiuser
```

This fixes PR40773

Reviewers: jhenderson, rupprecht, Bigcheese

Reviewed By: jhenderson, rupprecht, Bigcheese

Subscribers: MaskRay, Bigcheese, srhines, jdoerfert, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D58701

llvm-svn: 355014
This commit is contained in:
Matt Davis
2019-02-27 18:39:17 +00:00
parent d89d638055
commit 7a24dbdfd3
2 changed files with 46 additions and 8 deletions

View File

@@ -63,14 +63,20 @@
# LLVM: Type: Unknown (0x1000)
# LLVM: Name: loos
# LLVM: Type: Unknown (0x60000000)
# LLVM: Name: fooos
# LLVM: Type: Unknown (0x60000F00)
# LLVM: Name: hios
# LLVM: Type: SHT_GNU_versym
# LLVM: Name: loproc
# LLVM: Type: Unknown (0x70000000)
# LLVM: Name: fooproc
# LLVM: Type: Unknown (0x70000F00)
# LLVM: Name: hiproc
# LLVM: Type: Unknown (0x7FFFFFFF)
# LLVM: Name: louser
# LLVM: Type: Unknown (0x80000000)
# LLVM: Name: foouser
# LLVM: Type: Unknown (0x80000F00)
# LLVM: Name: hiuser
# LLVM: Type: Unknown (0xFFFFFFFF)
# LLVM: Name: .symtab
@@ -94,10 +100,8 @@
# GNU-NEXT: group GROUP
# GNU-NEXT: symtab_shndx SYMTAB SECTION INDICES
# GNU-NEXT: relr RELR
## FIXME: These next two lines should print something like ANDROID_REL and ANDROID_RELA.
## See https://bugs.llvm.org/show_bug.cgi?id=40773.
# GNU-NEXT: android_rel 0000000000000000
# GNU-NEXT: android_rela 0000000000000000
# GNU-NEXT: android_rel ANDROID_REL
# GNU-NEXT: android_rela ANDROID_RELA
# GNU-NEXT: android_relr RELR
# GNU-NEXT: llvm_odrtab LLVM_ODRTAB
# GNU-NEXT: linker_options LLVM_LINKER_OPTIONS
@@ -107,8 +111,18 @@
# GNU-NEXT: gnu_hash GNU_HASH
# GNU-NEXT: gnu_verdef VERDEF
# GNU-NEXT: gnu_verneed VERNEED
## TODO: Add testing for unknown section types in GNU output style.
## See https://bugs.llvm.org/show_bug.cgi?id=40773.
# GNU-NEXT: unknown 0x1000: <unknown>
# GNU-NEXT: loos LOOS+0x0
# GNU-NEXT: fooos LOOS+0xF00
# GNU-NEXT: hios VERSYM
# GNU-NEXT: loproc LOPROC+0x0
# GNU-NEXT: fooproc LOPROC+0xF00
# GNU-NEXT: hiproc LOPROC+0xFFFFFFF
# GNU-NEXT: louser LOUSER+0x0
# GNU-NEXT: foouser LOUSER+0xF00
# GNU-NEXT: hiuser LOUSER+0x7FFFFFFF
# GNU-NEXT: .symtab SYMTAB
# GNU-NEXT: .strtab STRTAB
--- !ELF
FileHeader:
@@ -186,15 +200,21 @@ Sections:
Type: 0x1000
- Name: loos
Type: 0x60000000
- Name: fooos
Type: 0x60000F00
- Name: hios
Type: 0x6fffffff
Entries: []
- Name: loproc
Type: 0x70000000
- Name: fooproc
Type: 0x70000F00
- Name: hiproc
Type: 0x7fffffff
- Name: louser
Type: 0x80000000
- Name: foouser
Type: 0x80000F00
- Name: hiuser
Type: 0xffffffff
Symbols:

View File

@@ -2830,7 +2830,21 @@ template <class ELFT> void GNUStyle<ELFT>::printRelocations(const ELFO *Obj) {
OS << "\nThere are no relocations in this file.\n";
}
std::string getSectionTypeString(unsigned Arch, unsigned Type) {
// Print the offset of a particular section from anyone of the ranges:
// [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].
// If 'Type' does not fall within any of those ranges, then a string is
// returned as '<unknown>' followed by the type value.
static std::string getSectionTypeOffsetString(unsigned Type) {
if (Type >= SHT_LOOS && Type <= SHT_HIOS)
return "LOOS+0x" + to_hexString(Type - SHT_LOOS);
else if (Type >= SHT_LOPROC && Type <= SHT_HIPROC)
return "LOPROC+0x" + to_hexString(Type - SHT_LOPROC);
else if (Type >= SHT_LOUSER && Type <= SHT_HIUSER)
return "LOUSER+0x" + to_hexString(Type - SHT_LOUSER);
return "0x" + to_hexString(Type) + ": <unknown>";
}
static std::string getSectionTypeString(unsigned Arch, unsigned Type) {
using namespace ELF;
switch (Arch) {
@@ -2903,6 +2917,10 @@ std::string getSectionTypeString(unsigned Arch, unsigned Type) {
return "GROUP";
case SHT_SYMTAB_SHNDX:
return "SYMTAB SECTION INDICES";
case SHT_ANDROID_REL:
return "ANDROID_REL";
case SHT_ANDROID_RELA:
return "ANDROID_RELA";
case SHT_RELR:
case SHT_ANDROID_RELR:
return "RELR";
@@ -2926,7 +2944,7 @@ std::string getSectionTypeString(unsigned Arch, unsigned Type) {
case SHT_GNU_versym:
return "VERSYM";
default:
return "";
return getSectionTypeOffsetString(Type);
}
return "";
}