summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-24 21:20:21 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-24 21:20:21 +0200
commite9934a81f6c69596c0f183abc411804a9d450208 (patch)
tree5896a41fbb208a2858cd143801e479a704afe0cd
parente962d7498be327df5b4a3c4f534c6ab203214e78 (diff)
downloadbxgen-e9934a81f6c69596c0f183abc411804a9d450208.zip
Separate codegen proc
-rwxr-xr-xbxgen.c91
1 files changed, 58 insertions, 33 deletions
diff --git a/bxgen.c b/bxgen.c
index 3223929..92285b0 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -163,10 +163,11 @@ enum {
MAX_NUM_OBJECT_FILES = 10 * 1024,
MAX_NUM_SECTIONS = 2 * 1024 * 1024,
MAX_NUM_SYMBOLS = 2 * 1024 * 1024,
- MAX_OBJECT_FILE_SIZE = 10 * 1024 * 1024, // 10 MB
- MAX_DEPENDENCIES_SIZE = 50 * 1024 * 1024, // 50 MB
- MAX_NOT_FOUND_SIZE = 10 * 1024, // 10 KB
- MAX_OUTPUT_SIZE = 20 * 1024 * 1024, // 20 MB
+ MAX_OBJECT_FILE_SIZE = 10 * 1024 * 1024, // 10 MB
+ MAX_DEPENDENCIES_SIZE = 50 * 1024 * 1024, // 50 MB
+ MAX_NOT_FOUND_SIZE = 10 * 1024, // 10 KB
+ MAX_CODE_SIZE = 100 * 1024, // 100 KB
+ MAX_OUTPUT_SIZE = 20 * 1024 * 1024, // 20 MB
MAX_PATH_SIZE = 10 * 1024,
MAX_LITERAL_SIZE = 400,
@@ -248,7 +249,7 @@ enum {
// Architecture
//
- ARCH_RISC_V = 64,
+ ARCH_RISC_V = 1,
ARCH_I386,
ARCH_X86_64,
ARCH_ARM32,
@@ -382,9 +383,11 @@ typedef struct {
i64 max_num_sections;
i64 max_num_symbols;
i64 max_not_found_size;
+ i64 max_code_size;
i64 max_output_size;
i64 num_obj_files;
+ i64 entry_point;
u8 * obj_file_buffer;
u8 * dependencies_buffer;
@@ -392,6 +395,7 @@ typedef struct {
i64 * section_addresses;
Internal_Symbol_Entry *symbols;
c8 * not_found_buffer;
+ u8 * code_buffer;
u8 * output_buffer;
} Pool;
@@ -446,7 +450,7 @@ void unit_link_add(Pool *pool, i64 unit, i64 link_unit);
void unit_link_remove(Pool *pool, i64 unit, i64 link_unit);
void unit_set_name(Pool *pool, i64 unit, i64 name_size, c8 *name);
void unit_set_entry_point(Pool *pool, i64 unit, i64 entry_point_proc);
-void unit_write(Pool *pool, i64 unit, u16 target, i64 io_id, void *io_user_data);
+void unit_write(Pool *pool, i64 unit, u16 format, u16 arch, i64 io_id, void *io_user_data);
i64 io_open_read(i64 name_size, c8 *name, void *user_data);
i64 io_open_write(i64 name_size, c8 *name, void *user_data);
@@ -1366,6 +1370,7 @@ enum {
X86_64_BASE_ADDRESS = 0x400000,
X86_64_ALIGNMENT = 8,
+ X86_64_PAGE_SIZE = 4 * 1024,
// ELF format constants
//
@@ -1604,6 +1609,28 @@ typedef struct {
// ================================================================
+i64 codegen_in_memory(Pool *pool, i64 unit, u16 arch) {
+ BX_CHECK(arch == ARCH_X86_64, "Target not supported",);
+
+ u8 code[32] = {
+ 0xb8, 0x3c, 0x00, 0x00, 0x00, // mov eax, 60
+ 0xbf, 0x2a, 0x00, 0x00, 0x00, // mov edi, 42
+ 0x0f, 0x05, // syscall
+ };
+
+ i64 code_size = bx_align(sizeof code, X86_64_ALIGNMENT);
+
+ BX_CHECK(code_size <= pool->max_code_size, "Out of memory", 0);
+
+ bx_mem_cpy(pool->code_buffer, code, sizeof code);
+
+ pool->entry_point = 0;
+
+ return code_size;
+}
+
+// ================================================================
+
i64 ar_find_symbol_offset_by_name(
u8 *ar_symbol_table,
u8 *ar_end,
@@ -2063,36 +2090,28 @@ void elf_dump(u32 log_level, Buffer_Context b) {
BX_LOG(log_level, "");
}
-i64 unit_write_in_memory(Pool *pool, i64 unit, u16 target) {
+i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) {
BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments",);
BX_CHECK(pool->entities[unit].is_enabled, "Unit does not exist",);
BX_CHECK(pool->entities[unit].unit.entry_point_index != UNDEFINED, "No entry point",);
- BX_CHECK(target == (FORMAT_ELF | ARCH_X86_64), "Target not supported",);
-
+ BX_CHECK(format == FORMAT_ELF, "Target not supported",);
+ BX_CHECK(arch == ARCH_X86_64, "Target not supported",);
BX_CHECK(pool->obj_file_buffer != NULL, "No object file buffer",);
BX_CHECK(pool->dependencies_buffer != NULL, "No dependencies buffer",);
BX_CHECK(pool->obj_file_offsets != NULL, "No object file offsets buffer",);
// ==============================================================
//
- // Our program
+ // Codegen
- u8 code[32] = {
- 0xb8, 0x3c, 0x00, 0x00, 0x00, // mov eax, 60
- 0xbf, 0x2a, 0x00, 0x00, 0x00, // mov edi, 42
- 0x0f, 0x05, // syscall
- };
+ i64 code_size = codegen_in_memory(pool, unit, arch);
u16 num_program_headers = 4;
-
- i64 page_size = 4096;
- i64 program_offset = bx_align(ELF_HEADER_SIZE + ELF_PROGRAM_HEADER_SIZE * num_program_headers, X86_64_ALIGNMENT);
- i64 code_size = bx_align(sizeof code, X86_64_ALIGNMENT);
- i64 entry_offset = 0;
+ i64 program_offset = bx_align(ELF_HEADER_SIZE + ELF_PROGRAM_HEADER_SIZE * num_program_headers, X86_64_ALIGNMENT);
i64 base_address = X86_64_BASE_ADDRESS;
i64 rotext_address = base_address + program_offset;
- i64 entry = rotext_address + entry_offset;
+ i64 entry = rotext_address + pool->entry_point;
Internal_Symbol_Entry sym_printf = {0};
@@ -2146,10 +2165,10 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 target) {
}
}
- rotext_size = bx_align(rotext_size, page_size);
- rwzval_size = bx_align(rwzval_size, page_size);
- rwdata_size = bx_align(rwdata_size, page_size);
- rodata_size = bx_align(rodata_size, page_size);
+ rotext_size = bx_align(rotext_size, X86_64_PAGE_SIZE);
+ rwzval_size = bx_align(rwzval_size, X86_64_PAGE_SIZE);
+ rwdata_size = bx_align(rwdata_size, X86_64_PAGE_SIZE);
+ rodata_size = bx_align(rodata_size, X86_64_PAGE_SIZE);
i64 rwzval_address = rotext_address + rotext_size;
i64 rwdata_address = rwzval_address + rwzval_size;
@@ -2496,10 +2515,10 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 target) {
i64 rwdata_offset = rwzval_offset;
i64 rodata_offset = rwdata_offset + rwdata_size;
- BX_CHECK(rotext_offset % page_size == rotext_address % page_size, "Invalid alignment",);
- BX_CHECK(rwzval_offset % page_size == rwzval_address % page_size, "Invalid alignment",);
- BX_CHECK(rwdata_offset % page_size == rwdata_address % page_size, "Invalid alignment",);
- BX_CHECK(rodata_offset % page_size == rodata_address % page_size, "Invalid alignment",);
+ BX_CHECK(rotext_offset % X86_64_PAGE_SIZE == rotext_address % X86_64_PAGE_SIZE, "Invalid alignment",);
+ BX_CHECK(rwzval_offset % X86_64_PAGE_SIZE == rwzval_address % X86_64_PAGE_SIZE, "Invalid alignment",);
+ BX_CHECK(rwdata_offset % X86_64_PAGE_SIZE == rwdata_address % X86_64_PAGE_SIZE, "Invalid alignment",);
+ BX_CHECK(rodata_offset % X86_64_PAGE_SIZE == rodata_address % X86_64_PAGE_SIZE, "Invalid alignment",);
// .rotext
write_u32(LE, 1, o + 64, o_end); // type (PT_LOAD)
@@ -2546,7 +2565,7 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 target) {
// Code
//
- bx_mem_cpy(o + rotext_offset, code, code_size);
+ bx_mem_cpy(o + rotext_offset, pool->code_buffer, code_size);
// ==============================================================
//
@@ -2574,7 +2593,7 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 target) {
return output_size;
}
-void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data) {
+void unit_write(Pool *pool, i64 unit, u16 format, u16 arch, i64 io_out, void *io_user_data) {
// ==============================================================
//
// Reading dependencies
@@ -2651,7 +2670,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
// ==============================================================
- i64 output_size = unit_write_in_memory(pool, unit, target);
+ i64 output_size = unit_write_in_memory(pool, unit, format, arch);
// ==============================================================
//
@@ -2664,6 +2683,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
// Cleanup
pool->num_obj_files = 0;
+ pool->entry_point = 0;
bx_mem_set(pool->obj_file_buffer, 0, pool->max_obj_file_size);
bx_mem_set(pool->dependencies_buffer, 0, pool->max_dependencies_size);
@@ -2923,14 +2943,19 @@ Pool g_pool = {
.max_num_sections = MAX_NUM_SECTIONS,
.max_num_symbols = MAX_NUM_SYMBOLS,
.max_not_found_size = MAX_NOT_FOUND_SIZE,
+ .max_code_size = MAX_CODE_SIZE,
.max_output_size = MAX_OUTPUT_SIZE,
+ .num_obj_files = 0,
+ .entry_point = 0,
+
.obj_file_buffer = (u8[MAX_OBJECT_FILE_SIZE]) {0},
.dependencies_buffer = (u8[MAX_DEPENDENCIES_SIZE]) {0},
.obj_file_offsets = (i64[MAX_NUM_OBJECT_FILES]) {0},
.section_addresses = (i64[MAX_NUM_SECTIONS]) {0},
.symbols = (Internal_Symbol_Entry[MAX_NUM_SYMBOLS]) {0},
.not_found_buffer = (c8[MAX_NOT_FOUND_SIZE]) {0},
+ .code_buffer = (u8[MAX_CODE_SIZE]) {0},
.output_buffer = (u8[MAX_OUTPUT_SIZE]) {0},
};
@@ -2978,7 +3003,7 @@ void u_entry_point(i64 unit, i64 proc) {
void u_elf_x86_64(i64 unit, c8 *output_file_name) {
i64 out = io_open_write(bx_str_len(output_file_name, output_file_name + MAX_PATH_SIZE), output_file_name, NULL);
- unit_write(&g_pool, unit, FORMAT_ELF | ARCH_X86_64, out, NULL);
+ unit_write(&g_pool, unit, FORMAT_ELF, ARCH_X86_64, out, NULL);
io_chmod_exe(out, NULL);
io_close(out, NULL);