Skip to content

Commit 0a84b1a

Browse files
committed
[llvm-objcopy] Add support for nested and overlapping segments
This change adds support for nested and even overlapping segments. This means that PT_PHDR, PT_GNU_RELRO, PT_TLS, and PT_DYNAMIC can be supported properly. Differential Revision: https://reviews.llvm.org/D36558 llvm-svn: 313656
1 parent 3887ba8 commit 0a84b1a

File tree

7 files changed

+522
-6
lines changed

7 files changed

+522
-6
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# This test tests that if two non-overlapping segments are right next to each
2+
# other no problems arise.
3+
4+
# RUN: yaml2obj %s -o %t
5+
# RUN: llvm-objcopy %t %t2
6+
# RUN: llvm-readobj --program-headers %t2 | FileCheck %s
7+
8+
!ELF
9+
FileHeader:
10+
Class: ELFCLASS64
11+
Data: ELFDATA2LSB
12+
Type: ET_EXEC
13+
Machine: EM_X86_64
14+
Sections:
15+
- Name: .text
16+
Type: SHT_PROGBITS
17+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
18+
AddressAlign: 0x1000
19+
Size: 24
20+
- Name: .text2
21+
Type: SHT_PROGBITS
22+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
23+
AddressAlign: 0x10
24+
Size: 16
25+
ProgramHeaders:
26+
- Type: PT_LOAD
27+
Flags: [ PF_X, PF_R ]
28+
Sections:
29+
- Section: .text
30+
- Type: PT_LOAD
31+
Flags: [ PF_X, PF_R ]
32+
Sections:
33+
- Section: .text2
34+
35+
#CHECK: ProgramHeaders [
36+
#CHECK-NEXT: ProgramHeader {
37+
#CHECK-NEXT: Type: PT_LOAD (0x1)
38+
#CHECK-NEXT: Offset: 0x1000
39+
#CHECK-NEXT: VirtualAddress: 0x0
40+
#CHECK-NEXT: PhysicalAddress: 0x0
41+
#CHECK-NEXT: FileSize: 24
42+
#CHECK-NEXT: MemSize: 24
43+
#CHECK-NEXT: Flags [ (0x5)
44+
#CHECK-NEXT: PF_R (0x4)
45+
#CHECK-NEXT: PF_X (0x1)
46+
#CHECK-NEXT: ]
47+
#CHECK-NEXT: Alignment: 4096
48+
#CHECK-NEXT: }
49+
#CHECK-NEXT: ProgramHeader {
50+
#CHECK-NEXT: Type: PT_LOAD (0x1)
51+
#CHECK-NEXT: Offset: 0x1020
52+
#CHECK-NEXT: VirtualAddress: 0x0
53+
#CHECK-NEXT: PhysicalAddress: 0x0
54+
#CHECK-NEXT: FileSize: 16
55+
#CHECK-NEXT: MemSize: 16
56+
#CHECK-NEXT: Flags [ (0x5)
57+
#CHECK-NEXT: PF_R (0x4)
58+
#CHECK-NEXT: PF_X (0x1)
59+
#CHECK-NEXT: ]
60+
#CHECK-NEXT: Alignment: 16
61+
#CHECK-NEXT: }
62+
#CHECK-NEXT:]
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# This test tests that if two possible parent segments have the same offset that
2+
# they're disambiguated based on their original index. This ensures that cycles
3+
# do not occur.
4+
5+
# RUN: yaml2obj %s -o %t
6+
# RUN: llvm-objcopy %t %t2
7+
# RUN: llvm-readobj --program-headers %t2 | FileCheck %s
8+
9+
!ELF
10+
FileHeader:
11+
Class: ELFCLASS64
12+
Data: ELFDATA2LSB
13+
Type: ET_EXEC
14+
Machine: EM_X86_64
15+
Sections:
16+
- Name: .text
17+
Type: SHT_PROGBITS
18+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
19+
AddressAlign: 0x1000
20+
Size: 4096
21+
- Name: .text2
22+
Type: SHT_PROGBITS
23+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
24+
AddressAlign: 0x1000
25+
Size: 4096
26+
ProgramHeaders:
27+
- Type: PT_LOAD
28+
Flags: [ PF_X, PF_R ]
29+
Sections:
30+
- Section: .text2
31+
- Type: PT_LOAD
32+
Flags: [ PF_X, PF_R ]
33+
Sections:
34+
- Section: .text
35+
- Section: .text2
36+
- Type: PT_LOAD
37+
Flags: [ PF_X, PF_R ]
38+
Sections:
39+
- Section: .text
40+
- Section: .text2
41+
42+
#CHECK: ProgramHeaders [
43+
#CHECK-NEXT: ProgramHeader {
44+
#CHECK-NEXT: Type: PT_LOAD (0x1)
45+
#CHECK-NEXT: Offset: 0x2000
46+
#CHECK-NEXT: VirtualAddress: 0x0
47+
#CHECK-NEXT: PhysicalAddress: 0x0
48+
#CHECK-NEXT: FileSize: 4096
49+
#CHECK-NEXT: MemSize: 4096
50+
#CHECK-NEXT: Flags [ (0x5)
51+
#CHECK-NEXT: PF_R (0x4)
52+
#CHECK-NEXT: PF_X (0x1)
53+
#CHECK-NEXT: ]
54+
#CHECK-NEXT: Alignment: 4096
55+
#CHECK-NEXT: }
56+
#CHECK-NEXT: ProgramHeader {
57+
#CHECK-NEXT: Type: PT_LOAD (0x1)
58+
#CHECK-NEXT: Offset: 0x1000
59+
#CHECK-NEXT: VirtualAddress: 0x0
60+
#CHECK-NEXT: PhysicalAddress: 0x0
61+
#CHECK-NEXT: FileSize: 8192
62+
#CHECK-NEXT: MemSize: 8192
63+
#CHECK-NEXT: Flags [ (0x5)
64+
#CHECK-NEXT: PF_R (0x4)
65+
#CHECK-NEXT: PF_X (0x1)
66+
#CHECK-NEXT: ]
67+
#CHECK-NEXT: Alignment: 4096
68+
#CHECK-NEXT: }
69+
#CHECK-NEXT: ProgramHeader {
70+
#CHECK-NEXT: Type: PT_LOAD (0x1)
71+
#CHECK-NEXT: Offset: 0x1000
72+
#CHECK-NEXT: VirtualAddress: 0x0
73+
#CHECK-NEXT: PhysicalAddress: 0x0
74+
#CHECK-NEXT: FileSize: 8192
75+
#CHECK-NEXT: MemSize: 8192
76+
#CHECK-NEXT: Flags [ (0x5)
77+
#CHECK-NEXT: PF_R (0x4)
78+
#CHECK-NEXT: PF_X (0x1)
79+
#CHECK-NEXT: ]
80+
#CHECK-NEXT: Alignment: 4096
81+
#CHECK-NEXT: }
82+
#CHECK-NEXT:]
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# This test tests how ParentSegment is set for Segments. In particular this test
2+
# tests that if a chain of parents forms, the offsets are chosen for parents
3+
# first despite the order of the list. It also tests multiple branches of the
4+
# code that assigns parents.
5+
6+
# RUN: yaml2obj %s -o %t
7+
# RUN: llvm-objcopy %t %t2
8+
# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
9+
10+
!ELF
11+
FileHeader:
12+
Class: ELFCLASS64
13+
Data: ELFDATA2LSB
14+
Type: ET_EXEC
15+
Machine: EM_X86_64
16+
Sections:
17+
- Name: .text
18+
Type: SHT_PROGBITS
19+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
20+
AddressAlign: 0x1000
21+
Size: 4096
22+
- Name: .text2
23+
Type: SHT_PROGBITS
24+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
25+
AddressAlign: 0x1000
26+
Size: 4096
27+
- Name: .text3
28+
Type: SHT_PROGBITS
29+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
30+
AddressAlign: 0x1000
31+
Size: 4096
32+
- Name: .text4
33+
Type: SHT_PROGBITS
34+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
35+
AddressAlign: 0x1000
36+
Size: 4096
37+
- Name: .text5
38+
Type: SHT_PROGBITS
39+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
40+
AddressAlign: 0x1000
41+
Size: 4096
42+
ProgramHeaders:
43+
- Type: PT_LOAD
44+
Flags: [ PF_X, PF_R ]
45+
Sections:
46+
- Section: .text
47+
- Section: .text2
48+
- Type: PT_LOAD
49+
Flags: [ PF_X, PF_R ]
50+
Sections:
51+
- Section: .text4
52+
- Section: .text5
53+
- Type: PT_LOAD
54+
Flags: [ PF_X, PF_R ]
55+
Sections:
56+
- Section: .text3
57+
- Section: .text4
58+
- Type: PT_LOAD
59+
Flags: [ PF_X, PF_R ]
60+
Sections:
61+
- Section: .text2
62+
- Section: .text3
63+
64+
#CHECK: ProgramHeaders [
65+
#CHECK-NEXT: ProgramHeader {
66+
#CHECK-NEXT: Type: PT_LOAD (0x1)
67+
#CHECK-NEXT: Offset: 0x1000
68+
#CHECK-NEXT: VirtualAddress: 0x0
69+
#CHECK-NEXT: PhysicalAddress: 0x0
70+
#CHECK-NEXT: FileSize: 8192
71+
#CHECK-NEXT: MemSize: 8192
72+
#CHECK-NEXT: Flags [ (0x5)
73+
#CHECK-NEXT: PF_R (0x4)
74+
#CHECK-NEXT: PF_X (0x1)
75+
#CHECK-NEXT: ]
76+
#CHECK-NEXT: Alignment: 4096
77+
#CHECK-NEXT: }
78+
#CHECK-NEXT: ProgramHeader {
79+
#CHECK-NEXT: Type: PT_LOAD (0x1)
80+
#CHECK-NEXT: Offset: 0x4000
81+
#CHECK-NEXT: VirtualAddress: 0x0
82+
#CHECK-NEXT: PhysicalAddress: 0x0
83+
#CHECK-NEXT: FileSize: 8192
84+
#CHECK-NEXT: MemSize: 8192
85+
#CHECK-NEXT: Flags [ (0x5)
86+
#CHECK-NEXT: PF_R (0x4)
87+
#CHECK-NEXT: PF_X (0x1)
88+
#CHECK-NEXT: ]
89+
#CHECK-NEXT: Alignment: 4096
90+
#CHECK-NEXT: }
91+
#CHECK-NEXT: ProgramHeader {
92+
#CHECK-NEXT: Type: PT_LOAD (0x1)
93+
#CHECK-NEXT: Offset: 0x3000
94+
#CHECK-NEXT: VirtualAddress: 0x0
95+
#CHECK-NEXT: PhysicalAddress: 0x0
96+
#CHECK-NEXT: FileSize: 8192
97+
#CHECK-NEXT: MemSize: 8192
98+
#CHECK-NEXT: Flags [ (0x5)
99+
#CHECK-NEXT: PF_R (0x4)
100+
#CHECK-NEXT: PF_X (0x1)
101+
#CHECK-NEXT: ]
102+
#CHECK-NEXT: Alignment: 4096
103+
#CHECK-NEXT: }
104+
#CHECK-NEXT: ProgramHeader {
105+
#CHECK-NEXT: Type: PT_LOAD (0x1)
106+
#CHECK-NEXT: Offset: 0x2000
107+
#CHECK-NEXT: VirtualAddress: 0x0
108+
#CHECK-NEXT: PhysicalAddress: 0x0
109+
#CHECK-NEXT: FileSize: 8192
110+
#CHECK-NEXT: MemSize: 8192
111+
#CHECK-NEXT: Flags [ (0x5)
112+
#CHECK-NEXT: PF_R (0x4)
113+
#CHECK-NEXT: PF_X (0x1)
114+
#CHECK-NEXT: ]
115+
#CHECK-NEXT: Alignment: 4096
116+
#CHECK-NEXT: }
117+
#CHECK-NEXT:]
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# This test simply tests a simple but common real world example of overlapping
2+
# segments.
3+
4+
# RUN: llvm-objcopy %p/Inputs/pt-phdr.elf %t
5+
# RUN: llvm-readobj -program-headers %t | FileCheck %s
6+
7+
#CHECK: ProgramHeaders [
8+
#CHECK-NEXT: ProgramHeader {
9+
#CHECK-NEXT: Type: PT_PHDR
10+
#CHECK-NEXT: Offset: 0x40
11+
#CHECK-NEXT: VirtualAddress: 0x200040
12+
#CHECK-NEXT: PhysicalAddress: 0x200040
13+
#CHECK-NEXT: FileSize: 280
14+
#CHECK-NEXT: MemSize: 280
15+
#CHECK-NEXT: Flags [
16+
#CHECK-NEXT: PF_R
17+
#CHECK-NEXT: ]
18+
#CHECK-NEXT: Alignment: 8
19+
#CHECK-NEXT: }
20+
#CHECK-NEXT: ProgramHeader {
21+
#CHECK-NEXT: Type: PT_LOAD
22+
#CHECK-NEXT: Offset: 0x0
23+
#CHECK-NEXT: VirtualAddress: 0x200000
24+
#CHECK-NEXT: PhysicalAddress: 0x200000
25+
#CHECK-NEXT: FileSize: 344
26+
#CHECK-NEXT: MemSize: 344
27+
#CHECK-NEXT: Flags [
28+
#CHECK-NEXT: PF_R
29+
#CHECK-NEXT: ]
30+
#CHECK-NEXT: Alignment: 4096
31+
#CHECK-NEXT: }
32+
#CHECK-NEXT: ProgramHeader {
33+
#CHECK-NEXT: Type: PT_LOAD
34+
#CHECK-NEXT: Offset: 0x1000
35+
#CHECK-NEXT: VirtualAddress: 0x201000
36+
#CHECK-NEXT: PhysicalAddress: 0x201000
37+
#CHECK-NEXT: FileSize: 1
38+
#CHECK-NEXT: MemSize: 1
39+
#CHECK-NEXT: Flags [
40+
#CHECK-NEXT: PF_R
41+
#CHECK-NEXT: PF_X
42+
#CHECK-NEXT: ]
43+
#CHECK-NEXT: Alignment: 4096
44+
#CHECK-NEXT: }
45+
#CHECK-NEXT: ProgramHeader {
46+
#CHECK-NEXT: Type: PT_LOAD
47+
#CHECK-NEXT: Offset: 0x2000
48+
#CHECK-NEXT: VirtualAddress: 0x202000
49+
#CHECK-NEXT: PhysicalAddress: 0x202000
50+
#CHECK-NEXT: FileSize: 14
51+
#CHECK-NEXT: MemSize: 14
52+
#CHECK-NEXT: Flags [
53+
#CHECK-NEXT: PF_R
54+
#CHECK-NEXT: PF_W
55+
#CHECK-NEXT: ]
56+
#CHECK-NEXT: Alignment: 4096
57+
#CHECK-NEXT: }
58+
#CHECK-NEXT: ProgramHeader {
59+
#CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
60+
#CHECK-NEXT: Offset: 0x0
61+
#CHECK-NEXT: VirtualAddress: 0x0
62+
#CHECK-NEXT: PhysicalAddress: 0x0
63+
#CHECK-NEXT: FileSize: 0
64+
#CHECK-NEXT: MemSize: 0
65+
#CHECK-NEXT: Flags [
66+
#CHECK-NEXT: PF_R
67+
#CHECK-NEXT: PF_W
68+
#CHECK-NEXT: ]
69+
#CHECK-NEXT: Alignment: 0
70+
#CHECK-NEXT: }
71+
#CHECK-NEXT:]

0 commit comments

Comments
 (0)