aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c196
1 files changed, 171 insertions, 25 deletions
diff --git a/src/main.c b/src/main.c
index aac79c7..405c5f0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,14 +1,14 @@
// #include <Windows.h>
#include <stdarg.h>
-#define NULL 0U
+// #define NULL 0U
typedef long HRESULT;
#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
#define VOID void
-typedef unsigned __int64 ULONGLONG;
-typedef __int64 LONGLONG;
+typedef unsigned long long ULONGLONG;
+typedef long long LONGLONG;
typedef char CHAR;
typedef short SHORT;
typedef long LONG;
@@ -36,7 +36,7 @@ typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
- } DUMMYSTRUCTNAME;
+ };
struct {
DWORD LowPart;
LONG HighPart;
@@ -199,6 +199,92 @@ typedef struct _IMAGE_SECTION_HEADER {
#define IMAGE_SIZEOF_FILE_HEADER 20
+//
+// Relocation format.
+//
+
+#pragma pack(push, 2) // Symbols, relocs, and linenumbers are 2 byte packed
+typedef struct _IMAGE_RELOCATION {
+ union {
+ DWORD VirtualAddress;
+ DWORD RelocCount; // Set to the real count when IMAGE_SCN_LNK_NRELOC_OVFL is set
+ };
+ DWORD SymbolTableIndex;
+ WORD Type;
+} IMAGE_RELOCATION;
+typedef IMAGE_RELOCATION __unaligned *PIMAGE_RELOCATION;
+
+//
+// x64 relocations
+//
+#define IMAGE_REL_AMD64_ABSOLUTE 0x0000 // Reference is absolute, no relocation is necessary
+#define IMAGE_REL_AMD64_ADDR64 0x0001 // 64-bit address (VA).
+#define IMAGE_REL_AMD64_ADDR32 0x0002 // 32-bit address (VA).
+#define IMAGE_REL_AMD64_ADDR32NB 0x0003 // 32-bit address w/o image base (RVA).
+#define IMAGE_REL_AMD64_REL32 0x0004 // 32-bit relative address from byte following reloc
+#define IMAGE_REL_AMD64_REL32_1 0x0005 // 32-bit relative address from byte distance 1 from reloc
+#define IMAGE_REL_AMD64_REL32_2 0x0006 // 32-bit relative address from byte distance 2 from reloc
+#define IMAGE_REL_AMD64_REL32_3 0x0007 // 32-bit relative address from byte distance 3 from reloc
+#define IMAGE_REL_AMD64_REL32_4 0x0008 // 32-bit relative address from byte distance 4 from reloc
+#define IMAGE_REL_AMD64_REL32_5 0x0009 // 32-bit relative address from byte distance 5 from reloc
+#define IMAGE_REL_AMD64_SECTION 0x000A // Section index
+#define IMAGE_REL_AMD64_SECREL 0x000B // 32 bit offset from base of section containing target
+#define IMAGE_REL_AMD64_SECREL7 0x000C // 7 bit unsigned offset from base of section containing target
+#define IMAGE_REL_AMD64_TOKEN 0x000D // 32 bit metadata token
+#define IMAGE_REL_AMD64_SREL32 0x000E // 32 bit signed span-dependent value emitted into object
+#define IMAGE_REL_AMD64_PAIR 0x000F
+#define IMAGE_REL_AMD64_SSPAN32 0x0010 // 32 bit signed span-dependent value applied at link time
+#define IMAGE_REL_AMD64_EHANDLER 0x0011
+#define IMAGE_REL_AMD64_IMPORT_BR 0x0012 // Indirect branch to an import
+#define IMAGE_REL_AMD64_IMPORT_CALL 0x0013 // Indirect call to an import
+#define IMAGE_REL_AMD64_CFG_BR 0x0014 // Indirect branch to a CFG check
+#define IMAGE_REL_AMD64_CFG_BR_REX 0x0015 // Indirect branch to a CFG check, with REX.W prefix
+#define IMAGE_REL_AMD64_CFG_CALL 0x0016 // Indirect call to a CFG check
+#define IMAGE_REL_AMD64_INDIR_BR 0x0017 // Indirect branch to a target in RAX (no CFG)
+#define IMAGE_REL_AMD64_INDIR_BR_REX 0x0018 // Indirect branch to a target in RAX, with REX.W prefix (no CFG)
+#define IMAGE_REL_AMD64_INDIR_CALL 0x0019 // Indirect call to a target in RAX (no CFG)
+#define IMAGE_REL_AMD64_INDIR_BR_SWITCHTABLE_FIRST 0x0020 // Indirect branch for a switch table using Reg 0 (RAX)
+#define IMAGE_REL_AMD64_INDIR_BR_SWITCHTABLE_LAST 0x002F // Indirect branch for a switch table using Reg 15 (R15)
+
+//
+// Symbol format.
+//
+
+__declspec(align(1)) typedef struct _IMAGE_SYMBOL {
+ union {
+ BYTE ShortName[8];
+ struct {
+ DWORD Short; // if 0, use LongName
+ DWORD Long; // offset into string table
+ } Name;
+ DWORD LongName[2]; // PBYTE [2]
+ } N;
+ DWORD Value;
+ SHORT SectionNumber;
+ WORD Type;
+ BYTE StorageClass;
+ BYTE NumberOfAuxSymbols;
+} IMAGE_SYMBOL;
+
+#define IMAGE_SIZEOF_SYMBOL 18
+
+typedef struct _IMAGE_SYMBOL_EX {
+ union {
+ BYTE ShortName[8];
+ struct {
+ DWORD Short; // if 0, use LongName
+ DWORD Long; // offset into string table
+ } Name;
+ DWORD LongName[2]; // PBYTE [2]
+ } N;
+ DWORD Value;
+ LONG SectionNumber;
+ WORD Type;
+ BYTE StorageClass;
+ BYTE NumberOfAuxSymbols;
+} IMAGE_SYMBOL_EX;
+#pragma pack(pop)
+
#define MEM_COMMIT 0x00001000
#define MEM_RESERVE 0x00002000
#define MEM_DECOMMIT 0x00004000
@@ -260,15 +346,15 @@ char* GetCommandLineA();
void* VirtualAlloc(void*, u64, u32, u32);
s32 VirtualFree(void*, u64, u32);
-_Static_assert(sizeof(s8) == 1U, "");
-_Static_assert(sizeof(s16) == 2U, "");
-_Static_assert(sizeof(s32) == 4U, "");
-_Static_assert(sizeof(s64) == 8U, "");
+static_assert(sizeof(s8) == 1U, "");
+static_assert(sizeof(s16) == 2U, "");
+static_assert(sizeof(s32) == 4U, "");
+static_assert(sizeof(s64) == 8U, "");
-_Static_assert(sizeof(u8) == 1U, "");
-_Static_assert(sizeof(u16) == 2U, "");
-_Static_assert(sizeof(u32) == 4U, "");
-_Static_assert(sizeof(u64) == 8U, "");
+static_assert(sizeof(u8) == 1U, "");
+static_assert(sizeof(u16) == 2U, "");
+static_assert(sizeof(u32) == 4U, "");
+static_assert(sizeof(u64) == 8U, "");
#define ALIGN(x, align) (((x) + (align - 1U)) / (align)) * (align)
@@ -305,25 +391,29 @@ static void str_cat(char* out, const char* str, size_t c_str) {
index++;
}
}
-static void mem_copy(void* src, void* dst, size_t size) {
+
+void* memcpy(void* dst, void* src, size_t size) {
u8* byte_src = (u8*)src;
u8* byte_dst = (u8*)dst;
for (u32 index = 0U; index < size; index++) {
byte_dst[index] = byte_src[index];
}
+
+ return dst;
}
-// static void mem_set(void* ptr, size_t size, u8 value) {
-static void* memset(void* ptr, size_t size, u8 value) {
+// static void* mem_set(void* ptr, size_t size, u8 value) {
+void* memset(void* ptr, s32 value, size_t size) {
u8* bytes = ptr;
for (u32 index = 0U; index < size; index++) {
- bytes[index] = value;
+ bytes[index] = (u8)value;
}
return ptr;
}
+
static void u64toa(u64 number, char* str, u32 base) {
static char codes[16U] = {
'0',
@@ -534,7 +624,7 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_
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);
- memset((void*)sections, nb_sections_size, 0U);
+ // memset((void*)sections, nb_sections_size, 0U);
for (u32 obj_id = 0U; obj_id < obj_files_count; obj_id++) {
struct COFF_sections* section = &sections[obj_id];
@@ -548,13 +638,13 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_
LARGE_INTEGER file_size = { 0 };
GetFileSizeEx(obj_file_handle, &file_size);
- section->file_buffer = (u8*)VirtualAlloc(NULL, file_size.DUMMYSTRUCTNAME.LowPart, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ 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));
u32 bread = 0U;
- if (!ReadFile(obj_file_handle, (void*)header, file_size.DUMMYSTRUCTNAME.LowPart, &bread, NULL)) {
+ if (!ReadFile(obj_file_handle, (void*)section->file_buffer, file_size.LowPart, &bread, NULL)) {
CloseHandle(obj_file_handle);
continue;
}
@@ -562,6 +652,9 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_
section->symbol_table_off = header->PointerToSymbolTable;
section->symbols_count = header->NumberOfSymbols;
+ IMAGE_SYMBOL* symbol_table = (IMAGE_SYMBOL*)(section->file_buffer + section->symbol_table_off);
+ u8* string_table = (u8*)symbol_table + sizeof(*symbol_table) * section->symbols_count;
+
for (u32 section_index = 0U; section_index < header->NumberOfSections; section_index++) {
IMAGE_SECTION_HEADER* curr_section = &section_table[section_index];
if ((curr_section->Characteristics & BSS_SECTION_FLAGS) == BSS_SECTION_FLAGS) {
@@ -589,6 +682,58 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_
section->text_section_off = curr_section->PointerToRawData;
section->text_section_size = curr_section->SizeOfRawData;
}
+
+ u8* reloc_start = &section->file_buffer[curr_section->PointerToRelocations];
+ PIMAGE_RELOCATION cur_reloc_entry = (PIMAGE_RELOCATION)reloc_start;
+
+ // Section relocations
+ for (u32 reloc_index = 0U; reloc_index < curr_section->NumberOfRelocations; reloc_index++, cur_reloc_entry++) {
+ print("SYMBOL INDEX : %u\n", cur_reloc_entry->SymbolTableIndex);
+
+ IMAGE_SYMBOL* sym = symbol_table + cur_reloc_entry->SymbolTableIndex;
+ if (sym->N.Name.Short == 0U) { // use longname
+ print("SYMBOL NAME : %s\n", string_table + sym->N.Name.Long);
+ } else {
+ print("SYMBOL NAME : %s.8\n", sym->N.ShortName);
+ }
+
+ if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ABSOLUTE) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_ABSOLUTE\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR64) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_ADDR64\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR32) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_ADDR32\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR32NB) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_ADDR32NB\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_1) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_1\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_2) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_2\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_3) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_3\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_4) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_4\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_5) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_5\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECTION) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_SECTION\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECREL) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_SECREL\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECREL7) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_SECREL7\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_TOKEN) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_TOKEN\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SREL32) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_SREL32\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_PAIR) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_PAIR\n");
+ } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SSPAN32) {
+ print("SYMBOL TYPE : IMAGE_REL_AMD64_SSPAN32\n");
+ }
+ print("\n\n");
+ }
}
CloseHandle(obj_file_handle);
}
@@ -868,7 +1013,8 @@ static void write_exe_headers(struct PE_headers * buffer, u16 c_sections, u32 ad
.e_oemid = 0x0U,
.e_oeminfo = 0x0U,
.e_res2 = { 0x0 },
- .e_lfanew = __builtin_offsetof(struct PE_headers, nt_signature),
+ // .e_lfanew = __builtin_offsetof(struct PE_headers, nt_signature),
+ .e_lfanew = 256,
},
.dos_stub = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -940,12 +1086,12 @@ static void write_exe_headers(struct PE_headers * buffer, u16 c_sections, u32 ad
PE_headers.opt_header.SizeOfImage = size_of_image;
PE_headers.opt_header.SizeOfHeaders = size_of_headers;
- mem_copy(&PE_headers, buffer, sizeof(PE_headers));
+ memcpy(buffer, &PE_headers, sizeof(PE_headers));
}
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);
+ memcpy(text_section_header->Name, ".text", 6U);
text_section_header->VirtualAddress = 0x0U;
text_section_header->PointerToRawData = 0x0U;
@@ -960,7 +1106,7 @@ static void write_text_section_header(IMAGE_SECTION_HEADER* section_table, u16*
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);
+ memcpy(data_section_header->Name, ".data", 6U);
data_section_header->VirtualAddress = 0x0U;
data_section_header->PointerToRawData = 0x0U;
@@ -975,7 +1121,7 @@ static void write_data_section_header(IMAGE_SECTION_HEADER* section_table, u16*
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);
+ memcpy(bss_section_header->Name, ".bss", 6U);
bss_section_header->VirtualAddress = 0x0U;
bss_section_header->PointerToRawData = 0x0U;
@@ -1144,7 +1290,7 @@ int mainCRTStartup(void) {
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);
+ memcpy(text_start, (void*)(cur_section->file_buffer + cur_section->text_section_off), 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);
}