mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[obj2yaml] - Fix the issue with dumping empty sections when dumping program headers.
Imagine we have: ``` ProgramHeaders: - Type: PT_LOAD Flags: [ PF_W, PF_R ] Sections: - Section: .bar VAddr: 0x2000 Sections: - Name: .foo Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_EXECINSTR ] Address: 0x1000 - Name: .bar Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_EXECINSTR ] Address: 0x2000 ``` Both `.foo` and `.bar` share the same starting file offset, but `VA(.foo)` < `VA(PT_LOAD)`, we should not include it into segment. This patch fixes the issue. Differential revision: https://reviews.llvm.org/D77652
This commit is contained in:
parent
04ed5838a4
commit
c57ab2a547
@ -664,7 +664,6 @@ Symbols:
|
||||
# ELF-AVR-NEXT: Flags: [ PF_X, PF_R ]
|
||||
# ELF-AVR-NEXT: Sections:
|
||||
# ELF-AVR-NEXT: - Section: .text
|
||||
# ELF-AVR-NEXT: - Section: .data
|
||||
# ELF-AVR-NEXT: Align: 0x0000000000000002
|
||||
# ELF-AVR-NEXT: - Type: PT_LOAD
|
||||
# ELF-AVR-NEXT: Flags: [ PF_W, PF_R ]
|
||||
|
@ -574,3 +574,118 @@ Sections:
|
||||
Flags: [ SHF_ALLOC ]
|
||||
Size: 0x1
|
||||
ShOffset: 0x0
|
||||
|
||||
## Check how we dump segments which contain empty sections.
|
||||
# RUN: yaml2obj --docnum=7 %s -o %t7
|
||||
|
||||
## Show the layout of the object before we dump it using obj2yaml.
|
||||
## Notes: 1) '.empty.foo', '.empty.bar1' and '.bar' have the same file offset, but '.empty.foo'
|
||||
## has a VA that is outside of the segment, hence we should not include it in it.
|
||||
## 2) '.bar1' ends at 0x79, which is the starting file offset of both '.empty.bar2'
|
||||
## and '.empty.zed'. We should only include '.empty.bar2', because the VA of the
|
||||
## '.empty.zed' section is outside the segment's virtual space.
|
||||
# RUN: llvm-readelf -sections %t7 | FileCheck %s --check-prefix=ZERO-SIZE-MAPPING
|
||||
|
||||
# ZERO-SIZE-MAPPING: Section Headers:
|
||||
# ZERO-SIZE-MAPPING-NEXT: [Nr] Name Type Address Off Size
|
||||
# ZERO-SIZE-MAPPING: [ 1] .empty.foo PROGBITS 0000000000001000 000078 000000
|
||||
# ZERO-SIZE-MAPPING-NEXT: [ 2] .empty.bar1 PROGBITS 0000000000002000 000078 000000
|
||||
# ZERO-SIZE-MAPPING-NEXT: [ 3] .bar PROGBITS 0000000000002000 000078 000001
|
||||
# ZERO-SIZE-MAPPING-NEXT: [ 4] .empty.bar2 PROGBITS 0000000000002001 000079 000000
|
||||
# ZERO-SIZE-MAPPING-NEXT: [ 5] .empty.zed PROGBITS 0000000000003000 000079 000000
|
||||
|
||||
# RUN: obj2yaml %t7 | FileCheck %s --check-prefix=ZERO-SIZE
|
||||
|
||||
# ZERO-SIZE: ProgramHeaders:
|
||||
# ZERO-SIZE-NEXT: - Type: PT_LOAD
|
||||
# ZERO-SIZE-NEXT: Flags: [ PF_W, PF_R ]
|
||||
# ZERO-SIZE-NEXT: Sections:
|
||||
# ZERO-SIZE-NEXT: - Section: .empty.bar1
|
||||
# ZERO-SIZE-NEXT: - Section: .bar
|
||||
# ZERO-SIZE-NEXT: - Section: .empty.bar2
|
||||
# ZERO-SIZE-NEXT: VAddr: 0x0000000000002000
|
||||
# ZERO-SIZE-NEXT: Sections:
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
ProgramHeaders:
|
||||
- Type: PT_LOAD
|
||||
Flags: [ PF_W, PF_R ]
|
||||
Sections:
|
||||
- Section: .bar
|
||||
VAddr: 0x2000
|
||||
Sections:
|
||||
- Name: .empty.foo
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Address: 0x1000
|
||||
- Name: .empty.bar1
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Address: 0x2000
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
Address: 0x2000
|
||||
Size: 0x1
|
||||
- Name: .empty.bar2
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Address: 0x2001
|
||||
- Name: .empty.zed
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Address: 0x3000
|
||||
|
||||
## Check how we dump a segment when we have sections that are outside of the virtual
|
||||
## address space of a segment, but inside its file space. We do not include such sections
|
||||
## in a segment when they are at the edges of a segment, because this is a normal case and
|
||||
## it may mean they belong to a different segment.
|
||||
# RUN: yaml2obj --docnum=8 %s -o %t8
|
||||
# RUN: obj2yaml %t8 | FileCheck %s --check-prefix=BROKEN-VA
|
||||
|
||||
# BROKEN-VA: ProgramHeaders:
|
||||
# BROKEN-VA-NEXT: - Type: PT_LOAD
|
||||
# BROKEN-VA-NEXT: Flags: [ PF_W, PF_R ]
|
||||
# BROKEN-VA-NEXT: Sections:
|
||||
# BROKEN-VA-NEXT: - Section: .empty_middle
|
||||
# BROKEN-VA-NEXT: VAddr: 0x0000000000001000
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
ProgramHeaders:
|
||||
- Type: PT_LOAD
|
||||
Flags: [ PF_W, PF_R ]
|
||||
VAddr: 0x1000
|
||||
Sections:
|
||||
- Section: .empty_begin
|
||||
- Section: .empty_middle
|
||||
- Section: .empty_end
|
||||
Sections:
|
||||
- Name: .empty_begin
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Address: 0xFEFEFEFE
|
||||
- Type: Fill
|
||||
Pattern: "00"
|
||||
Size: 1
|
||||
Name: begin
|
||||
- Name: .empty_middle
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Address: 0xFEFEFEFE
|
||||
- Type: Fill
|
||||
Pattern: "00"
|
||||
Size: 1
|
||||
- Name: .empty_end
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Address: 0xFEFEFEFE
|
||||
|
@ -305,17 +305,25 @@ static bool isInSegment(const ELFYAML::Section &Sec,
|
||||
SHdr.sh_offset >= Phdr.p_offset &&
|
||||
(SHdr.sh_offset + SHdr.sh_size <= Phdr.p_offset + Phdr.p_filesz);
|
||||
|
||||
if (FileOffsetsMatch)
|
||||
bool VirtualAddressesMatch = SHdr.sh_addr >= Phdr.p_vaddr &&
|
||||
SHdr.sh_addr <= Phdr.p_vaddr + Phdr.p_memsz;
|
||||
|
||||
if (FileOffsetsMatch) {
|
||||
// An empty section on the edges of a program header can be outside of the
|
||||
// virtual address space of the segment. This means it is not included in
|
||||
// the segment and we should ignore it.
|
||||
if (SHdr.sh_size == 0 && (SHdr.sh_offset == Phdr.p_offset ||
|
||||
SHdr.sh_offset == Phdr.p_offset + Phdr.p_filesz))
|
||||
return VirtualAddressesMatch;
|
||||
return true;
|
||||
}
|
||||
|
||||
// SHT_NOBITS sections usually occupy no physical space in a file. Such
|
||||
// sections belong to a segment when they reside in the segment's virtual
|
||||
// address space.
|
||||
if (Sec.Type != ELF::SHT_NOBITS)
|
||||
return false;
|
||||
|
||||
return SHdr.sh_addr >= Phdr.p_vaddr &&
|
||||
SHdr.sh_addr <= Phdr.p_vaddr + Phdr.p_memsz;
|
||||
return VirtualAddressesMatch;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
Loading…
Reference in New Issue
Block a user