[libObject, llvm-readobj] - Reimplement `ELFFile<ELFT>::getEntry`.
authorGeorgii Rymar <grimar@accesssoftek.com>
Fri, 11 Dec 2020 11:54:39 +0000 (14:54 +0300)
committerGeorgii Rymar <grimar@accesssoftek.com>
Fri, 18 Dec 2020 13:52:27 +0000 (16:52 +0300)
Currently, `ELFFile<ELFT>::getEntry` does not check an index of
an entry. Because of that the code might read past the end of the symbol
table silently. I've added a test to `llvm-readobj\ELF\relocations.test`
to demonstrate the possible issue. Also, I've added a unit test for
this method.

After this change, `getEntry` stops reporting the section index and
reuses the `getSectionContentsAsArray` method, which already has
all the validation needed. Our related warnings now provide
more and better context sometimes.

Differential revision: https://reviews.llvm.org/D93209

16 files changed:
lld/test/ELF/invalid/dynamic-section-broken.test
llvm/include/llvm/Object/ELF.h
llvm/test/Object/invalid.test
llvm/test/tools/llvm-readobj/ELF/call-graph-profile.test
llvm/test/tools/llvm-readobj/ELF/reloc-symbol-with-versioning.test
llvm/test/tools/llvm-readobj/ELF/relocation-errors.test
llvm/test/tools/llvm-readobj/ELF/relocations.test
llvm/test/tools/llvm-readobj/ELF/relr-relocs.test
llvm/test/tools/llvm-readobj/ELF/stack-sizes.test
llvm/test/tools/llvm-readobj/ELF/symbols.test
llvm/test/tools/llvm-readobj/ELF/versym-invalid.test
llvm/test/tools/obj2yaml/ELF/dynamic-section.yaml
llvm/test/tools/obj2yaml/ELF/rel-rela-section.yaml
llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml
llvm/tools/llvm-readobj/ELFDumper.cpp
llvm/unittests/Object/ELFObjectFileTest.cpp

index 31317f6..62f3114 100644 (file)
@@ -1,7 +1,7 @@
 ## .dynamic section has invalid sh_entsize, check we report it.
 # RUN: yaml2obj --docnum=1 %s -o %t.so
 # RUN: not ld.lld %t.so -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
-# ERR1: error: {{.*}}.so: section [index 1] has an invalid sh_entsize: 291
+# ERR1: error: {{.*}}.so: section [index 1] has invalid sh_entsize: expected 16, but got 291
 
 --- !ELF
 FileHeader:
index efe518f..25f2df4 100644 (file)
@@ -412,7 +412,8 @@ Expected<ArrayRef<T>>
 ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr &Sec) const {
   if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1)
     return createError("section " + getSecIndexForError(*this, Sec) +
-                       " has an invalid sh_entsize: " + Twine(Sec.sh_entsize));
+                       " has invalid sh_entsize: expected " + Twine(sizeof(T)) +
+                       ", but got " + Twine(Sec.sh_entsize));
 
   uintX_t Offset = Sec.sh_offset;
   uintX_t Size = Sec.sh_size;
@@ -618,17 +619,17 @@ template <class ELFT>
 template <typename T>
 Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr &Section,
                                             uint32_t Entry) const {
-  if (sizeof(T) != Section.sh_entsize)
-    return createError("section " + getSecIndexForError(*this, Section) +
-                       " has invalid sh_entsize: expected " + Twine(sizeof(T)) +
-                       ", but got " + Twine(Section.sh_entsize));
-  uint64_t Pos = Section.sh_offset + (uint64_t)Entry * sizeof(T);
-  if (Pos + sizeof(T) > Buf.size())
-    return createError("unable to access section " +
-                       getSecIndexForError(*this, Section) + " data at 0x" +
-                       Twine::utohexstr(Pos) +
-                       ": offset goes past the end of file");
-  return reinterpret_cast<const T *>(base() + Pos);
+  Expected<ArrayRef<T>> EntriesOrErr = getSectionContentsAsArray<T>(Section);
+  if (!EntriesOrErr)
+    return EntriesOrErr.takeError();
+
+  ArrayRef<T> Arr = *EntriesOrErr;
+  if (Entry >= Arr.size())
+    return createError("can't read an entry at 0x" +
+                       Twine::utohexstr(Entry * sizeof(T)) +
+                       ": it goes past the end of the section (0x" +
+                       Twine::utohexstr(Section.sh_size) + ")");
+  return &Arr[Entry];
 }
 
 template <class ELFT>
index 57fb006..95b677f 100644 (file)
@@ -118,7 +118,7 @@ Symbols:
 # RUN: yaml2obj %s --docnum=6 -o %t6
 # RUN: llvm-readobj --symbols %t6 2>&1 | FileCheck -DFILE=%t6 --check-prefix=INVALID-SYM-SIZE %s
 
-# INVALID-SYM-SIZE: warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has an invalid sh_entsize: 32
+# INVALID-SYM-SIZE: warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has invalid sh_entsize: expected 24, but got 32
 
 --- !ELF
 FileHeader:
@@ -630,7 +630,7 @@ Symbols:
 # RUN: yaml2obj %s --docnum=29 -o %t29
 # RUN: llvm-readobj -V %t29 2>&1 | FileCheck -DFILE=%t29 --check-prefix=INVALID-VER-SHENTSIZE %s
 
-# INVALID-VER-SHENTSIZE: warning: '[[FILE]]': cannot read content of SHT_GNU_versym section with index 1: section [index 1] has an invalid sh_entsize: 3
+# INVALID-VER-SHENTSIZE: warning: '[[FILE]]': cannot read content of SHT_GNU_versym section with index 1: section [index 1] has invalid sh_entsize: expected 2, but got 3
 
 --- !ELF
 FileHeader:
index ca64a34..92539a4 100644 (file)
@@ -47,7 +47,7 @@ Symbols:
 # RUN: llvm-readelf %t2.o --cg-profile | FileCheck %s --check-prefix=GNU
 
 # LLVM-ERR:      CGProfile [
-# LLVM-ERR-NEXT: warning: '[[FILE]]': unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 1] has an invalid sh_entsize: 15
+# LLVM-ERR-NEXT: warning: '[[FILE]]': unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 1] has invalid sh_entsize: expected 16, but got 15
 # LLVM-ERR-NEXT: ]
 
 ## Check we report a warning when unable to dump a name of a symbol.
index 933d53f..1034f0f 100644 (file)
@@ -1,6 +1,8 @@
 # RUN: yaml2obj %s -o %t.o
-# RUN: llvm-readobj --demangle -r %t.o | FileCheck %s --check-prefix LLVM
-# RUN: llvm-readelf --demangle -r %t.o | FileCheck %s --check-prefix GNU
+# RUN: llvm-readobj --demangle -r %t.o 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=LLVM --implicit-check-not=warning:
+# RUN: llvm-readelf --demangle -r %t.o 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=GNU --implicit-check-not=warning:
 
 # GNU:      Relocation section '.rela.plt' at offset {{.*}} contains 5 entries:
 # GNU-NEXT:     Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
@@ -30,7 +32,7 @@ Sections:
   - Name:    .gnu.version
     Type:    SHT_GNU_versym
     Flags:   [ SHF_ALLOC ]
-    Entries: [ 0, 2, 3, 4, 2 ]
+    Entries: [ 0, 2, 3, 4, 2, 1 ]
   - Name:         .gnu.version_r
     Type:         SHT_GNU_verneed
     Flags:        [ SHF_ALLOC ]
index 3935149..e46bc15 100644 (file)
@@ -6,8 +6,8 @@
 
 # LLVM:      Relocations [
 # LLVM-NEXT:   Section (3) .rel.text {
-# LLVM-NEXT: warning: '[[FILE]]': unable to print relocation 1 in SHT_REL section with index 3: unable to access section [index 6] data at 0x17e7e7e8d0: offset goes past the end of file
-# LLVM-NEXT: warning: '[[FILE]]': unable to print relocation 2 in SHT_REL section with index 3: unable to access section [index 6] data at 0x17e7e7e8d0: offset goes past the end of file
+# LLVM-NEXT: warning: '[[FILE]]': unable to print relocation 1 in SHT_REL section with index 3: unable to read an entry with index 4278124286 from SHT_SYMTAB section with index 6: can't read an entry at 0x17e7e7e7d0: it goes past the end of the section (0x90)
+# LLVM-NEXT: warning: '[[FILE]]': unable to print relocation 2 in SHT_REL section with index 3: unable to read an entry with index 4278124286 from SHT_SYMTAB section with index 6: can't read an entry at 0x17e7e7e7d0: it goes past the end of the section (0x90)
 # LLVM-NEXT:     0x2 R_X86_64_NONE -{{$}}
 # LLVM-NEXT:     0x3 R_X86_64_NONE .sec.symbol1{{$}}
 # LLVM-NEXT: warning: '[[FILE]]': invalid section index: 255
@@ -23,8 +23,8 @@
 
 # GNU:       Relocation section '.rel.text' at offset 0x41 contains 7 entries:
 # GNU-NEXT:      Offset             Info             Type               Symbol's Value  Symbol's Name
-# GNU-NEXT:  warning: '[[FILE]]': unable to print relocation 1 in SHT_REL section with index 3: unable to access section [index 6] data at 0x17e7e7e8d0: offset goes past the end of file
-# GNU-NEXT:  warning: '[[FILE]]': unable to print relocation 2 in SHT_REL section with index 3: unable to access section [index 6] data at 0x17e7e7e8d0: offset goes past the end of file
+# GNU-NEXT:  warning: '[[FILE]]': unable to print relocation 1 in SHT_REL section with index 3: unable to read an entry with index 4278124286 from SHT_SYMTAB section with index 6: can't read an entry at 0x17e7e7e7d0: it goes past the end of the section (0x90)
+# GNU-NEXT:  warning: '[[FILE]]': unable to print relocation 2 in SHT_REL section with index 3: unable to read an entry with index 4278124286 from SHT_SYMTAB section with index 6: can't read an entry at 0x17e7e7e7d0: it goes past the end of the section (0x90)
 # GNU-NEXT:  0000000000000002  0000000000000000 R_X86_64_NONE
 # GNU-NEXT:  0000000000000003  0000000200000000 R_X86_64_NONE 0000000000000000 .sec.symbol1
 # GNU-NEXT:  warning: '[[FILE]]': invalid section index: 255
index 887bada..67ba562 100644 (file)
@@ -207,7 +207,7 @@ Symbols:
 
 # BROKEN-REL-LLVM:      Relocations [
 # BROKEN-REL-LLVM-NEXT:   Section (2) .rel.text {
-# BROKEN-REL-LLVM-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_REL section with index 2: section [index 2] has an invalid sh_entsize: 1
+# BROKEN-REL-LLVM-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_REL section with index 2: section [index 2] has invalid sh_entsize: expected 16, but got 1
 # BROKEN-REL-LLVM-NEXT:   }
 # BROKEN-REL-LLVM-NEXT:   Section (3) .rela.text {
 # BROKEN-REL-LLVM-NEXT:     0x0 R_X86_64_NONE rela_0 0x0
@@ -220,7 +220,7 @@ Symbols:
 
 # BROKEN-REL-GNU:      Relocation section '.rel.text' at offset 0x51 contains 64 entries:
 # BROKEN-REL-GNU-NEXT:     Offset             Info             Type       Symbol's Value  Symbol's Name
-# BROKEN-REL-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_REL section with index 2: section [index 2] has an invalid sh_entsize: 1
+# BROKEN-REL-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_REL section with index 2: section [index 2] has invalid sh_entsize: expected 16, but got 1
 # BROKEN-REL-GNU:      Relocation section '.rela.text' at offset 0x91 contains 5 entries:
 # BROKEN-REL-GNU-NEXT:     Offset             Info             Type       Symbol's Value  Symbol's Name
 # BROKEN-REL-GNU-NEXT: 0000000000000000  0000000500000000 R_X86_64_NONE  0000000000000000 rela_0 + 0
@@ -245,7 +245,7 @@ Symbols:
 # BROKEN-RELA-LLVM-NEXT:     0x9 R_X86_64_64 rel_64{{$}}
 # BROKEN-RELA-LLVM-NEXT:   }
 # BROKEN-RELA-LLVM-NEXT:   Section (3) .rela.text {
-# BROKEN-RELA-LLVM-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_RELA section with index 3: section [index 3] has an invalid sh_entsize: 1
+# BROKEN-RELA-LLVM-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_RELA section with index 3: section [index 3] has invalid sh_entsize: expected 24, but got 1
 # BROKEN-RELA-LLVM-NEXT:   }
 # BROKEN-RELA-LLVM-NEXT: ]
 
@@ -258,7 +258,7 @@ Symbols:
 # BROKEN-RELA-GNU-EMPTY:
 # BROKEN-RELA-GNU-NEXT: Relocation section '.rela.text' at offset 0x91 contains 120 entries:
 # BROKEN-RELA-GNU-NEXT:     Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
-# BROKEN-RELA-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_RELA section with index 3: section [index 3] has an invalid sh_entsize: 1
+# BROKEN-RELA-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_RELA section with index 3: section [index 3] has invalid sh_entsize: expected 24, but got 1
 
 ## Case C: check the case when relocations can't be read from SHT_REL/SHT_RELA sections
 ##         because of broken sh_link fields.
@@ -498,3 +498,41 @@ Symbols:
 # GNU-SHNAME-NEXT: 0000000000000005  0000000700000004 R_X86_64_PLT32 0000000000000002 rela_pos + 2
 # GNU-SHNAME-NEXT: ffffffffffffffff  0000000800000001 R_X86_64_64    0000000000000003 rela_minneg - 8000000000000000
 # GNU-SHNAME-NEXT: 0000000000000009  000000090000000b R_X86_64_32S   ffffffffffffffff rela_maxpos + 7fffffffffffffff
+
+## Check that we report a warning when a relocation has a
+## symbol index past the end of the symbol table
+
+# RUN: yaml2obj %s --docnum=3 -o %t3
+# RUN: llvm-readobj --relocs %t3 2>&1 | \
+# RUN:   FileCheck %s --implicit-check-not=warning: -DFILE=%t3 --check-prefix=LLVM-SYMNDX
+# RUN: llvm-readelf --relocs %t3 2>&1 | \
+# RUN:   FileCheck %s --implicit-check-not=warning: -DFILE=%t3 --check-prefix=GNU-SYMNDX
+
+# LLVM-SYMNDX:      Relocations [
+# LLVM-SYMNDX-NEXT:   Section (1) .rela.text {
+# LLVM-SYMNDX-NEXT: warning: '[[FILE]]': unable to print relocation 1 in SHT_RELA section with index 1: unable to read an entry with index 2 from SHT_SYMTAB section with index 2: can't read an entry at 0x30: it goes past the end of the section (0x30)
+# LLVM-SYMNDX-NEXT: warning: '[[FILE]]': unable to print relocation 2 in SHT_RELA section with index 1: unable to read an entry with index 3 from SHT_SYMTAB section with index 2: can't read an entry at 0x48: it goes past the end of the section (0x30)
+# LLVM-SYMNDX-NEXT:   }
+# LLVM-SYMNDX-NEXT: ]
+
+# GNU-SYMNDX:      Relocation section '.rela.text' at offset 0x40 contains 2 entries:
+# GNU-SYMNDX-NEXT:     Offset             Info             Type     Symbol's Value  Symbol's Name + Addend
+# GNU-SYMNDX-NEXT: warning: '[[FILE]]': unable to print relocation 1 in SHT_RELA section with index 1: unable to read an entry with index 2 from SHT_SYMTAB section with index 2: can't read an entry at 0x30: it goes past the end of the section (0x30)
+# GNU-SYMNDX-NEXT: warning: '[[FILE]]': unable to print relocation 2 in SHT_RELA section with index 1: unable to read an entry with index 3 from SHT_SYMTAB section with index 2: can't read an entry at 0x48: it goes past the end of the section (0x30)
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_X86_64
+Sections:
+  - Name: .rela.text
+    Type: SHT_RELA
+    Relocations:
+      - Type:   R_X86_64_NONE
+        Symbol: 0x2
+      - Type:   R_X86_64_NONE
+        Symbol: 0x3
+Symbols:
+  - Name: foo
index 06bea76..3bb54b1 100644 (file)
@@ -169,14 +169,14 @@ Sections:
 
 # BROKEN-LLVM:      Relocations [
 # BROKEN-LLVM-NEXT:   Section (1) .relr.dyn {
-# BROKEN-LLVM-NEXT: warning: '[[FILE]]': unable to read relocations from [[SECNAME]] section with index 1: section [index 1] has an invalid sh_entsize: 1
+# BROKEN-LLVM-NEXT: warning: '[[FILE]]': unable to read relocations from [[SECNAME]] section with index 1: section [index 1] has invalid sh_entsize: expected 4, but got 1
 # BROKEN-LLVM-NEXT:   }
 # BROKEN-LLVM-NEXT: ]
 
-# BROKEN-GNU:      warning: '[[FILE]]': unable to get the number of relocations in [[SECNAME]] section with index 1: section [index 1] has an invalid sh_entsize: 1
+# BROKEN-GNU:      warning: '[[FILE]]': unable to get the number of relocations in [[SECNAME]] section with index 1: section [index 1] has invalid sh_entsize: expected 4, but got 1
 # BROKEN-GNU:      Relocation section '.relr.dyn' at offset 0x34 contains <?> entries:
 # BROKEN-GNU-NEXT:  Offset     Info    Type                Sym. Value  Symbol's Name
-# BROKEN-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from [[SECNAME]] section with index 1: section [index 1] has an invalid sh_entsize: 1
+# BROKEN-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from [[SECNAME]] section with index 1: section [index 1] has invalid sh_entsize: expected 4, but got 1
 
 ## Case B: check the case when relocations can't be read from an SHT_ANDROID_RELR section.
 ##         SHT_ANDROID_RELR = 0x6fffff00.
index 35c400d..9d0c0b5 100644 (file)
@@ -106,30 +106,30 @@ Symbols:
 
 # SYMTAB-GNU:      Stack Sizes:
 # SYMTAB-GNU-NEXT:          Size     Function
-# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xffffef36: offset goes past the end of file
+# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 5: unable to read an entry with index 3 from SHT_SYMTAB section with index 7: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
 # SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to read the symbol table: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
 # SYMTAB-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
 # SYMTAB-GNU-NEXT:            16     ?
-# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xffffef1e: offset goes past the end of file
+# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 5: unable to read an entry with index 2 from SHT_SYMTAB section with index 7: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
 # SYMTAB-GNU-NEXT:            32     ?
-# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 6: unable to access section [index 7] data at 0xffffef06: offset goes past the end of file
+# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 6: unable to read an entry with index 1 from SHT_SYMTAB section with index 7: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
 # SYMTAB-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 4
 # SYMTAB-GNU-NEXT:             8     ?
 
 # SYMTAB-LLVM:      StackSizes [
-# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xffffef36: offset goes past the end of file
+# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 5: unable to read an entry with index 3 from SHT_SYMTAB section with index 7: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
 # SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to read the symbol table: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
 # SYMTAB-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
 # SYMTAB-LLVM-NEXT:   Entry {
 # SYMTAB-LLVM-NEXT:     Function: ?
 # SYMTAB-LLVM-NEXT:     Size: 0x10
 # SYMTAB-LLVM-NEXT:   }
-# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xffffef1e: offset goes past the end of file
+# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 5: unable to read an entry with index 2 from SHT_SYMTAB section with index 7: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
 # SYMTAB-LLVM-NEXT:   Entry {
 # SYMTAB-LLVM-NEXT:     Function: ?
 # SYMTAB-LLVM-NEXT:     Size: 0x20
 # SYMTAB-LLVM-NEXT:   }
-# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 6: unable to access section [index 7] data at 0xffffef06: offset goes past the end of file
+# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 6: unable to read an entry with index 1 from SHT_SYMTAB section with index 7: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
 # SYMTAB-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 4
 # SYMTAB-LLVM-NEXT:   Entry {
 # SYMTAB-LLVM-NEXT:     Function: ?
@@ -489,9 +489,9 @@ Symbols:
 # BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get address of symbol '_Z3foof': invalid section index: 10
 # BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 2
 # BADSECTION-OUT-GNU-NEXT:             8     ?
-# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x18a0: offset goes past the end of file
+# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to read an entry with index 255 from SHT_SYMTAB section with index 4: can't read an entry at 0x17e8: it goes past the end of the section (0x30)
 # BADSECTION-OUT-GNU-NEXT:            22     ?
-# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 3 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x18a0: offset goes past the end of file
+# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 3 in SHT_RELA section with index 3: unable to read an entry with index 255 from SHT_SYMTAB section with index 4: can't read an entry at 0x17e8: it goes past the end of the section (0x30)
 # BADSECTION-OUT-GNU-NEXT:            36     ?
 
 # BADSECTION-OUT-LLVM:      StackSizes [
@@ -502,12 +502,12 @@ Symbols:
 # BADSECTION-OUT-LLVM-NEXT:     Function: ?
 # BADSECTION-OUT-LLVM-NEXT:     Size: 0x8
 # BADSECTION-OUT-LLVM-NEXT:   }
-# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x18a0: offset goes past the end of file
+# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to read an entry with index 255 from SHT_SYMTAB section with index 4: can't read an entry at 0x17e8: it goes past the end of the section (0x30)
 # BADSECTION-OUT-LLVM-NEXT:   Entry {
 # BADSECTION-OUT-LLVM-NEXT:     Function: ?
 # BADSECTION-OUT-LLVM-NEXT:     Size: 0x16
 # BADSECTION-OUT-LLVM-NEXT:   }
-# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 3 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x18a0: offset goes past the end of file
+# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 3 in SHT_RELA section with index 3: unable to read an entry with index 255 from SHT_SYMTAB section with index 4: can't read an entry at 0x17e8: it goes past the end of the section (0x30)
 # BADSECTION-OUT-LLVM-NEXT:   Entry {
 # BADSECTION-OUT-LLVM-NEXT:     Function: ?
 # BADSECTION-OUT-LLVM-NEXT:     Size: 0x24
index 486718e..bd126b2 100644 (file)
@@ -191,10 +191,10 @@ Symbols:
 # RUN:  FileCheck %s -DFILE=%t64.err2 --check-prefix=SYMTAB-ENTSIZE-ERR-GNU
 
 # SYMTAB-ENTSIZE-ERR-LLVM:      Symbols [
-# SYMTAB-ENTSIZE-ERR-LLVM-NEXT:   warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has an invalid sh_entsize: 255
+# SYMTAB-ENTSIZE-ERR-LLVM-NEXT:   warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has invalid sh_entsize: expected 24, but got 255
 # SYMTAB-ENTSIZE-ERR-LLVM:      ]
 
-# SYMTAB-ENTSIZE-ERR-GNU:     warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has an invalid sh_entsize: 255
+# SYMTAB-ENTSIZE-ERR-GNU:     warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has invalid sh_entsize: expected 24, but got 255
 # SYMTAB-ENTSIZE-ERR-GNU-NOT: {{.}}
 
 ## Case 3: check we report a warning, but continue dumping, when we are unable to read the name of the SHT_SYMTAB section.
index 9b665b9..9c7cc37 100644 (file)
@@ -150,7 +150,7 @@ DynamicSymbols: []
 # INVALID-ENT-SIZE-GNU-NEXT:      1: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND foo@<corrupt>
 # INVALID-ENT-SIZE-GNU:      Version symbols section '.gnu.version' contains 1 entries:
 # INVALID-ENT-SIZE-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 0 ()
-# INVALID-ENT-SIZE-GNU-NEXT: warning: '[[FILE]]': cannot read content of SHT_GNU_versym section with index 1: section [index 1] has an invalid sh_entsize: 3
+# INVALID-ENT-SIZE-GNU-NEXT: warning: '[[FILE]]': cannot read content of SHT_GNU_versym section with index 1: section [index 1] has invalid sh_entsize: expected 2, but got 3
 
 # INVALID-ENT-SIZE-LLVM:      DynamicSymbols [
 # INVALID-ENT-SIZE-LLVM-NEXT: warning: '[[FILE]]': section [index 1] has invalid sh_entsize: expected 2, but got 3
@@ -174,7 +174,7 @@ DynamicSymbols: []
 # INVALID-ENT-SIZE-LLVM-NEXT:   }
 # INVALID-ENT-SIZE-LLVM-NEXT: ]
 # INVALID-ENT-SIZE-LLVM:      VersionSymbols [
-# INVALID-ENT-SIZE-LLVM-NEXT: warning: '[[FILE]]': cannot read content of SHT_GNU_versym section with index 1: section [index 1] has an invalid sh_entsize: 3
+# INVALID-ENT-SIZE-LLVM-NEXT: warning: '[[FILE]]': cannot read content of SHT_GNU_versym section with index 1: section [index 1] has invalid sh_entsize: expected 2, but got 3
 # INVALID-ENT-SIZE-LLVM-NEXT: ]
 
 --- !ELF
index 0e28238..ed413dc 100644 (file)
@@ -255,4 +255,4 @@ Sections:
 # RUN: yaml2obj -DENTSIZE=0xff %s -o %t2
 # RUN: not obj2yaml %t2 2>&1 | FileCheck %s --check-prefix=ENTSIZE
 
-# ENTSIZE: section [index 1] has an invalid sh_entsize: 255
+# ENTSIZE: section [index 1] has invalid sh_entsize: expected 16, but got 255
index d426239..9de3bac 100644 (file)
@@ -30,11 +30,12 @@ DynamicSymbols: []
 ## Here we use the 0xFE value instead of expected 0x18/0x10.
 
 # RUN: yaml2obj -DTYPE=SHT_RELA --docnum=2 %s -o %t2.rela
-# RUN: not obj2yaml %t2.rela 2>&1 | FileCheck %s --check-prefix=ERR
+# RUN: not obj2yaml %t2.rela 2>&1 | FileCheck %s --check-prefix=ERR1
 # RUN: yaml2obj -DTYPE=SHT_REL  --docnum=2 %s -o %t2.rel
-# RUN: not obj2yaml %t2.rel 2>&1 | FileCheck %s --check-prefix=ERR
+# RUN: not obj2yaml %t2.rel 2>&1 | FileCheck %s --check-prefix=ERR2
 
-# ERR: section [index 1] has an invalid sh_entsize: 254
+# ERR1: section [index 1] has invalid sh_entsize: expected 24, but got 254
+# ERR2: section [index 1] has invalid sh_entsize: expected 16, but got 254
 
 --- !ELF
 FileHeader:
index 4c18581..ec754de 100644 (file)
@@ -109,7 +109,7 @@ Symbols:
 # RUN: yaml2obj --docnum=5 %s -o %t5
 # RUN: llvm-readelf -S 2>&1 %t5 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5
 
-# CASE5: warning: '[[FILE]]': section [index 1] has an invalid sh_entsize: 2
+# CASE5: warning: '[[FILE]]': section [index 1] has invalid sh_entsize: expected 4, but got 2
 
 --- !ELF
 FileHeader:
index c937218..178cca8 100644 (file)
@@ -1119,7 +1119,9 @@ ELFDumper<ELFT>::getRelocationTarget(const Relocation<ELFT> &R,
   Expected<const Elf_Sym *> SymOrErr =
       Obj.template getEntry<Elf_Sym>(*SymTab, R.Symbol);
   if (!SymOrErr)
-    return SymOrErr.takeError();
+    return createError("unable to read an entry with index " + Twine(R.Symbol) +
+                       " from " + describe(*SymTab) + ": " +
+                       toString(SymOrErr.takeError()));
   const Elf_Sym *Sym = *SymOrErr;
   if (!Sym)
     return RelSymbol<ELFT>(nullptr, "");
@@ -6233,9 +6235,8 @@ void GNUStyle<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
     OS << "   Address  Initial Sym.Val. Type    Ndx Name\n";
     for (auto &E : Parser.getPltEntries()) {
       const Elf_Sym &Sym = *Parser.getPltSym(&E);
-      const Elf_Sym &FirstSym =
-          *cantFail(this->Obj.template getEntry<const Elf_Sym>(
-              *Parser.getPltSymTable(), 0));
+      const Elf_Sym &FirstSym = *cantFail(
+          this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));
       std::string SymName = this->dumper().getFullSymbolName(
           Sym, &Sym - &FirstSym, this->dumper().getDynamicStringTable(), false);
 
@@ -7104,9 +7105,8 @@ void LLVMStyle<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
       W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes));
       printSymbolSection(Sym, &Sym - this->dumper().dynamic_symbols().begin());
 
-      const Elf_Sym *FirstSym =
-          cantFail(this->Obj.template getEntry<const Elf_Sym>(
-              *Parser.getPltSymTable(), 0));
+      const Elf_Sym *FirstSym = cantFail(
+          this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0));
       std::string SymName = this->dumper().getFullSymbolName(
           Sym, &Sym - FirstSym, Parser.getPltStrTable(), true);
       W.printNumber("Name", SymName, Sym.st_name);
index aabb07c..e15e9b7 100644 (file)
@@ -422,50 +422,59 @@ Sections:
   ASSERT_THAT_EXPECTED(SymtabSecOrErr, Succeeded());
   ASSERT_EQ((*SymtabSecOrErr)->sh_type, ELF::SHT_SYMTAB);
 
+  auto DoCheck = [&](unsigned BrokenSymIndex, const char *ErrMsg) {
+    ELFSymbolRef BrokenSym = Obj.toSymbolRef(*SymtabSecOrErr, BrokenSymIndex);
+
+    // 1) Check the behavior of ELFObjectFile<ELFT>::getSymbolName().
+    //    SymbolRef::getName() calls it internally. We can't test it directly,
+    //    because it is protected.
+    EXPECT_THAT_ERROR(BrokenSym.getName().takeError(),
+                      FailedWithMessage(ErrMsg));
+
+    // 2) Check the behavior of ELFObjectFile<ELFT>::getSymbol().
+    EXPECT_THAT_ERROR(Obj.getSymbol(BrokenSym.getRawDataRefImpl()).takeError(),
+                      FailedWithMessage(ErrMsg));
+
+    // 3) Check the behavior of ELFObjectFile<ELFT>::getSymbolSection().
+    //    SymbolRef::getSection() calls it internally. We can't test it
+    //    directly, because it is protected.
+    EXPECT_THAT_ERROR(BrokenSym.getSection().takeError(),
+                      FailedWithMessage(ErrMsg));
+
+    // 4) Check the behavior of ELFObjectFile<ELFT>::getSymbolFlags().
+    //    SymbolRef::getFlags() calls it internally. We can't test it directly,
+    //    because it is protected.
+    EXPECT_THAT_ERROR(BrokenSym.getFlags().takeError(),
+                      FailedWithMessage(ErrMsg));
+
+    // 5) Check the behavior of ELFObjectFile<ELFT>::getSymbolType().
+    //    SymbolRef::getType() calls it internally. We can't test it directly,
+    //    because it is protected.
+    EXPECT_THAT_ERROR(BrokenSym.getType().takeError(),
+                      FailedWithMessage(ErrMsg));
+
+    // 6) Check the behavior of ELFObjectFile<ELFT>::getSymbolAddress().
+    //    SymbolRef::getAddress() calls it internally. We can't test it
+    //    directly, because it is protected.
+    EXPECT_THAT_ERROR(BrokenSym.getAddress().takeError(),
+                      FailedWithMessage(ErrMsg));
+
+    // Finally, check the `ELFFile<ELFT>::getEntry` API. This is an underlying
+    // method that generates errors for all cases above.
+    EXPECT_THAT_EXPECTED(
+        Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, 0), Succeeded());
+    EXPECT_THAT_ERROR(
+        Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, BrokenSymIndex)
+            .takeError(),
+        FailedWithMessage(ErrMsg));
+  };
+
+  // We create a symbol with an index that is too large to exist in the symbol
+  // table.
+  DoCheck(0x1, "can't read an entry at 0x18: it goes past the end of the "
+               "section (0x18)");
+
   // We create a symbol with an index that is too large to exist in the object.
-  constexpr unsigned BrokenSymIndex = 0xFFFFFFFF;
-  ELFSymbolRef BrokenSym = Obj.toSymbolRef(*SymtabSecOrErr, BrokenSymIndex);
-
-  const char *ErrMsg = "unable to access section [index 1] data at "
-                       "0x1800000028: offset goes past the end of file";
-  // 1) Check the behavior of ELFObjectFile<ELFT>::getSymbolName().
-  //    SymbolRef::getName() calls it internally. We can't test it directly,
-  //    because it is protected.
-  EXPECT_THAT_ERROR(BrokenSym.getName().takeError(), FailedWithMessage(ErrMsg));
-
-  // 2) Check the behavior of ELFObjectFile<ELFT>::getSymbol().
-  EXPECT_THAT_ERROR(Obj.getSymbol(BrokenSym.getRawDataRefImpl()).takeError(),
-                    FailedWithMessage(ErrMsg));
-
-  // 3) Check the behavior of ELFObjectFile<ELFT>::getSymbolSection().
-  //    SymbolRef::getSection() calls it internally. We can't test it directly,
-  //    because it is protected.
-  EXPECT_THAT_ERROR(BrokenSym.getSection().takeError(),
-                    FailedWithMessage(ErrMsg));
-
-  // 4) Check the behavior of ELFObjectFile<ELFT>::getSymbolFlags().
-  //    SymbolRef::getFlags() calls it internally. We can't test it directly,
-  //    because it is protected.
-  EXPECT_THAT_ERROR(BrokenSym.getFlags().takeError(),
-                    FailedWithMessage(ErrMsg));
-
-  // 5) Check the behavior of ELFObjectFile<ELFT>::getSymbolType().
-  //    SymbolRef::getType() calls it internally. We can't test it directly,
-  //    because it is protected.
-  EXPECT_THAT_ERROR(BrokenSym.getType().takeError(), FailedWithMessage(ErrMsg));
-
-  // 6) Check the behavior of ELFObjectFile<ELFT>::getSymbolAddress().
-  //    SymbolRef::getAddress() calls it internally. We can't test it directly,
-  //    because it is protected.
-  EXPECT_THAT_ERROR(BrokenSym.getAddress().takeError(),
-                    FailedWithMessage(ErrMsg));
-
-  // Finally, check the `ELFFile<ELFT>::getEntry` API. This is an underlying
-  // method that generates errors for all cases above.
-  EXPECT_THAT_EXPECTED(Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, 0),
-                       Succeeded());
-  EXPECT_THAT_ERROR(
-      Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, BrokenSymIndex)
-          .takeError(),
-      FailedWithMessage(ErrMsg));
+  DoCheck(0xFFFFFFFF, "can't read an entry at 0x17ffffffe8: it goes past the "
+                      "end of the section (0x18)");
 }