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
## 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
# CHECK: MemSize: 6
# CHECK: ]
-!ELF
+--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
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
- 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