aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.c91
-rw-r--r--test/main.c5
2 files changed, 54 insertions, 42 deletions
diff --git a/src/main.c b/src/main.c
index 880cd0b..6d63575 100644
--- a/src/main.c
+++ b/src/main.c
@@ -232,6 +232,7 @@ enum {
// we allow for only one of each type
struct COFF_sections {
+ u8* file_buffer;
u32 text_section_off;
u32 text_section_size;
u32 data_section_off;
@@ -244,40 +245,37 @@ struct COFF_sections {
u32 string_section_size;
};
-static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_files_count, u8* sections_flag) {
+static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_files_count, u8* sections_flag, u32* c_COFF_sections) {
ASSERT(*sections_flag == 0U);
if (obj_files_count == 0U) {
return NULL;
}
- size_t max_header_size = sizeof(IMAGE_SECTION_HEADER) * 96U + sizeof(IMAGE_FILE_HEADER);
-
// TODO: Make an array type
u32 nb_sections_size = sizeof(struct COFF_sections) * obj_files_count;
struct COFF_sections* sections = (struct COFF_sections*)VirtualAlloc(NULL, nb_sections_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
mem_set((void*)sections, nb_sections_size, 0U);
- IMAGE_FILE_HEADER* header = (IMAGE_FILE_HEADER*)VirtualAlloc(NULL, max_header_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
- IMAGE_SECTION_HEADER* section_table = (IMAGE_SECTION_HEADER*)(((u8*)header) + sizeof(*header));
-
for (u32 obj_id = 0U; obj_id < obj_files_count; obj_id++) {
struct COFF_sections* section = &sections[obj_id];
const char* obj_file = obj_files[obj_id];
-
HANDLE obj_file_handle = CreateFileA(obj_file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0U, NULL);
if (!obj_file_handle && obj_file_handle != INVALID_HANDLE_VALUE) {
continue;
}
- DWORD bread = 0U;
- if (!ReadFile(obj_file_handle, (void*)header, sizeof(*header), &bread, NULL)) {
- CloseHandle(obj_file_handle);
- continue;
- }
+ LARGE_INTEGER file_size = { 0 };
+ GetFileSizeEx(obj_file_handle, &file_size);
+
+ section->file_buffer = (u8*)VirtualAlloc(NULL, file_size.LowPart, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+
+ IMAGE_FILE_HEADER* header = (IMAGE_FILE_HEADER*)section->file_buffer;
+ IMAGE_SECTION_HEADER* section_table = (IMAGE_SECTION_HEADER*)(((u8*)header) + sizeof(*header));
- if (!ReadFile(obj_file_handle, (void*)section_table, sizeof(section_table[0U]) * header->NumberOfSections, &bread, NULL)) {
+ DWORD bread = 0U;
+ if (!ReadFile(obj_file_handle, (void*)header, file_size.LowPart, &bread, NULL)) {
CloseHandle(obj_file_handle);
continue;
}
@@ -316,7 +314,7 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_
CloseHandle(obj_file_handle);
}
- VirtualFree(header, 0U, MEM_RELEASE);
+ *c_COFF_sections = obj_files_count;
return sections;
}
@@ -570,7 +568,7 @@ struct PE_headers {
#define OBJ_EXT 0x6A626F2E // .obj
-static void write_exe_headers(u8* buffer) {
+static void write_exe_headers(struct PE_headers * buffer, u16 c_sections, u32 addr_entry_point, u32 base_of_code, u32 size_of_code, u32 size_of_headers, u32 size_of_image) {
static struct PE_headers PE_headers = {
.dos_header = {
.e_magic = IMAGE_DOS_SIGNATURE,
@@ -653,14 +651,20 @@ static void write_exe_headers(u8* buffer) {
FILETIME filetime = { 0U };
GetSystemTimeAsFileTime(&filetime);
- PE_headers.img_header.TimeDateStamp = filetime.dwLowDateTime;
+ PE_headers.img_header.TimeDateStamp = filetime.dwLowDateTime;
+
+ PE_headers.img_header.NumberOfSections = c_sections;
+
+ PE_headers.opt_header.AddressOfEntryPoint = addr_entry_point;
+ PE_headers.opt_header.BaseOfCode = base_of_code;
+ PE_headers.opt_header.SizeOfCode = size_of_code;
+ PE_headers.opt_header.SizeOfImage = size_of_image;
+ PE_headers.opt_header.SizeOfHeaders = size_of_headers;
mem_copy(&PE_headers, buffer, sizeof(PE_headers));
}
-static u8 test_main[] = { 0x33, 0xc0, 0xc3 };
-
-static void write_text_section(IMAGE_SECTION_HEADER* section_table, u16* section_count) {
+static void write_text_section_header(IMAGE_SECTION_HEADER* section_table, u16* section_count) {
IMAGE_SECTION_HEADER* text_section_header = &section_table[*section_count];
mem_copy(".text", text_section_header->Name, 6U);
@@ -675,7 +679,7 @@ static void write_text_section(IMAGE_SECTION_HEADER* section_table, u16* section
(*section_count)++;
}
-static void write_data_section(IMAGE_SECTION_HEADER* section_table, u16* section_count) {
+static void write_data_section_header(IMAGE_SECTION_HEADER* section_table, u16* section_count) {
IMAGE_SECTION_HEADER* data_section_header = &section_table[*section_count];
mem_copy(".text", data_section_header->Name, 6U);
@@ -690,7 +694,7 @@ static void write_data_section(IMAGE_SECTION_HEADER* section_table, u16* section
(*section_count)++;
}
-static void write_bss_section(IMAGE_SECTION_HEADER* section_table, u16* section_count) {
+static void write_bss_section_header(IMAGE_SECTION_HEADER* section_table, u16* section_count) {
IMAGE_SECTION_HEADER* bss_section_header = &section_table[*section_count];
mem_copy(".text", bss_section_header->Name, 6U);
@@ -829,7 +833,8 @@ int mainCRTStartup(void) {
// loop through all OBJs header to find out which sections we need
u8 sections_flag = 0U;
- struct COFF_sections* sections = read_COFFs_header(obj_files, c_obj_files, &sections_flag);
+ u32 c_COFF_sections = 0U;
+ struct COFF_sections* sections = read_COFFs_header(obj_files, c_obj_files, &sections_flag, &c_COFF_sections);
__debugbreak();
@@ -839,30 +844,31 @@ int mainCRTStartup(void) {
IMAGE_SECTION_HEADER* section_table = (IMAGE_SECTION_HEADER*)(exe_buffer + sizeof(*headers));
u16 c_sections = 0U;
- // dont write section count to img header
- write_exe_headers(exe_buffer);
-
// write the relevant sections
if (sections_flag & TEXT_SECTION_FLAG) {
// TODO: copy text to the relevant part of the buffer
- write_text_section(section_table, &c_sections);
+ write_text_section_header(section_table, &c_sections);
}
if (sections_flag & DATA_SECTION_FLAG) {
- write_data_section(section_table, &c_sections);
+ write_data_section_header(section_table, &c_sections);
}
if (sections_flag & BSS_SECTION_FLAG) {
- write_bss_section(section_table, &c_sections);
+ write_bss_section_header(section_table, &c_sections);
}
- headers->img_header.NumberOfSections = c_sections;
-
// Write section bodies
// TODO: index per section ?
- u32 code_size = sizeof(test_main);
u32 headers_size = ALIGN(sizeof(*headers) + (sizeof(IMAGE_SECTION_HEADER) * c_sections), FILE_ALIGNMENT);
- mem_copy(test_main, (void*)(exe_buffer + headers_size), code_size);
- section_table[0U].SizeOfRawData = ALIGN(code_size, FILE_ALIGNMENT);
- section_table[0U].Misc.VirtualSize = ALIGN(code_size, SECTION_ALIGNMENT);
+ void* text_start = (void*)((u8*)headers + headers_size);
+
+ for (u32 COFF_section_index = 0U; COFF_section_index < c_COFF_sections; COFF_section_index++) {
+ struct COFF_sections const* cur_section = &sections[COFF_section_index];
+ if ( cur_section->text_section_off ) {
+ mem_copy((void*)(cur_section->file_buffer + cur_section->text_section_off), text_start, cur_section->text_section_size);
+ section_table[0U].SizeOfRawData = ALIGN(cur_section->text_section_size, FILE_ALIGNMENT);
+ section_table[0U].Misc.VirtualSize = ALIGN(cur_section->text_section_size, SECTION_ALIGNMENT);
+ }
+ }
// Set sections pointer to raw data
_Static_assert(FILE_ALIGNMENT < SECTION_ALIGNMENT, "section alignment must greater or equal to file alignment in order to align headers_size on section alignment");
@@ -879,13 +885,12 @@ int mainCRTStartup(void) {
virtual_offset += cur_section->Misc.VirtualSize;
}
- // Fill remaining header informations
-
- headers->opt_header.SizeOfHeaders = headers_size; // aligned on file alignment
- headers->opt_header.AddressOfEntryPoint = section_table[0U].VirtualAddress;
- headers->opt_header.BaseOfCode = section_table[0U].PointerToRawData;
- headers->opt_header.SizeOfCode = section_table[0U].SizeOfRawData;
- headers->opt_header.SizeOfImage = ALIGN(section_table[c_sections - 1U].VirtualAddress + section_table[c_sections - 1U].Misc.VirtualSize, SECTION_ALIGNMENT);
+ // Fill header informations
+ u32 addr_entry_point = section_table[0U].VirtualAddress;
+ u32 base_of_code = section_table[0U].PointerToRawData;
+ u32 size_of_code = section_table[0U].SizeOfRawData;
+ u32 size_of_image = ALIGN(section_table[c_sections - 1U].VirtualAddress + section_table[c_sections - 1U].Misc.VirtualSize, SECTION_ALIGNMENT);
+ write_exe_headers(headers, c_sections, addr_entry_point, base_of_code, size_of_code, headers_size, size_of_image);
DWORD bwrite = 0U;
WriteFile(output_file, exe_buffer, headers->opt_header.SizeOfImage, &bwrite, NULL);
@@ -894,6 +899,10 @@ int mainCRTStartup(void) {
CloseHandle(output_file);
}
+ for (u32 COFF_section_index = 0U; COFF_section_index < c_COFF_sections; COFF_section_index++) {
+ VirtualFree(sections[COFF_section_index].file_buffer, 0U, MEM_RELEASE);
+ }
+
VirtualFree(sections, 0U, MEM_RELEASE);
VirtualFree(exe_buffer, 0U, MEM_RELEASE);
VirtualFree(lib_path_env, 0U, MEM_RELEASE);
diff --git a/test/main.c b/test/main.c
index c09079b..de11ce3 100644
--- a/test/main.c
+++ b/test/main.c
@@ -1 +1,4 @@
-int mainCRTStartup() { return 0; }
+int mainCRTStartup() {
+ __debugbreak();
+ return 0;
+}