summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-30 05:42:17 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-30 05:42:17 +0200
commitbf90ea7800231d1d9ebe3f38f3aa716721fc29fa (patch)
treee5e2432cd8f8e7d48335adce7afcbab63374ade3
parent93e92c14448bbd804b805bbf0daae038b1145488 (diff)
downloadbxgen-bf90ea7800231d1d9ebe3f38f3aa716721fc29fa.zip
Codegen: call (incomplete)
-rwxr-xr-xbxgen.c71
1 files changed, 34 insertions, 37 deletions
diff --git a/bxgen.c b/bxgen.c
index 75033d8..848fd72 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -264,8 +264,9 @@ enum {
// Relocations
//
- REL_ADD_RODATA_ADDRESS = 0,
- REL_PROC_ADDRESS_RELATIVE,
+ REL_ADD_INSTRUCTION_ADDRESS,
+ REL_ADD_RODATA_ADDRESS,
+ REL_ADD_PROC_ADDRESS,
};
// TODO
@@ -1743,36 +1744,33 @@ void x86_64_emit_node(
// Write code and relocations
//
- write_u8(LE, 0x90, begin, end); // nop
- write_u8(LE, 0xbf, begin + 1, end); // mov edi
+ write_u8(LE, 0x48, begin, end); // movabs
+ write_u8(LE, 0xbf, begin + 1, end); // rdi
codegen->rels[codegen->num_rels++] = (Rel_Entry) {
.type = REL_ADD_RODATA_ADDRESS,
.offset = codegen->offset_code + 2,
- .size = 4,
+ .size = 8,
.value = arg_offset,
};
- write_u8(LE, 0x31, begin + 6, end); // xor eax
- write_u8(LE, 0xc0, begin + 7, end); // eax
- write_u8(LE, 0xe8, begin + 8, end); // call
+ write_u8(LE, 0x31, begin + 10, end); // xor eax
+ write_u8(LE, 0xc0, begin + 11, end); // eax
+ write_u8(LE, 0x48, begin + 12, end); // movabs
+ write_u8(LE, 0xba, begin + 13, end); // rdx
codegen->rels[codegen->num_rels++] = (Rel_Entry) {
- .type = REL_PROC_ADDRESS_RELATIVE,
- .offset = codegen->offset_code + 9,
- .size = 4,
+ .type = REL_ADD_PROC_ADDRESS,
+ .offset = codegen->offset_code + 14,
+ .size = 8,
.name_size = n->call.target_name_size,
.name = n->call.target_name,
};
- write_u8(LE, 0x90, begin + 13, end); // nop
+ write_u8(LE, 0xff, begin + 22, end); // call
+ write_u8(LE, 0xd2, begin + 23, end); // rdx
- // write_u8(LE, 0xeb, begin, end); // jmp
- // write_u8(LE, 0x0c, begin + 1, end); // 12
-
- codegen->offset_code += 14;
-
- BX_CHECK(codegen->offset_code <= codegen->max_code_size, "Out of memory", 0);
+ codegen->offset_code += 24;
} break;
case CTRL_RET: {
@@ -2365,7 +2363,7 @@ i64 unit_write_in_memory(
Buffer_Context buf = elf_buffer_context(pool, linker, linker->num_obj_files, elf_index);
elf_checks(buf);
- //elf_dump(VERBOSE, buf);
+ // elf_dump(VERBOSE, buf);
Offset_Num headers = elf_section_headers(buf);
@@ -2691,32 +2689,31 @@ i64 unit_write_in_memory(
u8 *end = codegen->buffer_code + codegen->offset_code;
switch (rel.type) {
- case REL_ADD_RODATA_ADDRESS: {
- BX_CHECK(rel.size == 4, "Not implemented", 0);
+ case REL_ADD_INSTRUCTION_ADDRESS: {
+ BX_CHECK(rel.size == 8, "Not implemented", 0);
+ i64 value = rel.value + rotext_address + rel.offset;
+ write_i64(LE, value, begin, end);
+ } break;
+ case REL_ADD_RODATA_ADDRESS: {
+ BX_CHECK(rel.size == 8, "Not implemented", 0);
i64 value = rel.value + rodata_address;
- BX_CHECK(value == (i64) (i32) value, "Integer overflow", 0);
- write_i32(LE, (i32) value, begin, end);
+ write_i64(LE, value, begin, end);
} break;
- case REL_PROC_ADDRESS_RELATIVE: {
- BX_CHECK(rel.size == 4, "Not implemented", 0);
+ case REL_ADD_PROC_ADDRESS: {
+ BX_CHECK(rel.size == 8, "Not implemented", 0);
BX_CHECK(rel.name_size > 0 && rel.name != NULL, "No proc name", 0);
b8 found = 0;
for (i64 i = 0; i < num_symbols; ++i)
- if (linker->symbols[i].name_size == rel.name_size &&
+ if (linker->symbols[i].section != 0 &&
+ linker->symbols[i].name_size == rel.name_size &&
bx_mem_eq(linker->symbols[i].name, rel.name, 6)) {
- i64 rel_address = rotext_address + rel.offset;
- i64 sym_address = linker->symbols[i].address;
- i64 value = sym_address - rel_address;
-
- BX_CHECK(value == (i64) (i32) value, "Integer overflow", 0);
-
- write_i32(LE, (i32) value, begin, end);
-
- BX_LOG(VERBOSE, "Found %.*s: %08llx (+%llx)", rel.name_size, rel.name, sym_address, value);
+ i64 value = rel.value + linker->symbols[i].address;
+ write_i64(LE, value, begin, end);
found = 1;
+ BX_LOG(VERBOSE, "Found %.*s: %08llx", rel.name_size, rel.name, value);
break;
}
@@ -3259,8 +3256,8 @@ Linker_Context g_linker = {
//
i64 n_str(i64 proc, c8 *value) {
- i64 len = bx_str_len(value, value + MAX_LITERAL_SIZE);
- i64 n_data = node_data_array_c8(&g_pool, len, value);
+ i64 len = bx_str_len(value, value + MAX_LITERAL_SIZE - 1);
+ i64 n_data = node_data_array_c8(&g_pool, len + 1, value);
i64 n_ref = node_data_reference(&g_pool, n_data);
p_add(proc, n_data);
p_add(proc, n_ref);