[lld] r327001 - [COFF] Make the DOS stub a real DOS program
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 8 06:27:28 PST 2018
Author: hans
Date: Thu Mar 8 06:27:28 2018
New Revision: 327001
URL: http://llvm.org/viewvc/llvm-project?rev=327001&view=rev
Log:
[COFF] Make the DOS stub a real DOS program
It only adds a few bytes and is nice for backward compatibility.
Differential Revision: https://reviews.llvm.org/D44018
Modified:
lld/trunk/COFF/Writer.cpp
lld/trunk/test/COFF/hello32.test
Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=327001&r1=327000&r2=327001&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Thu Mar 8 06:27:28 2018
@@ -42,8 +42,40 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::coff;
+/* To re-generate DOSProgram:
+$ cat > /tmp/DOSProgram.asm
+org 0
+ ; Copy cs to ds.
+ push cs
+ pop ds
+ ; Point ds:dx at the $-terminated string.
+ mov dx, str
+ ; Int 21/AH=09h: Write string to standard output.
+ mov ah, 0x9
+ int 0x21
+ ; Int 21/AH=4Ch: Exit with return code (in AL).
+ mov ax, 0x4C01
+ int 0x21
+str:
+ db 'This program cannot be run in DOS mode.$'
+align 8, db 0
+$ nasm -fbin /tmp/DOSProgram.asm -o /tmp/DOSProgram.bin
+$ xxd -i /tmp/DOSProgram.bin
+*/
+static unsigned char DOSProgram[] = {
+ 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c,
+ 0xcd, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
+ 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65,
+ 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
+ 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x24, 0x00, 0x00
+};
+static_assert(sizeof(DOSProgram) % 8 == 0,
+ "DOSProgram size must be multiple of 8");
+
static const int SectorSize = 512;
-static const int DOSStubSize = 64;
+static const int DOSStubSize = sizeof(dos_header) + sizeof(DOSProgram);
+static_assert(DOSStubSize % 8 == 0, "DOSStub size must be multiple of 8");
+
static const int NumberfOfDataDirectory = 16;
namespace {
@@ -657,15 +689,27 @@ void Writer::assignAddresses() {
}
template <typename PEHeaderTy> void Writer::writeHeader() {
- // Write DOS stub
+ // Write DOS header. For backwards compatibility, the first part of a PE/COFF
+ // executable consists of an MS-DOS MZ executable. If the executable is run
+ // under DOS, that program gets run (usually to just print an error message).
+ // When run under Windows, the loader looks at AddressOfNewExeHeader and uses
+ // the PE header instead.
uint8_t *Buf = Buffer->getBufferStart();
auto *DOS = reinterpret_cast<dos_header *>(Buf);
- Buf += DOSStubSize;
+ Buf += sizeof(dos_header);
DOS->Magic[0] = 'M';
DOS->Magic[1] = 'Z';
+ DOS->UsedBytesInTheLastPage = DOSStubSize % 512;
+ DOS->FileSizeInPages = divideCeil(DOSStubSize, 512);
+ DOS->HeaderSizeInParagraphs = sizeof(dos_header) / 16;
+
DOS->AddressOfRelocationTable = sizeof(dos_header);
DOS->AddressOfNewExeHeader = DOSStubSize;
+ // Write DOS program.
+ memcpy(Buf, DOSProgram, sizeof(DOSProgram));
+ Buf += sizeof(DOSProgram);
+
// Write PE magic
memcpy(Buf, PEMagic, sizeof(PEMagic));
Buf += sizeof(PEMagic);
Modified: lld/trunk/test/COFF/hello32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/hello32.test?rev=327001&r1=327000&r2=327001&view=diff
==============================================================================
--- lld/trunk/test/COFF/hello32.test (original)
+++ lld/trunk/test/COFF/hello32.test Thu Mar 8 06:27:28 2018
@@ -40,7 +40,7 @@ HEADER-NEXT: MinorImageVersion: 0
HEADER-NEXT: MajorSubsystemVersion: 6
HEADER-NEXT: MinorSubsystemVersion: 0
HEADER-NEXT: SizeOfImage: 20480
-HEADER-NEXT: SizeOfHeaders: 512
+HEADER-NEXT: SizeOfHeaders: 1024
HEADER-NEXT: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3)
HEADER-NEXT: Characteristics [ (0x9540)
HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_APPCONTAINER (0x1000)
@@ -91,10 +91,10 @@ HEADER-NEXT: }
HEADER-NEXT: }
HEADER-NEXT: DOSHeader {
HEADER-NEXT: Magic: MZ
-HEADER-NEXT: UsedBytesInTheLastPage: 0
-HEADER-NEXT: FileSizeInPages: 0
+HEADER-NEXT: UsedBytesInTheLastPage: 120
+HEADER-NEXT: FileSizeInPages: 1
HEADER-NEXT: NumberOfRelocationItems: 0
-HEADER-NEXT: HeaderSizeInParagraphs: 0
+HEADER-NEXT: HeaderSizeInParagraphs: 4
HEADER-NEXT: MinimumExtraParagraphs: 0
HEADER-NEXT: MaximumExtraParagraphs: 0
HEADER-NEXT: InitialRelativeSS: 0
@@ -106,7 +106,7 @@ HEADER-NEXT: AddressOfRelocationTable:
HEADER-NEXT: OverlayNumber: 0
HEADER-NEXT: OEMid: 0
HEADER-NEXT: OEMinfo: 0
-HEADER-NEXT: AddressOfNewExeHeader: 64
+HEADER-NEXT: AddressOfNewExeHeader: 120
HEADER-NEXT: }
IMPORTS: Format: COFF-i386
More information about the llvm-commits
mailing list