summaryrefslogtreecommitdiff
path: root/bxgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'bxgen.c')
-rwxr-xr-xbxgen.c243
1 files changed, 143 insertions, 100 deletions
diff --git a/bxgen.c b/bxgen.c
index 6951657..bc1d09b 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -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);