From e9934a81f6c69596c0f183abc411804a9d450208 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Wed, 24 Jul 2024 21:20:21 +0200 Subject: Separate codegen proc --- bxgen.c | 91 +++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 33 deletions(-) (limited to 'bxgen.c') 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); -- cgit v1.2.3