authorgravatar for r00ster91@proton.meWooster <r00ster91@proton.me> 2025-01-14 19:33:11+09:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-14 16:34:59+00:00
logaffe45b31f48d216a407f060c49df6bad82ad30c
tree907c14732590f3c254cf86183962438013ecd644
parent8019694e17b6e6b6d3f9cab91233deea7c39a301

Coff msdos-stub: replace with documented byte array

This replaces the msdos-stub binary with a fully documented byte array with inline comments to make it easy to understand what every byte actually means.

2 files changed, 61 insertions(+), 2 deletions(-)

src/link/Coff.zig+61-2
......@@ -2784,7 +2784,7 @@ fn writeHeader(coff: *Coff) !void {
27842784 const writer = buffer.writer();
27852785
27862786 try buffer.ensureTotalCapacity(coff.getSizeOfHeaders());
2787 writer.writeAll(msdos_stub) catch unreachable;
2787 writer.writeAll(&msdos_stub) catch unreachable;
27882788 mem.writeInt(u32, buffer.items[0x3c..][0..4], msdos_stub.len, .little);
27892789
27902790 writer.writeAll("PE\x00\x00") catch unreachable;
......@@ -3748,4 +3748,63 @@ const Value = @import("../Value.zig");
37483748const AnalUnit = InternPool.AnalUnit;
37493749const dev = @import("../dev.zig");
37503750
3751const msdos_stub = @embedFile("msdos-stub.bin");
3751/// This is the start of a Portable Executable (PE) file.
3752/// It starts with a MS-DOS header followed by a MS-DOS stub program.
3753/// This data does not change so we include it as follows in all binaries.
3754///
3755/// In this context,
3756/// A "paragraph" is 16 bytes.
3757/// A "page" is 512 bytes.
3758/// A "long" is 4 bytes.
3759/// A "word" is 2 bytes.
3760const msdos_stub: [120]u8 = .{
3761 'M', 'Z', // Magic number. Stands for Mark Zbikowski (designer of the MS-DOS executable format).
3762 0x78, 0x00, // Number of bytes in the last page. This matches the size of this entire MS-DOS stub.
3763 0x01, 0x00, // Number of pages.
3764 0x00, 0x00, // Number of entries in the relocation table.
3765 0x04, 0x00, // The number of paragraphs taken up by the header. 4 * 16 = 64, which matches the header size (all bytes before the MS-DOS stub program).
3766 0x00, 0x00, // The number of paragraphs required by the program.
3767 0x00, 0x00, // The number of paragraphs requested by the program.
3768 0x00, 0x00, // Initial value for SS (relocatable segment address).
3769 0x00, 0x00, // Initial value for SP.
3770 0x00, 0x00, // Checksum.
3771 0x00, 0x00, // Initial value for IP.
3772 0x00, 0x00, // Initial value for CS (relocatable segment address).
3773 0x40, 0x00, // Absolute offset to relocation table. 64 matches the header size (all bytes before the MS-DOS stub program).
3774 0x00, 0x00, // Overlay number. Zero means this is the main executable.
3775}
3776// Reserved words.
3777++ .{ 0x00, 0x00 } ** 4
3778// OEM-related fields.
3779++ .{
3780 0x00, 0x00, // OEM identifier.
3781 0x00, 0x00, // OEM information.
3782}
3783// Reserved words.
3784++ .{ 0x00, 0x00 } ** 10
3785// Address of the PE header (a long). This matches the size of this entire MS-DOS stub, so that's the address of what's after this MS-DOS stub.
3786++ .{ 0x78, 0x00, 0x00, 0x00 }
3787// What follows is a 16-bit x86 MS-DOS program of 7 instructions that prints the bytes after these instructions and then exits.
3788++ .{
3789 // Set the value of the data segment to the same value as the code segment.
3790 0x0e, // push cs
3791 0x1f, // pop ds
3792 // Set the DX register to the address of the message.
3793 // If you count all bytes of these 7 instructions you get 14, so that's the address of what's after these instructions.
3794 0xba, 14, 0x00, // mov dx, 14
3795 // Set AH to the system call code for printing a message.
3796 0xb4, 0x09, // mov ah, 0x09
3797 // Perform the system call to print the message.
3798 0xcd, 0x21, // int 0x21
3799 // Set AH to 0x4c which is the system call code for exiting, and set AL to 0x01 which is the exit code.
3800 0xb8, 0x01, 0x4c, // mov ax, 0x4c01
3801 // Peform the system call to exit the program with exit code 1.
3802 0xcd, 0x21, // int 0x21
3803}
3804// Message to print.
3805++ "This program cannot be run in DOS mode.".*
3806// Message terminators.
3807++ .{
3808 '$', // We do not pass a length to the print system call; the string is terminated by this character.
3809 0x00, 0x00, // Terminating zero bytes.
3810};
src/link/msdos-stub.bin deleted
Binary files a/src/link/msdos-stub.bin and /dev/null differ