From aa36c50a6b89d36ce7edefd23a833de141f5d2cc Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Wed, 24 Jul 2024 13:42:24 +0200 Subject: Relocations --- bxgen.c | 702 +++++++++++++++++++++++----------------------------------------- 1 file changed, 249 insertions(+), 453 deletions(-) (limited to 'bxgen.c') 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; // ================================================================ @@ -1569,18 +1577,12 @@ typedef struct { Offset_Size value; } Symbol_Entry; -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 -- cgit v1.2.3