[llvm-readobj]Add testing for ELF symbol and section table printing for a wider range of values

The existing ELF symbol and section table testing doesn't test many of
the corner-cases or valid values for various ELF properties, including
things like binding, visibility, section type and so on. This patch adds
a series of tests that test these and other related edge-cases.

Reviewed by: grimar, MaskRay

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354577 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
James Henderson
2019-02-21 12:47:10 +00:00
parent 1730d3775c
commit 75980a4cd5
7 changed files with 623 additions and 0 deletions
@@ -0,0 +1,95 @@
# Show that all machine-specific section types are properly printed for both LLVM and
# GNU styles for ELF files with that machine type.
# RUN: yaml2obj %s --docnum=1 -o %t-arm.o
# RUN: llvm-readobj --section-headers %t-arm.o | FileCheck %s --check-prefix=ARM-LLVM
# RUN: llvm-readelf --section-headers %t-arm.o | FileCheck %s --check-prefix=ARM-GNU
# RUN: yaml2obj %s --docnum=2 -o %t-x86_64.o
# RUN: llvm-readobj --section-headers %t-x86_64.o | FileCheck %s --check-prefix=X86-LLVM
# RUN: llvm-readelf --section-headers %t-x86_64.o | FileCheck %s --check-prefix=X86-GNU
# RUN: yaml2obj %s --docnum=3 -o %t-mips.o
# RUN: llvm-readobj --section-headers %t-mips.o | FileCheck %s --check-prefix=MIPS-LLVM
# RUN: llvm-readelf --section-headers %t-mips.o | FileCheck %s --check-prefix=MIPS-GNU
# ARM-LLVM: Name: exidx
# ARM-LLVM: Type: SHT_ARM_EXIDX
# ARM-LLVM: Name: preemptmap
# ARM-LLVM: Type: SHT_ARM_PREEMPTMAP
# ARM-LLVM: Name: attributes
# ARM-LLVM: Type: SHT_ARM_ATTRIBUTES
# ARM-LLVM: Name: debugoverlay
# ARM-LLVM: Type: SHT_ARM_DEBUGOVERLAY
# ARM-LLVM: Name: overlaysection
# ARM-LLVM: Type: SHT_ARM_OVERLAYSECTION
# ARM-GNU: exidx ARM_EXIDX
# ARM-GNU: preemptmap ARM_PREEMPTMAP
# ARM-GNU: attributes ARM_ATTRIBUTES
# ARM-GNU: debugoverlay ARM_DEBUGOVERLAY
# ARM-GNU: overlaysection ARM_OVERLAYSECTION
# X86-LLVM: Name: unwind
# X86-LLVM: Type: SHT_X86_64_UNWIND
# X86-GNU: unwind X86_64_UNWIND
# MIPS-LLVM: Name: reginfo
# MIPS-LLVM: Type: SHT_MIPS_REGINFO
# MIPS-LLVM: Name: options
# MIPS-LLVM: Type: SHT_MIPS_OPTIONS
# MIPS-LLVM: Name: abiflags
# MIPS-LLVM: Type: SHT_MIPS_ABIFLAGS
# MIPS-LLVM: Name: dwarf
# MIPS-LLVM: Type: SHT_MIPS_DWARF
# MIPS-GNU: reginfo MIPS_REGINFO
# MIPS-GNU: options MIPS_OPTIONS
# MIPS-GNU: abiflags MIPS_ABIFLAGS
# MIPS-GNU: dwarf MIPS_DWARF
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_ARM
Sections:
- Name: exidx
Type: SHT_ARM_EXIDX
- Name: preemptmap
Type: SHT_ARM_PREEMPTMAP
- Name: attributes
Type: SHT_ARM_ATTRIBUTES
- Name: debugoverlay
Type: SHT_ARM_DEBUGOVERLAY
- Name: overlaysection
Type: SHT_ARM_OVERLAYSECTION
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: unwind
Type: SHT_X86_64_UNWIND
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Sections:
- Name: reginfo
Type: SHT_MIPS_REGINFO
- Name: options
Type: SHT_MIPS_OPTIONS
- Name: abiflags
Type: SHT_MIPS_ABIFLAGS
ISA: MIPS64
- Name: dwarf
Type: SHT_MIPS_DWARF
@@ -0,0 +1,202 @@
# Show that all regular section types are properly printed for both LLVM and
# GNU styles.
# RUN: yaml2obj %s -o %t-basic.o
# RUN: llvm-readobj --section-headers %t-basic.o | FileCheck %s --check-prefix=LLVM
# RUN: llvm-readelf --section-headers %t-basic.o | FileCheck %s --check-prefix=GNU
# LLVM: Name: (0)
# LLVM: Type: SHT_NULL
# LLVM: Name: progbits
# LLVM: Type: SHT_PROGBITS
# LLVM: Name: rela
# LLVM: Type: SHT_RELA
# LLVM: Name: hash
# LLVM: Type: SHT_HASH
# LLVM: Name: dynamic
# LLVM: Type: SHT_DYNAMIC
# LLVM: Name: note
# LLVM: Type: SHT_NOTE
# LLVM: Name: nobits
# LLVM: Type: SHT_NOBITS
# LLVM: Name: rel
# LLVM: Type: SHT_REL
# LLVM: Name: shlib
# LLVM: Type: SHT_SHLIB
# LLVM: Name: dynsym
# LLVM: Type: SHT_DYNSYM
# LLVM: Name: init_array
# LLVM: Type: SHT_INIT_ARRAY
# LLVM: Name: fini_array
# LLVM: Type: SHT_FINI_ARRAY
# LLVM: Name: preinit_array
# LLVM: Type: SHT_PREINIT_ARRAY
# LLVM: Name: group
# LLVM: Type: SHT_GROUP
# LLVM: Name: symtab_shndx
# LLVM: Type: SHT_SYMTAB_SHNDX
# LLVM: Name: relr
# LLVM: Type: SHT_RELR
# LLVM: Name: android_rel
# LLVM: Type: SHT_ANDROID_REL
# LLVM: Name: android_rela
# LLVM: Type: SHT_ANDROID_RELA
# LLVM: Name: android_relr
# LLVM: Type: SHT_ANDROID_RELR
# LLVM: Name: llvm_odrtab
# LLVM: Type: SHT_LLVM_ODRTAB
# LLVM: Name: linker_options
# LLVM: Type: SHT_LLVM_LINKER_OPTIONS
# LLVM: Name: llvm_call_graph_profile
# LLVM: Type: SHT_LLVM_CALL_GRAPH_PROFILE
# LLVM: Name: llvm_addrsig
# LLVM: Type: SHT_LLVM_ADDRSIG
# LLVM: Name: gnu_attributes
# LLVM: Type: SHT_GNU_ATTRIBUTES
# LLVM: Name: gnu_hash
# LLVM: Type: SHT_GNU_HASH
# LLVM: Name: gnu_verdef
# LLVM: Type: SHT_GNU_verdef
# LLVM: Name: gnu_verneed
# LLVM: Type: SHT_GNU_verneed
# LLVM: Name: unknown
# LLVM: Type: Unknown (0x1000)
# LLVM: Name: loos
# LLVM: Type: Unknown (0x60000000)
# LLVM: Name: hios
# LLVM: Type: SHT_GNU_versym
# LLVM: Name: loproc
# LLVM: Type: Unknown (0x70000000)
# LLVM: Name: hiproc
# LLVM: Type: Unknown (0x7FFFFFFF)
# LLVM: Name: louser
# LLVM: Type: Unknown (0x80000000)
# LLVM: Name: hiuser
# LLVM: Type: Unknown (0xFFFFFFFF)
# LLVM: Name: .symtab
# LLVM: Type: SHT_SYMTAB
# LLVM: Name: .strtab
# LLVM: Type: SHT_STRTAB
# GNU: [ 0] NULL
# GNU-NEXT: progbits PROGBITS
# GNU-NEXT: rela RELA
# GNU-NEXT: hash HASH
# GNU-NEXT: dynamic DYNAMIC
# GNU-NEXT: note NOTE
# GNU-NEXT: nobits NOBITS
# GNU-NEXT: rel REL
# GNU-NEXT: shlib SHLIB
# GNU-NEXT: dynsym DYNSYM
# GNU-NEXT: init_array INIT_ARRAY
# GNU-NEXT: fini_array FINI_ARRAY
# GNU-NEXT: preinit_array PREINIT_ARRAY
# 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_relr RELR
# GNU-NEXT: llvm_odrtab LLVM_ODRTAB
# GNU-NEXT: linker_options LLVM_LINKER_OPTIONS
# GNU-NEXT: llvm_call_graph_profile LLVM_CALL_GRAPH_PROFILE
# GNU-NEXT: llvm_addrsig LLVM_ADDRSIG
# GNU-NEXT: gnu_attributes ATTRIBUTES
# 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.
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: progbits
Type: SHT_PROGBITS
- Name: rela
Type: SHT_RELA
Info: progbits
- Name: hash
Type: SHT_HASH
- Name: dynamic
Type: SHT_DYNAMIC
- Name: note
Type: SHT_NOTE
- Name: nobits
Type: SHT_NOBITS
- Name: rel
Type: SHT_REL
Info: progbits
- Name: shlib
Type: SHT_SHLIB
- Name: dynsym
Type: SHT_DYNSYM
Link: .strtab
- Name: init_array
Type: SHT_INIT_ARRAY
- Name: fini_array
Type: SHT_FINI_ARRAY
- Name: preinit_array
Type: SHT_PREINIT_ARRAY
- Name: group
Type: SHT_GROUP
Info: foo
Members:
- SectionOrType: 0
- Name: symtab_shndx
Type: SHT_SYMTAB_SHNDX
Link: .symtab
EntSize: 0x4
Content: "0000000000000000"
- Name: relr
Type: SHT_RELR
- Name: android_rel
Type: SHT_ANDROID_REL
- Name: android_rela
Type: SHT_ANDROID_RELA
- Name: android_relr
Type: SHT_ANDROID_RELR
- Name: llvm_odrtab
Type: SHT_LLVM_ODRTAB
- Name: linker_options
Type: SHT_LLVM_LINKER_OPTIONS
- Name: llvm_call_graph_profile
Type: SHT_LLVM_CALL_GRAPH_PROFILE
- Name: llvm_addrsig
Type: SHT_LLVM_ADDRSIG
- Name: gnu_attributes
Type: SHT_GNU_ATTRIBUTES
- Name: gnu_hash
Type: SHT_GNU_HASH
- Name: gnu_verdef
Type: SHT_GNU_verdef
Info: 0
Entries:
- Name: gnu_verneed
Type: SHT_GNU_verneed
Info: 0
Dependencies:
- Name: unknown
Type: 0x1000
- Name: loos
Type: 0x60000000
- Name: hios
Type: 0x6fffffff
Entries: []
- Name: loproc
Type: 0x70000000
- Name: hiproc
Type: 0x7fffffff
- Name: louser
Type: 0x80000000
- Name: hiuser
Type: 0xffffffff
Symbols:
Global:
- Name: foo
@@ -0,0 +1,24 @@
# Show that both GNU and LLVM styles can properly print symbol values and sizes
# that do not fit in 32-bit integers.
# RUN: yaml2obj %s > %t
# RUN: llvm-readobj --symbols %t | FileCheck %s --check-prefix=LLVM
# RUN: llvm-readelf --symbols %t | FileCheck %s --check-prefix=GNU
# LLVM: Name: a_sym
# LLVM-NEXT: Value: 0xFEDCBA9876543210
# LLVM-NEXT: Size: 81985529216486895
# GNU: 1: fedcba9876543210 81985529216486895 {{.*}} a_sym
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Symbols:
Local:
- Name: a_sym
Value: 0xfedcba9876543210
Size: 0x0123456789abcdef
@@ -0,0 +1,60 @@
# Show that llvm-readobj can print symbol bindings correctly for both LLVM and
# GNU styles, including for symbol bindings that are not recognised.
# RUN: yaml2obj %s > %t
# RUN: llvm-readobj --symbols --dyn-symbols %t | FileCheck %s --check-prefix=LLVM
# RUN: llvm-readelf --symbols --dyn-symbols %t | FileCheck %s --check-prefix=GNU
# LLVM: Name: local
# LLVM: Binding: Local
# LLVM: Name: global
# LLVM: Binding: Global
# LLVM: Name: weak
# LLVM: Binding: Weak
# LLVM: Name: unknown
# LLVM: Binding: 0x3
# LLVM: Name: unique
# LLVM: Binding: Unique (0xA)
# LLVM: Name: os
# LLVM: Binding: 0xB
# LLVM: Name: proc
# LLVM: Binding: 0xF
# GNU: 3 {{.*}} unknown
# GNU-NEXT: UNIQUE {{.*}} unique
# GNU-NEXT: b {{.*}} os
# GNU-NEXT: f {{.*}} proc
# GNU: LOCAL {{.*}} local
# GNU-NEXT: GLOBAL {{.*}} global
# GNU-NEXT: WEAK {{.*}} weak
# yaml2obj doesn't have a way of specifying static symbols with custom bindings,
# so use a custom dynamic symbol table section instead.
--- !ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_386
Sections:
- Name: .dynstr
Type: SHT_STRTAB
#\0unknown\0unique\0os\0proc\0
Content: "00756e6b6e6f776e00756e69717565006f730070726f6300"
- Name: .dynsym
Type: SHT_DYNSYM
Link: .dynstr
EntSize: 16
# Null symbol
# Symbol with st_name = 1, binding = 0x3
# Symbol with st_name = 9, binding = 0xa
# Symbol with st_name = 16, binding = 0xb
# Symbol with st_name = 19, binding = 0xf
Content: "0000000000000000000000000000000001000000000000000000000030000000090000000000000000000000a0000000100000000000000000000000b0000000130000000000000000000000f0000000"
Symbols:
Local:
- Name: local
Global:
- Name: global
Weak:
- Name: weak
@@ -0,0 +1,102 @@
# Show that llvm-readobj prints symbol shndxes correctly, for valid indexes,
# invalid indexes (i.e. section indexes that don't correspond to a real
# section), reserved values and processor/os-specific index values, for both GNU
# and LLVM styles.
# Use --dyn-symbols because yaml2obj does not currently support large section indexes
# and also does not allow hand-crafting of static symbol tables.
# RUN: yaml2obj --docnum=1 %s > %t1
# RUN: llvm-readobj --symbols --dyn-symbols %t1 | FileCheck %s --check-prefix=LLVM
# RUN: llvm-readelf --symbols --dyn-symbols %t1 | FileCheck %s --check-prefix=GNU1
# llvm-readobj doesn't accept shndx values that are not valid section indexes
# for LLVM style, so only test GNU output in this case.
# RUN: yaml2obj --docnum=2 %s > %t2
# RUN: llvm-readelf --symbols %t2 | FileCheck %s --check-prefix=GNU2
# LLVM: Name: undef
# LLVM: Section: Undefined (0x0)
# LLVM: Name: normal
# LLVM: Section: .text (0x1)
# LLVM: Name: common
# LLVM: Section: Common (0xFFF2)
# LLVM: Name: absolute
# LLVM: Section: Absolute (0xFFF1)
# LLVM: Name: proc
# LLVM: Section: Processor Specific (0xFF01)
# LLVM: Name: os
# LLVM: Section: Operating System Specific (0xFF21)
# LLVM: Name: reserved
# LLVM: Section: Reserved (0xFFFE)
# GNU1: Symbol table '.dynsym' contains 2 entries:
# GNU1-NEXT: Num: {{.*}} Ndx Name
# GNU1-NEXT: 0: {{.*}} UND
# GNU1-NEXT: 1: {{.*}} 1 xindex
# GNU1: Symbol table '.symtab' contains 8 entries:
# GNU1-NEXT: Num: {{.*}} Ndx Name
# GNU1-NEXT: 0: {{.*}} UND
# GNU1-NEXT: 1: {{.*}} UND undef
# GNU1-NEXT: 2: {{.*}} 1 normal
# GNU1-NEXT: 3: {{.*}} COM common
# GNU1-NEXT: 4: {{.*}} ABS absolute
# GNU1-NEXT: 5: {{.*}} PRC[0xff01] proc
# GNU1-NEXT: 6: {{.*}} OS[0xff21] os
# GNU1-NEXT: 7: {{.*}} RSV[0xfffe] reserved
# GNU2: Symbol table '.symtab' contains 2 entries:
# GNU2-NEXT: Num: {{.*}} Ndx Name
# GNU2-NEXT: 0: {{.*}} UND
# GNU2-NEXT: 1: {{.*}} 66 bad
--- !ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_386
Sections:
- Name: .text
Type: SHT_PROGBITS
- Name: .dynstr
Type: SHT_STRTAB
#\0xindex\0
Content: "0078696e64657800"
- Name: .dynsym
Type: SHT_DYNSYM
Link: .dynstr
EntSize: 16
# Null symbol
# Symbol with st_name = 1, st_shndx = SHN_XINDEX
Content: "000000000000000000000000000000000100000000000000000000000000ffff"
- Name: .symtab_shndx
Type: SHT_SYMTAB_SHNDX
Link: .dynsym
EntSize: 4
Content: "0000000001000000"
Symbols:
Global:
- Name: undef
- Name: normal
Section: .text
- Name: common
Index: SHN_COMMON
- Name: absolute
Index: SHN_ABS
- Name: proc
Index: 0xff01
- Name: os
Index: 0xff21
- Name: reserved
Index: 0xfffe
--- !ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_386
Symbols:
Global:
- Name: bad
Index: 0x42
@@ -0,0 +1,77 @@
# Show that llvm-readobj can print the type of symbol for all known symbol types
# and also for unknown types, both in the os/processor specific ranges and not,
# for both GNU and LLVM styles.
# RUN: yaml2obj %s > %t
# RUN: llvm-readobj --symbols %t | FileCheck %s --check-prefix=LLVM
# RUN: llvm-readelf --symbols %t | FileCheck %s --check-prefix=GNU
# LLVM: Name: notype
# LLVM: Type: None
# LLVM: Name: object
# LLVM: Type: Object
# LLVM: Name: func
# LLVM: Type: Function
# LLVM: Name: .text
# LLVM: Type: Section
# LLVM: Name: file
# LLVM: Type: File
# LLVM: Name: common
# LLVM: Type: Common
# LLVM: Name: tls
# LLVM: Type: TLS
# LLVM: Name: gnu_ifunc
# LLVM: Type: GNU_IFunc
# LLVM: Name: os_specific
# LLVM: Type: 0xB
# LLVM: Name: proc_specific
# LLVM: Type: 0xD
# LLVM: Name: unknown
# LLVM: Type: 0x7
# GNU: NOTYPE {{.*}} notype
# GNU: OBJECT {{.*}} object
# GNU: FUNC {{.*}} func
# GNU: SECTION {{.*}} .text
# GNU: FILE {{.*}} file
# GNU: COMMON {{.*}} common
# GNU: TLS {{.*}} tls
# GNU: IFUNC {{.*}} gnu_ifunc
# GNU: b {{.*}} os_specific
# GNU: d {{.*}} proc_specific
# GNU: 7 {{.*}} unknown
!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: .text
Type: SHT_PROGBITS
Symbols:
Global:
- Name: notype
Type: STT_NOTYPE
- Name: object
Type: STT_OBJECT
- Name: func
Type: STT_FUNC
- Name: .text
Type: STT_SECTION
Section: .text
- Name: file
Type: STT_FILE
- Name: common
Type: STT_COMMON
- Name: tls
Type: STT_TLS
- Name: gnu_ifunc
Type: STT_GNU_IFUNC
- Name: os_specific
Type: 11
- Name: proc_specific
Type: 13
- Name: unknown
Type: 7
@@ -0,0 +1,63 @@
# Show that llvm-readobj prints the symbol visibility where recognised, or
# something sensible when not, for both GNU and LLVM output.
# Use --dyn-symbols because it is only possible to hand-craft symbols with
# non-standard st_other values for .dynsym.
# RUN: yaml2obj %s > %t
# RUN: llvm-readobj --symbols --dyn-symbols %t | FileCheck %s --check-prefix=LLVM
# RUN: llvm-readelf --symbols --dyn-symbols %t | FileCheck %s --check-prefix=GNU
# LLVM: Name: default
# LLVM: Other: 0
# LLVM: Name: internal
# LLVM: Other [ (0x1)
# LLVM-NEXT: STV_INTERNAL (0x1)
# LLVM-NEXT: ]
# LLVM: Name: hidden
# LLVM: Other [ (0x2)
# LLVM-NEXT: STV_HIDDEN (0x2)
# LLVM-NEXT: ]
# LLVM: Name: protected
# LLVM: Other [ (0x3)
# LLVM-NEXT: STV_PROTECTED (0x3)
# LLVM-NEXT: ]
# LLVM: Name: other
# LLVM: Other [ (0x4)
# LLVM-NEXT: ]
# FIXME - the "other" symbol should print something indicating its non-zero st_other value.
# See https://bugs.llvm.org/show_bug.cgi?id=40785.
# GNU: DEFAULT {{.*}} other
# GNU: DEFAULT {{.*}} default
# GNU-NEXT: INTERNAL {{.*}} internal
# GNU-NEXT: HIDDEN {{.*}} hidden
# GNU-NEXT: PROTECTED {{.*}} protected
!ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_386
Sections:
- Name: .dynstr
Type: SHT_STRTAB
#\0other\0
Content: "006f7468657200"
- Name: .dynsym
Type: SHT_DYNSYM
Link: .dynstr
EntSize: 16
# Null symbol
# Symbol with st_name = 1, st_other = 0x4
Content: "0000000000000000000000000000000001000000000000000000000000040000"
Symbols:
Global:
- Name: default
Visibility: STV_DEFAULT
- Name: internal
Visibility: STV_INTERNAL
- Name: hidden
Visibility: STV_HIDDEN
- Name: protected
Visibility: STV_PROTECTED