diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-07-25 11:12:03 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-07-25 11:12:03 +0200 |
commit | 8a78b1b3dba5e0c589f91a42bece8f797ab5856a (patch) | |
tree | 3c472af1a8cfdb19d698f421bc7dc3120c014dff | |
parent | fea7c754e443e29b1185fc3cfe50a3c778ccb82b (diff) | |
download | bxgen-8a78b1b3dba5e0c589f91a42bece8f797ab5856a.zip |
Codegen and linker context
-rwxr-xr-x | bxgen.c | 243 |
1 files changed, 143 insertions, 100 deletions
@@ -383,20 +383,27 @@ typedef struct { i64 capacity; Entity *entities; - // TEMP Linker buffers - // TODO Use string table for buffers also. +} Pool; + +// TEMP Codegen and linker buffers +// TODO Use string table for buffers also. + +typedef struct { + i64 max_code_size; + i64 entry_point; + u8 *code_buffer; +} Codegen_Context; +typedef struct { i64 max_obj_file_size; i64 max_dependencies_size; i64 max_num_obj_files; 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; @@ -404,9 +411,8 @@ typedef struct { i64 * section_addresses; Internal_Symbol_Entry *symbols; c8 * not_found_buffer; - u8 * code_buffer; u8 * output_buffer; -} Pool; +} Linker_Context; // ================================================================ // @@ -459,7 +465,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 format, u16 arch, i64 io_id, void *io_user_data); +void unit_write(Pool *pool, Codegen_Context *codegen, Linker_Context *linker, 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); @@ -1625,15 +1631,21 @@ typedef struct { // Codegen // -i64 x86_64_emit_node(Pool *pool, i64 offset, i64 node, u32 context) { +i64 x86_64_emit_node( + Pool * pool, + Codegen_Context *codegen, + i64 offset, + i64 node, + u32 context +) { BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments", 0); BX_CHECK(node != UNDEFINED && pool->entities[node].is_enabled, "No node", 0); BX_CHECK(pool->entities[node].type == ENTITY_NODE, "Invalid entity", 0); Node *n = &pool->entities[node].node; - u8 *begin = pool->code_buffer + offset; - u8 *end = pool->code_buffer + pool->max_code_size; + u8 *begin = codegen->code_buffer + offset; + u8 *end = codegen->code_buffer + codegen->max_code_size; switch (n->op) { case DATA_I64: { @@ -1678,7 +1690,14 @@ i64 x86_64_emit_node(Pool *pool, i64 offset, i64 node, u32 context) { return offset; } -i64 emit_proc(Pool *pool, i64 offset, i64 proc, u16 arch, u32 context) { +i64 emit_proc( + Pool * pool, + Codegen_Context *codegen, + i64 offset, + i64 proc, + u16 arch, + u32 context +) { BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments", 0); BX_CHECK(proc != UNDEFINED && pool->entities[proc].is_enabled, "No proc", 0); BX_CHECK(pool->entities[proc].type == ENTITY_PROC, "Invalid entity", 0); @@ -1692,12 +1711,12 @@ i64 emit_proc(Pool *pool, i64 offset, i64 proc, u16 arch, u32 context) { // Now we assume that nodes are already sorted. for (i64 i = 0; i < p->num_nodes; ++i) - offset = x86_64_emit_node(pool, offset, p->nodes[i], context); + offset = x86_64_emit_node(pool, codegen, offset, p->nodes[i], context); return offset; } -i64 emit_unit(Pool *pool, i64 offset, i64 unit, u16 arch) { +i64 emit_unit(Pool *pool, Codegen_Context *codegen, i64 offset, i64 unit, u16 arch) { BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments", 0); BX_CHECK(unit != UNDEFINED && pool->entities[unit].is_enabled, "No unit", 0); BX_CHECK(pool->entities[unit].type == ENTITY_UNIT, "Invalid entity", 0); @@ -1706,11 +1725,11 @@ i64 emit_unit(Pool *pool, i64 offset, i64 unit, u16 arch) { u32 context = 0; if (i == pool->entities[unit].unit.entry_point_index) { - pool->entry_point = offset; + codegen->entry_point = offset; context |= EMIT_ENTRY_PROC; } - offset = emit_proc(pool, offset, pool->entities[unit].unit.procs[i], arch, context); + offset = emit_proc(pool, codegen, offset, pool->entities[unit].unit.procs[i], arch, context); } return offset; @@ -1754,16 +1773,17 @@ i64 ar_find_symbol_offset_by_name( } Buffer_Context elf_buffer_context( - Pool *pool, - i64 num_obj_files, - i64 elf_index + Pool * pool, + Linker_Context *linker, + i64 num_obj_files, + i64 elf_index ) { return (Buffer_Context) { - .begin = pool->dependencies_buffer, - .end = pool->dependencies_buffer + pool->obj_file_offsets[num_obj_files], + .begin = linker->dependencies_buffer, + .end = linker->dependencies_buffer + linker->obj_file_offsets[num_obj_files], .elf = { - .offset = pool->obj_file_offsets[elf_index], - .size = pool->obj_file_offsets[elf_index + 1] - pool->obj_file_offsets[elf_index], + .offset = linker->obj_file_offsets[elf_index], + .size = linker->obj_file_offsets[elf_index + 1] - linker->obj_file_offsets[elf_index], }, }; } @@ -2180,24 +2200,31 @@ void elf_dump(u32 log_level, Buffer_Context b) { BX_LOG(log_level, ""); } -i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { +i64 unit_write_in_memory( + Pool * pool, + Codegen_Context *codegen, + Linker_Context * linker, + i64 unit, + u16 format, + u16 arch +) { BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments",); BX_CHECK(unit != UNDEFINED && pool->entities[unit].is_enabled, "No unit",); BX_CHECK(pool->entities[unit].type == ENTITY_UNIT, "Invalid entity", 0); BX_CHECK(pool->entities[unit].unit.entry_point_index != UNDEFINED, "No entry point",); BX_CHECK(format == FORMAT_ELF && 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",); + BX_CHECK(linker->obj_file_buffer != NULL, "No object file buffer",); + BX_CHECK(linker->dependencies_buffer != NULL, "No dependencies buffer",); + BX_CHECK(linker->obj_file_offsets != NULL, "No object file offsets buffer",); - i64 code_size = emit_unit(pool, 0, unit, arch); + i64 code_size = emit_unit(pool, codegen, 0, unit, arch); u16 num_program_headers = 4; 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 + pool->entry_point; + i64 entry = rotext_address + codegen->entry_point; Internal_Symbol_Entry sym_printf = {0}; @@ -2214,8 +2241,8 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { // // Calculate section offsets - for (i64 elf_index = 0; elf_index < pool->num_obj_files; ++elf_index) { - Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index); + for (i64 elf_index = 0; elf_index < linker->num_obj_files; ++elf_index) { + Buffer_Context buf = elf_buffer_context(pool, linker, linker->num_obj_files, elf_index); elf_checks(buf); //elf_dump(VERBOSE, buf); @@ -2223,9 +2250,9 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { Offset_Num headers = elf_section_headers(buf); for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++num_sections) { - BX_CHECK(num_sections < pool->max_num_sections, "Too many sections",); + BX_CHECK(num_sections < linker->max_num_sections, "Too many sections",); - pool->section_addresses[num_sections] = 0; + linker->section_addresses[num_sections] = 0; Section_Header section = elf_section(buf, sec_index); @@ -2233,16 +2260,16 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { continue; if (section.exec) { - pool->section_addresses[num_sections] = rotext_size; + linker->section_addresses[num_sections] = rotext_size; rotext_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else if (section.write && section.type == SEC_NOBITS) { - pool->section_addresses[num_sections] = rwzval_size; + linker->section_addresses[num_sections] = rwzval_size; rwzval_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else if (section.write) { - pool->section_addresses[num_sections] = rwdata_size; + linker->section_addresses[num_sections] = rwdata_size; rwdata_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else if (section.data.size > 0) { - pool->section_addresses[num_sections] = rodata_size; + linker->section_addresses[num_sections] = rodata_size; rodata_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else { BX_LAX(0, "Unsupported section type"); @@ -2260,14 +2287,14 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { i64 rwdata_address = rwzval_address + rwzval_size; i64 rodata_address = rwdata_address + rwdata_size; - for (i64 elf_index = 0, sec_index_global = 0; elf_index < pool->num_obj_files; ++elf_index) { - Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index); + for (i64 elf_index = 0, sec_index_global = 0; elf_index < linker->num_obj_files; ++elf_index) { + Buffer_Context buf = elf_buffer_context(pool, linker, linker->num_obj_files, elf_index); Offset_Num headers = elf_section_headers(buf); for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++sec_index_global) { BX_CHECK(sec_index_global < num_sections, "Buffer overflow",); - pool->section_addresses[sec_index_global] = 0; + linker->section_addresses[sec_index_global] = 0; Section_Header section = elf_section(buf, sec_index); @@ -2275,13 +2302,13 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { continue; if (section.exec) - pool->section_addresses[sec_index_global] += rotext_address + code_size; + linker->section_addresses[sec_index_global] += rotext_address + code_size; else if (section.write && section.type == SEC_NOBITS) - pool->section_addresses[sec_index_global] += rwzval_address; + linker->section_addresses[sec_index_global] += rwzval_address; else if (section.write) - pool->section_addresses[sec_index_global] += rwdata_address; + linker->section_addresses[sec_index_global] += rwdata_address; else if (section.data.size > 0) - pool->section_addresses[sec_index_global] += rodata_address; + linker->section_addresses[sec_index_global] += rodata_address; } } @@ -2289,8 +2316,8 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { // // Relocate defined symbols - for (i64 elf_index = 0, sec_index_global = 0; elf_index < pool->num_obj_files; ++elf_index) { - Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index); + for (i64 elf_index = 0, sec_index_global = 0; elf_index < linker->num_obj_files; ++elf_index) { + Buffer_Context buf = elf_buffer_context(pool, linker, linker->num_obj_files, elf_index); Offset_Num headers = elf_section_headers(buf); Offset_Size strtab = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; @@ -2315,12 +2342,12 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { if (sym.section != 65521) { sym_section = sec_index_global + sym.section - 1; BX_CHECK(sym_section < num_sections, "Buffer overflow",); - sym_address = pool->section_addresses[sym_section] + sym.value.offset; + sym_address = linker->section_addresses[sym_section] + sym.value.offset; } - BX_CHECK(num_symbols < pool->max_num_symbols, "Too many symbols",); + BX_CHECK(num_symbols < linker->max_num_symbols, "Too many symbols",); - pool->symbols[num_symbols++] = (Internal_Symbol_Entry) { + linker->symbols[num_symbols++] = (Internal_Symbol_Entry) { .name_size = sym.name.size, .name = sym_name, .section = sym_section, @@ -2393,8 +2420,8 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { // // TODO Apply relocations - for (i64 elf_index = 0, sec_index_global = 0; elf_index < pool->num_obj_files; ++elf_index) { - Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index); + for (i64 elf_index = 0, sec_index_global = 0; elf_index < linker->num_obj_files; ++elf_index) { + Buffer_Context buf = elf_buffer_context(pool, linker, linker->num_obj_files, elf_index); i64 num_sections = elf_section_headers(buf).num; Offset_Size strtab = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; @@ -2407,7 +2434,7 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { i64 dst_index = elf_find_related_section_index(buf, sec_index); - BX_CHECK(dst_index >= 0 && dst_index < pool->max_num_sections, "Buffer overflow",); + BX_CHECK(dst_index >= 0 && dst_index < linker->max_num_sections, "Buffer overflow",); for (i64 entry_index = 0; entry_index < src_sec.num_entries; ++entry_index) { Relx_Entry relx = elf_relx(buf, symtab, strtab, src_sec.data, entry_index, src_sec.type == SEC_RELA); @@ -2418,25 +2445,25 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { if (relx.symbol.section == 0) { for (i64 i = 0; i < num_symbols; ++i) - if (pool->symbols[i].name_size == relx.symbol.name.size && + if (linker->symbols[i].name_size == relx.symbol.name.size && bx_mem_eq( - pool->symbols[i].name, + linker->symbols[i].name, sym_name, relx.symbol.name.size )) { - symbol = pool->symbols[i]; + symbol = linker->symbols[i]; break; } if (symbol.name_size == 0 && bx_find_str_in_table( - pool->not_found_buffer, - pool->not_found_buffer + not_found_size, + linker->not_found_buffer, + linker->not_found_buffer + not_found_size, sym_name, sym_name + relx.symbol.name.size ) == NULL) { BX_LOG(WARNING, "Undefined symbol: %s", sym_name); - BX_CHECK(not_found_size + relx.symbol.name.size + 1 <= pool->max_not_found_size, "Out of memory",); - bx_mem_cpy(pool->not_found_buffer + not_found_size, sym_name, relx.symbol.name.size); + BX_CHECK(not_found_size + relx.symbol.name.size + 1 <= linker->max_not_found_size, "Out of memory",); + bx_mem_cpy(linker->not_found_buffer + not_found_size, sym_name, relx.symbol.name.size); not_found_size += relx.symbol.name.size + 1; } } else @@ -2452,7 +2479,7 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { i64 A = relx.addent; // Represents the base address at which a shared object has been loaded into memory during execution. Generally, a shared object is built with a 0 base virtual address, but the execution address will be different. - i64 B = pool->section_addresses[dst_index]; + i64 B = linker->section_addresses[dst_index]; // Represents the offset into the global offset table at which the relocation entry's symbol will reside during execution. i64 G = symbol.address - base_address - program_offset; @@ -2464,7 +2491,7 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { i64 L = base_address + program_offset; // Represents the place (section offset or address) of the storage unit being relocated (computed using r_offset). - i64 P = pool->section_addresses[dst_index] + relx.offset; + i64 P = linker->section_addresses[dst_index] + relx.offset; // Represents the value of the symbol whose index resides in the relocation entry. i64 S = symbol.address; @@ -2536,8 +2563,8 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { // TODO Search symbols for (i64 i = 0; i < num_symbols; ++i) - if (pool->symbols[i].name_size == 6 && bx_mem_eq(pool->symbols[i].name, "printf", 6)) { - sym_printf = pool->symbols[i]; + if (linker->symbols[i].name_size == 6 && bx_mem_eq(linker->symbols[i].name, "printf", 6)) { + sym_printf = linker->symbols[i]; break; } @@ -2548,7 +2575,7 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { i64 output_size = bx_align(program_offset + rotext_size + rwzval_size + rwdata_size + rodata_size, X86_64_ALIGNMENT); - BX_CHECK(output_size <= pool->max_output_size, "Out of memory",); + BX_CHECK(output_size <= linker->max_output_size, "Out of memory",); BX_LOG(VERBOSE, "Total %lld sections", num_sections); BX_LOG(VERBOSE, "Total %lld symbols", num_symbols); @@ -2564,8 +2591,8 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { BX_LOG(VERBOSE, "Writing ELF x86_64 executable"); - u8 *o = pool->output_buffer; - u8 *o_end = o + pool->max_output_size; + u8 *o = linker->output_buffer; + u8 *o_end = o + linker->max_output_size; // ELF header // @@ -2651,25 +2678,25 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { // Code // - bx_mem_cpy(o + rotext_offset, pool->code_buffer, code_size); + bx_mem_cpy(o + rotext_offset, codegen->code_buffer, code_size); // ============================================================== // // Write sections into the output buffer - for (i64 elf_index = 0; elf_index < pool->num_obj_files; ++elf_index) { - Buffer_Context buf = elf_buffer_context(pool, pool->num_obj_files, elf_index); + for (i64 elf_index = 0; elf_index < linker->num_obj_files; ++elf_index) { + Buffer_Context buf = elf_buffer_context(pool, linker, linker->num_obj_files, elf_index); Offset_Num headers = elf_section_headers(buf); for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++num_sections) { Section_Header section = elf_section(buf, sec_index); - if (pool->section_addresses[sec_index] == 0 || - !section.alloc || + if (linker->section_addresses[sec_index] == 0 || + !section.alloc || section.data.size == 0) continue; - u8 *p = o + (pool->section_addresses[sec_index] - base_address); - BX_CHECK(p >= pool->output_buffer + program_offset + code_size, "Buffer overflow",); - BX_CHECK(p + section.data.size <= pool->output_buffer + output_size, "Buffer overflow",); + u8 *p = o + (linker->section_addresses[sec_index] - base_address); + BX_CHECK(p >= linker->output_buffer + program_offset + code_size, "Buffer overflow",); + BX_CHECK(p + section.data.size <= linker->output_buffer + output_size, "Buffer overflow",); bx_mem_cpy(p, buf.begin + section.data.offset, section.data.size); } } @@ -2679,7 +2706,16 @@ i64 unit_write_in_memory(Pool *pool, i64 unit, u16 format, u16 arch) { return output_size; } -void unit_write(Pool *pool, i64 unit, u16 format, u16 arch, i64 io_out, void *io_user_data) { +void unit_write( + Pool * pool, + Codegen_Context *codegen, + Linker_Context * linker, + i64 unit, + u16 format, + u16 arch, + i64 io_out, + void * io_user_data +) { // ============================================================== // // Reading dependencies @@ -2702,10 +2738,10 @@ void unit_write(Pool *pool, i64 unit, u16 format, u16 arch, i64 io_out, void *io io_seek(f, 0, IO_SEEK_END, io_user_data); i64 in_size = io_tell(f, io_user_data); - BX_CHECK(in_size <= pool->max_obj_file_size, "AR file too big",); + BX_CHECK(in_size <= linker->max_obj_file_size, "AR file too big",); io_seek(f, 0, IO_SEEK_BEGIN, io_user_data); - i64 n = io_read(f, in_size, pool->obj_file_buffer, io_user_data); + i64 n = io_read(f, in_size, linker->obj_file_buffer, io_user_data); BX_CHECK(n == in_size, "Read failed",); io_close(f, io_user_data); @@ -2714,8 +2750,8 @@ void unit_write(Pool *pool, i64 unit, u16 format, u16 arch, i64 io_out, void *io // // Read AR library - u8 *ar_begin = pool->obj_file_buffer; - u8 *ar_end = pool->obj_file_buffer + in_size; + u8 *ar_begin = linker->obj_file_buffer; + u8 *ar_end = linker->obj_file_buffer + in_size; BX_CHECK(bx_mem_eq(ar_begin, AR_MAGIC, 8), "Invalid AR file",); @@ -2740,14 +2776,14 @@ void unit_write(Pool *pool, i64 unit, u16 format, u16 arch, i64 io_out, void *io i64 delta_size = bx_align(size, X86_64_ALIGNMENT); - BX_CHECK(obj_files_size + delta_size < pool->max_dependencies_size, "Out of memory",); - BX_CHECK(pool->num_obj_files + 1 < pool->max_num_obj_files, "Out of memory",); + BX_CHECK(obj_files_size + delta_size < linker->max_dependencies_size, "Out of memory",); + BX_CHECK(linker->num_obj_files + 1 < linker->max_num_obj_files, "Out of memory",); - bx_mem_cpy(pool->dependencies_buffer + obj_files_size, f_data, size); + bx_mem_cpy(linker->dependencies_buffer + obj_files_size, f_data, size); - pool->obj_file_offsets[pool->num_obj_files] = obj_files_size; - obj_files_size += delta_size; - pool->obj_file_offsets[++pool->num_obj_files] = obj_files_size; + linker->obj_file_offsets[linker->num_obj_files] = obj_files_size; + obj_files_size += delta_size; + linker->obj_file_offsets[++linker->num_obj_files] = obj_files_size; } f_begin = f_data + size; @@ -2756,28 +2792,29 @@ void unit_write(Pool *pool, i64 unit, u16 format, u16 arch, i64 io_out, void *io // ============================================================== - i64 output_size = unit_write_in_memory(pool, unit, format, arch); + i64 output_size = unit_write_in_memory(pool, codegen, linker, unit, format, arch); // ============================================================== // // Write the output buffer into the file - io_write(io_out, output_size, pool->output_buffer, io_user_data); + io_write(io_out, output_size, linker->output_buffer, io_user_data); // ============================================================== // // Cleanup - pool->num_obj_files = 0; - pool->entry_point = 0; + codegen->entry_point = 0; + linker->num_obj_files = 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); - bx_mem_set(pool->obj_file_offsets, 0, pool->max_num_obj_files * sizeof *pool->obj_file_offsets); - bx_mem_set(pool->section_addresses, 0, pool->max_num_sections * sizeof *pool->section_addresses); - bx_mem_set(pool->symbols, 0, pool->max_num_symbols * sizeof *pool->symbols); - bx_mem_set(pool->not_found_buffer, 0, pool->max_not_found_size); - bx_mem_set(pool->output_buffer, 0, pool->max_output_size); + bx_mem_set(codegen->code_buffer, 0, codegen->max_code_size); + bx_mem_set(linker->obj_file_buffer, 0, linker->max_obj_file_size); + bx_mem_set(linker->dependencies_buffer, 0, linker->max_dependencies_size); + bx_mem_set(linker->obj_file_offsets, 0, linker->max_num_obj_files * sizeof *linker->obj_file_offsets); + bx_mem_set(linker->section_addresses, 0, linker->max_num_sections * sizeof *linker->section_addresses); + bx_mem_set(linker->symbols, 0, linker->max_num_symbols * sizeof *linker->symbols); + bx_mem_set(linker->not_found_buffer, 0, linker->max_not_found_size); + bx_mem_set(linker->output_buffer, 0, linker->max_output_size); } i64 io_open_read(i64 name_size, c8 *name, void *user_data) { @@ -3022,18 +3059,24 @@ Pool g_pool = { .capacity = MAX_NUM_ENTITIES, .entities = (Entity[MAX_NUM_ENTITIES]) {0}, +}; +Codegen_Context g_codegen = { + .max_code_size = MAX_CODE_SIZE, + .entry_point = 0, + .code_buffer = (u8[MAX_CODE_SIZE]) {0}, +}; + +Linker_Context g_linker = { .max_obj_file_size = MAX_OBJECT_FILE_SIZE, .max_dependencies_size = MAX_DEPENDENCIES_SIZE, .max_num_obj_files = MAX_NUM_OBJECT_FILES, .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}, @@ -3041,7 +3084,6 @@ Pool g_pool = { .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}, }; @@ -3087,9 +3129,10 @@ 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); + i64 name_len = bx_str_len(output_file_name, output_file_name + MAX_PATH_SIZE); + i64 out = io_open_write(name_len, output_file_name, NULL); - unit_write(&g_pool, unit, FORMAT_ELF, ARCH_X86_64, out, NULL); + unit_write(&g_pool, &g_codegen, &g_linker, unit, FORMAT_ELF, ARCH_X86_64, out, NULL); io_chmod_exe(out, NULL); io_close(out, NULL); |