Skip to content

Commit 27f05d1

Browse files
committed
[lld][COFF] Fill only gaps in code sections.
Filling entire buffer would require all chunks to overwrite it later, which is not the case for uninitialized chunks merged into a code section.
1 parent e823136 commit 27f05d1

File tree

2 files changed

+159
-3
lines changed

2 files changed

+159
-3
lines changed

lld/COFF/Writer.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,10 +2019,20 @@ void Writer::writeSections() {
20192019
uint8_t *secBuf = buf + sec->getFileOff();
20202020
// Fill gaps between functions in .text with INT3 instructions
20212021
// instead of leaving as NUL bytes (which can be interpreted as
2022-
// ADD instructions).
2022+
// ADD instructions). Only fill the gaps between chunks. Most
2023+
// chunks overwrite it anyway, but uninitialized data chunks
2024+
// merged into a code section don't.
20232025
if ((sec->header.Characteristics & IMAGE_SCN_CNT_CODE) &&
2024-
(ctx.config.machine == AMD64 || ctx.config.machine == I386))
2025-
memset(secBuf, 0xCC, sec->getRawSize());
2026+
(ctx.config.machine == AMD64 || ctx.config.machine == I386)) {
2027+
uint32_t prevEnd = 0;
2028+
for (Chunk *c : sec->chunks) {
2029+
uint32_t off = c->getRVA() - sec->getRVA();
2030+
memset(secBuf + prevEnd, 0xCC, off - prevEnd);
2031+
prevEnd = off + c->getSize();
2032+
}
2033+
memset(secBuf + prevEnd, 0xCC, sec->getRawSize() - prevEnd);
2034+
}
2035+
20262036
parallelForEach(sec->chunks, [&](Chunk *c) {
20272037
c->writeTo(secBuf + c->getRVA() - sec->getRVA());
20282038
});

lld/test/COFF/code-merge.s

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# REQUIRES: x86
2+
3+
# Test merging code sections with data sections.
4+
5+
# RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj
6+
# RUN: lld-link -machine:amd64 -dll -noentry -out:%t.dll %t.obj -merge:.testx=.testd -merge:.testx2=.testbss -merge:.testd2=.testx3 -merge:.testbss2=.testx4
7+
8+
# RUN: llvm-readobj --sections %t.dll | FileCheck %s
9+
# CHECK: Sections [
10+
# CHECK-NEXT: Section {
11+
# CHECK-NEXT: Number: 1
12+
# CHECK-NEXT: Name: .testbss (2E 74 65 73 74 62 73 73)
13+
# CHECK-NEXT: VirtualSize: 0x18
14+
# CHECK-NEXT: VirtualAddress: 0x1000
15+
# CHECK-NEXT: RawDataSize: 512
16+
# CHECK-NEXT: PointerToRawData: 0x400
17+
# CHECK-NEXT: PointerToRelocations: 0x0
18+
# CHECK-NEXT: PointerToLineNumbers: 0x0
19+
# CHECK-NEXT: RelocationCount: 0
20+
# CHECK-NEXT: LineNumberCount: 0
21+
# CHECK-NEXT: Characteristics [ (0xC0000080)
22+
# CHECK-NEXT: IMAGE_SCN_CNT_UNINITIALIZED_DATA (0x80)
23+
# CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
24+
# CHECK-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000)
25+
# CHECK-NEXT: ]
26+
# CHECK-NEXT: }
27+
# CHECK-NEXT: Section {
28+
# CHECK-NEXT: Number: 2
29+
# CHECK-NEXT: Name: .testd (2E 74 65 73 74 64 00 00)
30+
# CHECK-NEXT: VirtualSize: 0x18
31+
# CHECK-NEXT: VirtualAddress: 0x2000
32+
# CHECK-NEXT: RawDataSize: 512
33+
# CHECK-NEXT: PointerToRawData: 0x600
34+
# CHECK-NEXT: PointerToRelocations: 0x0
35+
# CHECK-NEXT: PointerToLineNumbers: 0x0
36+
# CHECK-NEXT: RelocationCount: 0
37+
# CHECK-NEXT: LineNumberCount: 0
38+
# CHECK-NEXT: Characteristics [ (0x40000040)
39+
# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
40+
# CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
41+
# CHECK-NEXT: ]
42+
# CHECK-NEXT: }
43+
# CHECK-NEXT: Section {
44+
# CHECK-NEXT: Number: 3
45+
# CHECK-NEXT: Name: .testx3 (2E 74 65 73 74 78 33 00)
46+
# CHECK-NEXT: VirtualSize: 0x12
47+
# CHECK-NEXT: VirtualAddress: 0x3000
48+
# CHECK-NEXT: RawDataSize: 512
49+
# CHECK-NEXT: PointerToRawData: 0x800
50+
# CHECK-NEXT: PointerToRelocations: 0x0
51+
# CHECK-NEXT: PointerToLineNumbers: 0x0
52+
# CHECK-NEXT: RelocationCount: 0
53+
# CHECK-NEXT: LineNumberCount: 0
54+
# CHECK-NEXT: Characteristics [ (0x60000020)
55+
# CHECK-NEXT: IMAGE_SCN_CNT_CODE (0x20)
56+
# CHECK-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
57+
# CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
58+
# CHECK-NEXT: ]
59+
# CHECK-NEXT: }
60+
# CHECK-NEXT: Section {
61+
# CHECK-NEXT: Number: 4
62+
# CHECK-NEXT: Name: .testx4 (2E 74 65 73 74 78 34 00)
63+
# CHECK-NEXT: VirtualSize: 0x14
64+
# CHECK-NEXT: VirtualAddress: 0x4000
65+
# CHECK-NEXT: RawDataSize: 512
66+
# CHECK-NEXT: PointerToRawData: 0xA00
67+
# CHECK-NEXT: PointerToRelocations: 0x0
68+
# CHECK-NEXT: PointerToLineNumbers: 0x0
69+
# CHECK-NEXT: RelocationCount: 0
70+
# CHECK-NEXT: LineNumberCount: 0
71+
# CHECK-NEXT: Characteristics [ (0x60000020)
72+
# CHECK-NEXT: IMAGE_SCN_CNT_CODE (0x20)
73+
# CHECK-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
74+
# CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
75+
# CHECK-NEXT: ]
76+
# CHECK-NEXT: }
77+
# CHECK-NEXT: ]
78+
79+
# RUN: llvm-objdump -d %t.dll | FileCheck -check-prefix=DISASM %s
80+
# DISASM: Disassembly of section .testx3:
81+
# DISASM-EMPTY:
82+
# DISASM-NEXT: 0000000180003000 <.testx3>:
83+
# DISASM-NEXT: 180003000: 48 c7 c0 03 00 00 00 movq $0x3, %rax
84+
# DISASM-NEXT: 180003007: c3 retq
85+
# DISASM-NEXT: 180003008: cc int3
86+
# DISASM-NEXT: 180003009: cc int3
87+
# DISASM-NEXT: 18000300a: cc int3
88+
# DISASM-NEXT: 18000300b: cc int3
89+
# DISASM-NEXT: 18000300c: cc int3
90+
# DISASM-NEXT: 18000300d: cc int3
91+
# DISASM-NEXT: 18000300e: cc int3
92+
# DISASM-NEXT: 18000300f: cc int3
93+
# DISASM-NEXT: 180003010: 02 00 addb (%rax), %al
94+
# DISASM-EMPTY:
95+
# DISASM-NEXT: Disassembly of section .testx4:
96+
# DISASM-EMPTY:
97+
# DISASM-NEXT: 0000000180004000 <.testx4>:
98+
# DISASM-NEXT: 180004000: 48 c7 c0 04 00 00 00 movq $0x4, %rax
99+
# DISASM-NEXT: 180004007: c3 retq
100+
# DISASM-NEXT: 180004008: cc int3
101+
# DISASM-NEXT: 180004009: cc int3
102+
# DISASM-NEXT: 18000400a: cc int3
103+
# DISASM-NEXT: 18000400b: cc int3
104+
# DISASM-NEXT: 18000400c: cc int3
105+
# DISASM-NEXT: 18000400d: cc int3
106+
# DISASM-NEXT: 18000400e: cc int3
107+
# DISASM-NEXT: 18000400f: cc int3
108+
# DISASM-NEXT: 180004010: 00 00 addb %al, (%rax)
109+
# DISASM-NEXT: 180004012: 00 00 addb %al, (%rax)
110+
111+
112+
.section .testx, "xr"
113+
.p2align 4
114+
movq $1, %rax
115+
retq
116+
117+
.section .testx2, "xr"
118+
.p2align 4
119+
movq $2, %rax
120+
retq
121+
122+
.section .testd, "dr"
123+
.p2align 4
124+
.word 1
125+
126+
.section .testbss, "b"
127+
.p2align 4
128+
.skip 4
129+
130+
.section .testx3, "xr"
131+
.p2align 4
132+
movq $3, %rax
133+
retq
134+
135+
.section .testx4, "xr"
136+
.p2align 4
137+
movq $4, %rax
138+
retq
139+
140+
.section .testd2, "dr"
141+
.p2align 4
142+
.word 2
143+
144+
.section .testbss2, "b"
145+
.p2align 4
146+
.skip 4

0 commit comments

Comments
 (0)