summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-25 22:43:44 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-25 22:43:44 +0200
commit941491cf484bd6f11dd743aae76e8dea8057cc60 (patch)
treeae35c6a202c3c786306eaff045fd47221c6ecd76
parent7a0155cab821a6bc2102123c02f72e705df1f4cd (diff)
downloadbxgen-941491cf484bd6f11dd743aae76e8dea8057cc60.zip
Codegen: call (incomplete)
-rwxr-xr-xbxgen.c280
1 files changed, 165 insertions, 115 deletions
diff --git a/bxgen.c b/bxgen.c
index 47ea9d2..1442daf 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -31,6 +31,7 @@
#/ - Linking libraries
#/ - GNU ld script
#/ - Unused dependencies elimination
+#/ - Use 0 for UNDEFINED
#/ - String table for names and arrays
#/ - Proper prefixes for identifiers
#/ - Effective entity allocation
@@ -164,6 +165,7 @@ enum {
MAX_NUM_OBJECT_FILES = 10 * 1024,
MAX_NUM_SECTIONS = 2 * 1024 * 1024,
MAX_NUM_SYMBOLS = 2 * 1024 * 1024,
+ MAX_NUM_RELS = 100 * 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
@@ -257,6 +259,11 @@ enum {
ARCH_X86_64,
ARCH_ARM32,
ARCH_ARM64,
+
+ // Relocations
+ //
+
+ REL_CALL = 0,
};
// TODO
@@ -275,7 +282,7 @@ typedef struct {
typedef struct {
i16 num;
- i16 type;
+ u16 type;
i64 node;
} Var;
@@ -289,7 +296,7 @@ typedef struct {
// We may call a local procedure by it's id,
// or a global procedure by name.
- i16 convention; // can be implicitly retrieved from the procedure
+ u16 convention; // can be implicitly retrieved from the procedure
i64 target_proc;
i64 target_name_size;
c8 target_name[MAX_NAME_SIZE]; // TODO use string table
@@ -301,7 +308,7 @@ typedef struct {
// and possible references to other nodes.
typedef struct {
- i16 op;
+ u16 op;
i64 index_in_proc;
union {
u8 lit_bytes[MAX_LITERAL_SIZE]; // byte array literal
@@ -325,7 +332,7 @@ typedef struct {
// and has a string name.
typedef struct {
- i16 convention;
+ u16 convention;
i64 name_size;
c8 name[MAX_NAME_SIZE]; // TODO use string table
i64 num_nodes;
@@ -339,7 +346,7 @@ typedef struct {
//
typedef struct {
- i16 type;
+ u16 type;
i64 entry_point_index;
i64 name_size;
c8 name[MAX_NAME_SIZE]; // TODO use string table
@@ -359,7 +366,7 @@ typedef struct {
typedef struct {
b8 is_enabled;
- i16 type;
+ u16 type;
union {
Node node;
Proc proc;
@@ -368,12 +375,20 @@ typedef struct {
} Entity;
typedef struct {
+ u16 type;
+ i64 name_size;
+ i64 name[MAX_NAME_SIZE];
+ i64 address;
+ i64 size;
+} Rel_Entry;
+
+typedef struct {
i64 name_size;
c8 *name;
i64 section;
i64 address;
i64 size;
-} Internal_Symbol_Entry;
+} Symbol_Entry;
// Pool, a collection of all entities.
//
@@ -392,9 +407,16 @@ typedef struct {
// TODO Use string table for buffers also.
typedef struct {
- i64 max_code_size;
- i64 entry_point;
- u8 *code_buffer;
+ i64 max_num_rels;
+ i64 max_code_size;
+ i64 max_rodata_size;
+ i64 entry_point;
+ i64 num_rels;
+ i64 offset_code;
+ i64 offset_rodata;
+ Rel_Entry *rels;
+ u8 * buffer_code;
+ u8 * buffer_rodata;
} Codegen_Context;
typedef struct {
@@ -408,13 +430,13 @@ typedef struct {
i64 num_obj_files;
- u8 * obj_file_buffer;
- u8 * dependencies_buffer;
- i64 * obj_file_offsets;
- i64 * section_addresses;
- Internal_Symbol_Entry *symbols;
- c8 * not_found_buffer;
- u8 * output_buffer;
+ u8 * obj_file_buffer;
+ u8 * dependencies_buffer;
+ i64 * obj_file_offsets;
+ i64 * section_addresses;
+ Symbol_Entry *symbols;
+ c8 * not_found_buffer;
+ u8 * output_buffer;
} Linker_Context;
// ================================================================
@@ -437,31 +459,31 @@ extern "C" {
//
void bx_log(i32 log_level, u32 line, c8 *file, c8 *format, ...);
void bx_assert(b8 condition, c8 *message, u32 line, c8 *file);
-void io_dispatch(i16 op, i64 *id, i64 *size, void *data, void *user_data);
+void io_dispatch(u16 op, i64 *id, i64 *size, void *data, void *user_data);
// ================================================================
//
// Main API
//
i64 pool_add(Pool *pool, Entity data);
-void pool_remove(Pool *pool, i64 entity, i16 type);
+void pool_remove(Pool *pool, i64 entity, u16 type);
i64 node_init(Pool *pool, Node data);
void node_destroy(Pool *pool, i64 node);
i64 node_data_array_c8(Pool *pool, i64 size, c8 *data);
i64 node_data_i64(Pool *pool, i64 value);
-i64 node_ctrl_call(Pool *pool, i16 convention, i64 target_proc, i64 num_args, Var *args);
-i64 node_ctrl_call_by_name(Pool *pool, i16 convention, i64 name_size, c8 *name, i64 num_args, Var *args);
+i64 node_ctrl_call(Pool *pool, u16 convention, i64 target_proc, i64 num_args, Var *args);
+i64 node_ctrl_call_by_name(Pool *pool, u16 convention, i64 name_size, c8 *name, i64 num_args, Var *args);
i64 node_ctrl_ret(Pool *pool, i64 num_values, Var *values);
i64 proc_init(Pool *pool);
void proc_destroy(Pool *pool, i64 proc);
-void proc_set_convention(Pool *pool, i64 proc, i16 convention);
+void proc_set_convention(Pool *pool, i64 proc, u16 convention);
void proc_set_name(Pool *pool, i64 proc, i64 name_size, c8 *name);
void proc_node_add(Pool *pool, i64 proc, i64 node);
void proc_node_remove(Pool *pool, i64 proc, i64 node);
-i64 unit_init(Pool *pool, i16 type);
+i64 unit_init(Pool *pool, u16 type);
void unit_destroy(Pool *pool, i64 unit);
void unit_proc_add(Pool *pool, i64 unit, i64 proc);
void unit_proc_remove(Pool *pool, i64 unit, i64 proc);
@@ -487,8 +509,8 @@ void io_chmod_exe(i64 f, void *user_data);
#ifndef DISABLE_HELPERS
i64 n_str(i64 proc, c8 *value);
i64 n_i64(i64 proc, i64 value);
-i64 n_call(i64 proc, i16 convention, i64 target_proc, i64 num_args, Var *args);
-i64 n_call_by_name(i64 proc, i16 convention, c8 *name, i64 num_args, Var *args);
+i64 n_call(i64 proc, u16 convention, i64 target_proc, i64 num_args, Var *args);
+i64 n_call_by_name(i64 proc, u16 convention, c8 *name, i64 num_args, Var *args);
i64 n_ret(i64 proc, i64 num_vals, Var *vals);
i64 p_new(i64 unit, c8 *name);
i64 p_new_entry(i64 unit, c8 *name);
@@ -584,10 +606,10 @@ void bx_mem_set(void *dst, u8 val, i64 size) {
((u8 *)dst)[i] = val;
}
-void bx_mem_cpy(void *dst, void *src, i64 size) {
+void bx_mem_cpy(void *dst, void *__restrict src, i64 size) {
BX_CHECK(dst != NULL, "Invalid arguments",);
BX_CHECK(src != NULL, "Invalid arguments",);
- BX_CHECK(size > 0, "Invalid size",);
+ BX_CHECK(size >= 0, "Invalid size",);
for (i64 i = 0; i < size; ++i)
((u8 *)dst)[i] = ((u8 *)src)[i];
@@ -705,7 +727,7 @@ i64 pool_add(Pool *pool, Entity data) {
return id;
}
-void pool_remove(Pool *pool, i64 entity, i16 type) {
+void pool_remove(Pool *pool, i64 entity, u16 type) {
BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments",);
BX_CHECK(entity >= 0 && entity < pool->num_entities, "Buffer overflow",);
BX_CHECK(pool->entities[entity].is_enabled, "Entity already removed",);
@@ -741,7 +763,7 @@ i64 node_data_i64(Pool *pool, i64 value) {
});
}
-i64 node_ctrl_call(Pool *pool, i16 convention, i64 target_proc, i64 num_args, Var *args) {
+i64 node_ctrl_call(Pool *pool, u16 convention, i64 target_proc, i64 num_args, Var *args) {
BX_CHECK(num_args <= MAX_NUM_ARGS, "Array too big", UNDEFINED);
Call call = {
@@ -759,7 +781,7 @@ i64 node_ctrl_call(Pool *pool, i16 convention, i64 target_proc, i64 num_args, Va
});
}
-i64 node_ctrl_call_by_name(Pool *pool, i16 convention, i64 name_size, c8 *name, i64 num_args, Var *args) {
+i64 node_ctrl_call_by_name(Pool *pool, u16 convention, i64 name_size, c8 *name, i64 num_args, Var *args) {
BX_CHECK(num_args <= MAX_NUM_ARGS, "Array too big", UNDEFINED);
Call call = {
@@ -807,7 +829,7 @@ void proc_destroy(Pool *pool, i64 proc) {
pool_remove(pool, proc, ENTITY_PROC);
}
-void proc_set_convention(Pool *pool, i64 proc, i16 convention) {
+void proc_set_convention(Pool *pool, i64 proc, u16 convention) {
BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments",);
BX_CHECK(proc >= 0 && proc < pool->num_entities, "Buffer overflow",);
BX_CHECK(pool->entities[proc].is_enabled, "Entity does not exist",);
@@ -886,7 +908,7 @@ void proc_node_remove(Pool *pool, i64 proc, i64 node) {
n->index_in_proc = UNDEFINED;
}
-i64 unit_init(Pool *pool, i16 type) {
+i64 unit_init(Pool *pool, u16 type) {
return pool_add(pool, (Entity) {
.type = ENTITY_UNIT,
.unit = (Unit) {
@@ -1366,6 +1388,9 @@ void write_f64(u32 ordering, f64 x, void *v, void *v_end) {
// https://man7.org/linux/man-pages/man2/syscalls.2.html
// https://man7.org/linux/man-pages/man2/syscall.2.html
//
+// Linker scripts
+// https://home.cs.colorado.edu/~main/cs1300/doc/gnu/ld_3.html
+//
// ----------------------------------------------------------------
//
// TODO Experiment with mapping several p_vaddr into one p_paddr.
@@ -1623,7 +1648,7 @@ typedef struct {
i64 entry_size;
i64 num_entries;
Offset_Size data;
-} Section_Header;
+} Elf_Section_Header;
typedef struct {
Offset_Size name;
@@ -1631,24 +1656,23 @@ typedef struct {
u8 bind;
i64 section;
Offset_Size value;
-} Symbol_Entry;
+} Elf_Symbol_Entry;
typedef struct {
- Symbol_Entry symbol;
- i64 offset;
- u32 type;
- i64 addent;
-} Relx_Entry;
+ Elf_Symbol_Entry symbol;
+ i64 offset;
+ u32 type;
+ i64 addent;
+} Elf_Relx_Entry;
// ================================================================
//
// Codegen
//
-i64 x86_64_emit_node(
+void x86_64_emit_node(
Pool * pool,
Codegen_Context *codegen,
- i64 offset,
i64 node,
u32 context
) {
@@ -1658,8 +1682,8 @@ i64 x86_64_emit_node(
Node *n = &pool->entities[node].node;
- u8 *begin = codegen->code_buffer + offset;
- u8 *end = codegen->code_buffer + codegen->max_code_size;
+ u8 *begin = codegen->buffer_code + codegen->offset_code;
+ u8 *end = codegen->buffer_code + codegen->max_code_size;
switch (n->op) {
case DATA_C8:
@@ -1669,6 +1693,26 @@ i64 x86_64_emit_node(
case CTRL_CALL: {
BX_LOG(ERROR, "CTRL_CALL: not implemented", 0);
+
+ if (0) {
+ BX_CHECK(n->call.convention == CONV_CDECL, "Not implemented", 0);
+ BX_CHECK(n->call.target_proc == UNDEFINED, "Not implemented", 0);
+ BX_CHECK(n->call.target_name_size > 0, "No proc name", 0);
+
+ BX_CHECK(n->call.num_args == 1, "Not implemented", 0);
+ BX_CHECK(n->call.args[0].num == 1, "Not implemented", 0);
+ BX_CHECK(n->call.args[0].type == TYPE_PTR, "Not implemented", 0);
+
+ i64 n_arg = n->call.args[0].node;
+ BX_CHECK(n_arg != UNDEFINED, "Internal", 0);
+ BX_CHECK(pool->entities[n_arg].is_enabled, "Internal", 0);
+ BX_CHECK(pool->entities[n_arg].type == ENTITY_NODE, "Internal", 0);
+
+ Node *arg = &pool->entities[n_arg].node;
+ BX_CHECK(arg->op == DATA_C8, "Not implemented", 0);
+
+ // TODO
+ }
} break;
case CTRL_RET: {
@@ -1702,23 +1746,20 @@ i64 x86_64_emit_node(
write_u8 (LE, 0x0f, begin + 10, end); // syscall
write_u8 (LE, 0x05, begin + 11, end);
- offset += 12;
+ codegen->offset_code += 12;
} else {
- BX_FAIL("Not implemented", 0);
+ BX_FAIL("Not implemented",);
}
} break;
default:
- BX_FAIL("Unknown operation", 0);
+ BX_FAIL("Unknown operation",);
}
-
- return offset;
}
-i64 emit_proc(
+void emit_proc(
Pool * pool,
Codegen_Context *codegen,
- i64 offset,
i64 proc,
u16 arch,
u32 context
@@ -1736,12 +1777,10 @@ i64 emit_proc(
// Now we assume that nodes are already sorted.
for (i64 i = 0; i < p->num_nodes; ++i)
- offset = x86_64_emit_node(pool, codegen, offset, p->nodes[i], context);
-
- return offset;
+ x86_64_emit_node(pool, codegen, p->nodes[i], context);
}
-i64 emit_unit(Pool *pool, Codegen_Context *codegen, i64 offset, i64 unit, u16 arch) {
+void emit_unit(Pool *pool, Codegen_Context *codegen, 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);
@@ -1750,14 +1789,12 @@ i64 emit_unit(Pool *pool, Codegen_Context *codegen, i64 offset, i64 unit, u16 ar
u32 context = 0;
if (i == pool->entities[unit].unit.entry_point_index) {
- codegen->entry_point = offset;
+ codegen->entry_point = codegen->offset_code;
context |= EMIT_ENTRY_PROC;
}
- offset = emit_proc(pool, codegen, offset, pool->entities[unit].unit.procs[i], arch, context);
+ emit_proc(pool, codegen, pool->entities[unit].unit.procs[i], arch, context);
}
-
- return offset;
}
// ================================================================
@@ -1898,14 +1935,14 @@ i64 elf_find_section_index_by_name(
return 0;
}
-Section_Header elf_section(
+Elf_Section_Header elf_section(
Buffer_Context b,
i64 index
) {
Offset_Size names = elf_section_names_data(b);
u8 * begin = b.begin + elf_section_header_offset(b, index);
u8 * end = b.begin + b.elf.offset + b.elf.size;
- BX_CHECK(end <= b.end, "Buffer overflow", (Section_Header) {0});
+ BX_CHECK(end <= b.end, "Buffer overflow", (Elf_Section_Header) {0});
i64 name_index = (i64) read_u32(LE, begin, end);
i64 size = read_i64(LE, begin + 32, end);
@@ -1919,7 +1956,7 @@ Section_Header elf_section(
type = SEC_NONE;
}
- return (Section_Header) {
+ return (Elf_Section_Header) {
.name = elf_name_in_string_table(b, names, name_index),
.type = type,
.alloc = (flags & 2) == 2,
@@ -1935,13 +1972,13 @@ Section_Header elf_section(
};
}
-Section_Header elf_find_section_by_name(
+Elf_Section_Header elf_find_section_by_name(
Buffer_Context b,
c8 * name,
i64 name_size
) {
i64 index = elf_find_section_index_by_name(b, name, name_size);
- return index == 0 ? (Section_Header) {0} : elf_section(b, index);
+ return index == 0 ? (Elf_Section_Header) {0} : elf_section(b, index);
}
c8 *elf_name_from_offset(
@@ -1963,7 +2000,7 @@ i64 elf_find_related_section_index(
i64 section_index
) {
Offset_Size src_name = elf_section(b, section_index).name;
- Section_Header dst = elf_section(b, section_index - 1);
+ Elf_Section_Header dst = elf_section(b, section_index - 1);
if (src_name.size > dst.name.size &&
bx_mem_eq(
@@ -1998,7 +2035,7 @@ Offset_Size elf_find_related_data(
return elf_section(b, elf_find_related_section_index(b, section_index)).data;
}
-Symbol_Entry elf_symbol(
+Elf_Symbol_Entry elf_symbol(
Buffer_Context b,
Offset_Size symbol_table,
Offset_Size string_table,
@@ -2007,8 +2044,8 @@ Symbol_Entry elf_symbol(
u8 *begin = b.begin + symbol_table.offset + symbol_index * ELF_SYMBOL_ENTRY_SIZE;
u8 *end = b.begin + symbol_table.offset + symbol_table.size;
- BX_CHECK(end <= b.end, "Buffer overflow", (Symbol_Entry) {0});
- BX_CHECK(end <= b.begin + b.elf.offset + b.elf.size, "Buffer overflow", (Symbol_Entry) {0});
+ BX_CHECK(end <= b.end, "Buffer overflow", (Elf_Symbol_Entry) {0});
+ BX_CHECK(end <= b.begin + b.elf.offset + b.elf.size, "Buffer overflow", (Elf_Symbol_Entry) {0});
i64 sym_name = (i64) read_u32(LE, begin, end);
u8 sym_info = read_u8 (LE, begin + 4, end);
@@ -2028,7 +2065,7 @@ Symbol_Entry elf_symbol(
(sym_info >> 4) == 2 ? BIND_WEAK :
BIND_LOCAL;
- return (Symbol_Entry) {
+ return (Elf_Symbol_Entry) {
.name = elf_name_in_string_table(b, string_table, sym_name),
.type = type,
.bind = bind,
@@ -2040,7 +2077,7 @@ Symbol_Entry elf_symbol(
};
}
-Relx_Entry elf_relx(
+Elf_Relx_Entry elf_relx(
Buffer_Context b,
Offset_Size symbol_table,
Offset_Size string_table,
@@ -2051,16 +2088,16 @@ Relx_Entry elf_relx(
u8 *begin = b.begin + relocations.offset + relx_index * (is_rela ? ELF_RELA_ENTRY_SIZE : ELF_REL_ENTRY_SIZE);
u8 *end = begin + ELF_RELA_ENTRY_SIZE;
- BX_CHECK(end <= b.end, "Buffer overflow", (Relx_Entry) {0});
- BX_CHECK(end <= b.begin + b.elf.offset + b.elf.size, "Buffer overflow", (Relx_Entry) {0});
- BX_CHECK(end <= b.begin + relocations.offset + relocations.size, "Buffer overflow", (Relx_Entry) {0});
+ BX_CHECK(end <= b.end, "Buffer overflow", (Elf_Relx_Entry) {0});
+ BX_CHECK(end <= b.begin + b.elf.offset + b.elf.size, "Buffer overflow", (Elf_Relx_Entry) {0});
+ BX_CHECK(end <= b.begin + relocations.offset + relocations.size, "Buffer overflow", (Elf_Relx_Entry) {0});
i64 relx_offset = read_i64(LE, begin, end);
u32 relx_type = read_u32(LE, begin + 8, end);
i64 relx_sym = (i64) read_u32(LE, begin + 12, end);
i64 relx_addent = is_rela ? read_i64(LE, begin + 16, end) : 0;
- return (Relx_Entry) {
+ return (Elf_Relx_Entry) {
.symbol = elf_symbol(b, symbol_table, string_table, relx_sym),
.offset = relx_offset,
.type = relx_type,
@@ -2068,26 +2105,26 @@ Relx_Entry elf_relx(
};
}
-Symbol_Entry elf_find_symbol_by_name(
+Elf_Symbol_Entry elf_find_symbol_by_name(
Buffer_Context b,
i64 symbol_table_index,
Offset_Size string_table,
c8 * name,
i64 name_size
) {
- Section_Header symbol_table = elf_section(b, symbol_table_index);
+ Elf_Section_Header symbol_table = elf_section(b, symbol_table_index);
for (i64 i = 0; i < symbol_table.num_entries; ++i) {
- Symbol_Entry sym = elf_symbol(b, symbol_table.data, string_table, i);
+ Elf_Symbol_Entry sym = elf_symbol(b, symbol_table.data, string_table, i);
- BX_CHECK(b.begin + sym.name.offset + name_size <= b.end, "Buffer overflow", (Symbol_Entry) {0});
- BX_CHECK(sym.name.offset + name_size <= b.elf.size, "Buffer overflow", (Symbol_Entry) {0});
+ BX_CHECK(b.begin + sym.name.offset + name_size <= b.end, "Buffer overflow", (Elf_Symbol_Entry) {0});
+ BX_CHECK(sym.name.offset + name_size <= b.elf.size, "Buffer overflow", (Elf_Symbol_Entry) {0});
if (name_size == sym.name.size && bx_mem_eq(name, b.begin + sym.name.offset, name_size))
return sym;
}
- BX_FAIL("Not found", (Symbol_Entry) {0});
+ BX_FAIL("Not found", (Elf_Symbol_Entry) {0});
}
void elf_checks(Buffer_Context b) {
@@ -2125,7 +2162,7 @@ void elf_dump(u32 log_level, Buffer_Context b) {
Offset_Size symtab = elf_find_section_by_name(b, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data;
for (i64 sec_index = 1; sec_index < headers.num; ++sec_index) {
- Section_Header section = elf_section(b, sec_index);
+ Elf_Section_Header section = elf_section(b, sec_index);
c8 *name = elf_name_from_offset(b, section.name);
@@ -2155,7 +2192,7 @@ void elf_dump(u32 log_level, Buffer_Context b) {
BX_LOG(log_level, " - -");
for (i64 sym_index = 1; sym_index < section.num_entries; ++sym_index) {
- Symbol_Entry sym = elf_symbol(b, section.data, strtab, (u16) sym_index);
+ Elf_Symbol_Entry sym = elf_symbol(b, section.data, strtab, (u16) sym_index);
c8 *name = elf_name_from_offset(b, sym.name);
@@ -2194,7 +2231,7 @@ void elf_dump(u32 log_level, Buffer_Context b) {
BX_LOG(log_level, " - -");
for (i64 relx_index = 0; relx_index < section.num_entries; ++relx_index) {
- Relx_Entry relx = elf_relx(b, symtab, strtab, section.data, relx_index, section.type == SEC_RELA);
+ Elf_Relx_Entry relx = elf_relx(b, symtab, strtab, section.data, relx_index, section.type == SEC_RELA);
BX_LOG(
log_level,
@@ -2242,7 +2279,7 @@ i64 unit_write_in_memory(
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, codegen, 0, unit, arch);
+ emit_unit(pool, codegen, 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);
@@ -2251,12 +2288,12 @@ i64 unit_write_in_memory(
i64 rotext_address = base_address + program_offset;
i64 entry = rotext_address + codegen->entry_point;
- Internal_Symbol_Entry sym_printf = {0};
+ Symbol_Entry sym_printf = {0};
- i64 rotext_size = code_size;
+ i64 rotext_size = codegen->offset_code;
i64 rwzval_size = 0;
i64 rwdata_size = 0;
- i64 rodata_size = 0;
+ i64 rodata_size = codegen->offset_rodata;
i64 num_sections = 0;
i64 num_symbols = 0;
@@ -2279,7 +2316,7 @@ i64 unit_write_in_memory(
linker->section_addresses[num_sections] = 0;
- Section_Header section = elf_section(buf, sec_index);
+ Elf_Section_Header section = elf_section(buf, sec_index);
if (!section.alloc)
continue;
@@ -2321,19 +2358,19 @@ i64 unit_write_in_memory(
linker->section_addresses[sec_index_global] = 0;
- Section_Header section = elf_section(buf, sec_index);
+ Elf_Section_Header section = elf_section(buf, sec_index);
if (!section.alloc)
continue;
if (section.exec)
- linker->section_addresses[sec_index_global] += rotext_address + code_size;
+ linker->section_addresses[sec_index_global] += rotext_address + codegen->offset_code;
else if (section.write && section.type == SEC_NOBITS)
linker->section_addresses[sec_index_global] += rwzval_address;
else if (section.write)
linker->section_addresses[sec_index_global] += rwdata_address;
else if (section.data.size > 0)
- linker->section_addresses[sec_index_global] += rodata_address;
+ linker->section_addresses[sec_index_global] += rodata_address + codegen->offset_rodata;
}
}
@@ -2348,12 +2385,12 @@ i64 unit_write_in_memory(
Offset_Size strtab = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data;
for (i64 sec_index = 1; sec_index < headers.num; ++sec_index) {
- Section_Header tab = elf_section(buf, sec_index);
+ Elf_Section_Header tab = elf_section(buf, sec_index);
if (tab.type != SEC_SYMTAB)
continue;
for (i64 sym_index = 1; sym_index < tab.num_entries; ++sym_index) {
- Symbol_Entry sym = elf_symbol(buf, tab.data, strtab, sym_index);
+ Elf_Symbol_Entry sym = elf_symbol(buf, tab.data, strtab, sym_index);
c8 * sym_name = elf_name_from_offset(buf, sym.name);
if (sym.section == 0) // undefined symbol
@@ -2372,7 +2409,7 @@ i64 unit_write_in_memory(
BX_CHECK(num_symbols < linker->max_num_symbols, "Too many symbols",);
- linker->symbols[num_symbols++] = (Internal_Symbol_Entry) {
+ linker->symbols[num_symbols++] = (Symbol_Entry) {
.name_size = sym.name.size,
.name = sym_name,
.section = sym_section,
@@ -2453,7 +2490,7 @@ i64 unit_write_in_memory(
Offset_Size symtab = elf_find_section_by_name(buf, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data;
for (i64 sec_index = 1; sec_index < num_sections; ++sec_index, ++sec_index_global) {
- Section_Header src_sec = elf_section(buf, sec_index);
+ Elf_Section_Header src_sec = elf_section(buf, sec_index);
if (src_sec.type != SEC_REL && src_sec.type != SEC_RELA)
continue;
@@ -2462,11 +2499,11 @@ i64 unit_write_in_memory(
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);
+ Elf_Relx_Entry relx = elf_relx(buf, symtab, strtab, src_sec.data, entry_index, src_sec.type == SEC_RELA);
c8 *sym_name = elf_name_from_offset(buf, relx.symbol.name);
- Internal_Symbol_Entry symbol = {0};
+ Symbol_Entry symbol = {0};
if (relx.symbol.section == 0) {
for (i64 i = 0; i < num_symbols; ++i)
@@ -2492,7 +2529,7 @@ i64 unit_write_in_memory(
not_found_size += relx.symbol.name.size + 1;
}
} else
- symbol = (Internal_Symbol_Entry) {
+ symbol = (Symbol_Entry) {
.section = sec_index_global,
.address = relx.symbol.value.offset,
.size = relx.symbol.value.size,
@@ -2705,7 +2742,8 @@ i64 unit_write_in_memory(
// Code
//
- bx_mem_cpy(o + rotext_offset, codegen->code_buffer, code_size);
+ bx_mem_cpy(o + rotext_offset, codegen->buffer_code, codegen->offset_code);
+ bx_mem_cpy(o + rodata_offset, codegen->buffer_rodata, codegen->offset_rodata);
// ==============================================================
//
@@ -2716,13 +2754,13 @@ i64 unit_write_in_memory(
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);
+ Elf_Section_Header section = elf_section(buf, sec_index);
if (linker->section_addresses[sec_index] == 0 ||
!section.alloc ||
section.data.size == 0)
continue;
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 >= linker->output_buffer + program_offset + codegen->offset_code, "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);
}
@@ -2831,10 +2869,13 @@ void unit_write(
//
// Cleanup
+ codegen->num_rels = 0;
codegen->entry_point = 0;
linker->num_obj_files = 0;
- bx_mem_set(codegen->code_buffer, 0, codegen->max_code_size);
+ bx_mem_set(codegen->rels, 0, codegen->max_num_rels * sizeof *codegen->rels);
+ bx_mem_set(codegen->buffer_code, 0, codegen->max_code_size);
+ bx_mem_set(codegen->buffer_rodata, 0, codegen->max_rodata_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);
@@ -2987,7 +3028,7 @@ void bx_assert(b8 condition, c8 *message, u32 line, c8 *file) {
// IO dispatch procedure
//
-void io_dispatch(i16 op, i64 *id, i64 *size, void *data, void *user_data) {
+void io_dispatch(u16 op, i64 *id, i64 *size, void *data, void *user_data) {
BX_CHECK(id != NULL, "Invalid arguments",);
(void) user_data;
@@ -3089,9 +3130,18 @@ Pool g_pool = {
};
Codegen_Context g_codegen = {
- .max_code_size = MAX_CODE_SIZE,
- .entry_point = 0,
- .code_buffer = (u8[MAX_CODE_SIZE]) {0},
+ .max_num_rels = MAX_NUM_RELS,
+ .max_code_size = MAX_CODE_SIZE,
+ .max_rodata_size = MAX_CODE_SIZE,
+
+ .entry_point = 0,
+ .num_rels = 0,
+ .offset_code = 0,
+ .offset_rodata = 0,
+
+ .rels = (Rel_Entry[MAX_NUM_RELS]) {0},
+ .buffer_code = (u8[MAX_CODE_SIZE]) {0},
+ .buffer_rodata = (u8[MAX_CODE_SIZE]) {0},
};
Linker_Context g_linker = {
@@ -3103,15 +3153,15 @@ Linker_Context g_linker = {
.max_not_found_size = MAX_NOT_FOUND_SIZE,
.max_output_size = MAX_OUTPUT_SIZE,
- .num_obj_files = 0,
+ .num_obj_files = 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},
- .output_buffer = (u8[MAX_OUTPUT_SIZE]) {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 = (Symbol_Entry[MAX_NUM_SYMBOLS]) {0},
+ .not_found_buffer = (c8[MAX_NOT_FOUND_SIZE]) {0},
+ .output_buffer = (u8[MAX_OUTPUT_SIZE]) {0},
};
// Handy procedures
@@ -3130,13 +3180,13 @@ i64 n_i64(i64 proc, i64 value) {
return n;
}
-i64 n_call(i64 proc, i16 convention, i64 target_proc, i64 num_args, Var *args) {
+i64 n_call(i64 proc, u16 convention, i64 target_proc, i64 num_args, Var *args) {
i64 n = node_ctrl_call(&g_pool, convention, target_proc, num_args, args);
p_add(proc, n);
return n;
}
-i64 n_call_by_name(i64 proc, i16 convention, c8 *name, i64 num_args, Var *args) {
+i64 n_call_by_name(i64 proc, u16 convention, c8 *name, i64 num_args, Var *args) {
i64 n = node_ctrl_call_by_name(&g_pool, convention, bx_str_len(name, name + MAX_NAME_SIZE), name, num_args, args);
p_add(proc, n);
return n;