[llvm] 2bf5674 - [yaml2obj] - Program headers: add an additional check for `Offset`
Georgii Rymar via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 22 02:55:54 PDT 2020
Author: Georgii Rymar
Date: 2020-04-22T12:49:05+03:00
New Revision: 2bf56743172c536b201a6f68b497694253236bd4
URL: https://github.com/llvm/llvm-project/commit/2bf56743172c536b201a6f68b497694253236bd4
DIFF: https://github.com/llvm/llvm-project/commit/2bf56743172c536b201a6f68b497694253236bd4.diff
LOG: [yaml2obj] - Program headers: add an additional check for `Offset`
The `Offset` field is used to set the file offset of a program header.
In a normal object it should not be greater than the minimal offset
of sections included into segment.
This patch adds a check for that and adds tests.
Differential revision: https://reviews.llvm.org/D78304
Added:
Modified:
llvm/lib/ObjectYAML/ELFEmitter.cpp
llvm/test/Object/invalid.test
llvm/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test
llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
Removed:
################################################################################
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 450856daa874..c32c42b795e7 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -759,12 +759,16 @@ void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,
reportError("sections in the program header with index " +
Twine(PhdrIdx) + " are not sorted by their file offset");
- if (YamlPhdr.Offset)
- PHeader.p_offset = *YamlPhdr.Offset;
- else if (!Fragments.empty())
- PHeader.p_offset = Fragments.front().Offset;
- else
- PHeader.p_offset = 0;
+ uint64_t PhdrFileOffset = Fragments.empty() ? 0 : Fragments.front().Offset;
+ if (YamlPhdr.Offset) {
+ if (!Fragments.empty() && *YamlPhdr.Offset > PhdrFileOffset)
+ reportError("'Offset' for segment with index " + Twine(PhdrIdx) +
+ " must be less than or equal to the minimum file offset of "
+ "all included sections (0x" +
+ Twine::utohexstr(PhdrFileOffset) + ")");
+ PhdrFileOffset = *YamlPhdr.Offset;
+ }
+ PHeader.p_offset = PhdrFileOffset;
// Find the maximum offset of the end of a section in order to set p_filesz
// and p_memsz. When setting p_filesz, trailing SHT_NOBITS sections are not
diff --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test
index 3a1ef2b3318c..a7363abcace0 100644
--- a/llvm/test/Object/invalid.test
+++ b/llvm/test/Object/invalid.test
@@ -485,17 +485,9 @@ FileHeader:
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
-Sections:
- - Name: .dynamic
- Type: SHT_DYNAMIC
- Entries:
- - Tag: DT_NULL
- Value: 0
ProgramHeaders:
- Type: PT_DYNAMIC
Offset: 0xffff0000
- Sections:
- - Section: .dynamic
## PT_DYNAMIC's p_filesz field is so large that p_offset + p_filesz is larger
## than the object size. Check llvm-readobj reports it.
diff --git a/llvm/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test b/llvm/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test
index b2f746e04200..db6b59189fb0 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test
@@ -33,13 +33,7 @@ FileHeader:
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
-Sections:
- - Name: .foo
- Type: SHT_PROGBITS
- Size: 1
ProgramHeaders:
- - Type: PT_LOAD
- Offset: 0x100000
- FileSize: 1
- Sections:
- - Section: .foo
+ - Type: PT_LOAD
+ Offset: 0x100000
+ FileSize: 1
diff --git a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
index cb4ea1da48f7..366d435e8e48 100644
--- a/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
+++ b/llvm/test/tools/llvm-readobj/ELF/gnu-notes.test
@@ -165,15 +165,9 @@ FileHeader:
Data: ELFDATA2LSB
Type: ET_CORE
Machine: EM_X86_64
-Sections:
- - Name: .note
- Type: SHT_NOTE
- Notes: []
ProgramHeaders:
- - Type: PT_NOTE
+ - Type: PT_NOTE
Offset: 0xffff0000
- Sections:
- - Section: .note
## Test tools report an error if a note program header has an invalid size that
## goes past the end of file.
diff --git a/llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml b/llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
index a2f727dab5fd..9b16b32e50a5 100644
--- a/llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
@@ -1,8 +1,8 @@
## Show that yaml2obj properly emits program headers with explicit file size,
## memory size and offset parameters.
-# RUN: yaml2obj %s -o %t
-# RUN: llvm-readobj %t --program-headers | FileCheck %s
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readobj %t1 --program-headers | FileCheck %s
# CHECK: ProgramHeaders [
# CHECK: Offset: 0x1234
@@ -34,7 +34,7 @@
# CHECK: MemSize: 6
# CHECK: ]
-!ELF
+--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
@@ -92,13 +92,11 @@ ProgramHeaders:
MemSize: 9
Sections:
- Section: .text
- # Program header with sections, invalid properties.
+ # Program header with invalid properties.
- Type: 0x6abcdef0
Offset: 0x3000
FileSize: 3
MemSize: 2
- Sections:
- - Section: .data
# Program header with 2 SHT_NOBITS sections.
- Type: 0x6abcdef0
Offset: 0x2004
@@ -106,3 +104,113 @@ ProgramHeaders:
- Section: .data
- Section: .nobits1
- Section: .nobits2
+
+## Test the "Offset" property.
+
+## Check that by default the p_offset field of a segment is set to the
+## offset of the section with the minimum offset.
+# RUN: yaml2obj --docnum=2 %s -o %t2
+# RUN: llvm-readelf %t2 --sections --program-headers | \
+# RUN: FileCheck %s --check-prefixes=DEFAULT-OFFSET
+
+# DEFAULT-OFFSET: [Nr] Name Type Address Off
+# DEFAULT-OFFSET: [ 1] .foo PROGBITS 0000000000001000 0000b0
+# DEFAULT-OFFSET-NEXT: [ 2] .bar PROGBITS 0000000000001001 0000b1
+
+# DEFAULT-OFFSET: Type Offset
+# DEFAULT-OFFSET-NEXT: LOAD 0x0000b0
+# DEFAULT-OFFSET-NEXT: LOAD 0x0000b1
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Size: 0x1
+ Address: 0x1000
+ - Name: .bar
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Size: 0x1
+ProgramHeaders:
+ - Type: PT_LOAD
+ Sections:
+ - Section: .foo
+ - Section: .bar
+ - Type: PT_LOAD
+ Sections:
+ - Section: .bar
+
+## Check we can set the "Offset" value explicitly to be less than or equal to
+## the offset of a section in the segment.
+# RUN: yaml2obj --docnum=3 -DOFFSET=0x77 %s -o %t3
+# RUN: llvm-readelf %t3 --sections --program-headers | \
+# RUN: FileCheck %s --check-prefixes=VALID-OFFSET,VALID-OFFSET-LESS
+# RUN: yaml2obj --docnum=3 -DOFFSET=0x78 %s -o %t4
+# RUN: llvm-readelf %t4 --sections --program-headers | \
+# RUN: FileCheck %s --check-prefixes=VALID-OFFSET,VALID-OFFSET-EQ
+
+# VALID-OFFSET: [Nr] Name Type Address Off
+# VALID-OFFSET: [ 1] .foo PROGBITS 0000000000000000 000078
+
+# VALID-OFFSET: Type Offset
+# VALID-OFFSET-EQ: LOAD 0x000078
+# VALID-OFFSET-LESS: LOAD 0x000077
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Size: 0x1
+ProgramHeaders:
+ - Type: PT_LOAD
+ Offset: [[OFFSET]]
+ Sections:
+ - Section: .foo
+
+## Check we report an error when the "Offset" value is larger than the offset of a section in the segment.
+# RUN: not yaml2obj --docnum=3 -DOFFSET=0x79 %s -o /dev/null 2>&1 | \
+# RUN: FileCheck %s --check-prefix=INVALID-OFFSET
+
+# INVALID-OFFSET: yaml2obj: error: 'Offset' for segment with index 1 must be less than or equal to the minimum file offset of all included sections (0x78)
+
+## Document that the "Offset" value is checked after the section offset is overriden using "ShOffset".
+# RUN: yaml2obj --docnum=4 %s -o %t5
+# RUN: llvm-readelf %t5 --sections --program-headers | FileCheck %s --check-prefix=SHOFFSET
+
+# SHOFFSET: [Nr] Name Type Address Off
+# SHOFFSET: [ 1] .foo PROGBITS 0000000000000000 ffffffff
+
+# SHOFFSET: Type Offset
+# SHOFFSET-NEXT: LOAD 0xffffff00
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Size: 0x1
+## Note: the real .foo offset is much less than 0xFFFFFFFF or
+## 0xFFFFFF00, but no error is reported.
+ ShOffset: 0xFFFFFFFF
+ProgramHeaders:
+ - Type: PT_LOAD
+ Offset: 0xFFFFFF00
+ Sections:
+ - Section: .foo
More information about the llvm-commits
mailing list