## In this test we test that dynamic symbols are dumped as expected. ## Case 1: Dynamic symbol table found via the DT_SYMTAB dynamic tag. # RUN: yaml2obj --docnum=1 %s -o %t1.so # RUN: llvm-readobj --dyn-symbols %t1.so 2>&1 \ # RUN: | FileCheck %s --implicit-check-not="warning:" --check-prefix=DYNSYMS-LLVM # RUN: llvm-readelf --dyn-symbols %t1.so 2>&1 \ # RUN: | FileCheck %s --implicit-check-not="warning:" --check-prefix=DYNSYMS-GNU # DYNSYMS-LLVM: DynamicSymbols [ # DYNSYMS-LLVM-NEXT: Symbol { # DYNSYMS-LLVM-NEXT: Name: (0) # DYNSYMS-LLVM-NEXT: Value: 0x0 # DYNSYMS-LLVM-NEXT: Size: 0 # DYNSYMS-LLVM-NEXT: Binding: Local (0x0) # DYNSYMS-LLVM-NEXT: Type: None (0x0) # DYNSYMS-LLVM-NEXT: Other: 0 # DYNSYMS-LLVM-NEXT: Section: Undefined (0x0) # DYNSYMS-LLVM-NEXT: } # DYNSYMS-LLVM-NEXT: Symbol { # DYNSYMS-LLVM-NEXT: Name: foo (5) # DYNSYMS-LLVM-NEXT: Value: 0x0 # DYNSYMS-LLVM-NEXT: Size: 0 # DYNSYMS-LLVM-NEXT: Binding: Local (0x0) # DYNSYMS-LLVM-NEXT: Type: None (0x0) # DYNSYMS-LLVM-NEXT: Other: 0 # DYNSYMS-LLVM-NEXT: Section: Undefined (0x0) # DYNSYMS-LLVM-NEXT: } # DYNSYMS-LLVM-NEXT: Symbol { # DYNSYMS-LLVM-NEXT: Name: bar (1) # DYNSYMS-LLVM-NEXT: Value: 0x0 # DYNSYMS-LLVM-NEXT: Size: 0 # DYNSYMS-LLVM-NEXT: Binding: Local (0x0) # DYNSYMS-LLVM-NEXT: Type: None (0x0) # DYNSYMS-LLVM-NEXT: Other: 0 # DYNSYMS-LLVM-NEXT: Section: Undefined (0x0) # DYNSYMS-LLVM-NEXT: } # DYNSYMS-LLVM-NEXT: ] # DYNSYMS-GNU: Symbol table '.dynsym' contains 3 entries: # DYNSYMS-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name # DYNSYMS-GNU-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND # DYNSYMS-GNU-NEXT: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND foo # DYNSYMS-GNU-NEXT: 2: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND bar --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynamic Type: SHT_DYNAMIC Entries: - Tag: DT_SYMTAB Value: 0x100 - Tag: DT_NULL Value: 0 - Name: .dynsym Type: SHT_DYNSYM Address: 0x100 DynamicSymbols: - Name: foo - Name: bar ProgramHeaders: - Type: PT_LOAD VAddr: 0x100 FirstSec: .dynsym LastSec: .dynsym ## Case 2: Check the output for aliases. ## a) Check the two-letter alias --dt is equivalent to the --dyn-symbols ## full flag name. # RUN: llvm-readobj --dt %t1.so > %t.readobj-dt-alias # RUN: llvm-readobj --dyn-symbols %t1.so > %t.readobj-dt-no-alias # RUN: cmp %t.readobj-dt-alias %t.readobj-dt-no-alias ## b) Check --dyn-syms equals --dyn-symbols, --dt for llvm-readobj. # RUN: llvm-readobj --dyn-syms %t1.so > %t.readobj-dyn-syms # RUN: cmp %t.readobj-dt-alias %t.readobj-dyn-syms ## c) Check --dyn-syms equals --dyn-symbols for llvm-readelf. # RUN: llvm-readelf --dyn-syms %t1.so > %t.readelf-dyn-syms # RUN: llvm-readelf --dyn-symbols %t1.so > %t.readelf-dyn-symbols # RUN: cmp %t.readelf-dyn-symbols %t.readelf-dyn-syms ## Case 3.1: Check that we are able to dump the dynamic symbol table even when we have no program headers. ## In this case we find the table by it's type (SHT_DYNSYM) and ignore the DT_SYMTAB value. # RUN: yaml2obj --docnum=2 %s -o %t2.so # RUN: llvm-readobj %t2.so --dyn-symbols 2>&1 | \ # RUN: FileCheck %s -DFILE=%t2.so --implicit-check-not=warning: --check-prefix=NOPHDRS-LLVM # RUN: llvm-readelf %t2.so --dyn-symbols 2>&1 | \ # RUN: FileCheck %s -DFILE=%t2.so --implicit-check-not=warning: -DNAME=.dynsym --check-prefix=NOPHDRS-GNU # NOPHDRS-LLVM: warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0xffff1234 # NOPHDRS-LLVM: DynamicSymbols [ # NOPHDRS-LLVM-NEXT: Symbol { # NOPHDRS-LLVM-NEXT: Name: (0) # NOPHDRS-LLVM-NEXT: Value: 0x0 # NOPHDRS-LLVM-NEXT: Size: 0 # NOPHDRS-LLVM-NEXT: Binding: Local (0x0) # NOPHDRS-LLVM-NEXT: Type: None (0x0) # NOPHDRS-LLVM-NEXT: Other: 0 # NOPHDRS-LLVM-NEXT: Section: Undefined (0x0) # NOPHDRS-LLVM-NEXT: } # NOPHDRS-LLVM-NEXT: Symbol { # NOPHDRS-LLVM-NEXT: Name: foo (1) # NOPHDRS-LLVM-NEXT: Value: 0x0 # NOPHDRS-LLVM-NEXT: Size: 0 # NOPHDRS-LLVM-NEXT: Binding: Local (0x0) # NOPHDRS-LLVM-NEXT: Type: None (0x0) # NOPHDRS-LLVM-NEXT: Other: 0 # NOPHDRS-LLVM-NEXT: Section: Undefined (0x0) # NOPHDRS-LLVM-NEXT: } # NOPHDRS-LLVM-NEXT: ] # NOPHDRS-GNU: warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0xffff1234 # NOPHDRS-NAMEWARN: warning: '[[FILE]]': unable to get the name of SHT_DYNSYM section with index 2: a section [index 2] has an invalid sh_name (0xffffffff) offset which goes past the end of the section name string table # NOPHDRS-GNU: Symbol table '[[NAME]]' contains 2 entries: # NOPHDRS-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name # NOPHDRS-GNU-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND # NOPHDRS-GNU-NEXT: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND foo --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynamic Type: SHT_DYNAMIC Entries: - Tag: DT_SYMTAB Value: 0xffff1234 - Tag: DT_NULL Value: 0 - Name: .dynsym Type: SHT_DYNSYM ShName: [[DYNSYMNAME=]] DynamicSymbols: - Name: foo ## Case 3.2: the same as 3.1, but the sh_name field of the SHT_DYNSYM section is invalid. ## Check we are still able to dump symbols. # RUN: yaml2obj --docnum=2 -DDYNSYMNAME=0xffffffff %s -o %t2.broken.name # RUN: llvm-readobj %t2.broken.name --dyn-symbols 2>&1 | \ # RUN: FileCheck %s -DFILE=%t2.broken.name --check-prefix=NOPHDRS-LLVM --implicit-check-not=warning: # RUN: llvm-readelf %t2.broken.name --dyn-symbols 2>&1 | \ # RUN: FileCheck %s -DFILE=%t2.broken.name -DNAME="" \ # RUN: --check-prefixes=NOPHDRS-GNU,NOPHDRS-NAMEWARN --implicit-check-not=warning: ## Case 4: Check we report a warning when there is no SHT_DYNSYM section and we can't map the DT_SYMTAB value ## to an address because of the absence of a corresponding PT_LOAD program header. # RUN: yaml2obj --docnum=3 %s -o %t3.so # RUN: llvm-readobj %t3.so --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t3.so --check-prefixes=NOSHT-DYNSYM,NOSHT-DYNSYM-LLVM # RUN: llvm-readelf %t3.so --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t3.so --check-prefix=NOSHT-DYNSYM # NOSHT-DYNSYM: warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0x0 # NOSHT-DYNSYM-LLVM: DynamicSymbols [ # NOSHT-DYNSYM-LLVM-NEXT: ] --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynsym Type: SHT_PROGBITS - Name: .dynamic Type: SHT_DYNAMIC Entries: - Tag: DT_SYMTAB Value: 0 - Tag: DT_NULL Value: 0 DynamicSymbols: - Name: foo ## Case 5: Check that when we can't map the value of the DT_SYMTAB tag to an address, we report a warning and ## use the information in the section header table to locate the dynamic symbol table. # RUN: yaml2obj --docnum=4 %s -o %t4.so # RUN: llvm-readobj %t4.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefixes=BROKEN-DTSYMTAB,BROKEN-DTSYMTAB-LLVM # RUN: llvm-readelf %t4.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefixes=BROKEN-DTSYMTAB,BROKEN-DTSYMTAB-GNU # BROKEN-DTSYMTAB: warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0xffff1234 # BROKEN-DTSYMTAB-LLVM: Name: foo # BROKEN-DTSYMTAB-GNU: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND foo --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynamic Type: SHT_DYNAMIC Entries: - Tag: DT_SYMTAB Value: 0xffff1234 - Tag: DT_NULL Value: 0 DynamicSymbols: - Name: foo ProgramHeaders: - Type: PT_LOAD VAddr: 0x0000 FirstSec: .dynsym LastSec: .dynsym ## Case 6: Check that if we can get the location of the dynamic symbol table using both the DT_SYMTAB value ## and the section headers table then we prefer the former and report a warning. # RUN: yaml2obj --docnum=5 %s -o %t5.so # RUN: llvm-readobj %t5.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t5.so %s --check-prefixes=PREFER-DTSYMTAB,PREFER-DTSYMTAB-LLVM # RUN: llvm-readelf %t5.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t5.so %s --check-prefixes=PREFER-DTSYMTAB,PREFER-DTSYMTAB-GNU # PREFER-DTSYMTAB: warning: '[[FILE]]': SHT_DYNSYM section header and DT_SYMTAB disagree about the location of the dynamic symbol table # PREFER-DTSYMTAB-LLVM: Name: o # PREFER-DTSYMTAB-GNU: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND o --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynamic Type: SHT_DYNAMIC Entries: - Tag: DT_SYMTAB Value: 0x0 - Tag: DT_NULL Value: 0 - Name: .dynsym Type: SHT_DYNSYM - Name: .mydynsym Type: SHT_DYNSYM ## The Content describes 2 symbols: zero symbol and symbol with st_name == 3. Content: "000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000" DynamicSymbols: - Name: foo ProgramHeaders: - Type: PT_LOAD VAddr: 0x0000 FirstSec: .mydynsym LastSec: .mydynsym ## Case 7: Check how we dump versioned symbols. Use both -V and --dyn-symbols ## to check that printed version is consistent. # RUN: yaml2obj %s --docnum=6 -o %t6 # RUN: llvm-readobj -V --dyn-symbols %t6 | FileCheck %s --check-prefix=VERSIONED-LLVM # RUN: llvm-readelf -V --dyn-symbols %t6 | FileCheck %s --check-prefix=VERSIONED-GNU # VERSIONED-LLVM: Symbol { # VERSIONED-LLVM: Name: foo (16) # VERSIONED-LLVM-NEXT: Value: 0x0 # VERSIONED-LLVM-NEXT: Size: 0 # VERSIONED-LLVM-NEXT: Binding: Local (0x0) # VERSIONED-LLVM-NEXT: Type: None (0x0) # VERSIONED-LLVM-NEXT: Other: 0 # VERSIONED-LLVM-NEXT: Section: Undefined (0x0) # VERSIONED-LLVM-NEXT: } # VERSIONED-LLVM-NEXT: Symbol { # VERSIONED-LLVM-NEXT: Name: bar@@Default (12) # VERSIONED-LLVM-NEXT: Value: 0x0 # VERSIONED-LLVM-NEXT: Size: 0 # VERSIONED-LLVM-NEXT: Binding: Local (0x0) # VERSIONED-LLVM-NEXT: Type: None (0x0) # VERSIONED-LLVM-NEXT: Other: 0 # VERSIONED-LLVM-NEXT: Section: Undefined (0x0) # VERSIONED-LLVM-NEXT: } # VERSIONED-LLVM-NEXT: Symbol { # VERSIONED-LLVM-NEXT: Name: zed@NonDefault (20) # VERSIONED-LLVM-NEXT: Value: 0x0 # VERSIONED-LLVM-NEXT: Size: 0 # VERSIONED-LLVM-NEXT: Binding: Local (0x0) # VERSIONED-LLVM-NEXT: Type: None (0x0) # VERSIONED-LLVM-NEXT: Other: 0 # VERSIONED-LLVM-NEXT: Section: Undefined (0x0) # VERSIONED-LLVM-NEXT: } # VERSIONED-LLVM: VersionSymbols [ # VERSIONED-LLVM: Name: foo # VERSIONED-LLVM: Name: bar@@Default # VERSIONED-LLVM: Name: zed@NonDefault # VERSIONED-GNU: Num: Value Size Type Bind Vis Ndx Name # VERSIONED-GNU: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND foo # VERSIONED-GNU-NEXT: 2: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND bar@@Default # VERSIONED-GNU-NEXT: 3: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND zed@NonDefault # VERSIONED-GNU: 000: 0 (*local*) 1 (*global*) 2 (Default) 3h(NonDefault) --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .gnu.version Type: SHT_GNU_versym Flags: [ SHF_ALLOC ] Link: .dynsym AddressAlign: 0x2 EntSize: 0x2 ## 0x8000 is a special VERSYM_HIDDEN bit. Entries: [ 0, 1, 2, 0x8003 ] - Name: .gnu.version_d Type: SHT_GNU_verdef Flags: [ SHF_ALLOC ] Link: .dynstr AddressAlign: 0x4 Info: 0x2 Entries: - Version: 1 Flags: 0 VersionNdx: 2 Hash: 0 Names: - Default - Version: 1 Flags: 0 VersionNdx: 3 Hash: 0 Names: - NonDefault DynamicSymbols: - Name: foo - Name: [[NAME=bar]] Type: [[TYPE=STT_NOTYPE]] Index: [[INDEX=]] - Name: [[NAME=zed]] Type: [[TYPE=STT_NOTYPE]] ## Check the behavior for unnamed versioned section symbols. # RUN: yaml2obj %s -DTYPE=STT_SECTION -DNAME="''" -DINDEX=SHN_ABS --docnum=6 -o %t6.sec.sym # RUN: llvm-readobj -V --dyn-symbols %t6.sec.sym 2>&1 | \ # RUN: FileCheck %s -DFILE=%t6.sec.sym --check-prefix=VERSIONED-SEC-SYM-LLVM # RUN: llvm-readelf -V --dyn-symbols %t6.sec.sym 2>&1 | \ # RUN: FileCheck %s -DFILE=%t6.sec.sym --check-prefix=VERSIONED-SEC-SYM-GNU # VERSIONED-SEC-SYM-LLVM: DynamicSymbols [ # VERSIONED-SEC-SYM-LLVM: Name: foo (12) # VERSIONED-SEC-SYM-LLVM: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0xfff1 (SHN_ABS) # VERSIONED-SEC-SYM-LLVM: Name: (0) # VERSIONED-SEC-SYM-LLVM: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0x0 (SHN_UNDEF) # VERSIONED-SEC-SYM-LLVM: Name: (0) # VERSIONED-SEC-SYM-LLVM: VersionSymbols [ # VERSIONED-SEC-SYM-LLVM: Name: foo # VERSIONED-SEC-SYM-LLVM: Name: # VERSIONED-SEC-SYM-LLVM: Name: # VERSIONED-SEC-SYM-GNU: Symbol table '.dynsym' contains 4 entries: # VERSIONED-SEC-SYM-GNU: Num: {{.*}} Ndx Name # VERSIONED-SEC-SYM-GNU: 1: {{.*}} UND foo # VERSIONED-SEC-SYM-GNU: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0xfff1 (SHN_ABS) # VERSIONED-SEC-SYM-GNU-NEXT: 2: {{.*}} ABS # VERSIONED-SEC-SYM-GNU-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0x0 (SHN_UNDEF) # VERSIONED-SEC-SYM-GNU-NEXT: 3: {{.*}} UND ## Check we print a proper warning when an unnamed versioned section symbol has st_shndx = SHN_XINDEX, but there ## is no SHT_SYMTAB_SHNDX section in the object. # RUN: yaml2obj %s -DTYPE=STT_SECTION -DNAME="''" -DINDEX=SHN_XINDEX --docnum=6 -o %t6.sec.xindex.sym # RUN: llvm-readobj -V --dyn-symbols %t6.sec.xindex.sym 2>&1 | \ # RUN: FileCheck %s -DFILE=%t6.sec.xindex.sym --check-prefix=VERSIONED-SEC-SYM-XINDEX-LLVM # RUN: llvm-readelf -V --dyn-symbols %t6.sec.xindex.sym 2>&1 | \ # RUN: FileCheck %s -DFILE=%t6.sec.xindex.sym --check-prefix=VERSIONED-SEC-SYM-XINDEX-GNU # VERSIONED-SEC-SYM-XINDEX-LLVM: Name: (0) # VERSIONED-SEC-SYM-XINDEX-LLVM: Name: foo (12) # VERSIONED-SEC-SYM-XINDEX-LLVM: warning: '[[FILE]]': extended symbol index (2) is past the end of the SHT_SYMTAB_SHNDX section of size 0 # VERSIONED-SEC-SYM-XINDEX-LLVM-NEXT: Symbol { # VERSIONED-SEC-SYM-XINDEX-LLVM-NEXT: Name: (0) # VERSIONED-SEC-SYM-XINDEX-LLVM: Name: (0) # VERSIONED-SEC-SYM-XINDEX-GNU: Symbol table '.dynsym' contains 4 entries: # VERSIONED-SEC-SYM-XINDEX-GNU: Num: {{.*}} Ndx Name # VERSIONED-SEC-SYM-XINDEX-GNU: warning: '[[FILE]]': extended symbol index (2) is past the end of the SHT_SYMTAB_SHNDX section of size 0 # VERSIONED-SEC-SYM-XINDEX-GNU-NEXT: 2: {{.*}} RSV[0xffff] ## Case 8: Check what we print when: ## a) The dynamic symbol table does not exist. # RUN: yaml2obj %s --docnum=7 -o %t7 # RUN: llvm-readobj --dyn-symbols %t7 | FileCheck %s --check-prefix=NO-DYNSYM-LLVM # RUN: llvm-readelf --dyn-symbols %t7 | count 0 ## b) The dynamic symbol table has a size of 0. # RUN: yaml2obj %s --docnum=8 -o %t8 # RUN: llvm-readobj --dyn-symbols %t8 | FileCheck %s --check-prefix=NO-DYNSYM-LLVM # RUN: llvm-readelf --dyn-symbols %t8 | count 0 ## c) The dynamic symbol table only contains the null symbol. # RUN: yaml2obj %s --docnum=9 -o %t9 # RUN: llvm-readobj --dyn-symbols %t9 | FileCheck %s --check-prefix=DYNSYM-EMPTY-LLVM # RUN: llvm-readelf --dyn-symbols %t9 | FileCheck %s --check-prefix=DYNSYM-EMPTY-GNU # NO-DYNSYM-LLVM: DynamicSymbols [ # NO-DYNSYM-LLVM-NEXT: ] # DYNSYM-EMPTY-LLVM: DynamicSymbols [ # DYNSYM-EMPTY-LLVM-NEXT: Symbol { # DYNSYM-EMPTY-LLVM-NEXT: Name: (0) # DYNSYM-EMPTY-LLVM-NEXT: Value: 0x0 # DYNSYM-EMPTY-LLVM-NEXT: Size: 0 # DYNSYM-EMPTY-LLVM-NEXT: Binding: Local (0x0) # DYNSYM-EMPTY-LLVM-NEXT: Type: None (0x0) # DYNSYM-EMPTY-LLVM-NEXT: Other: 0 # DYNSYM-EMPTY-LLVM-NEXT: Section: Undefined (0x0) # DYNSYM-EMPTY-LLVM-NEXT: } # DYNSYM-EMPTY-LLVM-NEXT: ] # DYNSYM-EMPTY-GNU: Symbol table '.dynsym' contains 1 entries: # DYNSYM-EMPTY-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name # DYNSYM-EMPTY-GNU-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND --- !ELF FileHeader: Class: ELFCLASS32 Data: ELFDATA2LSB Type: ET_DYN --- !ELF FileHeader: Class: ELFCLASS32 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynsym Type: SHT_DYNSYM Size: 0 --- !ELF FileHeader: Class: ELFCLASS32 Data: ELFDATA2LSB Type: ET_DYN DynamicSymbols: [] ## Case 9: Check what we print when: ## a) The size of the dynamic symbol table is not a multiple of its entry size. # RUN: yaml2obj %s --docnum=10 -o %t10 # RUN: llvm-readobj --dyn-symbols %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=DYNSYM-SIZE-INVALID1 # RUN: llvm-readelf --dyn-symbols %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=DYNSYM-SIZE-INVALID1 # DYNSYM-SIZE-INVALID1: warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x1) or entry size (0x10) ## b) The same, but the DT_SYMTAB tag is present. In this case the dynamic tag has priority over the ## information about a location and an entity size of the dynamic symbol table from the section header. ## The code uses sizeof(Elf_Sym) for an entity size, so it can't be incorrect and ## the message printed is a bit shorter. # RUN: yaml2obj %s --docnum=11 -o %t11 # RUN: llvm-readobj --dyn-symbols %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=DYNSYM-SIZE-INVALID2 # RUN: llvm-readelf --dyn-symbols %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=DYNSYM-SIZE-INVALID2 # DYNSYM-SIZE-INVALID2: warning: '[[FILE]]': SHT_DYNSYM section with index 2 has invalid size (0x1){{$}} ## c) In the case when the DT_SYMENT tag is present, we report when it's value does not match the # value of the symbol size for the platform. # RUN: yaml2obj %s -D BITS=32 --docnum=12 -o %t12 # RUN: llvm-readobj --dyn-symbols %t12 2>&1 | \ # RUN: FileCheck %s -DFILE=%t12 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID3 # RUN: llvm-readelf --dyn-symbols %t12 2>&1 | \ # RUN: FileCheck %s -DFILE=%t12 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID3 # RUN: yaml2obj %s -D BITS=64 --docnum=12 -o %t13 # RUN: llvm-readobj --dyn-symbols %t13 2>&1 | \ # RUN: FileCheck %s -DFILE=%t13 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID4 # RUN: llvm-readelf --dyn-symbols %t13 2>&1 | \ # RUN: FileCheck %s -DFILE=%t13 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID4 # DYNSYM-SIZE-INVALID3: warning: '[[FILE]]': DT_SYMENT value of 0x123 is not the size of a symbol (0x10){{$}} # DYNSYM-SIZE-INVALID4: warning: '[[FILE]]': DT_SYMENT value of 0x123 is not the size of a symbol (0x18){{$}} --- !ELF FileHeader: Class: ELFCLASS32 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynsym Type: SHT_DYNSYM Size: 0x1 --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynamic Type: SHT_DYNAMIC Entries: - Tag: DT_SYMTAB Value: 0x100 - Tag: DT_NULL Value: 0 - Name: .dynsym Type: SHT_DYNSYM Address: 0x100 Size: 0x1 ProgramHeaders: - Type: PT_LOAD VAddr: 0x100 FirstSec: .dynsym LastSec: .dynsym --- !ELF FileHeader: Class: ELFCLASS[[BITS]] Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynamic Type: SHT_DYNAMIC Entries: - Tag: DT_SYMENT Value: 0x123 - Tag: DT_SYMENT Value: 0x123 - Tag: DT_NULL Value: 0 ## Case 10: Check we report a warning when the DT_STRSZ value is broken so that the dynamic string ## table goes past the end of the file. Document we stop dumping symbols and report an error. # RUN: yaml2obj %s --docnum=13 -o %t14 # RUN: llvm-readobj --dyn-symbols %t14 2>&1 | \ # RUN: FileCheck %s -DFILE=%t14 --check-prefix=DYNSTR-INVALID-LLVM # RUN: llvm-readelf --dyn-symbols %t14 2>&1 | \ # RUN: FileCheck %s -DFILE=%t14 --check-prefix=DYNSTR-INVALID-GNU # DYNSTR-INVALID-LLVM: warning: '[[FILE]]': the dynamic string table at 0x78 goes past the end of the file (0x2a8) with DT_STRSZ = 0xffffffff # DYNSTR-INVALID-LLVM: DynamicSymbols [ # DYNSTR-INVALID-LLVM-NEXT: Symbol { # DYNSTR-INVALID-LLVM-NEXT: Name: (0) # DYNSTR-INVALID-LLVM-NEXT: Value: 0x0 # DYNSTR-INVALID-LLVM-NEXT: Size: 0 # DYNSTR-INVALID-LLVM-NEXT: Binding: Local (0x0) # DYNSTR-INVALID-LLVM-NEXT: Type: None (0x0) # DYNSTR-INVALID-LLVM-NEXT: Other: 0 # DYNSTR-INVALID-LLVM-NEXT: Section: Undefined (0x0) # DYNSTR-INVALID-LLVM-NEXT: } # DYNSTR-INVALID-LLVM-NEXT: warning: '[[FILE]]': st_name (0xffffff00) is past the end of the string table of size 0x6 # DYNSTR-INVALID-LLVM-NEXT: Symbol { # DYNSTR-INVALID-LLVM-NEXT: Name: (4294967040) # DYNSTR-INVALID-LLVM-NEXT: Value: 0x0 # DYNSTR-INVALID-LLVM-NEXT: Size: 0 # DYNSTR-INVALID-LLVM-NEXT: Binding: Local (0x0) # DYNSTR-INVALID-LLVM-NEXT: Type: None (0x0) # DYNSTR-INVALID-LLVM-NEXT: Other: 0 # DYNSTR-INVALID-LLVM-NEXT: Section: Undefined (0x0) # DYNSTR-INVALID-LLVM-NEXT: } # DYNSTR-INVALID-LLVM-NEXT: Symbol { # DYNSTR-INVALID-LLVM-NEXT: Name: test (1) # DYNSTR-INVALID-LLVM-NEXT: Value: 0x0 # DYNSTR-INVALID-LLVM-NEXT: Size: 0 # DYNSTR-INVALID-LLVM-NEXT: Binding: Local (0x0) # DYNSTR-INVALID-LLVM-NEXT: Type: None (0x0) # DYNSTR-INVALID-LLVM-NEXT: Other: 0 # DYNSTR-INVALID-LLVM-NEXT: Section: Undefined (0x0) # DYNSTR-INVALID-LLVM-NEXT: } # DYNSTR-INVALID-LLVM-NEXT: ] # DYNSTR-INVALID-GNU: warning: '[[FILE]]': the dynamic string table at 0x78 goes past the end of the file (0x2a8) with DT_STRSZ = 0xffffffff # DYNSTR-INVALID-GNU: Symbol table '.dynsym' contains 3 entries: # DYNSTR-INVALID-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name # DYNSTR-INVALID-GNU-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND # DYNSTR-INVALID-GNU-NEXT: warning: '[[FILE]]': st_name (0xffffff00) is past the end of the string table of size 0x6 # DYNSTR-INVALID-GNU-NEXT: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND # DYNSTR-INVALID-GNU-NEXT: 2: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND test --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_EXEC Sections: - Name: .dynstr Type: SHT_STRTAB Flags: [ SHF_ALLOC ] Content: '007465737400' ## '\0', 'test', '\0' - Name: .dynamic Type: SHT_DYNAMIC Flags: [ SHF_ALLOC ] Link: .dynstr Entries: - Tag: DT_STRTAB Value: 0x0 - Tag: DT_STRSZ Value: 0xffffffff - Tag: DT_NULL Value: 0x0 DynamicSymbols: - StName: 0xffffff00 ## An arbitrary valid symbol to document we report an error before dumping it. - StName: 0x1 ProgramHeaders: - Type: PT_LOAD Flags: [ PF_R ] FirstSec: .dynstr LastSec: .dynamic ## Case 11: check various warnings we report when fields of the SHT_DYNSYM section are broken. ## a) check we report a warning when the entry size of the dynamic symbol table is zero. # RUN: yaml2obj %s --docnum=14 -DENTSIZE=0x0 -o %t15.entsize # RUN: llvm-readobj --dyn-symbols %t15.entsize 2>&1 | FileCheck %s -DFILE=%t15.entsize --check-prefix=DYNSYM-ZERO-ENTSIZE-LLVM # RUN: llvm-readelf --dyn-symbols %t15.entsize 2>&1 | \ # RUN: FileCheck %s -DFILE=%t15.entsize --check-prefix=DYNSYM-ZERO-ENTSIZE-GNU --implicit-check-not="Symbol table" # DYNSYM-ZERO-ENTSIZE-LLVM: DynamicSymbols [ # DYNSYM-ZERO-ENTSIZE-LLVM-NEXT: warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x20) or entry size (0x0) # DYNSYM-ZERO-ENTSIZE-LLVM-NEXT: ] # DYNSYM-ZERO-ENTSIZE-GNU: warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x20) or entry size (0x0) --- !ELF FileHeader: Class: ELFCLASS32 Data: ELFDATA2LSB Type: ET_DYN Sections: - Name: .dynsym Type: SHT_DYNSYM EntSize: [[ENTSIZE=]] Link: [[LINK=]] ShOffset: [[OFFSET=]] ShSize: [[SIZE=]] DynamicSymbols: - Name: foo ## b) check we report a warning when the sh_offset field of the SHT_DYNSYM section is ## invalid (sh_offset + sh_size is greater than the file size). Check we don't dump ## dynamic symbols in this case. # RUN: yaml2obj --docnum=14 %s -DOFFSET=0xffffffff -o %t15.offset # RUN: llvm-readobj %t15.offset --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t15.offset \ # RUN: --check-prefixes=OFFSET-BROKEN,OFFSET-BROKEN-LLVM # RUN: llvm-readelf %t15.offset --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t15.offset \ # RUN: --implicit-check-not="Symbol table" --check-prefix=OFFSET-BROKEN # OFFSET-BROKEN: warning: '[[FILE]]': unable to read dynamic symbols from SHT_DYNSYM section with index 1: offset (0xffffffff) + size (0x20) is greater than the file size (0x148) # OFFSET-BROKEN-LLVM: DynamicSymbols [ # OFFSET-BROKEN-LLVM-NEXT: ] ## c) check we report a warning when the sh_size field of the SHT_DYNSYM section is ## invalid (sh_offset + sh_size is greater than the file size). Check we don't dump ## dynamic symbols in this case. # RUN: yaml2obj --docnum=14 %s -DSIZE=0xffffffff -o %t15.size # RUN: llvm-readobj %t15.size --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t15.size \ # RUN: --check-prefixes=SIZE-BROKEN,SIZE-BROKEN-LLVM # RUN: llvm-readelf %t15.size --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t15.size \ # RUN: --implicit-check-not="Symbol table" --check-prefix=SIZE-BROKEN # SIZE-BROKEN: warning: '[[FILE]]': unable to read dynamic symbols from SHT_DYNSYM section with index 1: offset (0x34) + size (0xffffffff) is greater than the file size (0x148) # SIZE-BROKEN-LLVM: DynamicSymbols [ # SIZE-BROKEN-LLVM-NEXT: ] ## d) check we report a warning when the sh_link field of the SHT_DYNSYM section ## is not a valid section index or is not an index of a valid string table. # RUN: yaml2obj --docnum=14 %s -DLINK=0xffffffff -o %t16.link # RUN: llvm-readobj %t16.link --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \ # RUN: --check-prefixes=LINK-BROKEN1,LINK-BROKEN-LLVM --implicit-check-not=warning: # RUN: llvm-readelf %t16.link --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \ # RUN: --check-prefixes=LINK-BROKEN1,LINK-BROKEN-GNU --implicit-check-not=warning: ## Also test that we are able to dump section headers even if the .dynsym section's sh_link field is broken. # RUN: llvm-readobj %t16.link --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \ # RUN: --check-prefixes=LINK-BROKEN1,LINK-SEC-HDRS-LLVM,LINK-BROKEN-LLVM --implicit-check-not=warning: # RUN: llvm-readelf %t16.link --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \ # RUN: --check-prefixes=LINK-BROKEN1,LINK-SEC-HDRS-GNU,LINK-BROKEN-GNU # RUN: yaml2obj --docnum=14 %s -DLINK=0x0 -o %t16.link.0 # RUN: llvm-readobj %t16.link.0 --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link.0 \ # RUN: --check-prefixes=LINK-BROKEN2,LINK-BROKEN-LLVM --implicit-check-not=warning: # RUN: llvm-readelf %t16.link.0 --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link.0 \ # RUN: --check-prefixes=LINK-BROKEN2,LINK-BROKEN-GNU --implicit-check-not=warning: ## Also test that we are able to dump section headers even if the .dynsym section's sh_link field is broken. # RUN: llvm-readobj %t16.link.0 --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link.0 \ # RUN: --check-prefixes=LINK-BROKEN2,LINK-SEC-HDRS-LLVM,LINK-BROKEN-LLVM --implicit-check-not=warning: # RUN: llvm-readelf %t16.link.0 --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link.0 \ # RUN: --check-prefixes=LINK-BROKEN2,LINK-SEC-HDRS-GNU,LINK-BROKEN-GNU --implicit-check-not=warning: # LINK-BROKEN1: warning: '[[FILE]]': unable to get the string table for the SHT_DYNSYM section with index 1: invalid section index: 4294967295 # LINK-BROKEN2: warning: '[[FILE]]': unable to get the string table for the SHT_DYNSYM section with index 1: invalid sh_type for string table section [index 0]: expected SHT_STRTAB, but got SHT_NULL # LINK-SEC-HDRS-LLVM: Sections [ # LINK-SEC-HDRS-GNU: There are 5 section headers, starting at offset 0x80: # LINK-BROKEN-LLVM: DynamicSymbols [ # LINK-BROKEN-LLVM-NEXT: warning: '[[FILE]]': st_name (0x0) is past the end of the string table of size 0x0 # LINK-BROKEN-LLVM-NEXT: Symbol { # LINK-BROKEN-LLVM-NEXT: Name: (0) # LINK-BROKEN-LLVM-NEXT: Value: 0x0 # LINK-BROKEN-LLVM-NEXT: Size: 0 # LINK-BROKEN-LLVM-NEXT: Binding: Local (0x0) # LINK-BROKEN-LLVM-NEXT: Type: None (0x0) # LINK-BROKEN-LLVM-NEXT: Other: 0 # LINK-BROKEN-LLVM-NEXT: Section: Undefined (0x0) # LINK-BROKEN-LLVM-NEXT: } # LINK-BROKEN-LLVM-NEXT: warning: '[[FILE]]': st_name (0x1) is past the end of the string table of size 0x0 # LINK-BROKEN-LLVM-NEXT: Symbol { # LINK-BROKEN-LLVM-NEXT: Name: (1) # LINK-BROKEN-LLVM-NEXT: Value: 0x0 # LINK-BROKEN-LLVM-NEXT: Size: 0 # LINK-BROKEN-LLVM-NEXT: Binding: Local (0x0) # LINK-BROKEN-LLVM-NEXT: Type: None (0x0) # LINK-BROKEN-LLVM-NEXT: Other: 0 # LINK-BROKEN-LLVM-NEXT: Section: Undefined (0x0) # LINK-BROKEN-LLVM-NEXT: } # LINK-BROKEN-LLVM-NEXT: ] # LINK-BROKEN-GNU: Symbol table '.dynsym' contains 2 entries: # LINK-BROKEN-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name # LINK-BROKEN-GNU-NEXT: warning: '[[FILE]]': st_name (0x0) is past the end of the string table of size 0x0 # LINK-BROKEN-GNU-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND # LINK-BROKEN-GNU-NEXT: warning: '[[FILE]]': st_name (0x1) is past the end of the string table of size 0x0 # LINK-BROKEN-GNU-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT UND