mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[llvm-readelf] - Allow dumping dynamic symbols when there is no program headers.
D62179 introduced a regression. llvm-readelf lose the ability to dump the dynamic symbols when there is .dynamic section with a DT_SYMTAB, but there are no program headers: https://reviews.llvm.org/D62179#1652778 Below is a program flow before the D62179 change: 1) Find SHT_DYNSYM. 2) Find there is no PT_DYNAMIC => don't try to parse it. 3) Print dynamic symbols using information about them found on step (1). And after the change it became: 1) Find SHT_DYNSYM. 2) Find there is no PT_DYNAMIC => find SHT_DYNAMIC. 3) Parse dynamic table, but fail to handle the DT_SYMTAB because of the absence of the PT_LOAD. Report the "Virtual address is not in any segment" error. This patch fixes the issue. For doing this it checks that the value of DT_SYMTAB was mapped to a segment. If not - it ignores it. Differential revision: https://reviews.llvm.org/D67078 llvm-svn: 371071
This commit is contained in:
parent
03965166e2
commit
2e7c3b12d7
@ -1,10 +1,11 @@
|
||||
RUN: llvm-readobj --dyn-symbols %p/Inputs/dynamic-table-so.x86 | FileCheck %s
|
||||
# RUN: llvm-readobj --dyn-symbols %p/Inputs/dynamic-table-so.x86 | FileCheck %s
|
||||
|
||||
# Check the two-letter alias --dt is equivalent to the --dyn-symbols full flag
|
||||
# name.
|
||||
RUN: llvm-readobj --dt %p/Inputs/dynamic-table-so.x86 > %t.readobj-dt-alias
|
||||
RUN: llvm-readobj --dyn-symbols %p/Inputs/dynamic-table-so.x86 > %t.readobj-dt-no-alias
|
||||
RUN: diff %t.readobj-dt-alias %t.readobj-dt-no-alias
|
||||
## Check the two-letter alias --dt is equivalent to the --dyn-symbols full flag
|
||||
## name.
|
||||
|
||||
# RUN: llvm-readobj --dt %p/Inputs/dynamic-table-so.x86 > %t.readobj-dt-alias
|
||||
# RUN: llvm-readobj --dyn-symbols %p/Inputs/dynamic-table-so.x86 > %t.readobj-dt-no-alias
|
||||
# RUN: diff %t.readobj-dt-alias %t.readobj-dt-no-alias
|
||||
|
||||
# CHECK: DynamicSymbols [
|
||||
# CHECK-NEXT: Symbol {
|
||||
@ -161,3 +162,125 @@ RUN: diff %t.readobj-dt-alias %t.readobj-dt-no-alias
|
||||
# CHECK-NEXT: Section: .fini
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
## 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=1 %s -o %t1.so
|
||||
# RUN: llvm-readobj %t1.so --dyn-symbols | FileCheck %s --check-prefix=NOPHDRS
|
||||
|
||||
# NOPHDRS: Name: 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
|
||||
|
||||
## 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=2 %s -o %t2.so
|
||||
# RUN: llvm-readobj %t2.so --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t2.so --check-prefix=NOSHT-DYNSYM
|
||||
|
||||
# NOSHT-DYNSYM: warning: '[[FILE]]': Unable to parse DT_SYMTAB: virtual address is not in any segment: 0x0
|
||||
# NOSHT-DYNSYM: DynamicSymbols [
|
||||
# NOSHT-DYNSYM-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
|
||||
|
||||
## 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=3 %s -o %t3.so
|
||||
# RUN: llvm-readobj %t3.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t3.so %s --check-prefix=BROKEN-DTSYMTAB
|
||||
|
||||
# BROKEN-DTSYMTAB: warning: '[[FILE]]': Unable to parse DT_SYMTAB: virtual address is not in any segment: 0xffff1234
|
||||
# BROKEN-DTSYMTAB: Name: 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
|
||||
|
||||
## 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=4 %s -o %t4.so
|
||||
# RUN: llvm-readobj %t4.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefix=PREFER-DTSYMTAB
|
||||
|
||||
# PREFER-DTSYMTAB: warning: '[[FILE]]': SHT_DYNSYM section header and DT_SYMTAB disagree about the location of the dynamic symbol table
|
||||
# PREFER-DTSYMTAB: Name: 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
|
||||
|
@ -1643,10 +1643,29 @@ template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() {
|
||||
case ELF::DT_STRSZ:
|
||||
StringTableSize = Dyn.getVal();
|
||||
break;
|
||||
case ELF::DT_SYMTAB:
|
||||
DynSymRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
|
||||
DynSymRegion.EntSize = sizeof(Elf_Sym);
|
||||
case ELF::DT_SYMTAB: {
|
||||
// Often we find the information about the dynamic symbol table
|
||||
// location in the SHT_DYNSYM section header. However, the value in
|
||||
// DT_SYMTAB has priority, because it is used by dynamic loaders to
|
||||
// locate .dynsym at runtime. The location we find in the section header
|
||||
// and the location we find here should match. If we can't map the
|
||||
// DT_SYMTAB value to an address (e.g. when there are no program headers), we
|
||||
// ignore its value.
|
||||
if (const uint8_t *VA = toMappedAddr(Dyn.getTag(), Dyn.getPtr())) {
|
||||
// EntSize is non-zero if the dynamic symbol table has been found via a
|
||||
// section header.
|
||||
if (DynSymRegion.EntSize && VA != DynSymRegion.Addr)
|
||||
reportWarning(
|
||||
createError(
|
||||
"SHT_DYNSYM section header and DT_SYMTAB disagree about "
|
||||
"the location of the dynamic symbol table"),
|
||||
ObjF->getFileName());
|
||||
|
||||
DynSymRegion.Addr = VA;
|
||||
DynSymRegion.EntSize = sizeof(Elf_Sym);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ELF::DT_RELA:
|
||||
DynRelaRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user