From f04018abed0f40278725648f851cadce5b7528d6 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 11:57:31 +0100 Subject: [PATCH 01/53] feat: added compiler utils header --- src/compiler/utils.h | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/compiler/utils.h diff --git a/src/compiler/utils.h b/src/compiler/utils.h new file mode 100644 index 0000000..b4f1589 --- /dev/null +++ b/src/compiler/utils.h @@ -0,0 +1,8 @@ +/** + * Utilities for the Quickfall Compiler. + */ + +#ifndef COMPILER_UTILS_H +#define COMPILER_UTILS_H + +#endif From 8228e15e1d86303f8d9014d9a0254d302f828359 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:02:47 +0100 Subject: [PATCH 02/53] feat: added write8, write16 and write32 into compiler utils header --- src/compiler/utils.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/compiler/utils.h b/src/compiler/utils.h index b4f1589..c44635c 100644 --- a/src/compiler/utils.h +++ b/src/compiler/utils.h @@ -2,7 +2,13 @@ * Utilities for the Quickfall Compiler. */ +#include + #ifndef COMPILER_UTILS_H #define COMPILER_UTILS_H +void write8(FILE* fptr, uint8_t value); +void write16(FILE* fptr, uint16_t value); +void write32(FILE* fptr, uint32_t value); + #endif From 09f6fb216eed191d7373ac477ca6e00b88be5003 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:02:59 +0100 Subject: [PATCH 03/53] chore: added clean target --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 21ef43c..6244ce4 100644 --- a/Makefile +++ b/Makefile @@ -82,12 +82,13 @@ prepare_build: @echo [INFO] Using "${COMPILER}" as a compiler! @echo [INFO] Detected current operating system as ${DETECTED_OS} $(CHECK_COMMANDS) - @echo [INFO] Clearing old builds + @echo [INFO] Starting building logic + +clean: $(RM) build $(RM) $(TARGET) $(RM) $(TEST_TARGET) $(RM) $(BENCH_TARGET) - @echo [INFO] Starting building logic $(TARGET): $(COMPILER) $(FLAGS) $(SOURCES) src/cli/main.c -o $(TARGET) From 19fa7f2b208a0ea9416e8ce4e62cf56bbfccecfc Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:05:52 +0100 Subject: [PATCH 04/53] feat: added docs for previously added functions --- src/compiler/utils.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/compiler/utils.h b/src/compiler/utils.h index c44635c..c110ec5 100644 --- a/src/compiler/utils.h +++ b/src/compiler/utils.h @@ -7,8 +7,19 @@ #ifndef COMPILER_UTILS_H #define COMPILER_UTILS_H +/** + * Writes an 8 bit number into the file. + */ void write8(FILE* fptr, uint8_t value); + +/** + * Writes an 16 bit number into the file. + */ void write16(FILE* fptr, uint16_t value); + +/** + * Writes a 32 bit number into the file. + */ void write32(FILE* fptr, uint32_t value); #endif From 5c6553b7171ff12faa89742ac42571e594dc504e Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:08:12 +0100 Subject: [PATCH 05/53] feat: added writestr8 and writestr16 functions in header --- src/compiler/utils.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/compiler/utils.h b/src/compiler/utils.h index c110ec5..9b9905b 100644 --- a/src/compiler/utils.h +++ b/src/compiler/utils.h @@ -22,4 +22,14 @@ void write16(FILE* fptr, uint16_t value); */ void write32(FILE* fptr, uint32_t value); +/** + * Writes a string with a 8 bit padding. + */ +void writestr8(FILE* fptr, char* str); + +/** + * Writes a string with a 16 bit padding. + */ +void writestr16(FILE* fptr, char* str); + #endif From b117b32adcf8512a09b7a1fd7fb0d6d6685201f5 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:08:53 +0100 Subject: [PATCH 06/53] feat: added seek in header --- src/compiler/utils.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/compiler/utils.h b/src/compiler/utils.h index 9b9905b..f448639 100644 --- a/src/compiler/utils.h +++ b/src/compiler/utils.h @@ -32,4 +32,9 @@ void writestr8(FILE* fptr, char* str); */ void writestr16(FILE* fptr, char* str); +/** + * Seeks to offset in a file. + */ +void seek(FILE* fptr, long offset); + #endif From a659532caeab192c75ac33831fff41c0b31ce4ff Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:09:58 +0100 Subject: [PATCH 07/53] feat: added align_to in header --- src/compiler/utils.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/compiler/utils.h b/src/compiler/utils.h index f448639..55e8cf7 100644 --- a/src/compiler/utils.h +++ b/src/compiler/utils.h @@ -37,4 +37,9 @@ void writestr16(FILE* fptr, char* str); */ void seek(FILE* fptr, long offset); +/** + * Rounds the number to the provided alignment. + */ +uint32_t align_to(uint32_t value, uint32_t alignment); + #endif From 0a991ed5ba2c47f8c506a15386e8d36ccd81b5ea Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:14:12 +0100 Subject: [PATCH 08/53] feat: added implementations of compiler utils --- src/compiler/utils.c | 82 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/compiler/utils.c diff --git a/src/compiler/utils.c b/src/compiler/utils.c new file mode 100644 index 0000000..89ca7d8 --- /dev/null +++ b/src/compiler/utils.c @@ -0,0 +1,82 @@ +/** + * Utilities for the Quickfall compiler. + */ + +/** + * Writes an 8 bit number into the file. + */ +void write8(FILE *file, uint8_t value) { + if (fputc(value, file) == EOF) { + perror("fputc"); + exit(1); + } +} + +/** + * Writes an 16 bit number into the file. + */ +void write16(FILE *file, uint16_t value) { + write8(file, (value >> 0) & 0xff); + write8(file, (value >> 8) & 0xff); +} + +/** + * Writes an 32 bit number into the file. + */ +void write32(FILE *file, uint32_t value) { + write8(file, (value >> 0) & 0xff); + write8(file, (value >> 8) & 0xff); + write8(file, (value >> 16) & 0xff); + write8(file, (value >> 24) & 0xff); +} + +/** + * Writes a string with a 8 bit padding. + */ +void writestr8(FILE *file, char *str) { + size_t len, i; + + len = strlen(str); + assert(len <= 8 && "The string must fit in 8 bytes."); + + for (i = 0; i < 8; i++) { + write8(file, i < len ? str[i] : 0); + } +} + +/** + * Writes a string with a 16 bit padding. + */ +void writestr16(FILE *file, char *str) { + size_t len, i; + + len = strlen(str); + assert(len <= 15 && "The string and terminator must fit in 16 bytes."); + + for (i = 0; i < 16; i++) { + write8(file, i < len ? str[i] : 0); + } +} + +/** + * Seeks to offset in a file. + */ +void seek(FILE *file, long offset) { + if (fseek(file, offset, SEEK_SET) == -1) { + perror("fseek"); + exit(1); + } +} + +/** + * Rounds the number to the provided alignment. + */ +uint32_t align_to(uint32_t value, uint32_t alignment) { + uint32_t remainder = value % alignment; + + if (remainder == 0) { + return value; + } + + return value + (alignment - remainder); +} From a2ebf86f689de6297b766a9422d4778388f76165 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:16:14 +0100 Subject: [PATCH 09/53] fix: added missing includes --- src/compiler/utils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/utils.c b/src/compiler/utils.c index 89ca7d8..c0a053a 100644 --- a/src/compiler/utils.c +++ b/src/compiler/utils.c @@ -2,6 +2,9 @@ * Utilities for the Quickfall compiler. */ +#include +#include + /** * Writes an 8 bit number into the file. */ From d80c897bdc3b924178c33d593e4b33e4d5cd7941 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:18:47 +0100 Subject: [PATCH 10/53] fix: misc impl errors --- src/compiler/utils.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/compiler/utils.c b/src/compiler/utils.c index c0a053a..68d66d9 100644 --- a/src/compiler/utils.c +++ b/src/compiler/utils.c @@ -2,6 +2,7 @@ * Utilities for the Quickfall compiler. */ +#include #include #include @@ -11,7 +12,6 @@ void write8(FILE *file, uint8_t value) { if (fputc(value, file) == EOF) { perror("fputc"); - exit(1); } } @@ -40,7 +40,6 @@ void writestr8(FILE *file, char *str) { size_t len, i; len = strlen(str); - assert(len <= 8 && "The string must fit in 8 bytes."); for (i = 0; i < 8; i++) { write8(file, i < len ? str[i] : 0); @@ -54,7 +53,6 @@ void writestr16(FILE *file, char *str) { size_t len, i; len = strlen(str); - assert(len <= 15 && "The string and terminator must fit in 16 bytes."); for (i = 0; i < 16; i++) { write8(file, i < len ? str[i] : 0); @@ -67,7 +65,6 @@ void writestr16(FILE *file, char *str) { void seek(FILE *file, long offset) { if (fseek(file, offset, SEEK_SET) == -1) { perror("fseek"); - exit(1); } } From 0e0f010f348d18028777d021969c740cb04df56e Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:20:19 +0100 Subject: [PATCH 11/53] feat: started working on compiler win header --- src/compiler/win.h | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/compiler/win.h diff --git a/src/compiler/win.h b/src/compiler/win.h new file mode 100644 index 0000000..f6f36b3 --- /dev/null +++ b/src/compiler/win.h @@ -0,0 +1,10 @@ +/** + * Windows related Quickfall compiling. + */ + +#ifndef COMPILER_WIN +#define COMPILER_WIN + + + +#endif From b1bbe290a9a3a4a47af5a98108da5d9b34e1a642 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:22:20 +0100 Subject: [PATCH 12/53] feat: added win compiling constants --- src/compiler/win.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/compiler/win.h b/src/compiler/win.h index f6f36b3..181c238 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -5,6 +5,24 @@ #ifndef COMPILER_WIN #define COMPILER_WIN +/** + * Constants for Windows Executable Format. + */ + +#define DOS_HDR_SZ 0x40 +#define PE_SIG_SZ 0x4 +#define COFF_HDR_SZ 0x14 +#define OPT_HDR_SZ 0xe0 +#define PE_HDR_SZ (PE_SIG_SZ + COFF_HDR_SZ + OPT_HDR_SZ) +#define SEC_HDR_SZ 0x28 + +#define IAT_ENTRY_SZ 0x4 +#define IMPORT_DIR_ENTRY_SZ 0x14 +#define IMPORT_LOOKUP_TBL_ENTRY_SZ IAT_ENTRY_SZ +#define NAME_TABLE_ENTRY_SZ 0x12 +#define IMAGE_BASE 0x00400000 +#define SEC_ALIGN 0x1000 +#define FILE_ALIGN 0x200 #endif From 56e1f10030a3d3f3291109f977d4f04a8664314f Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:53:42 +0100 Subject: [PATCH 13/53] feat: added writWinExecutableHeader, writeWinPESignature, writeWinCoffHeader, writeWinSTDFields, writeWinSpecificFields and writeWinSection --- src/compiler/win.h | 51 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/compiler/win.h b/src/compiler/win.h index 181c238..1c5eaab 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -2,6 +2,8 @@ * Windows related Quickfall compiling. */ +#include + #ifndef COMPILER_WIN #define COMPILER_WIN @@ -9,20 +11,39 @@ * Constants for Windows Executable Format. */ -#define DOS_HDR_SZ 0x40 -#define PE_SIG_SZ 0x4 -#define COFF_HDR_SZ 0x14 -#define OPT_HDR_SZ 0xe0 -#define PE_HDR_SZ (PE_SIG_SZ + COFF_HDR_SZ + OPT_HDR_SZ) -#define SEC_HDR_SZ 0x28 - -#define IAT_ENTRY_SZ 0x4 -#define IMPORT_DIR_ENTRY_SZ 0x14 -#define IMPORT_LOOKUP_TBL_ENTRY_SZ IAT_ENTRY_SZ -#define NAME_TABLE_ENTRY_SZ 0x12 - -#define IMAGE_BASE 0x00400000 -#define SEC_ALIGN 0x1000 -#define FILE_ALIGN 0x200 +#define WIN_DOS_HDR_SZ 0x40 +#define WIN_PE_SIG_SZ 0x4 +#define WIN_COFF_HDR_SZ 0x14 +#define WIN_OPT_HDR_SZ 0xe0 +#define WIN_PE_HDR_SZ (PE_SIG_SZ + COFF_HDR_SZ + OPT_HDR_SZ) +#define WIN_SEC_HDR_SZ 0x28 + +#define WIN_IAT_ENTRY_SZ 0x4 +#define WIN_IMPORT_DIR_ENTRY_SZ 0x14 +#define WIN_IMPORT_LOOKUP_TBL_ENTRY_SZ IAT_ENTRY_SZ +#define WIN_NAME_TABLE_ENTRY_SZ 0x12 + +#define WIN_IMAGE_BASE 0x00400000 +#define WIN_SEC_ALIGN 0x1000 +#define WIN_FILE_ALIGN 0x200 + +/** + * Writing functions. + */ + +/** + * Writes the windows executable header. + */ +inline void writeWinExecutableHeader(FILE* fptr, int dosSize); + +inline void writeWinPESignature(FILE* fptr, int dosSize); + +inline void writeWinCoffHeader(FILE* fptr); + +inline void writeWinSTDFields(FILE* fptr); + +inline void writeWinSpecificFields(FILE* fptr); + +inline void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t virtualAddress, uint32_t size, uint32_t pointer, uint32_t characteristics); #endif From 9187c95e30d9642deafdf549e24077ece440801b Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:58:43 +0100 Subject: [PATCH 14/53] feat: started working on the win writing functions implementations (writeWinExecutableHeader) --- src/compiler/win.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/compiler/win.c diff --git a/src/compiler/win.c b/src/compiler/win.c new file mode 100644 index 0000000..555c565 --- /dev/null +++ b/src/compiler/win.c @@ -0,0 +1,42 @@ +/** + * Windows related compiling for Quickfall. + */ + +#include +#include + +#include "./utils.h" +#include "./win.h" + +/** + * Writes the windows executable header. + */ +inline void writeWinExecutableHeader(FILE* f, int dosSize) { + uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; + uint32_t pe_offset = align_to(dos_stub_sz, 8); + + write8(f, 'M'); /* Magic number (2 bytes) */ + write8(f, 'Z'); + write16(f, dos_stub_sz % 512); /* Last page size */ + write16(f, align_to(dos_stub_sz, 512) / 512); /* Pages in file */ + write16(f, 0); /* Relocations */ + write16(f, WIN_DOS_HDR_SZ / 16); /* Size of header in paragraphs */ + write16(f, 0); /* Minimum extra paragraphs needed */ + write16(f, 1); /* Maximum extra paragraphs needed */ + write16(f, 0); /* Initial (relative) SS value */ + write16(f, 0); /* Initial SP value */ + write16(f, 0); /* Checksum */ + write16(f, 0); /* Initial IP value */ + write16(f, 0); /* Initial (relative) CS value */ + write16(f, WIN_DOS_HDR_SZ); /* File address of relocation table */ + write16(f, 0); /* Overlay number */ + write16(f, 0); /* Reserved0 */ + write16(f, 0); /* Reserved1 */ + write16(f, 0); /* Reserved2 */ + write16(f, 0); /* Reserved3 */ + write16(f, 0); /* OEM id */ + write16(f, 0); /* OEM info */ + for (int i = 0; i < 10; i++) + write16(f, 0); /* Reserved (10 words) */ + write32(f, pe_offset); /* File offset of PE header. */ +} From 3939f067f3eb714148209eff76ee91d572e619ec Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 12:59:19 +0100 Subject: [PATCH 15/53] fix: fixed header constants names --- src/compiler/win.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/compiler/win.h b/src/compiler/win.h index 1c5eaab..dcbdfdc 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -15,12 +15,12 @@ #define WIN_PE_SIG_SZ 0x4 #define WIN_COFF_HDR_SZ 0x14 #define WIN_OPT_HDR_SZ 0xe0 -#define WIN_PE_HDR_SZ (PE_SIG_SZ + COFF_HDR_SZ + OPT_HDR_SZ) +#define WIN_PE_HDR_SZ (WIN_PE_SIG_SZ + WIN_COFF_HDR_SZ + WIN_OPT_HDR_SZ) #define WIN_SEC_HDR_SZ 0x28 #define WIN_IAT_ENTRY_SZ 0x4 #define WIN_IMPORT_DIR_ENTRY_SZ 0x14 -#define WIN_IMPORT_LOOKUP_TBL_ENTRY_SZ IAT_ENTRY_SZ +#define WIN_IMPORT_LOOKUP_TBL_ENTRY_SZ WIN_IAT_ENTRY_SZ #define WIN_NAME_TABLE_ENTRY_SZ 0x12 #define WIN_IMAGE_BASE 0x00400000 @@ -36,14 +36,29 @@ */ inline void writeWinExecutableHeader(FILE* fptr, int dosSize); +/** + * Writes the Windows PE Signature. + */ inline void writeWinPESignature(FILE* fptr, int dosSize); +/** + * Writes the Windows COFF Header. + */ inline void writeWinCoffHeader(FILE* fptr); +/** + * Writes the Windows standart fields header. + */ inline void writeWinSTDFields(FILE* fptr); +/** + * Writes the Windows-specific fields header. + */ inline void writeWinSpecificFields(FILE* fptr); +/** + * Writes a Windows section header. + */ inline void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t virtualAddress, uint32_t size, uint32_t pointer, uint32_t characteristics); #endif From aef6ef9cd7f4cac5aed05c010c8e9f60b9b4d207 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 13:04:24 +0100 Subject: [PATCH 16/53] feat: added writeWinExecutable in header --- src/compiler/win.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/compiler/win.h b/src/compiler/win.h index dcbdfdc..76dd985 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -61,4 +61,10 @@ inline void writeWinSpecificFields(FILE* fptr); */ inline void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t virtualAddress, uint32_t size, uint32_t pointer, uint32_t characteristics); + +/** + * Writes a windows executable. + */ +inline void writeWinExecutable(FILE* fptr, uint32_t dos); + #endif From 537d402600ff0355b7c10e2f48406a70d4742ac3 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 13:11:22 +0100 Subject: [PATCH 17/53] feat: added two implementations of win comp header --- src/compiler/win.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/compiler/win.c b/src/compiler/win.c index 555c565..f549102 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -40,3 +40,30 @@ inline void writeWinExecutableHeader(FILE* f, int dosSize) { write16(f, 0); /* Reserved (10 words) */ write32(f, pe_offset); /* File offset of PE header. */ } + +/** + * Writes the Windows PE Signature. + */ +inline void writeWinPESignature(FILE* fptr, int dosSize) { + uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; + uint32_t pe_offset = align_to(dos_stub_sz, 8); + + seek(fptr, pe_offset); + write8(fptr, 'P'); + write8(fptr, 'E'); + write8(fptr, 0); + write8(fptr, 0); +} + +/** + * Writes a Windows executable. + */ +inline void writeWinExecutable(FILE* fptr, uint32_t dos[]) { + int dosSize = sizeof(dos); + + writeWinExecutableHeader(fptr, dosSize); + + for(int i = 0; i < dosSize; ++i) { + write8(fptr, dos[i]); + } +} \ No newline at end of file From 914f9d629cf05f69582e2b36f1c4d32eb1655bd8 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 13:16:34 +0100 Subject: [PATCH 18/53] refactor: changed functions to pass calculated vars --- src/compiler/win.c | 24 +++++++++++------------- src/compiler/win.h | 4 ++-- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index f549102..e7f2263 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -11,14 +11,11 @@ /** * Writes the windows executable header. */ -inline void writeWinExecutableHeader(FILE* f, int dosSize) { - uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; - uint32_t pe_offset = align_to(dos_stub_sz, 8); - +inline void writeWinExecutableHeader(FILE* f, int dosStubSZ, int peOffset) { write8(f, 'M'); /* Magic number (2 bytes) */ write8(f, 'Z'); - write16(f, dos_stub_sz % 512); /* Last page size */ - write16(f, align_to(dos_stub_sz, 512) / 512); /* Pages in file */ + write16(f, dosStubSZ % 512); /* Last page size */ + write16(f, align_to(dosStubSZ, 512) / 512); /* Pages in file */ write16(f, 0); /* Relocations */ write16(f, WIN_DOS_HDR_SZ / 16); /* Size of header in paragraphs */ write16(f, 0); /* Minimum extra paragraphs needed */ @@ -38,17 +35,14 @@ inline void writeWinExecutableHeader(FILE* f, int dosSize) { write16(f, 0); /* OEM info */ for (int i = 0; i < 10; i++) write16(f, 0); /* Reserved (10 words) */ - write32(f, pe_offset); /* File offset of PE header. */ + write32(f, peOffset); /* File offset of PE header. */ } /** * Writes the Windows PE Signature. */ -inline void writeWinPESignature(FILE* fptr, int dosSize) { - uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; - uint32_t pe_offset = align_to(dos_stub_sz, 8); - - seek(fptr, pe_offset); +inline void writeWinPESignature(FILE* fptr, int peOffset) { + seek(fptr, peOffset); write8(fptr, 'P'); write8(fptr, 'E'); write8(fptr, 0); @@ -60,8 +54,12 @@ inline void writeWinPESignature(FILE* fptr, int dosSize) { */ inline void writeWinExecutable(FILE* fptr, uint32_t dos[]) { int dosSize = sizeof(dos); + + uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; + uint32_t pe_offset = align_to(dos_stub_sz, 8); - writeWinExecutableHeader(fptr, dosSize); + writeWinExecutableHeader(fptr, dosSize, pe_offset); + writeWinPESignature(fptr, pe_offset); for(int i = 0; i < dosSize; ++i) { write8(fptr, dos[i]); diff --git a/src/compiler/win.h b/src/compiler/win.h index 76dd985..effa473 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -34,12 +34,12 @@ /** * Writes the windows executable header. */ -inline void writeWinExecutableHeader(FILE* fptr, int dosSize); +inline void writeWinExecutableHeader(FILE* fptr, int dosStubSZ, int peOffset); /** * Writes the Windows PE Signature. */ -inline void writeWinPESignature(FILE* fptr, int dosSize); +inline void writeWinPESignature(FILE* fptr, int peOffset); /** * Writes the Windows COFF Header. From 2834230d7b4749624f03c7cb40e561d57ff80634 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 13:20:40 +0100 Subject: [PATCH 19/53] feat: writeCoffHeader impl --- src/compiler/win.c | 13 +++++++++++++ src/compiler/win.h | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index e7f2263..dbe5ab2 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -49,6 +49,19 @@ inline void writeWinPESignature(FILE* fptr, int peOffset) { write8(fptr, 0); } +/** + * Writes the Windows COFF Header. + */ +inline void writeWinCoffHeader(FILE* fptr, int numSections) { + write16(fptr, 0x14c); /* Machine: IMAGE_FILE_MACHINE_I386 */ + write16(fptr, numSections); /* NumberOfSections */ + write32(fptr, 0); /* TimeDateStamp */ + write32(fptr, 0); /* PointerToSymbolTable */ + write32(fptr, 0); /* NumberOfSymbols */ + write16(fptr, WIN_OPT_HDR_SZ); /* SizeOfOptionalHeader */ + write16(fptr, 0x103); /* Characteristics: no relocations, exec, 32-bit */ +} + /** * Writes a Windows executable. */ diff --git a/src/compiler/win.h b/src/compiler/win.h index effa473..e5fcdc8 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -44,7 +44,7 @@ inline void writeWinPESignature(FILE* fptr, int peOffset); /** * Writes the Windows COFF Header. */ -inline void writeWinCoffHeader(FILE* fptr); +inline void writeWinCoffHeader(FILE* fptr, int numSections); /** * Writes the Windows standart fields header. From 0dad4462fc3fb1cea917d077253f82f6df6957bc Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 13:29:30 +0100 Subject: [PATCH 20/53] feat: added writeWinSTDFields --- src/compiler/win.c | 63 ++++++++++++++++++++++++++++++++++++++++------ src/compiler/win.h | 4 +-- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index dbe5ab2..7791da0 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -53,19 +53,34 @@ inline void writeWinPESignature(FILE* fptr, int peOffset) { * Writes the Windows COFF Header. */ inline void writeWinCoffHeader(FILE* fptr, int numSections) { - write16(fptr, 0x14c); /* Machine: IMAGE_FILE_MACHINE_I386 */ - write16(fptr, numSections); /* NumberOfSections */ - write32(fptr, 0); /* TimeDateStamp */ - write32(fptr, 0); /* PointerToSymbolTable */ - write32(fptr, 0); /* NumberOfSymbols */ - write16(fptr, WIN_OPT_HDR_SZ); /* SizeOfOptionalHeader */ - write16(fptr, 0x103); /* Characteristics: no relocations, exec, 32-bit */ + write16(fptr, 0x14c); /* Machine: IMAGE_FILE_MACHINE_I386 */ + write16(fptr, numSections); /* NumberOfSections */ + write32(fptr, 0); /* TimeDateStamp */ + write32(fptr, 0); /* PointerToSymbolTable */ + write32(fptr, 0); /* NumberOfSymbols */ + write16(fptr, WIN_OPT_HDR_SZ); /* SizeOfOptionalHeader */ + write16(fptr, 0x103); /* Characteristics: no relocations, exec, 32-bit */ +} + +/** + * Writes the Windows standart fields header. + */ +inline void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iDataSize, int bssSize, int textPtr, int rdataPtr) { + write16(fptr, 0x10b); /* Magic: PE32 */ + write8(fptr, 0); /* MajorLinkerVersion */ + write8(fptr, 0); /* MinorLinkerVersion */ + write32(fptr, textSize); /* SizeOfCode */ + write32(fptr, rDataSize + iDataSize); /* SizeOfInitializedData */ + write32(fptr, bssSize); /* SizeOfUninitializedData */ + write32(fptr, textPtr); /* AddressOfEntryPoint */ + write32(fptr, textPtr); /* BaseOfCode */ + write32(fptr, rdataPtr); /* BaseOfData */ } /** * Writes a Windows executable. */ -inline void writeWinExecutable(FILE* fptr, uint32_t dos[]) { +inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[]) { int dosSize = sizeof(dos); uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; @@ -77,4 +92,36 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[]) { for(int i = 0; i < dosSize; ++i) { write8(fptr, dos[i]); } + + uint32_t num_sections = 4; + + uint32_t headers_sz = pe_offset + WIN_PE_HDR_SZ + num_sections * WIN_SEC_HDR_SZ; + + uint32_t text_rva = align_to(headers_sz, WIN_SEC_ALIGN); + uint32_t text_offset = align_to(headers_sz, WIN_FILE_ALIGN); + uint32_t text_sz = sizeof(program); + + uint32_t rdata_rva = align_to(text_rva + text_sz, WIN_SEC_ALIGN); + uint32_t rdata_offset = align_to(text_offset + text_sz, WIN_FILE_ALIGN); + uint32_t rdata_sz = sizeof(program); + + uint32_t idata_rva = align_to(rdata_rva + rdata_sz, WIN_SEC_ALIGN); + uint32_t idata_offset = align_to(rdata_offset + rdata_sz, WIN_FILE_ALIGN); + + uint32_t num_imports = 4; + uint32_t iat_rva = idata_rva; + uint32_t iat_sz = (num_imports + 1) * WIN_IAT_ENTRY_SZ; + uint32_t import_dir_table_rva = iat_rva + iat_sz; + uint32_t import_dir_table_sz = 2 * WIN_IMPORT_DIR_ENTRY_SZ; + uint32_t import_lookup_table_rva = import_dir_table_rva + + import_dir_table_sz; + uint32_t name_table_rva = import_lookup_table_rva + + (num_imports + 1) * WIN_IMPORT_LOOKUP_TBL_ENTRY_SZ; + uint32_t dll_name_rva = name_table_rva + + num_imports * WIN_NAME_TABLE_ENTRY_SZ; + uint32_t name_table_sz = num_imports * WIN_NAME_TABLE_ENTRY_SZ + 16; + uint32_t idata_sz = name_table_rva + name_table_sz - idata_rva; + + uint32_t bss_rva = align_to(idata_rva + idata_sz, WIN_SEC_ALIGN); + uint32_t bss_sz = 4096; } \ No newline at end of file diff --git a/src/compiler/win.h b/src/compiler/win.h index e5fcdc8..482960b 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -49,7 +49,7 @@ inline void writeWinCoffHeader(FILE* fptr, int numSections); /** * Writes the Windows standart fields header. */ -inline void writeWinSTDFields(FILE* fptr); +inline void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iDataSize, int bssSize, int textPtr, int rdataPtr); /** * Writes the Windows-specific fields header. @@ -65,6 +65,6 @@ inline void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t /** * Writes a windows executable. */ -inline void writeWinExecutable(FILE* fptr, uint32_t dos); +inline void writeWinExecutable(FILE* fptr, uint32_t dos[]); #endif From edfed2a9c87ccee8130fc83b61d9fdb4dd85b128 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 13:35:15 +0100 Subject: [PATCH 21/53] feat: added win specific fields --- src/compiler/win.c | 27 +++++++++++++++++++++++++++ src/compiler/win.h | 4 ++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index 7791da0..47d39f5 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -77,6 +77,30 @@ inline void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iData write32(fptr, rdataPtr); /* BaseOfData */ } +inline void writeWinSpecificFields(FILE* f, int bssPtr, int bssSize, int headersSize) { + write32(f, WIN_IMAGE_BASE); /* ImageBase */ + write32(f, WIN_SEC_ALIGN); /* SectionAlignment */ + write32(f, WIN_FILE_ALIGN); /* FileAlignment */ + write16(f, 3); /* MajorOperatingSystemVersion */ + write16(f, 10); /* MinorOperatingSystemVersion*/ + write16(f, 0); /* MajorImageVersion */ + write16(f, 0); /* MinorImageVersion */ + write16(f, 3); /* MajorSubsystemVersion */ + write16(f, 10); /* MinorSubsystemVersion */ + write32(f, 0); /* Win32VersionValue*/ + write32(f, align_to(bssPtr + bssSize, WIN_SEC_ALIGN)); /* SizeOfImage */ + write32(f, align_to(headersSize, WIN_FILE_ALIGN)); /* SizeOfHeaders */ + write32(f, 0); /* Checksum */ + write16(f, 3); /* Subsystem: Console */ + write16(f, 0); /* DllCharacteristics */ + write32(f, 0x100000); /* SizeOfStackReserve */ + write32(f, 0x1000); /* SizeOfStackCommit */ + write32(f, 0x100000); /* SizeOfHeapReserve */ + write32(f, 0x1000); /* SizeOfHeapCommit */ + write32(f, 0); /* LoadFlags */ + write32(f, 16); /* NumberOfRvaAndSizes */ +} + /** * Writes a Windows executable. */ @@ -124,4 +148,7 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u uint32_t bss_rva = align_to(idata_rva + idata_sz, WIN_SEC_ALIGN); uint32_t bss_sz = 4096; + + writeWinSTDFields(fptr, text_sz, rdata_sz, idata_sz, bss_sz, text_rva, rdata_rva); + writeWinSpecificFields(fptr, bss_rva, bss_sz, headers_sz); } \ No newline at end of file diff --git a/src/compiler/win.h b/src/compiler/win.h index 482960b..7f66b21 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -54,7 +54,7 @@ inline void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iData /** * Writes the Windows-specific fields header. */ -inline void writeWinSpecificFields(FILE* fptr); +inline void writeWinSpecificFields(FILE* f, int bssPtr, int bssSize, int headersSize); /** * Writes a Windows section header. @@ -65,6 +65,6 @@ inline void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t /** * Writes a windows executable. */ -inline void writeWinExecutable(FILE* fptr, uint32_t dos[]); +inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[]); #endif From 290f135057e90f4271942f403b1103a073b25f08 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 13:40:33 +0100 Subject: [PATCH 22/53] feat: added windows data fields --- src/compiler/win.c | 25 +++++++++++++++++++++++++ src/compiler/win.h | 4 ++++ 2 files changed, 29 insertions(+) diff --git a/src/compiler/win.c b/src/compiler/win.c index 47d39f5..1511b41 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -101,6 +101,30 @@ inline void writeWinSpecificFields(FILE* f, int bssPtr, int bssSize, int headers write32(f, 16); /* NumberOfRvaAndSizes */ } +/** + * Write Windows data fields. + */ +inline void writeWinDataFields(FILE* f, int importDirTablePtr, int importDirTableSize, int iatPtr, int iatSize) { + write32(f, 0); write32(f, 0); /* Export Table. */ + write32(f, importDirTablePtr); /* Import Table. */ + write32(f, importDirTableSize); + write32(f, 0); write32(f, 0); /* Resource Table. */ + write32(f, 0); write32(f, 0); /* Exception Table. */ + write32(f, 0); write32(f, 0); /* Certificate Table. */ + write32(f, 0); write32(f, 0); /* Base Relocation Table. */ + write32(f, 0); write32(f, 0); /* Debug. */ + write32(f, 0); write32(f, 0); /* Architecture. */ + write32(f, 0); write32(f, 0); /* Global Ptr. */ + write32(f, 0); write32(f, 0); /* TLS Table. */ + write32(f, 0); write32(f, 0); /* Load Config Table. */ + write32(f, 0); write32(f, 0); /* Bound Import. */ + write32(f, iatPtr); /* Import Address Table. */ + write32(f, iatSize); + write32(f, 0); write32(f, 0); /* Delay Import Descriptor. */ + write32(f, 0); write32(f, 0); /* CLR Runtime Header. */ + write32(f, 0); write32(f, 0); /* (Reserved). */ +} + /** * Writes a Windows executable. */ @@ -151,4 +175,5 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u writeWinSTDFields(fptr, text_sz, rdata_sz, idata_sz, bss_sz, text_rva, rdata_rva); writeWinSpecificFields(fptr, bss_rva, bss_sz, headers_sz); + writeWinDataFields(fptr, import_dir_table_rva, import_dir_table_sz, iat_rva, iat_sz); } \ No newline at end of file diff --git a/src/compiler/win.h b/src/compiler/win.h index 7f66b21..55073c7 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -56,6 +56,10 @@ inline void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iData */ inline void writeWinSpecificFields(FILE* f, int bssPtr, int bssSize, int headersSize); +/** + * Write Windows data fields. + */ +inline void writeWinDataFields(FILE* f, int importDirTablePtr, int importDirTableSize, int iatPtr, int iatSize); /** * Writes a Windows section header. */ From a3b33d7589c4080d607d89cb086fc9d35259e835 Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 13:45:00 +0100 Subject: [PATCH 23/53] feat: added section headers --- src/compiler/win.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/compiler/win.c b/src/compiler/win.c index 1511b41..ec9045f 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -176,4 +176,9 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u writeWinSTDFields(fptr, text_sz, rdata_sz, idata_sz, bss_sz, text_rva, rdata_rva); writeWinSpecificFields(fptr, bss_rva, bss_sz, headers_sz); writeWinDataFields(fptr, import_dir_table_rva, import_dir_table_sz, iat_rva, iat_sz); + + writeWinSection(fptr, ".text", text_sz, text_rva, align_to(text_sz, WIN_FILE_ALIGN), text_offset, 0x60000020); + writeWinSection(fptr, ".rdata", rdata_sz, rdata_rva, align_to(rdata_sz, WIN_FILE_ALIGN), rdata_offset, 0x40000040); + writeWinSection(fptr, ".idata", idata_sz, idata_rva, align_to(idata_sz, WIN_FILE_ALIGN), idata_offset, 0xc0000040); + writeWinSection(fptr, ".bss", bss_sz, bss_rva, 0, 0, 0xc0000080); } \ No newline at end of file From 8a995c56177dfae5c7201b09f8425436e11aceae Mon Sep 17 00:00:00 2001 From: Zffu Date: Thu, 19 Dec 2024 13:49:08 +0100 Subject: [PATCH 24/53] tables --- src/compiler/win.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/compiler/win.c b/src/compiler/win.c index ec9045f..a32f96e 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -181,4 +181,14 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u writeWinSection(fptr, ".rdata", rdata_sz, rdata_rva, align_to(rdata_sz, WIN_FILE_ALIGN), rdata_offset, 0x40000040); writeWinSection(fptr, ".idata", idata_sz, idata_rva, align_to(idata_sz, WIN_FILE_ALIGN), idata_offset, 0xc0000040); writeWinSection(fptr, ".bss", bss_sz, bss_rva, 0, 0, 0xc0000080); + + seek(fptr, text_offset); + for (int i = 0; i < sizeof(program); i++) { + write8(fptr, program[i]); + } + + seek(fptr, rdata_offset); + for (int i = 0; i < sizeof(table); i++) { + write8(fptr, table[i]); + } } \ No newline at end of file From b5d4d0cd670c6305445aac445020e74a0534e8de Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 20 Dec 2024 05:47:30 +0100 Subject: [PATCH 25/53] feat: added win .idata tables sizes --- src/compiler/win.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index a32f96e..cfdb221 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -191,4 +191,12 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u for (int i = 0; i < sizeof(table); i++) { write8(fptr, table[i]); } -} \ No newline at end of file + + seek(fptr, idata_offset); + + write32(fptr, name_table_tva + 0 * WIN_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + 1 * NAME_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + 2 * NAME_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + 3 * NAME_TABLE_ENTRY_SZ); + write(fptr, 0); +} From 959d83d115318ae9b66abfdfe9ca5957ffc2a356 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 20 Dec 2024 05:49:54 +0100 Subject: [PATCH 26/53] feat: added import table for win --- src/compiler/win.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/compiler/win.c b/src/compiler/win.c index cfdb221..0bd085f 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -199,4 +199,20 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u write32(fptr, name_table_rva + 2 * NAME_TABLE_ENTRY_SZ); write32(fptr, name_table_rva + 3 * NAME_TABLE_ENTRY_SZ); write(fptr, 0); + + // Windows STD Imports + + // kernel32.dll + write32(fptr, import_lookup_table_rva); + write32(fptr, 0); + write32(fptr, 0); + write32(fptr, dll_name_rva); + write32(fptr, iat_rva); + + // Null term + write32(f, 0); + write32(f, 0); + write32(f, 0); + write32(f, 0); + write32(f, 0); } From b04bf0266ad608ddca7e95564580afde44269b47 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 20 Dec 2024 05:55:47 +0100 Subject: [PATCH 27/53] feat: added win hint table --- src/compiler/win.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index 0bd085f..f88dfa9 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -194,10 +194,10 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u seek(fptr, idata_offset); - write32(fptr, name_table_tva + 0 * WIN_TABLE_ENTRY_SZ); - write32(fptr, name_table_rva + 1 * NAME_TABLE_ENTRY_SZ); - write32(fptr, name_table_rva + 2 * NAME_TABLE_ENTRY_SZ); - write32(fptr, name_table_rva + 3 * NAME_TABLE_ENTRY_SZ); + write32(fptr, name_table_tva + 0 * WIN_NAME_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + 1 * WIN_NAME_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + 2 * WIN_NAME_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + 3 * WIN_NAME_TABLE_ENTRY_SZ); write(fptr, 0); // Windows STD Imports @@ -215,4 +215,23 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u write32(f, 0); write32(f, 0); write32(f, 0); + + write32(fptr, name_table_rva + 0 * WIN_NAME_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + 1 * WIN_NAME_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + 2 * WIN_NAME_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + 3 * WIN_NAME_TABLE_ENTRY_SZ); + write32(fptr, 0); // Null term + + // Hint table + write16(fptr, 0); + writestr16(fptr, "GetStdHandle"); + write16(fptr, 0); + writestr16(fptr, "ReadFile"); + write16(fptr, 0); + writestr16(fptr, "WriteFile"); + write16(fptr, 0); + writestr16(fptr, "ExitProcess"); + + // We need to put the dll name somewhere. + writestr16(fptr, "kernel32.dll"); } From d44e242b5d6e942111adaef399a14372abb4577f Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 20 Dec 2024 05:57:16 +0100 Subject: [PATCH 28/53] feat: started working on passing imports size and imports in parameters of writeWinExecutable --- src/compiler/win.c | 2 +- src/compiler/win.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index f88dfa9..f7023db 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -128,7 +128,7 @@ inline void writeWinDataFields(FILE* f, int importDirTablePtr, int importDirTabl /** * Writes a Windows executable. */ -inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[]) { +inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[], int numImports, char* imports[]) { int dosSize = sizeof(dos); uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; diff --git a/src/compiler/win.h b/src/compiler/win.h index 55073c7..42d0d1a 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -69,6 +69,6 @@ inline void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t /** * Writes a windows executable. */ -inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[]); +inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[], int numImports, char* imports[]); #endif From da0ee1f121b64dd733696837a1d05b6113126f35 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 20 Dec 2024 06:00:19 +0100 Subject: [PATCH 29/53] feat: made num_imports change behaviors --- src/compiler/win.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index f7023db..1a24d0c 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -128,7 +128,7 @@ inline void writeWinDataFields(FILE* f, int importDirTablePtr, int importDirTabl /** * Writes a Windows executable. */ -inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[], int numImports, char* imports[]) { +inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[], int num_imports, char* imports[]) { int dosSize = sizeof(dos); uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; @@ -156,7 +156,6 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u uint32_t idata_rva = align_to(rdata_rva + rdata_sz, WIN_SEC_ALIGN); uint32_t idata_offset = align_to(rdata_offset + rdata_sz, WIN_FILE_ALIGN); - uint32_t num_imports = 4; uint32_t iat_rva = idata_rva; uint32_t iat_sz = (num_imports + 1) * WIN_IAT_ENTRY_SZ; uint32_t import_dir_table_rva = iat_rva + iat_sz; @@ -194,10 +193,10 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u seek(fptr, idata_offset); - write32(fptr, name_table_tva + 0 * WIN_NAME_TABLE_ENTRY_SZ); - write32(fptr, name_table_rva + 1 * WIN_NAME_TABLE_ENTRY_SZ); - write32(fptr, name_table_rva + 2 * WIN_NAME_TABLE_ENTRY_SZ); - write32(fptr, name_table_rva + 3 * WIN_NAME_TABLE_ENTRY_SZ); + for(int i = 0; i < num_imports; ++i) { + write32(fptr, name_table_rva + i * WIN_TABLE_ENTRY_SZ); + } + write(fptr, 0); // Windows STD Imports @@ -216,10 +215,10 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u write32(f, 0); write32(f, 0); - write32(fptr, name_table_rva + 0 * WIN_NAME_TABLE_ENTRY_SZ); - write32(fptr, name_table_rva + 1 * WIN_NAME_TABLE_ENTRY_SZ); - write32(fptr, name_table_rva + 2 * WIN_NAME_TABLE_ENTRY_SZ); - write32(fptr, name_table_rva + 3 * WIN_NAME_TABLE_ENTRY_SZ); + for(int i = 0; i < num_imports; ++i) { + write32(fptr, name_table_rva + i * WIN_NAME_TABLE_ENTRY_SZ); + } + write32(fptr, 0); // Null term // Hint table From 62fbc6262b5616b06c481fbaf2a6280f8f8ebbff Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 20 Dec 2024 06:00:49 +0100 Subject: [PATCH 30/53] fix: typo at WIN_NAME_TABLE_ENTRY_SZ --- src/compiler/win.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index 1a24d0c..07b5ac7 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -194,7 +194,7 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u seek(fptr, idata_offset); for(int i = 0; i < num_imports; ++i) { - write32(fptr, name_table_rva + i * WIN_TABLE_ENTRY_SZ); + write32(fptr, name_table_rva + i * WIN_NAME_TABLE_ENTRY_SZ); } write(fptr, 0); From 43b93a459239c88afbb0c36441f49af7aeb411d0 Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 20 Dec 2024 06:01:54 +0100 Subject: [PATCH 31/53] feat: made hint table dependant on num_imports and imports --- src/compiler/win.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index 07b5ac7..95506cb 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -222,14 +222,11 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u write32(fptr, 0); // Null term // Hint table - write16(fptr, 0); - writestr16(fptr, "GetStdHandle"); - write16(fptr, 0); - writestr16(fptr, "ReadFile"); - write16(fptr, 0); - writestr16(fptr, "WriteFile"); - write16(fptr, 0); - writestr16(fptr, "ExitProcess"); + + for(int i = 0; i < num_imports; ++i) { + write16(fptr, 0); + writestr16(fptr, imports[i]); + } // We need to put the dll name somewhere. writestr16(fptr, "kernel32.dll"); From 6e3337a2bf27b690e5d3a7878d03700759d7de1d Mon Sep 17 00:00:00 2001 From: Zffu Date: Fri, 20 Dec 2024 06:38:49 +0100 Subject: [PATCH 32/53] bump --- src/compiler/win.c | 53 +++++++++++++++++++++++++++++++++------------- src/compiler/win.h | 3 ++- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index 95506cb..f7f68b3 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -11,7 +11,7 @@ /** * Writes the windows executable header. */ -inline void writeWinExecutableHeader(FILE* f, int dosStubSZ, int peOffset) { +void writeWinExecutableHeader(FILE* f, int dosStubSZ, int peOffset) { write8(f, 'M'); /* Magic number (2 bytes) */ write8(f, 'Z'); write16(f, dosStubSZ % 512); /* Last page size */ @@ -41,7 +41,7 @@ inline void writeWinExecutableHeader(FILE* f, int dosStubSZ, int peOffset) { /** * Writes the Windows PE Signature. */ -inline void writeWinPESignature(FILE* fptr, int peOffset) { +void writeWinPESignature(FILE* fptr, int peOffset) { seek(fptr, peOffset); write8(fptr, 'P'); write8(fptr, 'E'); @@ -52,7 +52,7 @@ inline void writeWinPESignature(FILE* fptr, int peOffset) { /** * Writes the Windows COFF Header. */ -inline void writeWinCoffHeader(FILE* fptr, int numSections) { +void writeWinCoffHeader(FILE* fptr, int numSections) { write16(fptr, 0x14c); /* Machine: IMAGE_FILE_MACHINE_I386 */ write16(fptr, numSections); /* NumberOfSections */ write32(fptr, 0); /* TimeDateStamp */ @@ -65,7 +65,7 @@ inline void writeWinCoffHeader(FILE* fptr, int numSections) { /** * Writes the Windows standart fields header. */ -inline void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iDataSize, int bssSize, int textPtr, int rdataPtr) { +void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iDataSize, int bssSize, int textPtr, int rdataPtr) { write16(fptr, 0x10b); /* Magic: PE32 */ write8(fptr, 0); /* MajorLinkerVersion */ write8(fptr, 0); /* MinorLinkerVersion */ @@ -77,7 +77,7 @@ inline void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iData write32(fptr, rdataPtr); /* BaseOfData */ } -inline void writeWinSpecificFields(FILE* f, int bssPtr, int bssSize, int headersSize) { +void writeWinSpecificFields(FILE* f, int bssPtr, int bssSize, int headersSize) { write32(f, WIN_IMAGE_BASE); /* ImageBase */ write32(f, WIN_SEC_ALIGN); /* SectionAlignment */ write32(f, WIN_FILE_ALIGN); /* FileAlignment */ @@ -104,7 +104,7 @@ inline void writeWinSpecificFields(FILE* f, int bssPtr, int bssSize, int headers /** * Write Windows data fields. */ -inline void writeWinDataFields(FILE* f, int importDirTablePtr, int importDirTableSize, int iatPtr, int iatSize) { +void writeWinDataFields(FILE* f, int importDirTablePtr, int importDirTableSize, int iatPtr, int iatSize) { write32(f, 0); write32(f, 0); /* Export Table. */ write32(f, importDirTablePtr); /* Import Table. */ write32(f, importDirTableSize); @@ -125,10 +125,28 @@ inline void writeWinDataFields(FILE* f, int importDirTablePtr, int importDirTabl write32(f, 0); write32(f, 0); /* (Reserved). */ } +/** + * Writes a windows section.h + */ +void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t virtualAddress, uint32_t size, uint32_t ptr, uint32_t chrs) { + writestr8(fptr, secName); + write32(fptr, virtualSize); + write32(fptr, virtualAddress); + write32(fptr, size); + write32(fptr, ptr); + + write32(fptr, 0); + write32(fptr, 0); + write16(fptr, 0); + write16(fptr, 0); + + write32(fptr, chrs); +} + /** * Writes a Windows executable. */ -inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[], int num_imports, char* imports[]) { +void writeWinExecutable(FILE* fptr, uint8_t* dos, uint8_t* program, uint8_t* table, int num_imports, char* imports[]) { int dosSize = sizeof(dos); uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; @@ -136,9 +154,12 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u writeWinExecutableHeader(fptr, dosSize, pe_offset); writeWinPESignature(fptr, pe_offset); + writeWinCoffHeader(fptr, pe_offset); - for(int i = 0; i < dosSize; ++i) { - write8(fptr, dos[i]); + uint8_t b; + + while(b = *dos++) { + write8(fptr, b); } uint32_t num_sections = 4; @@ -197,7 +218,7 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u write32(fptr, name_table_rva + i * WIN_NAME_TABLE_ENTRY_SZ); } - write(fptr, 0); + write32(fptr, 0); // Windows STD Imports @@ -209,11 +230,11 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u write32(fptr, iat_rva); // Null term - write32(f, 0); - write32(f, 0); - write32(f, 0); - write32(f, 0); - write32(f, 0); + write32(fptr, 0); + write32(fptr, 0); + write32(fptr, 0); + write32(fptr, 0); + write32(fptr, 0); for(int i = 0; i < num_imports; ++i) { write32(fptr, name_table_rva + i * WIN_NAME_TABLE_ENTRY_SZ); @@ -230,4 +251,6 @@ inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], u // We need to put the dll name somewhere. writestr16(fptr, "kernel32.dll"); + + fclose(fptr); } diff --git a/src/compiler/win.h b/src/compiler/win.h index 42d0d1a..e4dbffa 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -2,6 +2,7 @@ * Windows related Quickfall compiling. */ +#include #include #ifndef COMPILER_WIN @@ -69,6 +70,6 @@ inline void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t /** * Writes a windows executable. */ -inline void writeWinExecutable(FILE* fptr, uint32_t dos[], uint32_t program[], uint32_t table[], int numImports, char* imports[]); +void writeWinExecutable(FILE* fptr, uint8_t dos[], uint8_t program[], uint8_t table[], int numImports, char* imports[]); #endif From 9efdb123d5f7a3cfb1859a9732fea7aadd6cf593 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sat, 21 Dec 2024 14:30:48 +0100 Subject: [PATCH 33/53] feat: added size for dos program and program in params --- src/compiler/win.c | 17 +++++++---------- src/compiler/win.h | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/compiler/win.c b/src/compiler/win.c index f7f68b3..e793a6b 100644 --- a/src/compiler/win.c +++ b/src/compiler/win.c @@ -146,20 +146,17 @@ void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t virtua /** * Writes a Windows executable. */ -void writeWinExecutable(FILE* fptr, uint8_t* dos, uint8_t* program, uint8_t* table, int num_imports, char* imports[]) { - int dosSize = sizeof(dos); +void writeWinExecutable(FILE* fptr, uint8_t dos[], int dosSize, uint8_t program[], int programSize, uint8_t* table, int num_imports, char* imports[]) { uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; uint32_t pe_offset = align_to(dos_stub_sz, 8); - writeWinExecutableHeader(fptr, dosSize, pe_offset); + writeWinExecutableHeader(fptr, dos_stub_sz, pe_offset); writeWinPESignature(fptr, pe_offset); writeWinCoffHeader(fptr, pe_offset); - uint8_t b; - - while(b = *dos++) { - write8(fptr, b); + for(int i = 0; i < dosSize; ++i) { + write8(fptr, dos[i]); } uint32_t num_sections = 4; @@ -168,11 +165,11 @@ void writeWinExecutable(FILE* fptr, uint8_t* dos, uint8_t* program, uint8_t* tab uint32_t text_rva = align_to(headers_sz, WIN_SEC_ALIGN); uint32_t text_offset = align_to(headers_sz, WIN_FILE_ALIGN); - uint32_t text_sz = sizeof(program); + uint32_t text_sz = programSize; uint32_t rdata_rva = align_to(text_rva + text_sz, WIN_SEC_ALIGN); uint32_t rdata_offset = align_to(text_offset + text_sz, WIN_FILE_ALIGN); - uint32_t rdata_sz = sizeof(program); + uint32_t rdata_sz = programSize; uint32_t idata_rva = align_to(rdata_rva + rdata_sz, WIN_SEC_ALIGN); uint32_t idata_offset = align_to(rdata_offset + rdata_sz, WIN_FILE_ALIGN); @@ -203,7 +200,7 @@ void writeWinExecutable(FILE* fptr, uint8_t* dos, uint8_t* program, uint8_t* tab writeWinSection(fptr, ".bss", bss_sz, bss_rva, 0, 0, 0xc0000080); seek(fptr, text_offset); - for (int i = 0; i < sizeof(program); i++) { + for (int i = 0; i < programSize; i++) { write8(fptr, program[i]); } diff --git a/src/compiler/win.h b/src/compiler/win.h index e4dbffa..445a5e9 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -70,6 +70,6 @@ inline void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t /** * Writes a windows executable. */ -void writeWinExecutable(FILE* fptr, uint8_t dos[], uint8_t program[], uint8_t table[], int numImports, char* imports[]); +void writeWinExecutable(FILE* fptr, uint8_t dos[], int dosSize, uint8_t program[], int programSize, uint8_t table[], int numImports, char* imports[]); #endif From e07d3e797e5cb4b7ef2f7777db279caa16f60e19 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:18:04 +0100 Subject: [PATCH 34/53] chore: removed old not working windows pe format --- src/compiler/utils.c | 13 ++- src/compiler/win.c | 253 ------------------------------------------- src/compiler/win.h | 75 ------------- 3 files changed, 12 insertions(+), 329 deletions(-) delete mode 100644 src/compiler/win.c delete mode 100644 src/compiler/win.h diff --git a/src/compiler/utils.c b/src/compiler/utils.c index 68d66d9..2fa9b41 100644 --- a/src/compiler/utils.c +++ b/src/compiler/utils.c @@ -2,16 +2,22 @@ * Utilities for the Quickfall compiler. */ +#include #include #include #include +#include /** * Writes an 8 bit number into the file. */ void write8(FILE *file, uint8_t value) { - if (fputc(value, file) == EOF) { + + printf("Input %d for: %02x\n", value, (value >> 0) & 0xff); + + if (fputc(value, file) == EOF) { perror("fputc"); + exit(1); } } @@ -31,6 +37,8 @@ void write32(FILE *file, uint32_t value) { write8(file, (value >> 8) & 0xff); write8(file, (value >> 16) & 0xff); write8(file, (value >> 24) & 0xff); + + printf("32 Input for %d: %02x %02x %02x %02x\n", (value >> 0) & 0xff, (value >> 8) & 0xff, (value >> 16) && 0xff, (value >> 24) & 0xff); } /** @@ -40,6 +48,7 @@ void writestr8(FILE *file, char *str) { size_t len, i; len = strlen(str); + assert(len <= 8 && "The string must fit in 8 bytes."); for (i = 0; i < 8; i++) { write8(file, i < len ? str[i] : 0); @@ -53,6 +62,7 @@ void writestr16(FILE *file, char *str) { size_t len, i; len = strlen(str); + assert(len <= 15 && "The string and terminator must fit in 16 bytes."); for (i = 0; i < 16; i++) { write8(file, i < len ? str[i] : 0); @@ -65,6 +75,7 @@ void writestr16(FILE *file, char *str) { void seek(FILE *file, long offset) { if (fseek(file, offset, SEEK_SET) == -1) { perror("fseek"); + exit(1); } } diff --git a/src/compiler/win.c b/src/compiler/win.c deleted file mode 100644 index e793a6b..0000000 --- a/src/compiler/win.c +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Windows related compiling for Quickfall. - */ - -#include -#include - -#include "./utils.h" -#include "./win.h" - -/** - * Writes the windows executable header. - */ -void writeWinExecutableHeader(FILE* f, int dosStubSZ, int peOffset) { - write8(f, 'M'); /* Magic number (2 bytes) */ - write8(f, 'Z'); - write16(f, dosStubSZ % 512); /* Last page size */ - write16(f, align_to(dosStubSZ, 512) / 512); /* Pages in file */ - write16(f, 0); /* Relocations */ - write16(f, WIN_DOS_HDR_SZ / 16); /* Size of header in paragraphs */ - write16(f, 0); /* Minimum extra paragraphs needed */ - write16(f, 1); /* Maximum extra paragraphs needed */ - write16(f, 0); /* Initial (relative) SS value */ - write16(f, 0); /* Initial SP value */ - write16(f, 0); /* Checksum */ - write16(f, 0); /* Initial IP value */ - write16(f, 0); /* Initial (relative) CS value */ - write16(f, WIN_DOS_HDR_SZ); /* File address of relocation table */ - write16(f, 0); /* Overlay number */ - write16(f, 0); /* Reserved0 */ - write16(f, 0); /* Reserved1 */ - write16(f, 0); /* Reserved2 */ - write16(f, 0); /* Reserved3 */ - write16(f, 0); /* OEM id */ - write16(f, 0); /* OEM info */ - for (int i = 0; i < 10; i++) - write16(f, 0); /* Reserved (10 words) */ - write32(f, peOffset); /* File offset of PE header. */ -} - -/** - * Writes the Windows PE Signature. - */ -void writeWinPESignature(FILE* fptr, int peOffset) { - seek(fptr, peOffset); - write8(fptr, 'P'); - write8(fptr, 'E'); - write8(fptr, 0); - write8(fptr, 0); -} - -/** - * Writes the Windows COFF Header. - */ -void writeWinCoffHeader(FILE* fptr, int numSections) { - write16(fptr, 0x14c); /* Machine: IMAGE_FILE_MACHINE_I386 */ - write16(fptr, numSections); /* NumberOfSections */ - write32(fptr, 0); /* TimeDateStamp */ - write32(fptr, 0); /* PointerToSymbolTable */ - write32(fptr, 0); /* NumberOfSymbols */ - write16(fptr, WIN_OPT_HDR_SZ); /* SizeOfOptionalHeader */ - write16(fptr, 0x103); /* Characteristics: no relocations, exec, 32-bit */ -} - -/** - * Writes the Windows standart fields header. - */ -void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iDataSize, int bssSize, int textPtr, int rdataPtr) { - write16(fptr, 0x10b); /* Magic: PE32 */ - write8(fptr, 0); /* MajorLinkerVersion */ - write8(fptr, 0); /* MinorLinkerVersion */ - write32(fptr, textSize); /* SizeOfCode */ - write32(fptr, rDataSize + iDataSize); /* SizeOfInitializedData */ - write32(fptr, bssSize); /* SizeOfUninitializedData */ - write32(fptr, textPtr); /* AddressOfEntryPoint */ - write32(fptr, textPtr); /* BaseOfCode */ - write32(fptr, rdataPtr); /* BaseOfData */ -} - -void writeWinSpecificFields(FILE* f, int bssPtr, int bssSize, int headersSize) { - write32(f, WIN_IMAGE_BASE); /* ImageBase */ - write32(f, WIN_SEC_ALIGN); /* SectionAlignment */ - write32(f, WIN_FILE_ALIGN); /* FileAlignment */ - write16(f, 3); /* MajorOperatingSystemVersion */ - write16(f, 10); /* MinorOperatingSystemVersion*/ - write16(f, 0); /* MajorImageVersion */ - write16(f, 0); /* MinorImageVersion */ - write16(f, 3); /* MajorSubsystemVersion */ - write16(f, 10); /* MinorSubsystemVersion */ - write32(f, 0); /* Win32VersionValue*/ - write32(f, align_to(bssPtr + bssSize, WIN_SEC_ALIGN)); /* SizeOfImage */ - write32(f, align_to(headersSize, WIN_FILE_ALIGN)); /* SizeOfHeaders */ - write32(f, 0); /* Checksum */ - write16(f, 3); /* Subsystem: Console */ - write16(f, 0); /* DllCharacteristics */ - write32(f, 0x100000); /* SizeOfStackReserve */ - write32(f, 0x1000); /* SizeOfStackCommit */ - write32(f, 0x100000); /* SizeOfHeapReserve */ - write32(f, 0x1000); /* SizeOfHeapCommit */ - write32(f, 0); /* LoadFlags */ - write32(f, 16); /* NumberOfRvaAndSizes */ -} - -/** - * Write Windows data fields. - */ -void writeWinDataFields(FILE* f, int importDirTablePtr, int importDirTableSize, int iatPtr, int iatSize) { - write32(f, 0); write32(f, 0); /* Export Table. */ - write32(f, importDirTablePtr); /* Import Table. */ - write32(f, importDirTableSize); - write32(f, 0); write32(f, 0); /* Resource Table. */ - write32(f, 0); write32(f, 0); /* Exception Table. */ - write32(f, 0); write32(f, 0); /* Certificate Table. */ - write32(f, 0); write32(f, 0); /* Base Relocation Table. */ - write32(f, 0); write32(f, 0); /* Debug. */ - write32(f, 0); write32(f, 0); /* Architecture. */ - write32(f, 0); write32(f, 0); /* Global Ptr. */ - write32(f, 0); write32(f, 0); /* TLS Table. */ - write32(f, 0); write32(f, 0); /* Load Config Table. */ - write32(f, 0); write32(f, 0); /* Bound Import. */ - write32(f, iatPtr); /* Import Address Table. */ - write32(f, iatSize); - write32(f, 0); write32(f, 0); /* Delay Import Descriptor. */ - write32(f, 0); write32(f, 0); /* CLR Runtime Header. */ - write32(f, 0); write32(f, 0); /* (Reserved). */ -} - -/** - * Writes a windows section.h - */ -void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t virtualAddress, uint32_t size, uint32_t ptr, uint32_t chrs) { - writestr8(fptr, secName); - write32(fptr, virtualSize); - write32(fptr, virtualAddress); - write32(fptr, size); - write32(fptr, ptr); - - write32(fptr, 0); - write32(fptr, 0); - write16(fptr, 0); - write16(fptr, 0); - - write32(fptr, chrs); -} - -/** - * Writes a Windows executable. - */ -void writeWinExecutable(FILE* fptr, uint8_t dos[], int dosSize, uint8_t program[], int programSize, uint8_t* table, int num_imports, char* imports[]) { - - uint32_t dos_stub_sz = WIN_DOS_HDR_SZ + dosSize; - uint32_t pe_offset = align_to(dos_stub_sz, 8); - - writeWinExecutableHeader(fptr, dos_stub_sz, pe_offset); - writeWinPESignature(fptr, pe_offset); - writeWinCoffHeader(fptr, pe_offset); - - for(int i = 0; i < dosSize; ++i) { - write8(fptr, dos[i]); - } - - uint32_t num_sections = 4; - - uint32_t headers_sz = pe_offset + WIN_PE_HDR_SZ + num_sections * WIN_SEC_HDR_SZ; - - uint32_t text_rva = align_to(headers_sz, WIN_SEC_ALIGN); - uint32_t text_offset = align_to(headers_sz, WIN_FILE_ALIGN); - uint32_t text_sz = programSize; - - uint32_t rdata_rva = align_to(text_rva + text_sz, WIN_SEC_ALIGN); - uint32_t rdata_offset = align_to(text_offset + text_sz, WIN_FILE_ALIGN); - uint32_t rdata_sz = programSize; - - uint32_t idata_rva = align_to(rdata_rva + rdata_sz, WIN_SEC_ALIGN); - uint32_t idata_offset = align_to(rdata_offset + rdata_sz, WIN_FILE_ALIGN); - - uint32_t iat_rva = idata_rva; - uint32_t iat_sz = (num_imports + 1) * WIN_IAT_ENTRY_SZ; - uint32_t import_dir_table_rva = iat_rva + iat_sz; - uint32_t import_dir_table_sz = 2 * WIN_IMPORT_DIR_ENTRY_SZ; - uint32_t import_lookup_table_rva = import_dir_table_rva + - import_dir_table_sz; - uint32_t name_table_rva = import_lookup_table_rva + - (num_imports + 1) * WIN_IMPORT_LOOKUP_TBL_ENTRY_SZ; - uint32_t dll_name_rva = name_table_rva + - num_imports * WIN_NAME_TABLE_ENTRY_SZ; - uint32_t name_table_sz = num_imports * WIN_NAME_TABLE_ENTRY_SZ + 16; - uint32_t idata_sz = name_table_rva + name_table_sz - idata_rva; - - uint32_t bss_rva = align_to(idata_rva + idata_sz, WIN_SEC_ALIGN); - uint32_t bss_sz = 4096; - - writeWinSTDFields(fptr, text_sz, rdata_sz, idata_sz, bss_sz, text_rva, rdata_rva); - writeWinSpecificFields(fptr, bss_rva, bss_sz, headers_sz); - writeWinDataFields(fptr, import_dir_table_rva, import_dir_table_sz, iat_rva, iat_sz); - - writeWinSection(fptr, ".text", text_sz, text_rva, align_to(text_sz, WIN_FILE_ALIGN), text_offset, 0x60000020); - writeWinSection(fptr, ".rdata", rdata_sz, rdata_rva, align_to(rdata_sz, WIN_FILE_ALIGN), rdata_offset, 0x40000040); - writeWinSection(fptr, ".idata", idata_sz, idata_rva, align_to(idata_sz, WIN_FILE_ALIGN), idata_offset, 0xc0000040); - writeWinSection(fptr, ".bss", bss_sz, bss_rva, 0, 0, 0xc0000080); - - seek(fptr, text_offset); - for (int i = 0; i < programSize; i++) { - write8(fptr, program[i]); - } - - seek(fptr, rdata_offset); - for (int i = 0; i < sizeof(table); i++) { - write8(fptr, table[i]); - } - - seek(fptr, idata_offset); - - for(int i = 0; i < num_imports; ++i) { - write32(fptr, name_table_rva + i * WIN_NAME_TABLE_ENTRY_SZ); - } - - write32(fptr, 0); - - // Windows STD Imports - - // kernel32.dll - write32(fptr, import_lookup_table_rva); - write32(fptr, 0); - write32(fptr, 0); - write32(fptr, dll_name_rva); - write32(fptr, iat_rva); - - // Null term - write32(fptr, 0); - write32(fptr, 0); - write32(fptr, 0); - write32(fptr, 0); - write32(fptr, 0); - - for(int i = 0; i < num_imports; ++i) { - write32(fptr, name_table_rva + i * WIN_NAME_TABLE_ENTRY_SZ); - } - - write32(fptr, 0); // Null term - - // Hint table - - for(int i = 0; i < num_imports; ++i) { - write16(fptr, 0); - writestr16(fptr, imports[i]); - } - - // We need to put the dll name somewhere. - writestr16(fptr, "kernel32.dll"); - - fclose(fptr); -} diff --git a/src/compiler/win.h b/src/compiler/win.h deleted file mode 100644 index 445a5e9..0000000 --- a/src/compiler/win.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Windows related Quickfall compiling. - */ - -#include -#include - -#ifndef COMPILER_WIN -#define COMPILER_WIN - -/** - * Constants for Windows Executable Format. - */ - -#define WIN_DOS_HDR_SZ 0x40 -#define WIN_PE_SIG_SZ 0x4 -#define WIN_COFF_HDR_SZ 0x14 -#define WIN_OPT_HDR_SZ 0xe0 -#define WIN_PE_HDR_SZ (WIN_PE_SIG_SZ + WIN_COFF_HDR_SZ + WIN_OPT_HDR_SZ) -#define WIN_SEC_HDR_SZ 0x28 - -#define WIN_IAT_ENTRY_SZ 0x4 -#define WIN_IMPORT_DIR_ENTRY_SZ 0x14 -#define WIN_IMPORT_LOOKUP_TBL_ENTRY_SZ WIN_IAT_ENTRY_SZ -#define WIN_NAME_TABLE_ENTRY_SZ 0x12 - -#define WIN_IMAGE_BASE 0x00400000 -#define WIN_SEC_ALIGN 0x1000 -#define WIN_FILE_ALIGN 0x200 - -/** - * Writing functions. - */ - -/** - * Writes the windows executable header. - */ -inline void writeWinExecutableHeader(FILE* fptr, int dosStubSZ, int peOffset); - -/** - * Writes the Windows PE Signature. - */ -inline void writeWinPESignature(FILE* fptr, int peOffset); - -/** - * Writes the Windows COFF Header. - */ -inline void writeWinCoffHeader(FILE* fptr, int numSections); - -/** - * Writes the Windows standart fields header. - */ -inline void writeWinSTDFields(FILE* fptr, int textSize, int rDataSize, int iDataSize, int bssSize, int textPtr, int rdataPtr); - -/** - * Writes the Windows-specific fields header. - */ -inline void writeWinSpecificFields(FILE* f, int bssPtr, int bssSize, int headersSize); - -/** - * Write Windows data fields. - */ -inline void writeWinDataFields(FILE* f, int importDirTablePtr, int importDirTableSize, int iatPtr, int iatSize); -/** - * Writes a Windows section header. - */ -inline void writeWinSection(FILE* fptr, char* secName, int virtualSize, uint32_t virtualAddress, uint32_t size, uint32_t pointer, uint32_t characteristics); - - -/** - * Writes a windows executable. - */ -void writeWinExecutable(FILE* fptr, uint8_t dos[], int dosSize, uint8_t program[], int programSize, uint8_t table[], int numImports, char* imports[]); - -#endif From 720c21cbb93c0d66b745cb5e4bc992d411e47d53 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:23:58 +0100 Subject: [PATCH 35/53] feat: added compiler PE format datatypes --- src/compiler/win.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/compiler/win.h diff --git a/src/compiler/win.h b/src/compiler/win.h new file mode 100644 index 0000000..2a7fedb --- /dev/null +++ b/src/compiler/win.h @@ -0,0 +1,14 @@ +/** + * Quickfall Windows-Compiling (PE format). + */ + +/** + * PE format data types. + */ +typedef DWORD unsigned long +typedef WORD unsigned int + +#ifndef COMPILER_WIN +#define COMPILER_WIN + +#endif From 0d108a508db684140f44e088682f4d86bdc77472 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:25:03 +0100 Subject: [PATCH 36/53] refactor: moved datatypes into def --- src/compiler/win.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/win.h b/src/compiler/win.h index 2a7fedb..599e034 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -2,13 +2,13 @@ * Quickfall Windows-Compiling (PE format). */ +#ifndef COMPILER_WIN +#define COMPILER_WIN + /** - * PE format data types. + * PE Format datatypes. */ typedef DWORD unsigned long typedef WORD unsigned int -#ifndef COMPILER_WIN -#define COMPILER_WIN - #endif From 7b4a80af84d42451d8d320b3e7a292be327bba1d Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:31:32 +0100 Subject: [PATCH 37/53] fix: fixed WORD and added PE_DOS_HEADER --- src/compiler/win.h | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/compiler/win.h b/src/compiler/win.h index 599e034..7aa262e 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -9,6 +9,33 @@ * PE Format datatypes. */ typedef DWORD unsigned long -typedef WORD unsigned int +typedef WORD unsigned short + +/** + * PE Format Structure Defintions. + */ +//todo: we could use Windows bundled structures but that wouldn't be cross platform compiling. + +typedef struct PE_DOS_HEADER { + WORD e_magic; + WORD e_cblp; + WORD e_cp; + WORD e_crlc; + WORD e_cpardhr; + WORD e_minalloc; + WORD e_maxalloc; + WORD e_ss; + WORD e_sp; + WORD e_csum; + WORD e_ip; + WORD e_cs; + WORD e_lfarlc; + WORD e_ovno; + WORD e_res[4]; + WORD e_oemid; + WORD e_oeminfo; + WORD e_res2[4]; + long e_lfanew; +} DOS_HEADER; #endif From 07c367e40b23e4e39de9d58a246d4c74e289d84e Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:33:38 +0100 Subject: [PATCH 38/53] feat: added PE_HEADER_SIGNATURE --- src/compiler/win.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/compiler/win.h b/src/compiler/win.h index 7aa262e..b184be1 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -11,6 +11,13 @@ typedef DWORD unsigned long typedef WORD unsigned short +/** + * PE Format Constants. + */ +//todo: we could use Windows bundled constants but that wouldn't be cross platform compiling. + +#define PE_HEADER_SIGNATURE 0x00004550 + /** * PE Format Structure Defintions. */ From a263300382a5c2ac5658dd13e104597610d68a4b Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:38:58 +0100 Subject: [PATCH 39/53] refactor: started moving pe format around --- src/compiler/pe/format.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/compiler/pe/format.h diff --git a/src/compiler/pe/format.h b/src/compiler/pe/format.h new file mode 100644 index 0000000..508f788 --- /dev/null +++ b/src/compiler/pe/format.h @@ -0,0 +1,14 @@ +/** + * Quickfall PE Format Defintion. + */ + +#ifndef PE_FORMAT +#define PE_FORMAT + +/** + * Constants. + */ + +#define PE_HEADER_SIGNATURE 0x00004550 + +#endif From 08831497e58273e21b6b809163cc11e2e30de005 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:40:32 +0100 Subject: [PATCH 40/53] feat: added units in header file --- src/compiler/units.h | 11 +++++++++++ src/compiler/win.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 src/compiler/units.h diff --git a/src/compiler/units.h b/src/compiler/units.h new file mode 100644 index 0000000..607fffd --- /dev/null +++ b/src/compiler/units.h @@ -0,0 +1,11 @@ +/** + * Quickfall Compiler common data-types. + */ + +#ifndef COMPILER_UNITS +#define COMPILER_UNITS + +typedef DWORD unsigned long // 32 bits +typedef WORD unsigned short // 16 bits + +#endif diff --git a/src/compiler/win.h b/src/compiler/win.h index b184be1..0b7ed8b 100644 --- a/src/compiler/win.h +++ b/src/compiler/win.h @@ -43,6 +43,6 @@ typedef struct PE_DOS_HEADER { WORD e_oeminfo; WORD e_res2[4]; long e_lfanew; -} DOS_HEADER; +} PE_DOS_HEADER; #endif From 5c0701097e04e21059b0ad6acae45695ce4d2f76 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:43:05 +0100 Subject: [PATCH 41/53] refactor: finished moving pe format around --- src/compiler/pe/format.h | 28 +++++++++++++++++++++++ src/compiler/win.h | 48 ---------------------------------------- 2 files changed, 28 insertions(+), 48 deletions(-) delete mode 100644 src/compiler/win.h diff --git a/src/compiler/pe/format.h b/src/compiler/pe/format.h index 508f788..2962dc5 100644 --- a/src/compiler/pe/format.h +++ b/src/compiler/pe/format.h @@ -2,6 +2,8 @@ * Quickfall PE Format Defintion. */ +#include "../units.h" + #ifndef PE_FORMAT #define PE_FORMAT @@ -11,4 +13,30 @@ #define PE_HEADER_SIGNATURE 0x00004550 +/** + * Structures. + */ + +typdef PE_DOS_HEADER { + WORD e_magic; // Magic number + WORD e_cblp; // Bytes on last page of file + WORD e_cp; // Pages in file + WORD e_crlc; // Relocations + WORD e_cparhdr; // Size of header in paragraphs + WORD e_minalloc; // Minimum extra paragraphs needed + WORD e_maxalloc; // Maximum extra paragraphs needed + WORD e_ss; // Initial (relative) SS value + WORD e_sp; // Initial SP value + WORD e_csum; // Checksum + WORD e_ip; // Initial IP value + WORD e_cs; // Initial (relative) CS value + WORD e_lfarlc; // File address of relocation table + WORD e_ovno; // Overlay number + WORD e_res[4]; // Reserved words + WORD e_oemid; // OEM identifier (for e_oeminfo) + WORD e_oeminfo; // OEM information; e_oemid specific + WORD e_res2[10]; // Reserved words + long e_lfanew; // File address of new exe header +} + #endif diff --git a/src/compiler/win.h b/src/compiler/win.h deleted file mode 100644 index 0b7ed8b..0000000 --- a/src/compiler/win.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Quickfall Windows-Compiling (PE format). - */ - -#ifndef COMPILER_WIN -#define COMPILER_WIN - -/** - * PE Format datatypes. - */ -typedef DWORD unsigned long -typedef WORD unsigned short - -/** - * PE Format Constants. - */ -//todo: we could use Windows bundled constants but that wouldn't be cross platform compiling. - -#define PE_HEADER_SIGNATURE 0x00004550 - -/** - * PE Format Structure Defintions. - */ -//todo: we could use Windows bundled structures but that wouldn't be cross platform compiling. - -typedef struct PE_DOS_HEADER { - WORD e_magic; - WORD e_cblp; - WORD e_cp; - WORD e_crlc; - WORD e_cpardhr; - WORD e_minalloc; - WORD e_maxalloc; - WORD e_ss; - WORD e_sp; - WORD e_csum; - WORD e_ip; - WORD e_cs; - WORD e_lfarlc; - WORD e_ovno; - WORD e_res[4]; - WORD e_oemid; - WORD e_oeminfo; - WORD e_res2[4]; - long e_lfanew; -} PE_DOS_HEADER; - -#endif From acfad1f67fd7023c47c35b0364d2f9505187f1b3 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:44:02 +0100 Subject: [PATCH 42/53] fix: struct def --- src/compiler/pe/format.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/pe/format.h b/src/compiler/pe/format.h index 2962dc5..50e1d46 100644 --- a/src/compiler/pe/format.h +++ b/src/compiler/pe/format.h @@ -17,7 +17,7 @@ * Structures. */ -typdef PE_DOS_HEADER { +typdef struct PE_DOS_HEADER { WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file @@ -37,6 +37,6 @@ typdef PE_DOS_HEADER { WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words long e_lfanew; // File address of new exe header -} +} PE_DOS_HEADER; #endif From f35c27327aac5326dcef3a91431886a73f6a9204 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:50:01 +0100 Subject: [PATCH 43/53] feat: added PE_HEADER --- src/compiler/pe/format.h | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/compiler/pe/format.h b/src/compiler/pe/format.h index 50e1d46..b555489 100644 --- a/src/compiler/pe/format.h +++ b/src/compiler/pe/format.h @@ -39,4 +39,54 @@ typdef struct PE_DOS_HEADER { long e_lfanew; // File address of new exe header } PE_DOS_HEADER; +typedef struct PE_FILE_HEADER { + WORD machine; + WORD sec_num; + DWORD timestamp; + DWORD symbolTablePtr; + DWORD symbolCount; + WORD optionalHeaderSize; + WORD chrs; +} PE_FILE_HEADER; + +typdef struct PE_OPTIONAL_HEADER { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; +} PE_OPTIONAL_HEADER; + +typedef struct PE_HEADER { + DWORD signature; + PE_FILE_HEADER file_header; + PE_OPTIONAL_HEADER optional_header; +} PE_HEADER; + + #endif From aba326a3b2a95e744cd3df6de47870694452db7c Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:52:48 +0100 Subject: [PATCH 44/53] feat: added PE_SECTION_HEADER --- src/compiler/pe/format.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/compiler/pe/format.h b/src/compiler/pe/format.h index b555489..8857c98 100644 --- a/src/compiler/pe/format.h +++ b/src/compiler/pe/format.h @@ -88,5 +88,19 @@ typedef struct PE_HEADER { PE_OPTIONAL_HEADER optional_header; } PE_HEADER; - +typedef struct PE_SECTION_HEADER { + byte name[8]; + union { + DWORD physical_addr; + DWORD virtual_size; + } Misc; + DWORD virtual_addr; + DWORD raw_sz; + DWORD raw_ptr; + DWORD reloc_ptr; + DWORD lnum_ptr; + WORD reloc_sz; + WORD lnum_sz; + DWORD chrs; +} PE_SECTION_HEADER; #endif From ad8c1fb41ba13ec6f79051f4da9a9dc60aaa205c Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 14:55:43 +0100 Subject: [PATCH 45/53] fix: types --- src/compiler/pe/format.h | 10 +++++----- src/compiler/units.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/pe/format.h b/src/compiler/pe/format.h index 8857c98..a64436b 100644 --- a/src/compiler/pe/format.h +++ b/src/compiler/pe/format.h @@ -17,7 +17,7 @@ * Structures. */ -typdef struct PE_DOS_HEADER { +typedef struct PE_DOS_HEADER { WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file @@ -49,10 +49,10 @@ typedef struct PE_FILE_HEADER { WORD chrs; } PE_FILE_HEADER; -typdef struct PE_OPTIONAL_HEADER { +typedef struct PE_OPTIONAL_HEADER { WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; + unsigned char MajorLinkerVersion; + unsigned char MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; @@ -89,7 +89,7 @@ typedef struct PE_HEADER { } PE_HEADER; typedef struct PE_SECTION_HEADER { - byte name[8]; + unsigned char name[8]; union { DWORD physical_addr; DWORD virtual_size; diff --git a/src/compiler/units.h b/src/compiler/units.h index 607fffd..b6dafcf 100644 --- a/src/compiler/units.h +++ b/src/compiler/units.h @@ -5,7 +5,7 @@ #ifndef COMPILER_UNITS #define COMPILER_UNITS -typedef DWORD unsigned long // 32 bits -typedef WORD unsigned short // 16 bits +typedef unsigned long DWORD; // 32 bits +typedef unsigned short WORD; // 16 bits #endif From 4de307eafa177df6311c139522d1d842410fc18b Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 16:01:06 +0100 Subject: [PATCH 46/53] feat: added new structs --- src/compiler/pe/format.h | 164 ++++++++++++++++++++------------------- src/compiler/pe/pe.c | 51 ++++++++++++ src/compiler/pe/pe.h | 16 ++++ 3 files changed, 151 insertions(+), 80 deletions(-) create mode 100644 src/compiler/pe/pe.c create mode 100644 src/compiler/pe/pe.h diff --git a/src/compiler/pe/format.h b/src/compiler/pe/format.h index a64436b..58d9257 100644 --- a/src/compiler/pe/format.h +++ b/src/compiler/pe/format.h @@ -12,95 +12,99 @@ */ #define PE_HEADER_SIGNATURE 0x00004550 +#define PE_DOS_HDR_SZ 0x40 /** * Structures. */ -typedef struct PE_DOS_HEADER { - WORD e_magic; // Magic number - WORD e_cblp; // Bytes on last page of file - WORD e_cp; // Pages in file - WORD e_crlc; // Relocations - WORD e_cparhdr; // Size of header in paragraphs - WORD e_minalloc; // Minimum extra paragraphs needed - WORD e_maxalloc; // Maximum extra paragraphs needed - WORD e_ss; // Initial (relative) SS value - WORD e_sp; // Initial SP value - WORD e_csum; // Checksum - WORD e_ip; // Initial IP value - WORD e_cs; // Initial (relative) CS value - WORD e_lfarlc; // File address of relocation table - WORD e_ovno; // Overlay number - WORD e_res[4]; // Reserved words - WORD e_oemid; // OEM identifier (for e_oeminfo) - WORD e_oeminfo; // OEM information; e_oemid specific - WORD e_res2[10]; // Reserved words - long e_lfanew; // File address of new exe header +#pragma pack(push, 1) + +typedef struct { + uint16_t e_magic; + uint16_t e_cblp; + uint16_t e_cp; + uint16_t e_crlc; + uint16_t e_cparhdr; + uint16_t e_minalloc; + uint16_t e_maxalloc; + uint16_t e_ss; + uint16_t e_sp; + uint16_t e_csum; + uint16_t e_ip; + uint16_t e_cs; + uint16_t e_lfarlc; + uint16_t e_ovno; + uint16_t e_res[4]; + uint16_t e_oemid; + uint16_t e_oeminfo; + uint16_t e_res2[10]; + uint32_t e_lfanew; } PE_DOS_HEADER; -typedef struct PE_FILE_HEADER { - WORD machine; - WORD sec_num; - DWORD timestamp; - DWORD symbolTablePtr; - DWORD symbolCount; - WORD optionalHeaderSize; - WORD chrs; -} PE_FILE_HEADER; +typedef struct { + uint32_t Signature; + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +} PE_NT_HEADERS; -typedef struct PE_OPTIONAL_HEADER { - WORD Magic; - unsigned char MajorLinkerVersion; - unsigned char MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Win32VersionValue; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - DWORD SizeOfStackReserve; - DWORD SizeOfStackCommit; - DWORD SizeOfHeapReserve; - DWORD SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; +typedef struct { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint64_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint64_t SizeOfStackReserve; + uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; + uint64_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + struct { + uint32_t VirtualAddress; + uint32_t Size; + } DataDirectory[16]; } PE_OPTIONAL_HEADER; -typedef struct PE_HEADER { - DWORD signature; - PE_FILE_HEADER file_header; - PE_OPTIONAL_HEADER optional_header; -} PE_HEADER; - -typedef struct PE_SECTION_HEADER { - unsigned char name[8]; - union { - DWORD physical_addr; - DWORD virtual_size; - } Misc; - DWORD virtual_addr; - DWORD raw_sz; - DWORD raw_ptr; - DWORD reloc_ptr; - DWORD lnum_ptr; - WORD reloc_sz; - WORD lnum_sz; - DWORD chrs; +typedef struct { + uint8_t Name[8]; + union { + uint32_t PhysicalAddress; + uint32_t VirtualSize; + } Misc; + uint32_t VirtualAddress; + uint32_t SizeOfRawData; + uint32_t PointerToRawData; + uint32_t PointerToRelocations; + uint32_t PointerToLinenumbers; + uint16_t NumberOfRelocations; + uint16_t NumberOfLinenumbers; + uint32_t Characteristics; } PE_SECTION_HEADER; + +#pragma pack(pop) + #endif diff --git a/src/compiler/pe/pe.c b/src/compiler/pe/pe.c new file mode 100644 index 0000000..48adf08 --- /dev/null +++ b/src/compiler/pe/pe.c @@ -0,0 +1,51 @@ +/** + * Quickfall PE executable compiling. + */ + +#include +#include + +#include "./format.h" + +/** + * Compiles into PE format. + */ +void compilePE(FILE* fptr, uint8_t program[], int programSize, uint8_t dos[], int dosSize) { + + uint8_t buff[512] = {0}; + + PE_DOS_HEADER* dos_header = (PE_DOS_HEADER*) buff; + dos_header->e_magic = 0x5A4D; + + dos_header->e_cblp = (PE_DOS_HDR_SZ + dosSize) % 512; + dos_header->e_cp = (PE_DOS_HDR_SZ + dosSize) / 512; + dos_header->e_crlc = 0; + dos_header->e_cparhdr = PE_DOS_HDR_SZ / 16; + dos_header->e_minalloc = 0; + dos_header->e_maxalloc = 0; + + dos_header->e_ss = 0; + dos_header->e_sp = 0; + dos_header->e_csum = 0; + dos_header->e_ip = 0; + dos_header->e_cs = 0; + dos_header->e_lfarlc = PE_DOS_HDR_SZ; + dos_header->e_ovno = 0; + + for(int i = 0; i < 4; ++i) { + dos_header->e_res[i] = 0; + } + + dos_header->e_oemid = 0; + dos_header->e_oeminfo = 0; + + for(int i = 0; i < 10; ++i) { + dos_header->e_res2[i] = 0; + } + + dos_header->e_lfanew = sizeof(dos_header); + + fwrite(buff, 1, sizeof(dos_header), fptr); + + fclose(fptr); +} diff --git a/src/compiler/pe/pe.h b/src/compiler/pe/pe.h new file mode 100644 index 0000000..e370dbe --- /dev/null +++ b/src/compiler/pe/pe.h @@ -0,0 +1,16 @@ +/** + * Quickfall PE executable compiling. + */ + +#include +#include + +#ifndef COMPILER_PE +#define COMPILER_PE + +/** + * Compiles into PE format. + */ +void compilePE(FILE* fptr, uint8_t program[], int programSize, uint8_t dos[], int dosSize); + +#endif From 445a236b2b8304ce72e2323ebfff0ad8aac1577d Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 16:04:01 +0100 Subject: [PATCH 47/53] feat: added potentially working PE compiling --- src/compiler/pe/pe.c | 95 ++++++++++++++++++++++++++------------------ src/compiler/pe/pe.h | 2 +- 2 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/compiler/pe/pe.c b/src/compiler/pe/pe.c index 48adf08..1327fdd 100644 --- a/src/compiler/pe/pe.c +++ b/src/compiler/pe/pe.c @@ -10,42 +10,61 @@ /** * Compiles into PE format. */ -void compilePE(FILE* fptr, uint8_t program[], int programSize, uint8_t dos[], int dosSize) { - - uint8_t buff[512] = {0}; - - PE_DOS_HEADER* dos_header = (PE_DOS_HEADER*) buff; - dos_header->e_magic = 0x5A4D; - - dos_header->e_cblp = (PE_DOS_HDR_SZ + dosSize) % 512; - dos_header->e_cp = (PE_DOS_HDR_SZ + dosSize) / 512; - dos_header->e_crlc = 0; - dos_header->e_cparhdr = PE_DOS_HDR_SZ / 16; - dos_header->e_minalloc = 0; - dos_header->e_maxalloc = 0; - - dos_header->e_ss = 0; - dos_header->e_sp = 0; - dos_header->e_csum = 0; - dos_header->e_ip = 0; - dos_header->e_cs = 0; - dos_header->e_lfarlc = PE_DOS_HDR_SZ; - dos_header->e_ovno = 0; - - for(int i = 0; i < 4; ++i) { - dos_header->e_res[i] = 0; - } - - dos_header->e_oemid = 0; - dos_header->e_oeminfo = 0; - - for(int i = 0; i < 10; ++i) { - dos_header->e_res2[i] = 0; - } - - dos_header->e_lfanew = sizeof(dos_header); - - fwrite(buff, 1, sizeof(dos_header), fptr); - - fclose(fptr); +void compilePE(FILE* fptr, uint8_t program[], int programSize) { + PE_DOS_HEADER dos_header = {0}; + dos_header.e_magic = 0x5A4D; // "MZ" + dos_header.e_lfanew = sizeof(PE_DOS_HEADER); + + fwrite(&dos_header, sizeof(dos_header), 1, fptr); + + // Create NT headers + PE_NT_HEADERS nt_headers = {0}; + nt_headers.Signature = 0x00004550; // "PE\0\0" + nt_headers.Machine = 0x8664; // x64 + nt_headers.NumberOfSections = 1; + nt_headers.SizeOfOptionalHeader = sizeof(PE_OPTIONAL_HEADER); + nt_headers.Characteristics = 0x0002 | 0x0100; // Executable | 32-bit machine + + fwrite(&nt_headers, sizeof(nt_headers), 1, fptr); + + // Create Optional header + PE_OPTIONAL_HEADER optional_header = {0}; + optional_header.Magic = 0x20B; // PE32+ + optional_header.AddressOfEntryPoint = 0x1000; + optional_header.ImageBase = 0x400000; + optional_header.SectionAlignment = 0x1000; + optional_header.FileAlignment = 0x200; + optional_header.MajorOperatingSystemVersion = 5; + optional_header.MinorOperatingSystemVersion = 1; + optional_header.MajorSubsystemVersion = 5; + optional_header.MinorSubsystemVersion = 1; + optional_header.SizeOfImage = 0x2000; + optional_header.SizeOfHeaders = 0x200; + optional_header.Subsystem = 3; // Windows CUI + optional_header.SizeOfStackReserve = 0x100000; + optional_header.SizeOfStackCommit = 0x1000; + optional_header.SizeOfHeapReserve = 0x100000; + optional_header.SizeOfHeapCommit = 0x1000; + optional_header.NumberOfRvaAndSizes = 16; + + fwrite(&optional_header, sizeof(optional_header), 1, fptr); + + // Create Section header + PE_SECTION_HEADER section_header = {0}; + memcpy(section_header.Name, ".text", 5); + section_header.Misc.VirtualSize = 0x1000; + section_header.VirtualAddress = 0x1000; + section_header.SizeOfRawData = 0x200; + section_header.PointerToRawData = 0x200; + section_header.Characteristics = 0x60000020; // Code | Execute | Read + + fwrite(§ion_header, sizeof(section_header), 1, fptr); + + // Write padding to align headers + uint8_t padding[256] = {0}; + fwrite(padding, 1, 0x200 - (sizeof(PE_DOS_HEADER) + sizeof(PE_NT_HEADERS) + sizeof(PE_OPTIONAL_HEADER) + sizeof(PE_SECTION_HEADER)), fptr); + + fwrite(program, 1, programSize, fptr); + + fclose(fptr); } diff --git a/src/compiler/pe/pe.h b/src/compiler/pe/pe.h index e370dbe..a94aa18 100644 --- a/src/compiler/pe/pe.h +++ b/src/compiler/pe/pe.h @@ -11,6 +11,6 @@ /** * Compiles into PE format. */ -void compilePE(FILE* fptr, uint8_t program[], int programSize, uint8_t dos[], int dosSize); +void compilePE(FILE* fptr, uint8_t program[], int programSize); #endif From c9f1567d251d06add39d9860dc425a41dfe31284 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 16:07:22 +0100 Subject: [PATCH 48/53] feat: it works WWW --- src/compiler/pe/pe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/pe/pe.c b/src/compiler/pe/pe.c index 1327fdd..87069a2 100644 --- a/src/compiler/pe/pe.c +++ b/src/compiler/pe/pe.c @@ -2,6 +2,7 @@ * Quickfall PE executable compiling. */ +#include #include #include From e26945c2c7abe32cfddbefa30c831b3cca47ecef Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 16:10:30 +0100 Subject: [PATCH 49/53] feat: made .text section the same size as the program instead of 0x200 --- src/compiler/pe/pe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/pe/pe.c b/src/compiler/pe/pe.c index 87069a2..a9f3b33 100644 --- a/src/compiler/pe/pe.c +++ b/src/compiler/pe/pe.c @@ -55,7 +55,7 @@ void compilePE(FILE* fptr, uint8_t program[], int programSize) { memcpy(section_header.Name, ".text", 5); section_header.Misc.VirtualSize = 0x1000; section_header.VirtualAddress = 0x1000; - section_header.SizeOfRawData = 0x200; + section_header.SizeOfRawData = programSize; section_header.PointerToRawData = 0x200; section_header.Characteristics = 0x60000020; // Code | Execute | Read From 2e4d9c7230cf75a08a875a040bedb21170632d50 Mon Sep 17 00:00:00 2001 From: Zffu Date: Sun, 22 Dec 2024 16:22:05 +0100 Subject: [PATCH 50/53] feat: added function invoke parsing --- src/parser/ast.h | 2 ++ src/parser/asts/functions.c | 14 ++++++++++++++ src/parser/asts/functions.h | 2 ++ src/parser/parser.c | 10 ++++++++++ 4 files changed, 28 insertions(+) diff --git a/src/parser/ast.h b/src/parser/ast.h index 3416964..d801728 100644 --- a/src/parser/ast.h +++ b/src/parser/ast.h @@ -23,6 +23,8 @@ enum ASTNodeType { AST_FUNCTION_DECLARATION, AST_FUNCTION_HEADER, + + AST_FUNCTION_INVOKE, AST_MATH_OPERATOR, AST_MATH_OPERATION, diff --git a/src/parser/asts/functions.c b/src/parser/asts/functions.c index fea19dc..0f1e164 100644 --- a/src/parser/asts/functions.c +++ b/src/parser/asts/functions.c @@ -186,3 +186,17 @@ AST_NODE* parseASMFunctionDeclaration(struct LexerResult result, int index) { return node; } + +AST_NODE* parseFunctionInvoke(struct LexerResult result, int index) { + AST_NODE* node = createASTNode(AST_FUNCTION_INVOKE); + + node->value = result.tokens[index].value; + + AST_NODE* args = parseArguments(result, index + 1); + + if(args != NULL) node->right = args; + + node->endingIndex = args->endingIndex; + + return node; +} \ No newline at end of file diff --git a/src/parser/asts/functions.h b/src/parser/asts/functions.h index 025f43e..5cc03da 100644 --- a/src/parser/asts/functions.h +++ b/src/parser/asts/functions.h @@ -37,4 +37,6 @@ AST_NODE* parseFunctionDeclaration(struct LexerResult result, int index); */ AST_NODE* parseASMFunctionDeclaration(struct LexerResult result, int index); +AST_NODE* parseFunctionInvoke(struct LexerResult result, int index); + #endif diff --git a/src/parser/parser.c b/src/parser/parser.c index bd250e7..ed6960a 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -53,6 +53,16 @@ AST_NODE* parseNodes(struct LexerResult result, int index, enum ASTNodeType type index = node->endingIndex; } break; + case KEYWORD: + if(result.tokens[index + 1].type == PAREN_OPEN) { + node = parseFunctionInvoke(result, index); + + if(node != NULL) { + current->next = node; + current = node; + index = node->endingIndex; + } + } } } From c06611b25df97cb508d0509401a6e085ef04cba9 Mon Sep 17 00:00:00 2001 From: Zffu Date: Mon, 23 Dec 2024 18:48:22 +0100 Subject: [PATCH 51/53] fix: lexer fixes --- src/lexer/lexer.c | 23 ++++++++++++++++++----- src/lexer/lexer.h | 2 +- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 60dc117..2d21ccb 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -20,7 +20,7 @@ void pushToken(struct LexerResult* result, enum TokenType type) { result->size++; } -struct LexerResult runLexer(char* string) { +struct LexerResult runLexer(char* string, int size) { struct LexerResult result; result.size = 0; @@ -28,14 +28,21 @@ struct LexerResult runLexer(char* string) { char c; - while(c = *string++) { + for(int i = 0; i < size; ++i) { + + c = string[i]; int buffLen = 32; char* buff = malloc(buffLen); + buff[0] = '\0'; if(c == ' ' || c == '\t' || c == '\n') { continue; - } else if (isdigit(c)) { + } + else if(c == '\0') { + break; + } + else if (isdigit(c)) { int numLen = 0; while(isdigit(c) || c == 'x') { @@ -55,22 +62,28 @@ struct LexerResult runLexer(char* string) { buff[strLen] = c; strLen++; - c = *string++; + ++i; + c = string[i]; } pushToken(&result, STRING); result.tokens[result.size - 1].value = buff; } else if(isalpha(c)) { + int keywordLen = 0; while(isalpha(c)) { buff[keywordLen] = c; + buff[keywordLen + 1] = '\0'; keywordLen++; - c = *string++; + ++i; + c = string[i]; } + if(keywordLen > 0) --i; + if(strcmp(buff, "func") == 0) { pushToken(&result, FUNCTION); } diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index f3a9072..68ac9ea 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -16,7 +16,7 @@ struct LexerResult { * Performs lexical analysis on an input string * Returns a LexerResult containing the tokens */ -struct LexerResult runLexer(char* input); +struct LexerResult runLexer(char* input, int size); /** * Adds a token to the LexerResult From fb81854bf3ada841667573f8be9e768cc20ac747 Mon Sep 17 00:00:00 2001 From: Zffu Date: Mon, 23 Dec 2024 19:23:30 +0100 Subject: [PATCH 52/53] fix: final fixes --- src/cli/main.c | 14 +++++++--- src/compiler/compiler.c | 54 ++++++++++++++++++++++++++++++++----- src/compiler/compiler.h | 4 +-- src/compiler/ir.h | 3 +++ src/parser/ast.h | 4 ++- src/parser/asts/functions.c | 10 +++++-- src/parser/parser.c | 8 +++++- src/utils/hashmap.c | 1 + 8 files changed, 82 insertions(+), 16 deletions(-) diff --git a/src/cli/main.c b/src/cli/main.c index 754b4ea..358187b 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "../lexer/lexer.h" @@ -16,6 +17,7 @@ #include "../parser/parser.h" #include "../compiler/compiler.h" +#include "../compiler/pe/pe.h" #include "../compiler/ir.h" #include "../utils/logging.c" @@ -23,6 +25,9 @@ // Version #define VERSION "0.1.0" +uint8_t code_section[6] = { + 0xB8, 0x4C, 0x00, 0x00, 0x00, 0xC3 +}; void showCommandEntry(char* commandName, char* description, int argumentCount, char* argumentNames[], char* argumentDescriptions[]) { printf("\n > %s\n\n %s%sDescription%s: %s\n", commandName, STYLE_BOLD, STYLE_UNDERLINE, RESET, description); @@ -108,11 +113,11 @@ int main(int argc, char* argv[]) { char* buff = malloc(size + 1); // Allocates one more byte for the \0 char. - fread(buff, 1, size, fptr); + size = fread(buff, 1, size, fptr); buff[size] = '\0'; fclose(fptr); - struct LexerResult result = runLexer(buff); + struct LexerResult result = runLexer(buff, size); struct ASTNode* root = parseNodes(result, 0, AST_ROOT); IR_CTX* ctx = makeContext(root); @@ -122,7 +127,10 @@ int main(int argc, char* argv[]) { return -1; } - compile(ctx, outputFile); + fptr = fopen(outputFile, "w"); + compile(ctx, fptr); + + //compilePE(fptr, code_section, sizeof(code_section)); break; case 'v': diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 280d288..5992f9f 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -2,6 +2,7 @@ * The compiler of Quickfall. */ +#include #include #include @@ -26,9 +27,7 @@ IR_CTX* makeContext(AST_NODE* tree) { ctx->nodeIndex = 0; ctx->nodeMap = createHashmap(512,200); - while(tree->next != NULL) { - tree = tree->next; - + while(tree != NULL) { switch(tree->type) { case AST_VARIABLE_DECLARATION: @@ -59,10 +58,10 @@ IR_CTX* makeContext(AST_NODE* tree) { case AST_FUNCTION_DECLARATION: - hash = hashstr(tree->left->value); + hash = hashstr(tree->left->right->value); if(hashGet(ctx->nodeMap, hash) != NULL) { - printf("Function %s was already declared!\n", tree->left->value); + printf("Function %s was already declared!\n", tree->left->right->value); return NULL; } @@ -86,9 +85,9 @@ IR_CTX* makeContext(AST_NODE* tree) { ctx->nodeIndex++; hashPut(ctx->nodeMap, hash, node); + break; case AST_ASM_FUNCTION_DECLARATION: - hash = hashstr(tree->left->right->value); if(hashGet(ctx->nodeMap, hash) != NULL) { @@ -121,6 +120,8 @@ IR_CTX* makeContext(AST_NODE* tree) { break; } + + tree = tree->next; } return ctx; @@ -131,6 +132,45 @@ IR_CTX* makeContext(AST_NODE* tree) { * @param ctx the IR context. * @param char the output file name. */ -void compile(IR_CTX* ctx, char* outputFileName) { +void compile(IR_CTX* ctx, FILE* out) { + + uint8_t* buff = malloc(sizeof(uint8_t) * 512); + int i = 0; + + int h = hashstr("main"); + + if(hashGet(ctx->nodeMap, h) == NULL) { + printf("Error: the main function wasn't defined!\n"); + return; + } + + IR_NODE* node = hashGet(ctx->nodeMap, h); + + if(node->nodeType != IR_FUNCTION) { + printf("Error: main must be a function!\n"); + return; + } + + while(node->tree->next != NULL) { + + if(node->tree->type == AST_FUNCTION_INVOKE) { + int hash = hashstr(node->tree->value); + + AST_NODE* wa = hashGet(ctx->nodeMap, hash); + + if(wa == NULL) { + printf("Error: The %s function doesn't exist!\n", node->tree->value); + return; + } + + if(wa->type == IR_ASM_FUNCTION) { + printf("%d", wa->value); + } + } + + node->tree = node->tree->next; + } + + } diff --git a/src/compiler/compiler.h b/src/compiler/compiler.h index f0506f8..93ec267 100644 --- a/src/compiler/compiler.h +++ b/src/compiler/compiler.h @@ -19,8 +19,8 @@ IR_CTX* makeContext(AST_NODE* tree); /** * Compiles the Context tree to an executable named the provided name. * @param ctx the IR context. - * @param char the output file name. + * @param char the output file. */ -void compile(IR_CTX* ctx, char* outputFileName); +void compile(IR_CTX* ctx, FILE* outputFileName); #endif diff --git a/src/compiler/ir.h b/src/compiler/ir.h index 54cb88a..bec18d7 100644 --- a/src/compiler/ir.h +++ b/src/compiler/ir.h @@ -49,6 +49,9 @@ struct IRContext { int nodeIndex; struct Hashmap* nodeMap; + + IR_NODE* mainFunc; + }; typedef struct IRContext IR_CTX; diff --git a/src/parser/ast.h b/src/parser/ast.h index d801728..9c9c916 100644 --- a/src/parser/ast.h +++ b/src/parser/ast.h @@ -25,7 +25,9 @@ enum ASTNodeType { AST_FUNCTION_HEADER, AST_FUNCTION_INVOKE, - + + AST_FUNCTION_ROOT, + AST_MATH_OPERATOR, AST_MATH_OPERATION, AST_MATH_OP_HEADER, diff --git a/src/parser/asts/functions.c b/src/parser/asts/functions.c index 0f1e164..12aec00 100644 --- a/src/parser/asts/functions.c +++ b/src/parser/asts/functions.c @@ -62,7 +62,10 @@ AST_NODE* parseParameters(struct LexerResult result, int index) { case PAREN_CLOSE: root->endingIndex = index; return root; + case PAREN_OPEN: + continue; default: + printf("Type: %d", t.type); return NULL; } @@ -109,6 +112,7 @@ AST_NODE* parseFunctionDeclaration(struct LexerResult result, int index) { node->left = createASTNode(AST_FUNCTION_HEADER); if(result.tokens[index].type != KEYWORD) { + printf("jd"); return NULL; } @@ -136,7 +140,9 @@ AST_NODE* parseFunctionDeclaration(struct LexerResult result, int index) { node->left->left = params; - node->right = parseNodes(result, params->endingIndex, AST_ROOT); + node->right = parseNodes(result, params->endingIndex, AST_FUNCTION_ROOT); + + node->endingIndex = node->right->endingIndex; return node; } @@ -199,4 +205,4 @@ AST_NODE* parseFunctionInvoke(struct LexerResult result, int index) { node->endingIndex = args->endingIndex; return node; -} \ No newline at end of file +} diff --git a/src/parser/parser.c b/src/parser/parser.c index ed6960a..169e1d8 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -27,8 +27,14 @@ AST_NODE* parseNodes(struct LexerResult result, int index, enum ASTNodeType type AST_NODE* node = NULL; switch(t.type) { + case BRACKETS_CLOSE: + if(type == AST_FUNCTION_ROOT) { + root->endingIndex = index; + return root; + } + break; case FUNCTION: - node = parseFunctionDeclaration(result, index); + node = parseFunctionDeclaration(result, index + 1); if(node != NULL) { current->next = node; current = node; diff --git a/src/utils/hashmap.c b/src/utils/hashmap.c index a6cfb1c..fd2f351 100644 --- a/src/utils/hashmap.c +++ b/src/utils/hashmap.c @@ -2,6 +2,7 @@ * A simple hashmap implementation. */ +#include #include #include "./hashmap.h" From f99bc8a0e15ea08a127d3f45d40cd8497273601a Mon Sep 17 00:00:00 2001 From: Zffu Date: Mon, 23 Dec 2024 22:50:50 +0100 Subject: [PATCH 53/53] fix: final fixes --- benchmarks/main.c | 18 ++++++------------ src/compiler/compiler.c | 26 +++++++++++++++++++------- src/compiler/ir.h | 3 ++- src/lexer/lexer.c | 10 ++++++++-- src/parser/ast.c | 1 + src/parser/ast.h | 2 ++ src/parser/asts/functions.c | 20 ++++++++++++++------ 7 files changed, 52 insertions(+), 28 deletions(-) diff --git a/benchmarks/main.c b/benchmarks/main.c index 1d49f55..3985c50 100644 --- a/benchmarks/main.c +++ b/benchmarks/main.c @@ -123,7 +123,7 @@ void main(int argc, char* argv[]) { endTimer(i, 0); startTimer(); - struct LexerResult result = runLexer(buff); + struct LexerResult result = runLexer(buff, size); free(buff); @@ -136,20 +136,14 @@ void main(int argc, char* argv[]) { endTimer(i, 2); startTimer(); - struct Context ctx = parseContext(node); - char* compiled = compileV2(ctx); + fptr = fopen("output.txt", "w"); - endTimer(i, 3); - - startTimer(); - - fptr = fopen("output.txt", "w"); - fprintf(fptr, compiled); - fclose(fptr); + IR_CTX* ctx = makeContext(node); + compile(ctx, fptr); - endTimer(i, 4); + fclose(fptr); - free(compiled); + endTimer(i, 3); } printf("========= Benchmarking Results =========\n"); diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 5992f9f..73cb241 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -14,6 +14,8 @@ #include "../utils/hash.h" #include "../utils/hashmap.h" +#include "./pe/pe.h" + /** * Parses the AST tree into a context. * @param tree the AST tree. @@ -76,11 +78,13 @@ IR_CTX* makeContext(AST_NODE* tree) { node->variables[node->variableIndex] = var; node->variableIndex++; - hashPut(node->variableMap, hashstr(tree->right->value), var); + hashPut(node->variableMap, hashstr(tree->left->left->right->value), var); tree->left->left = tree->left->left->next; } + node->tree = tree->right; + ctx->nodes[ctx->nodeIndex] = node; ctx->nodeIndex++; @@ -98,6 +102,7 @@ IR_CTX* makeContext(AST_NODE* tree) { node = createIRNode(IR_ASM_FUNCTION, tree->left->right->value); node->value = tree->value; + node->valueSize = tree->valueSize; while(tree->left->left->next != NULL) { @@ -151,26 +156,33 @@ void compile(IR_CTX* ctx, FILE* out) { return; } - while(node->tree->next != NULL) { + while(node->tree != NULL) { if(node->tree->type == AST_FUNCTION_INVOKE) { + int hash = hashstr(node->tree->value); - AST_NODE* wa = hashGet(ctx->nodeMap, hash); + IR_NODE* wa = hashGet(ctx->nodeMap, hash); if(wa == NULL) { printf("Error: The %s function doesn't exist!\n", node->tree->value); return; } - if(wa->type == IR_ASM_FUNCTION) { - printf("%d", wa->value); + if(wa->nodeType == IR_ASM_FUNCTION) { + unsigned char b; + unsigned char* ptr = (unsigned char*) wa->value; + + for(int ii = 0; ii < wa->valueSize; ++ii) { + buff[i] = ptr[ii]; + ++i; + } } } node->tree = node->tree->next; } - - + //todo: change format based on user + compilePE(out, buff, i); } diff --git a/src/compiler/ir.h b/src/compiler/ir.h index bec18d7..9271653 100644 --- a/src/compiler/ir.h +++ b/src/compiler/ir.h @@ -31,7 +31,8 @@ struct IRNode { char* type; // Variable Properties - char* value; + void* value; + int valueSize; // Function Properties struct IRNode** variables; diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 2d21ccb..c61f19a 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -45,13 +45,19 @@ struct LexerResult runLexer(char* string, int size) { else if (isdigit(c)) { int numLen = 0; - while(isdigit(c) || c == 'x') { + int foundX = 0; + while(isdigit(c) || c == 'x' || (foundX == 1 && c != '\0' && c != ' ' && c != '\n')) { buff[numLen] = c; numLen++; - c = *string++; + if(c == 'x') foundX = 1; + + ++i; + c = string[i]; } + buff[numLen] = '\0'; + pushToken(&result, NUMBER); result.tokens[result.size - 1].value = buff; diff --git a/src/parser/ast.c b/src/parser/ast.c index 21dc281..4400d84 100644 --- a/src/parser/ast.c +++ b/src/parser/ast.c @@ -13,6 +13,7 @@ AST_NODE* createASTNode(enum ASTNodeType type) { AST_NODE* node = malloc(sizeof(AST_NODE)); + node->valueSize = 0; node->type = type; node->left = NULL; node->right = NULL; diff --git a/src/parser/ast.h b/src/parser/ast.h index 9c9c916..d666f0b 100644 --- a/src/parser/ast.h +++ b/src/parser/ast.h @@ -45,6 +45,8 @@ struct ASTNode { struct ASTNode* next; enum ASTNodeType type; + + int valueSize; char* value; int endingIndex; // The index which the parsing ended diff --git a/src/parser/asts/functions.c b/src/parser/asts/functions.c index 12aec00..330b3f6 100644 --- a/src/parser/asts/functions.c +++ b/src/parser/asts/functions.c @@ -180,15 +180,20 @@ AST_NODE* parseASMFunctionDeclaration(struct LexerResult result, int index) { break; } - if(t.type != STRING) { + if(t.type != NUMBER) { return NULL; } buff[buffIndex] = strtol(t.value, NULL, 16); + buffIndex++; } node->endingIndex = index; - node->value = (char*) buff; + + buff = realloc(buff, sizeof(uint8_t) * buffIndex); + + node->valueSize = buffIndex; + node->value = buff; return node; } @@ -198,11 +203,14 @@ AST_NODE* parseFunctionInvoke(struct LexerResult result, int index) { node->value = result.tokens[index].value; - AST_NODE* args = parseArguments(result, index + 1); + AST_NODE* args = parseArguments(result, index + 2); - if(args != NULL) node->right = args; - - node->endingIndex = args->endingIndex; + node->endingIndex = index; + + if(args != NULL) { + node->right = args; + node->endingIndex = args->endingIndex; + } return node; }