Commit 2930dab3 authored by Georgii Rymar's avatar Georgii Rymar
Browse files

[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
parent 4fb1adcd
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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:
+0 −49
Original line number Diff line number Diff line
## 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
+375 −0
Original line number Diff line number Diff line
## 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
+52 −0
Original line number Diff line number Diff line
@@ -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
+4 −4
Original line number Diff line number Diff line
@@ -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:
Loading