## 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 Machine: EM_X86_64 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 Sections: - Section: .dynsym ## Case 2: 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 ## Case 3: 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 | FileCheck %s --check-prefix=NOPHDRS-LLVM # RUN: llvm-readelf %t2.so --dyn-symbols | FileCheck %s --check-prefix=NOPHDRS-GNU # NOPHDRS-LLVM: Name: foo # NOPHDRS-GNU: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND foo --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN Machine: EM_X86_64 Sections: - Name: .dynamic Type: SHT_DYNAMIC Entries: - Tag: DT_SYMTAB Value: 0xffff1234 - Tag: DT_NULL Value: 0 DynamicSymbols: - Name: foo ## 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 Machine: EM_X86_64 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 Machine: EM_X86_64 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 Sections: - Section: .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 Machine: EM_X86_64 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 Sections: - Section: .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 Machine: EM_X86_64 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: bar - Name: zed