[llvm-readobj] - Improve error message reported by DynRegionInfo.

DynRegionInfo is a helper class used to create memory ranges.
It is used for many things and can report errors.
Errors reported currently do not provide a good diagnostic.
This patch fixes it and adds a test for each possible case.

Differential revision: https://reviews.llvm.org/D73484
This commit is contained in:
Georgii Rymar 2020-01-23 18:56:24 +03:00
parent 4fb1adcde2
commit 2930dab315
8 changed files with 487 additions and 70 deletions

View File

@ -137,7 +137,7 @@ Symbols:
# RUN: yaml2obj %s --docnum=7 -o %t7
# RUN: llvm-readobj --dyn-symbols %t7 2>&1 | FileCheck -DFILE=%t7 --check-prefix=INVALID-DYNSYM-SIZE %s
# INVALID-DYNSYM-SIZE: warning: '[[FILE]]': invalid section size (48) or entity size (32)
# INVALID-DYNSYM-SIZE: warning: '[[FILE]]': section with index 1 has invalid size (0x30) or entry size (0x20)
--- !ELF
FileHeader:
@ -474,7 +474,7 @@ ProgramHeaders:
# RUN: %p/Inputs/corrupt-invalid-relocation-size.elf.x86-64 2>&1 \
# RUN: | FileCheck -DFILE=%p/Inputs/corrupt-invalid-relocation-size.elf.x86-64 --check-prefix=RELOC-BROKEN-ENTSIZE %s
# RELOC-BROKEN-ENTSIZE: warning: '[[FILE]]': invalid section size (24) or entity size (25)
# RELOC-BROKEN-ENTSIZE: warning: '[[FILE]]': invalid DT_RELASZ value (0x18) or DT_RELAENT value (0x19)
## Check that llvm-readobj reports a warning when .dynamic section has an invalid
## size, which isn't a multiple of the dynamic entry size.
@ -482,7 +482,7 @@ ProgramHeaders:
# RUN: yaml2obj %s --docnum=22 -o %t22
# RUN: llvm-readobj --dyn-relocations %t22 2>&1 | FileCheck -DFILE=%t22 --check-prefix=DYN-TABLE-SIZE %s
# DYN-TABLE-SIZE: warning: '[[FILE]]': invalid section size (1) or entity size (16)
# DYN-TABLE-SIZE: warning: '[[FILE]]': section with index 1 has invalid size (0x1){{$}}
--- !ELF
FileHeader:

View File

@ -1,49 +0,0 @@
## Check that llvm-readobj/llvm-readelf reports an error when dumping relocations if a dynamic
## symbol name offset is broken (goes past the end of the dynamic symbol string table).
# RUN: yaml2obj %s -o %t
# RUN: llvm-readobj --dyn-relocations %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=LLVM
# RUN: llvm-readelf --dyn-relocations %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=GNU
# LLVM: Dynamic Relocations {
# LLVM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 1: st_name (0x1234) is past the end of the string table of size 0x1
# LLVM-NEXT: 0x0 R_X86_64_NONE <corrupt> 0x0
# LLVM-NEXT: }
# GNU: 'RELA' relocation section at offset {{.+}} contains 24 bytes:
# GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
# GNU-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 1: st_name (0x1234) is past the end of the string table of size 0x1
# GNU-NEXT: 0000000000000000 0000000100000000 R_X86_64_NONE 0000000000000000 <corrupt> + 0
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .rela.dyn
Type: SHT_RELA
Link: .dynsym
Relocations:
- Offset: 0x0
Symbol: 1 ## Index of a dynamic symbol with a broken st_name.
Type: R_X86_64_NONE
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_RELA
Value: 0x0000000000000000
- Tag: DT_RELASZ
Value: 0x0000000000000018
- Tag: DT_RELAENT
Value: 0x0000000000000018
- Tag: DT_NULL
Value: 0x0000000000000000
DynamicSymbols:
- NameIndex: 0x1234
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .rela.dyn
- Section: .dynamic

View File

@ -0,0 +1,375 @@
## Test how we handle cases when dynamic relocations or corresponding dynamic tags are broken.
## Check that llvm-readobj/llvm-readelf reports an error when dumping relocations if a dynamic
## symbol name offset is broken (goes past the end of the dynamic symbol string table).
# RUN: yaml2obj --docnum=1 %s -o %t1
# RUN: llvm-readobj --dyn-relocations %t1 2>&1 | FileCheck %s -DFILE=%t1 --check-prefix=LLVM
# RUN: llvm-readelf --dyn-relocations %t1 2>&1 | FileCheck %s -DFILE=%t1 --check-prefix=GNU
# LLVM: Dynamic Relocations {
# LLVM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 1: st_name (0x1234) is past the end of the string table of size 0x1
# LLVM-NEXT: 0x0 R_X86_64_NONE <corrupt> 0x0
# LLVM-NEXT: }
# GNU: 'RELA' relocation section at offset {{.+}} contains 24 bytes:
# GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
# GNU-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 1: st_name (0x1234) is past the end of the string table of size 0x1
# GNU-NEXT: 0000000000000000 0000000100000000 R_X86_64_NONE 0000000000000000 <corrupt> + 0
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .rela.dyn
Type: SHT_RELA
Link: .dynsym
Relocations:
- Offset: 0x0
Symbol: 1 ## Index of a dynamic symbol with a broken st_name.
Type: R_X86_64_NONE
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_RELA
Value: 0x0000000000000000
- Tag: DT_RELASZ
Value: 0x0000000000000018
- Tag: DT_RELAENT
Value: 0x0000000000000018
- Tag: DT_NULL
Value: 0x0000000000000000
DynamicSymbols:
- NameIndex: 0x1234
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .rela.dyn
- Section: .dynamic
## Show we print a warning for an invalid relocation table size stored in a DT_RELASZ entry.
# RUN: yaml2obj --docnum=2 %s -o %t2
# RUN: llvm-readobj --dyn-relocations %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=INVALID-DT-RELASZ
# RUN: llvm-readelf --dyn-relocations %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=INVALID-DT-RELASZ
# INVALID-DT-RELASZ: warning: '[[FILE]]': invalid DT_RELASZ value (0xff) or DT_RELAENT value (0x18)
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .rela.dyn
Type: SHT_RELA
Relocations:
- Offset: 0x0
Type: R_X86_64_NONE
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_RELA
Value: 0x0
- Tag: DT_RELASZ
Value: 0xFF
- Tag: DT_RELAENT
Value: 0x18
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .rela.dyn
- Section: .dynamic
## Show we print a warning for an invalid relocation table entry size stored in a DT_RELAENT entry.
# RUN: yaml2obj --docnum=3 %s -o %t3
# RUN: llvm-readobj --dyn-relocations %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=INVALID-DT-RELAENT
# RUN: llvm-readelf --dyn-relocations %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=INVALID-DT-RELAENT
## INVALID-DT-RELAENT: warning: '[[FILE]]': invalid DT_RELASZ value (0x18) or DT_RELAENT value (0xff)
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .rela.dyn
Type: SHT_RELA
Relocations:
- Offset: 0x0
Type: R_X86_64_NONE
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_RELA
Value: 0x0
- Tag: DT_RELASZ
Value: 0x18
- Tag: DT_RELAENT
Value: 0xFF
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .rela.dyn
- Section: .dynamic
## Show we print a warning for an invalid relocation table size stored in a DT_RELSZ entry.
# RUN: yaml2obj --docnum=4 %s -o %t4
# RUN: llvm-readobj --dyn-relocations %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=INVALID-DT-RELSZ
# RUN: llvm-readelf --dyn-relocations %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=INVALID-DT-RELSZ
## INVALID-DT-RELSZ: warning: '[[FILE]]': invalid DT_RELSZ value (0xff) or DT_RELENT value (0x18)
--- !ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_386
Sections:
- Name: .rela.dyn
Type: SHT_REL
Relocations:
- Offset: 0x0
Type: R_386_NONE
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_REL
Value: 0x0
- Tag: DT_RELSZ
Value: 0xFF
- Tag: DT_RELENT
Value: 0x18
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .rela.dyn
- Section: .dynamic
## Show we print a warning for an invalid relocation table entry size stored in a DT_RELENT entry.
# RUN: yaml2obj --docnum=5 %s -o %t5
# RUN: llvm-readobj --dyn-relocations %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=INVALID-DT-RELENT
# RUN: llvm-readelf --dyn-relocations %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=INVALID-DT-RELENT
## INVALID-DT-RELENT: warning: '[[FILE]]': invalid DT_RELSZ value (0x18) or DT_RELENT value (0xff)
--- !ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_386
Sections:
- Name: .rela.dyn
Type: SHT_REL
Relocations:
- Offset: 0x0
Type: R_386_NONE
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_REL
Value: 0x0
- Tag: DT_RELSZ
Value: 0x18
- Tag: DT_RELENT
Value: 0xFF
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .rela.dyn
- Section: .dynamic
## Show we print a warning for an invalid relocation table size stored in a DT_RELRSZ/DT_ANDROID_RELRSZ entry.
# RUN: yaml2obj --docnum=6 %s -o %t6
# RUN: llvm-readobj --dyn-relocations %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=INVALID-DT-RELRSZ
# RUN: llvm-readelf --dyn-relocations %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=INVALID-DT-RELRSZ
# RUN: yaml2obj --docnum=7 %s -o %t7
# RUN: llvm-readobj --dyn-relocations %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=INVALID-DT-ANDROID-RELRSZ
# RUN: llvm-readelf --dyn-relocations %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=INVALID-DT-ANDROID-RELRSZ
## INVALID-DT-RELRSZ: warning: '[[FILE]]': invalid DT_RELRSZ value (0xff) or DT_RELRENT value (0x18)
## INVALID-DT-ANDROID-RELRSZ: warning: '[[FILE]]': invalid DT_ANDROID_RELRSZ value (0xff) or DT_ANDROID_RELRENT value (0x18)
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .relr.dyn
Type: SHT_RELR
Flags: [ SHF_ALLOC ]
Content: ""
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_RELR
Value: 0x0
- Tag: DT_RELRSZ
Value: 0xFF
- Tag: DT_RELRENT
Value: 0x18
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .relr.dyn
- Section: .dynamic
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .relr.dyn
Type: SHT_RELR
Flags: [ SHF_ALLOC ]
Content: ""
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_RELR
Value: 0x0
- Tag: DT_ANDROID_RELRSZ
Value: 0xFF
- Tag: DT_ANDROID_RELRENT
Value: 0x18
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .relr.dyn
- Section: .dynamic
## Show we print a warning for an invalid relocation table entry size stored in a DT_RELRENT/DT_ANDROID_RELRENT entry.
# RUN: yaml2obj --docnum=8 %s -o %t8
# RUN: llvm-readobj --dyn-relocations %t8 2>&1 | FileCheck %s -DFILE=%t8 --check-prefix=INVALID-DT-RELRENT
# RUN: llvm-readelf --dyn-relocations %t8 2>&1 | FileCheck %s -DFILE=%t8 --check-prefix=INVALID-DT-RELRENT
# RUN: yaml2obj --docnum=9 %s -o %t9
# RUN: llvm-readobj --dyn-relocations %t9 2>&1 | FileCheck %s -DFILE=%t9 --check-prefix=INVALID-DT-ANDROID-RELRENT
# RUN: llvm-readelf --dyn-relocations %t9 2>&1 | FileCheck %s -DFILE=%t9 --check-prefix=INVALID-DT-ANDROID-RELRENT
## INVALID-DT-RELRENT: invalid DT_RELRSZ value (0x18) or DT_RELRENT value (0xff)
## INVALID-DT-ANDROID-RELRENT: invalid DT_ANDROID_RELRSZ value (0x18) or DT_ANDROID_RELRENT value (0xff)
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .relr.dyn
Type: SHT_RELR
Flags: [ SHF_ALLOC ]
Content: ""
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_RELR
Value: 0x0
- Tag: DT_RELRSZ
Value: 0x18
- Tag: DT_RELRENT
Value: 0xFF
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .relr.dyn
- Section: .dynamic
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .relr.dyn
Type: SHT_RELR
Flags: [ SHF_ALLOC ]
Content: ""
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_RELR
Value: 0x0
- Tag: DT_ANDROID_RELRSZ
Value: 0x18
- Tag: DT_ANDROID_RELRENT
Value: 0xFF
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .relr.dyn
- Section: .dynamic
## Show we print a warning for an invalid value of DT_PLTRELSZ, which describes the total size
## of the relocation entries associated with the procedure linkage table.
# RUN: yaml2obj --docnum=10 %s -o %t10
# RUN: llvm-readobj --dyn-relocations %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=INVALID-DT-PLTRELSZ
# RUN: llvm-readelf --dyn-relocations %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=INVALID-DT-PLTRELSZ
# INVALID-DT-PLTRELSZ: warning: '[[FILE]]': invalid DT_PLTRELSZ value (0xff){{$}}
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .rela.plt
Type: SHT_RELA
Relocations:
- Offset: 0x0
Type: R_X86_64_NONE
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_JMPREL
Value: 0x0
- Tag: DT_PLTRELSZ
Value: 0xFF ## The valid value would be 0x18.
- Tag: DT_PLTREL
Value: 0x7 ## DT_RELA
- Tag: DT_NULL
Value: 0x0
DynamicSymbols: []
ProgramHeaders:
- Type: PT_LOAD
Sections:
- Section: .rela.plt
- Section: .dynamic

View File

@ -349,3 +349,55 @@ FileHeader:
Type: ET_DYN
Machine: EM_386
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
## 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-INVALID1: warning: '[[FILE]]': section with index 1 has invalid size (0x1) or entry size (0x10)
# DYNSYM-SIZE-INVALID2: warning: '[[FILE]]': section with index 2 has invalid size (0x1){{$}}
--- !ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_386
Sections:
- Name: .dynsym
Type: SHT_DYNSYM
Size: 0x1
--- !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
Size: 0x1
ProgramHeaders:
- Type: PT_LOAD
VAddr: 0x100
Sections:
- Section: .dynsym

View File

@ -7,8 +7,8 @@
# RUN: llvm-readelf --all %t.bad-size 2>&1 \
# RUN: | FileCheck %s -DFILE=%t.bad-size --implicit-check-not=warning --check-prefix WARN-GNU
# WARN: warning: '[[FILE]]': invalid section size (4) or entity size (16)
# WARN: warning: '[[FILE]]': invalid section size (4) or entity size (16)
# WARN: warning: '[[FILE]]': invalid PT_DYNAMIC size (0x4){{$}}
# WARN: warning: '[[FILE]]': section with index 1 has invalid size (0x4){{$}}
# WARN: warning: '[[FILE]]': no valid dynamic table was found
# WARN-EMPTY:
# WARN: File:
@ -16,8 +16,8 @@
# WARN: ]
# WARN: ProgramHeaders [
# WARN-GNU: warning: '[[FILE]]': invalid section size (4) or entity size (16)
# WARN-GNU: warning: '[[FILE]]': invalid section size (4) or entity size (16)
# WARN-GNU: warning: '[[FILE]]': invalid PT_DYNAMIC size (0x4){{$}}
# WARN-GNU: warning: '[[FILE]]': section with index 1 has invalid size (0x4){{$}}
# WARN-GNU: warning: '[[FILE]]': no valid dynamic table was found
# WARN-GNU-NEXT: ELF Header:
# WARN-GNU: Symbol table '.symtab' contains 1 entries:

View File

@ -12,7 +12,7 @@
# RUN: | FileCheck -DFILE=%t1.o --check-prefixes=WARNING1,GNU1 %s
# WARNING1: warning: '[[FILE]]': The SHT_DYNAMIC section '.dynamic' is not contained within the PT_DYNAMIC segment
# WARNING1: warning: '[[FILE]]': invalid section size (1) or entity size (16)
# WARNING1: warning: '[[FILE]]': invalid PT_DYNAMIC size (0x1){{$}}
# WARNING1: warning: '[[FILE]]': SHT_DYNAMIC section header and PT_DYNAMIC program header disagree about the location of the dynamic table
# WARNING1: warning: '[[FILE]]': PT_DYNAMIC dynamic table is invalid: SHT_DYNAMIC will be used
@ -124,7 +124,7 @@ ProgramHeaders:
# RUN: llvm-readelf --dynamic-table %t3.o 2>&1 \
# RUN: | FileCheck -DFILE=%t3.o --check-prefix=WARNING3 --implicit-check-not="Dynamic" %s
# WARNING3: warning: '[[FILE]]': invalid section size (1) or entity size (16)
# WARNING3: warning: '[[FILE]]': invalid PT_DYNAMIC size (0x1){{$}}
# WARNING3: warning: '[[FILE]]': SHT_DYNAMIC section header and PT_DYNAMIC program header disagree about the location of the dynamic table
# WARNING3: warning: '[[FILE]]': no valid dynamic table was found

View File

@ -11,7 +11,7 @@
# RUN: | FileCheck %s --DFILE=%t1.o --check-prefixes=WARNING,GNU
# WARNING: warning: '[[FILE]]': The SHT_DYNAMIC section '.dynamic' is not at the start of PT_DYNAMIC segment
# WARNING: warning: '[[FILE]]': invalid section size (33) or entity size (16)
# WARNING: warning: '[[FILE]]': invalid PT_DYNAMIC size (0x21){{$}}
# WARNING: warning: '[[FILE]]': SHT_DYNAMIC section header and PT_DYNAMIC program header disagree about the location of the dynamic table
# WARNING: warning: '[[FILE]]': PT_DYNAMIC dynamic table is invalid: SHT_DYNAMIC will be used
@ -122,7 +122,7 @@ ProgramHeaders:
# RUN: llvm-readobj --dynamic-table %t3.o 2>&1 | FileCheck %s --DFILE=%t3.o --check-prefixes=WARNING2,LLVM3
# RUN: llvm-readelf --dynamic-table %t3.o 2>&1 | FileCheck %s --DFILE=%t3.o --check-prefixes=WARNING2,GNU3
# WARNING2: warning: '[[FILE]]': invalid section size (257) or entity size (16)
# WARNING2: warning: '[[FILE]]': invalid PT_DYNAMIC size (0x101){{$}}
# WARNING2: warning: '[[FILE]]': PT_DYNAMIC dynamic table is invalid: SHT_DYNAMIC will be used
# LLVM3: DynamicSection [ (2 entries)

View File

@ -135,19 +135,34 @@ struct DynRegionInfo {
/// Name of the file. Used for error reporting.
StringRef FileName;
/// Error prefix. Used for error reporting to provide more information.
std::string Context;
/// Region size name. Used for error reporting.
StringRef SizePrintName = "size";
/// Entry size name. Used for error reporting. If this field is empty, errors
/// will not mention the entry size.
StringRef EntSizePrintName = "entry size";
template <typename Type> ArrayRef<Type> getAsArrayRef() const {
const Type *Start = reinterpret_cast<const Type *>(Addr);
if (!Start)
return {Start, Start};
if (EntSize != sizeof(Type) || Size % EntSize) {
// TODO: Add a section index to this warning.
reportWarning(createError("invalid section size (" + Twine(Size) +
") or entity size (" + Twine(EntSize) + ")"),
FileName);
return {Start, Start};
}
return {Start, Start + (Size / EntSize)};
if (EntSize == sizeof(Type) && (Size % EntSize == 0))
return {Start, Start + (Size / EntSize)};
std::string Msg;
if (!Context.empty())
Msg += Context + " has ";
Msg += ("invalid " + SizePrintName + " (0x" + Twine::utohexstr(Size) + ")")
.str();
if (!EntSizePrintName.empty())
Msg +=
(" or " + EntSizePrintName + " (0x" + Twine::utohexstr(EntSize) + ")")
.str();
reportWarning(createError(Msg.c_str()), FileName);
return {Start, Start};
}
};
@ -1847,6 +1862,9 @@ void ELFDumper<ELFT>::loadDynamicTable(const ELFFile<ELFT> *Obj) {
bool IsPhdrTableValid = false;
if (DynamicPhdr) {
FromPhdr = createDRIFrom(DynamicPhdr, sizeof(Elf_Dyn));
FromPhdr.SizePrintName = "PT_DYNAMIC size";
FromPhdr.EntSizePrintName = "";
IsPhdrTableValid = !FromPhdr.getAsArrayRef<Elf_Dyn>().empty();
}
@ -1860,6 +1878,11 @@ void ELFDumper<ELFT>::loadDynamicTable(const ELFFile<ELFT> *Obj) {
FromSec =
checkDRI({ObjF->getELFFile()->base() + DynamicSec->sh_offset,
DynamicSec->sh_size, sizeof(Elf_Dyn), ObjF->getFileName()});
FromSec.Context = ("section with index " +
Twine(DynamicSec - &cantFail(Obj->sections()).front()))
.str();
FromSec.EntSizePrintName = "";
IsSecTableValid = !FromSec.getAsArrayRef<Elf_Dyn>().empty();
}
@ -1920,8 +1943,9 @@ ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
DynPLTRelRegion(ObjF->getFileName()), DynSymRegion(ObjF->getFileName()),
DynamicTable(ObjF->getFileName()) {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
for (const Elf_Shdr &Sec :
unwrapOrError(ObjF->getFileName(), Obj->sections())) {
typename ELFT::ShdrRange Sections =
unwrapOrError(ObjF->getFileName(), Obj->sections());
for (const Elf_Shdr &Sec : Sections) {
switch (Sec.sh_type) {
case ELF::SHT_SYMTAB:
if (!DotSymtabSec)
@ -1930,6 +1954,8 @@ ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
case ELF::SHT_DYNSYM:
if (!DynSymRegion.Size) {
DynSymRegion = createDRIFrom(&Sec);
DynSymRegion.Context =
("section with index " + Twine(&Sec - &Sections.front())).str();
// This is only used (if Elf_Shdr present)for naming section in GNU
// style
DynSymtabName =
@ -2030,6 +2056,7 @@ void ELFDumper<ELFT>::parseDynamicTable(const ELFFile<ELFT> *Obj) {
DynSymRegion.Addr = VA;
DynSymRegion.EntSize = sizeof(Elf_Sym);
DynSymRegion.EntSizePrintName = "";
}
break;
}
@ -2038,9 +2065,11 @@ void ELFDumper<ELFT>::parseDynamicTable(const ELFFile<ELFT> *Obj) {
break;
case ELF::DT_RELASZ:
DynRelaRegion.Size = Dyn.getVal();
DynRelaRegion.SizePrintName = "DT_RELASZ value";
break;
case ELF::DT_RELAENT:
DynRelaRegion.EntSize = Dyn.getVal();
DynRelaRegion.EntSizePrintName = "DT_RELAENT value";
break;
case ELF::DT_SONAME:
SONameOffset = Dyn.getVal();
@ -2050,9 +2079,11 @@ void ELFDumper<ELFT>::parseDynamicTable(const ELFFile<ELFT> *Obj) {
break;
case ELF::DT_RELSZ:
DynRelRegion.Size = Dyn.getVal();
DynRelRegion.SizePrintName = "DT_RELSZ value";
break;
case ELF::DT_RELENT:
DynRelRegion.EntSize = Dyn.getVal();
DynRelRegion.EntSizePrintName = "DT_RELENT value";
break;
case ELF::DT_RELR:
case ELF::DT_ANDROID_RELR:
@ -2061,10 +2092,16 @@ void ELFDumper<ELFT>::parseDynamicTable(const ELFFile<ELFT> *Obj) {
case ELF::DT_RELRSZ:
case ELF::DT_ANDROID_RELRSZ:
DynRelrRegion.Size = Dyn.getVal();
DynRelrRegion.SizePrintName = Dyn.d_tag == ELF::DT_RELRSZ
? "DT_RELRSZ value"
: "DT_ANDROID_RELRSZ value";
break;
case ELF::DT_RELRENT:
case ELF::DT_ANDROID_RELRENT:
DynRelrRegion.EntSize = Dyn.getVal();
DynRelrRegion.EntSizePrintName = Dyn.d_tag == ELF::DT_RELRENT
? "DT_RELRENT value"
: "DT_ANDROID_RELRENT value";
break;
case ELF::DT_PLTREL:
if (Dyn.getVal() == DT_REL)
@ -2075,12 +2112,14 @@ void ELFDumper<ELFT>::parseDynamicTable(const ELFFile<ELFT> *Obj) {
reportError(createError(Twine("unknown DT_PLTREL value of ") +
Twine((uint64_t)Dyn.getVal())),
ObjF->getFileName());
DynPLTRelRegion.EntSizePrintName = "";
break;
case ELF::DT_JMPREL:
DynPLTRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
break;
case ELF::DT_PLTRELSZ:
DynPLTRelRegion.Size = Dyn.getVal();
DynPLTRelRegion.SizePrintName = "DT_PLTRELSZ value";
break;
}
}