summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-24 13:42:24 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-24 13:42:24 +0200
commitaa36c50a6b89d36ce7edefd23a833de141f5d2cc (patch)
tree6fb1de0e16981e16ef9ab51fefca903c71f14d6a
parent890e888ebc27c27f14580ac4bacde8a0ff9a5828 (diff)
downloadbxgen-aa36c50a6b89d36ce7edefd23a833de141f5d2cc.zip
Relocations
-rwxr-xr-xbxgen.c702
1 files changed, 249 insertions, 453 deletions
diff --git a/bxgen.c b/bxgen.c
index 2bc5e6a..6640ba7 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -158,11 +158,12 @@ enum {
STRING_TABLE_ALIGNMENT = 16, // TODO
+ // TEMP
MAX_NUM_OBJECT_FILES = 10 * 1024,
MAX_NUM_SECTIONS = 100 * 1024,
+ MAX_NUM_SYMBOLS = 200 * 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_PATH_SIZE = 10 * 1024,
MAX_LITERAL_SIZE = 400,
@@ -350,6 +351,13 @@ typedef struct {
};
} Entity;
+typedef struct {
+ i64 name_size;
+ c8 *name;
+ i64 section;
+ i64 address;
+} Internal_Symbol_Entry;
+
// Pool, a collection of all entities.
//
// NOTE
@@ -368,13 +376,13 @@ typedef struct {
i64 max_dependencies_size;
i64 max_num_obj_files;
i64 max_num_sections;
- i64 max_not_found_size;
+ i64 max_num_symbols;
- u8 * obj_file_buffer;
- u8 * dependencies_buffer;
- i64 *obj_file_offsets;
- i64 *section_offsets;
- c8 * not_found_buffer;
+ u8 * obj_file_buffer;
+ u8 * dependencies_buffer;
+ i64 * obj_file_offsets;
+ i64 * section_addresses;
+ Internal_Symbol_Entry *symbols;
} Pool;
// ================================================================
@@ -1573,14 +1581,8 @@ typedef struct {
Symbol_Entry symbol;
i64 dst;
u32 type;
-} Rel_Entry;
-
-typedef struct {
- Symbol_Entry symbol;
- i64 dst;
- u32 type;
i64 addent;
-} Rela_Entry;
+} Relx_Entry;
// ================================================================
@@ -1858,7 +1860,7 @@ Symbol_Entry elf_symbol(
};
}
-Rel_Entry elf_rel(
+Relx_Entry elf_rel(
Buffer_Context b,
Offset_Size symbol_table,
Offset_Size string_table,
@@ -1879,14 +1881,15 @@ Rel_Entry elf_rel(
BX_CHECK(rel_offset < dst.size, "Buffer overflow", (Rel_Entry) {0});
- return (Rel_Entry) {
+ return (Relx_Entry) {
.symbol = elf_symbol(b, symbol_table, string_table, rel_sym),
.dst = dst.offset + rel_offset,
.type = rel_type,
+ .addent = 0,
};
}
-Rela_Entry elf_rela(
+Relx_Entry elf_rela(
Buffer_Context b,
Offset_Size symbol_table,
Offset_Size string_table,
@@ -1908,7 +1911,7 @@ Rela_Entry elf_rela(
BX_CHECK(rela_offset < dst.size, "Buffer overflow", (Rel_Entry) {0});
- return (Rela_Entry) {
+ return (Relx_Entry) {
.symbol = elf_symbol(b, symbol_table, string_table, rela_sym),
.dst = dst.offset + rela_offset,
.type = rela_type,
@@ -2043,24 +2046,24 @@ void elf_dump(u32 log_level, Buffer_Context b) {
BX_LOG(log_level, " - -");
for (i64 rela_index = 0; rela_index < section.num_entries; ++rela_index) {
- Rela_Entry rela = elf_rela(b, symtab, strtab, section.data, dst, rela_index);
+ Relx_Entry relx = elf_rela(b, symtab, strtab, section.data, dst, rela_index);
BX_LOG(
log_level,
" %-16s %08llx %-+5lld <= %s%08llx\x1b[37m%s\x1b[37m \"%s\"",
- REL_NAMES[rela.type],
- rela.dst,
- rela.addent,
- rela.symbol.bind == BIND_WEAK ? "\x1b[33m" : "\x1b[32m",
- rela.symbol.value.offset + elf_section(b, rela.symbol.section).data.offset,
- rela.symbol.type == SYM_DATA ? " \x1b[34mdata" :
- rela.symbol.type == SYM_COMMON ? " \x1b[32mdata" :
- rela.symbol.type == SYM_TLS ? " \x1b[34mdata" :
- rela.symbol.type == SYM_PROC ? " \x1b[34mproc" :
- rela.symbol.type == SYM_SECTION ? " \x1b[36msect" :
- rela.symbol.type == SYM_SPECIFIC ? " \x1b[34mspec" :
+ REL_NAMES[relx.type],
+ relx.dst,
+ relx.addent,
+ relx.symbol.bind == BIND_WEAK ? "\x1b[33m" : "\x1b[32m",
+ relx.symbol.value.offset + elf_section(b, relx.symbol.section).data.offset,
+ relx.symbol.type == SYM_DATA ? " \x1b[34mdata" :
+ relx.symbol.type == SYM_COMMON ? " \x1b[32mdata" :
+ relx.symbol.type == SYM_TLS ? " \x1b[34mdata" :
+ relx.symbol.type == SYM_PROC ? " \x1b[34mproc" :
+ relx.symbol.type == SYM_SECTION ? " \x1b[36msect" :
+ relx.symbol.type == SYM_SPECIFIC ? " \x1b[34mspec" :
" \x1b[33mnone",
- elf_name_from_offset(b, rela.symbol.name)
+ elf_name_from_offset(b, relx.symbol.name)
);
}
@@ -2073,23 +2076,23 @@ void elf_dump(u32 log_level, Buffer_Context b) {
BX_LOG(log_level, " - -");
for (i64 rel_index = 0; rel_index < section.num_entries; ++rel_index) {
- Rel_Entry rel = elf_rel(b, symtab, strtab, section.data, dst, rel_index);
+ Relx_Entry relx = elf_rel(b, symtab, strtab, section.data, dst, rel_index);
BX_LOG(
log_level,
" %-16s %08llx <= %s%08llx\x1b[37m%s\x1b[37m \"%s\"",
- REL_NAMES[rel.type],
- rel.dst,
- rel.symbol.bind == BIND_WEAK ? "\x1b[33m" : "\x1b[32m",
- rel.symbol.value.offset + elf_section(b, rel.symbol.section).data.offset,
- rel.symbol.type == SYM_DATA ? " \x1b[34mdata" :
- rel.symbol.type == SYM_COMMON ? " \x1b[32mdata" :
- rel.symbol.type == SYM_TLS ? " \x1b[35mdata" :
- rel.symbol.type == SYM_PROC ? " \x1b[34mproc" :
- rel.symbol.type == SYM_SECTION ? " \x1b[36msect" :
- rel.symbol.type == SYM_SPECIFIC ? " \x1b[34mspec" :
+ REL_NAMES[relx.type],
+ relx.dst,
+ relx.symbol.bind == BIND_WEAK ? "\x1b[33m" : "\x1b[32m",
+ relx.symbol.value.offset + elf_section(b, relx.symbol.section).data.offset,
+ relx.symbol.type == SYM_DATA ? " \x1b[34mdata" :
+ relx.symbol.type == SYM_COMMON ? " \x1b[32mdata" :
+ relx.symbol.type == SYM_TLS ? " \x1b[35mdata" :
+ relx.symbol.type == SYM_PROC ? " \x1b[34mproc" :
+ relx.symbol.type == SYM_SECTION ? " \x1b[36msect" :
+ relx.symbol.type == SYM_SPECIFIC ? " \x1b[34mspec" :
" \x1b[33mnone",
- elf_name_from_offset(b, rel.symbol.name)
+ elf_name_from_offset(b, relx.symbol.name)
);
}
@@ -2112,7 +2115,6 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
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(pool->not_found_buffer != NULL, "No not found buffer",);
// ==============================================================
//
@@ -2147,7 +2149,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
i64 num_obj_files = 0;
i64 obj_files_size = 0;
- i64 not_found_size = 0;
+ i64 num_symbols = 0;
// Read all dependency files into the memory
//
@@ -2224,9 +2226,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
//
// Calculate section offsets
- i64 sec_index_global = 0;
-
- for (i64 elf_index = 0; elf_index < num_obj_files; ++elf_index) {
+ for (i64 elf_index = 0, sec_index_global = 0; elf_index < num_obj_files; ++elf_index) {
Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index);
elf_checks(buf);
@@ -2235,7 +2235,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
Offset_Num headers = elf_section_headers(buf);
for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++sec_index_global) {
- pool->section_offsets[sec_index_global] = 0;
+ pool->section_addresses[sec_index_global] = 0;
Section_Header section = elf_section(buf, sec_index);
@@ -2243,16 +2243,16 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
continue;
if (section.exec) {
- pool->section_offsets[sec_index_global] = text_size;
+ pool->section_addresses[sec_index_global] = base_address + data_offset + text_size;
text_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else if (section.write && section.type == SEC_NOBITS) {
- pool->section_offsets[sec_index_global] = bss_size;
+ pool->section_addresses[sec_index_global] = base_address + data_offset + bss_size;
bss_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else if (section.write) {
- pool->section_offsets[sec_index_global] = data_size;
+ pool->section_addresses[sec_index_global] = base_address + data_offset + data_size;
data_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else if (section.data.size > 0) {
- pool->section_offsets[sec_index_global] = rodata_size;
+ pool->section_addresses[sec_index_global] = base_address + data_offset + rodata_size;
rodata_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else {
BX_LAX(0, "Unsupported section type");
@@ -2265,9 +2265,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
//
// Relocate defined symbols
- sec_index_global = 0;
-
- for (i64 elf_index = 0; elf_index < num_obj_files; ++elf_index) {
+ for (i64 elf_index = 0, sec_index_global = 0; elf_index < num_obj_files; ++elf_index) {
Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index);
Offset_Num headers = elf_section_headers(buf);
@@ -2285,12 +2283,27 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
if (sym.section == 0) // undefined symbol
continue;
- i64 sec_index = sec_index_global + sym.section - 1;
- i64 sym_address = base_address + data_offset + pool->section_offsets[sec_index] + sym.value.offset;
+ i64 sym_section = sec_index_global + sym.section - 1;
+
+ BX_CHECK(sym_section < pool->max_num_sections, "Too many sections",);
+
+ i64 sym_address = pool->section_addresses[sym_section] + sym.value.offset;
+
+ BX_CHECK(num_symbols < pool->max_num_symbols, "Too many symbols",);
+
+ pool->symbols[num_symbols++] = (Internal_Symbol_Entry) {
+ .name_size = sym.name.size,
+ .name = sym_name,
+ .section = sym_section,
+ .address = sym_address,
+ };
u8 *begin = buf.begin + tab.data.offset + sym_index * ELF_SYMBOL_ENTRY_SIZE;
u8 *end = begin + tab.data.size;
+ if (end > buf.end)
+ end = buf.end;
+
write_i64(LE, sym_address, begin + 8, end);
}
}
@@ -2346,109 +2359,11 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
// __getf2
// __unordtf2
- // ==========================================================
- //
- // FIXME PERF Resolve undefined symbols
-
- BX_LOG(VERBOSE, "Resolve undefined symbols");
-
- sec_index_global = 0;
-
- for (i64 elf_index = 0; elf_index < num_obj_files; ++elf_index) {
- Buffer_Context buf = elf_buffer_context(pool, 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;
-
- for (i64 sec_index = 1; sec_index < num_sections; ++sec_index) {
- 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);
- c8 * sym_name = elf_name_from_offset(buf, sym.name);
-
- if (sym.section != 0 ||
- sym.bind == BIND_LOCAL)
- continue;
-
- // Global search for the symbol
- //
-
- i64 sec_index = 0;
- i64 offset = 0;
- b8 found = 0;
-
- // Check if the symbol is already saved as not found
- if (bx_find_str_in_table(pool->not_found_buffer, pool->not_found_buffer + not_found_size, sym_name, sym_name + sym.name.size) != NULL)
- continue;
-
- for (i64 search_index = 0; search_index < num_obj_files; ++search_index) {
- Buffer_Context search_buf = elf_buffer_context(pool, num_obj_files, search_index);
- Offset_Size search_strtab = elf_find_section_by_name(search_buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data;
- i64 search_num_sections = elf_section_headers(search_buf).num;
-
- for (i64 search_sec = 1; search_sec < search_num_sections; ++search_sec) {
- Section_Header search_symtab = elf_section(search_buf, search_sec);
- if (search_symtab.type != SEC_SYMTAB)
- continue;
-
- for (i64 k = 1; k < search_symtab.num_entries; ++k) {
- Symbol_Entry search_sym = elf_symbol(search_buf, search_symtab.data, search_strtab, k);
-
- if (search_sym.bind == BIND_LOCAL ||
- search_sym.section == 0 ||
- search_sym.name.size != sym.name.size)
- continue;
-
- c8 *search_name = elf_name_from_offset(search_buf, search_sym.name);
-
- if (!bx_mem_eq(sym_name, search_name, sym.name.size))
- continue;
-
- sec_index += search_sym.section - 1;
- offset = search_sym.value.offset;
- found = 1;
- break;
- }
-
- if (found)
- break;
- }
-
- if (found)
- break;
-
- sec_index += elf_section_headers(search_buf).num - 1;
- }
-
- if (!found) {
- BX_CHECK(not_found_size + sym.name.size + 1 < pool->max_not_found_size, "Out of memory",);
-
- bx_mem_cpy(pool->not_found_buffer + not_found_size, sym_name, sym.name.size);
- not_found_size += sym.name.size + 1;
- } else {
- u8 *begin = buf.begin + tab.data.offset + sym_index * ELF_SYMBOL_ENTRY_SIZE;
- u8 *end = begin + tab.data.size;
-
- i64 sym_address = base_address + data_offset + pool->section_offsets[sec_index] + sym.value.offset;
-
- write_i64(LE, sym_address, begin + 8, end);
- }
- }
- }
-
- sec_index_global += elf_section_headers(buf).num - 1;
- }
-
// ==============================================================
//
// TODO Apply relocations
- sec_index_global = 0;
-
- for (i64 elf_index = 0; elf_index < num_obj_files; ++elf_index) {
+ for (i64 elf_index = 0, sec_index_global = 0; elf_index < num_obj_files; ++elf_index) {
Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index);
i64 num_sections = elf_section_headers(buf).num;
@@ -2465,286 +2380,176 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
BX_CHECK(dst_index >= 0 && dst_index < pool->max_num_sections, "Buffer overflow",);
- switch (src_sec.type) {
- case SEC_REL: {
- for (i64 rel_index = 0; rel_index < src_sec.num_entries; ++rel_index) {
- Rel_Entry rel = elf_rel(buf, symtab, strtab, src_sec.data, dst, rel_index);
-
- switch (rel.type) {
- case R_X86_64_NONE: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PC32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOT32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PLT32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_COPY: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GLOB_DAT: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_JUMP_SLOT: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_RELATIVE: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPCREL: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_32S: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_16: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PC16: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_8: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PC8: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_DTPMOD64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_DTPOFF64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TPOFF64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TLSGD: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TLSLD: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_DTPOFF32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTTPOFF: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TPOFF32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PC64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTOFF64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPC32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOT64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPCREL64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPC64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPLT64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PLTOFF64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_SIZE32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_SIZE64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPC32_TLSDESC: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TLSDESC_CALL: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TLSDESC: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_IRELATIVE: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_RELATIVE64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPCRELX: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_REX_GOTPCRELX: {
- BX_FAIL("Not implemented",);
- } break;
- default:
- BX_LAX(0, "Unknown relocation type");
- }
- }
- } break;
-
- case SEC_RELA: {
- for (i64 rela_index = 0; rela_index < src_sec.num_entries; ++rela_index) {
- Rela_Entry rela = elf_rela(buf, symtab, strtab, src_sec.data, dst, rela_index);
-
- switch (rela.type) {
- case R_X86_64_NONE: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_64: {
- // TODO
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PC32: {
- // TODO
- i64 x =
- read_i32(LE, buf.begin + dst.offset, buf.end) +
- rela.symbol.value.offset + rela.addent;
- write_i32(LE, x, buf.begin + dst.offset, buf.end);
- } break;
- case R_X86_64_GOT32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PLT32: {
- // TODO
- i64 x =
- read_i32(LE, buf.begin + dst.offset, buf.end) +
- rela.symbol.value.offset + rela.addent;
- write_i32(LE, x, buf.begin + dst.offset, buf.end);
- } break;
- case R_X86_64_COPY: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GLOB_DAT: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_JUMP_SLOT: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_RELATIVE: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPCREL: {
- // TODO
- //BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_32S: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_16: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PC16: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_8: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PC8: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_DTPMOD64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_DTPOFF64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TPOFF64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TLSGD: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TLSLD: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_DTPOFF32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTTPOFF: {
- // TODO
- //BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TPOFF32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PC64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTOFF64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPC32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOT64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPCREL64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPC64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPLT64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_PLTOFF64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_SIZE32: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_SIZE64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPC32_TLSDESC: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TLSDESC_CALL: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_TLSDESC: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_IRELATIVE: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_RELATIVE64: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_GOTPCRELX: {
- BX_FAIL("Not implemented",);
- } break;
- case R_X86_64_REX_GOTPCRELX: {
- // TODO
- //BX_FAIL("Not implemented",);
- } break;
- default:
- BX_LAX(0, "Unknown relocation type");
+ for (i64 entry_index = 0; entry_index < src_sec.num_entries; ++entry_index) {
+ Relx_Entry relx = (src_sec.type == SEC_REL) ?
+ elf_rel (buf, symtab, strtab, src_sec.data, dst, entry_index) :
+ elf_rela(buf, symtab, strtab, src_sec.data, dst, entry_index);
+
+ c8 *sym_name = elf_name_from_offset(buf, relx.symbol.name);
+
+ Internal_Symbol_Entry symbol = {0};
+
+ if (relx.symbol.section == 0) {
+ for (i64 i = 0; i < num_symbols; ++i)
+ if (pool->symbols[i].name_size == relx.symbol.name.size && bx_mem_eq(pool->symbols[i].name, sym_name, relx.symbol.name.size)) {
+ symbol = pool->symbols[i];
+ break;
}
- }
- } break;
+ if (symbol.name_size == 0)
+ BX_LOG(WARNING, "Symbol not found: %s", sym_name);
+ } else
+ symbol = (Internal_Symbol_Entry) {
+ .section = sec_index_global,
+ .address = relx.symbol.value.offset,
+ };
+
+ switch (relx.type) {
+ // val = symbol.value.offset
+ case R_X86_64_NONE: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_64: {
+ // TODO
+ i64 x =
+ read_i64(LE, buf.begin + dst.offset, buf.end) +
+ symbol.address + relx.addent;
+ write_i64(LE, x, buf.begin + dst.offset, buf.end);
+ } break;
+ case R_X86_64_PC32: {
+ // TODO
+ i64 x =
+ read_i32(LE, buf.begin + dst.offset, buf.end) +
+ symbol.address + relx.addent;
+ write_i32(LE, (i32) x, buf.begin + dst.offset, buf.end);
+ } break;
+ case R_X86_64_GOT32: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_PLT32: {
+ // TODO
+ i64 x =
+ read_i32(LE, buf.begin + dst.offset, buf.end) +
+ symbol.address + relx.addent;
+ write_i32(LE, (i32) x, buf.begin + dst.offset, buf.end);
+ } break;
+ case R_X86_64_COPY: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GLOB_DAT: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_JUMP_SLOT: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_RELATIVE: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOTPCREL: {
+ // TODO
+ //BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_32: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_32S: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_16: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_PC16: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_8: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_PC8: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_DTPMOD64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_DTPOFF64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_TPOFF64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_TLSGD: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_TLSLD: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_DTPOFF32: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOTTPOFF: {
+ // TODO
+ //BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_TPOFF32: {
+ // TODO
+ i64 x =
+ read_i32(LE, buf.begin + dst.offset, buf.end) +
+ symbol.address + relx.addent - pool->section_addresses[symbol.section];
+ write_i32(LE, (i32) x, buf.begin + dst.offset, buf.end);
+ } break;
+ case R_X86_64_PC64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOTOFF64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOTPC32: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOT64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOTPCREL64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOTPC64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOTPLT64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_PLTOFF64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_SIZE32: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_SIZE64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOTPC32_TLSDESC: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_TLSDESC_CALL: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_TLSDESC: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_IRELATIVE: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_RELATIVE64: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_GOTPCRELX: {
+ BX_FAIL("Not implemented",);
+ } break;
+ case R_X86_64_REX_GOTPCRELX: {
+ // TODO
+ //BX_FAIL("Not implemented",);
+ } break;
+ default:
+ BX_LAX(0, "Unknown relocation type");
+ }
}
}
}
@@ -2798,15 +2603,6 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
BX_LOG(VERBOSE, ".data - %lld bytes", data_size);
BX_LOG(VERBOSE, ".rodata - %lld bytes", rodata_size);
- if (not_found_size > 0) {
- BX_LOG(ERROR, "Symbols not found");
- BX_LOG(VERBOSE, "");
- c8 *s_end = pool->not_found_buffer + not_found_size;
- for (c8 *s = pool->not_found_buffer; s < s_end; s += bx_str_len(s, s_end) + 1)
- BX_LOG(VERBOSE, "%s", s);
- BX_LOG(VERBOSE, "");
- }
-
BX_CHECK(sym_printf.section != 0, "Symbol not found: printf",);
BX_LOG(VERBOSE, "Found printf: %08llx", sym_printf.value.offset);
@@ -2880,8 +2676,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data
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_offsets, 0, pool->max_num_sections * sizeof *pool->section_offsets);
- bx_mem_set(pool->not_found_buffer, 0, pool->max_not_found_size);
+ 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);
}
i64 io_open_read(i64 name_size, c8 *name, void *user_data) {
@@ -3131,13 +2927,13 @@ Pool g_pool = {
.max_dependencies_size = MAX_DEPENDENCIES_SIZE,
.max_num_obj_files = MAX_NUM_OBJECT_FILES,
.max_num_sections = MAX_NUM_SECTIONS,
- .max_not_found_size = MAX_NOT_FOUND_SIZE,
+ .max_num_symbols = MAX_NUM_SYMBOLS,
- .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_offsets = (i64[MAX_NUM_SECTIONS]) {0},
- .not_found_buffer = (c8[MAX_NOT_FOUND_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 = (Internal_Symbol_Entry[MAX_NUM_SYMBOLS]) {0},
};
// Handy procedures