Skip to content

Commit 94ac28f

Browse files
committed
Accept unaligned stubs
1 parent d715929 commit 94ac28f

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

lld/COFF/DriverUtils.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,6 @@ void LinkerDriver::parseDosStub(StringRef path) {
260260
<< path;
261261
if (bufferStart[0] != 'M' || bufferStart[1] != 'Z')
262262
Err(ctx) << "/stub: invalid DOS signature: " << path;
263-
if (bufferSize % 8 != 0)
264-
Err(ctx) << "/stub: stub must be aligned to 8 bytes: " << path;
265263
ctx.config.dosStub = std::move(stub);
266264
}
267265

lld/COFF/Writer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,9 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
16921692
// updates it automatically. Replicate the same behaviour.
16931693
dos->AddressOfNewExeHeader = config->dosStub->getBufferSize();
16941694
buf += config->dosStub->getBufferSize();
1695+
// Unlike MS link.exe, LLD accepts non-8-byte-aligned stubs.
1696+
// In that case, we add zero paddings ourselves.
1697+
buf += (8 - (config->dosStub->getBufferSize() % 8)) % 8;
16951698
} else {
16961699
buf += sizeof(dos_header);
16971700
dos->Magic[0] = 'M';
@@ -1707,6 +1710,9 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
17071710
buf += sizeof(dosProgram);
17081711
}
17091712

1713+
// Make sure DOS stub is aligned to 8 bytes at this point
1714+
assert((buf - buffer->getBufferStart()) % 8 == 0);
1715+
17101716
// Write PE magic
17111717
memcpy(buf, PEMagic, sizeof(PEMagic));
17121718
buf += sizeof(PEMagic);

lld/test/COFF/stub.test

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,32 @@ CHECK1: AddressOfNewExeHeader: 64
2323

2424
## Invalid DOS signature (must be `MZ`)
2525
# RUN: not lld-link /out:%t.exe /entry:main /stub:%p/Inputs/stub64zz %t.obj 2>&1 | FileCheck -check-prefix=CHECK2 %s
26-
# CHECK2: lld-link: error: /stub: invalid DOS signature: {{.*}}
2726

28-
## Unaligned stub (must be aligned to 8)
29-
# RUN: not lld-link /out:%t.exe /entry:main /stub:%p/Inputs/stub68mz %t.obj 2>&1 | FileCheck -check-prefix=CHECK3 %s
30-
# CHECK3: lld-link: error: /stub: stub must be aligned to 8 bytes: {{.*}}
27+
CHECK2: lld-link: error: /stub: invalid DOS signature: {{.*}}
28+
29+
## Unlike MS linker, we accept non-8byte-aligned stubs and we add paddings ourselves
30+
# RUN: lld-link /out:%t.exe /entry:main /stub:%p/Inputs/stub64mz %t.obj
31+
# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK3 %s
32+
33+
CHECK3: Magic: MZ
34+
CHECK3: UsedBytesInTheLastPage: 144
35+
CHECK3: FileSizeInPages: 3
36+
CHECK3: NumberOfRelocationItems: 0
37+
CHECK3: HeaderSizeInParagraphs: 4
38+
CHECK3: MinimumExtraParagraphs: 0
39+
CHECK3: MaximumExtraParagraphs: 65535
40+
CHECK3: InitialRelativeSS: 0
41+
CHECK3: InitialSP: 184
42+
CHECK3: Checksum: 0
43+
CHECK3: InitialIP: 0
44+
CHECK3: InitialRelativeCS: 0
45+
CHECK3: AddressOfRelocationTable: 64
46+
CHECK3: OverlayNumber: 0
47+
CHECK3: OEMid: 0
48+
CHECK3: OEMinfo: 0
49+
CHECK3: AddressOfNewExeHeader: 64
3150

3251
## Too-small stub (must be at least 64 bytes long) && Unaligned
3352
# RUN: not lld-link /out:%t.exe /entry:main /stub:%p/Inputs/stub63mz %t.obj 2>&1 | FileCheck -check-prefix=CHECK4 %s
34-
# CHECK4: lld-link: error: /stub: stub must be greater than or equal to 64 bytes: {{.*}}
53+
54+
CHECK4: lld-link: error: /stub: stub must be greater than or equal to 64 bytes: {{.*}}

0 commit comments

Comments
 (0)