From 366bfa14cd2c93a8ec9b5b855bcb031c51742b6b Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Wed, 24 Jul 2024 08:18:50 +0200 Subject: Relocations (incomplete) --- bxgen.c | 329 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 305 insertions(+), 24 deletions(-) (limited to 'bxgen.c') diff --git a/bxgen.c b/bxgen.c index 03ea30d..d478699 100755 --- a/bxgen.c +++ b/bxgen.c @@ -1050,7 +1050,7 @@ void check_f32_format() { return; if ((*(u64 *) &(f64) { -1.4575323640233e-306 } & 0xffffffff00000000ull) == 0x40301fcb00000000ull) return; - + BX_FAIL("Unknown host floating-point number format",); } @@ -1776,7 +1776,7 @@ c8 *elf_name_from_offset( return begin; } -Offset_Size elf_find_related_data( +i64 elf_find_related_section_index( Buffer_Context b, i64 section_index ) { @@ -1788,7 +1788,7 @@ Offset_Size elf_find_related_data( elf_name_from_offset(b, src_name) + (src_name.size - dst.name.size), elf_name_from_offset(b, dst.name), dst.name.size)) - return dst.data; + return section_index - 1; i64 num_sections = elf_section_headers(b).num; @@ -1801,12 +1801,19 @@ Offset_Size elf_find_related_data( elf_name_from_offset(b, src_name) + (src_name.size - dst.name.size), elf_name_from_offset(b, dst.name), dst.name.size)) { - BX_LOG(WARNING, "Unexpected sections order"); - return dst.data; + BX_LOG(WARNING, "Unexpected section order"); + return i; } } - BX_FAIL("Not found", (Offset_Size) {0}); + BX_FAIL("Not found", 0); +} + +Offset_Size elf_find_related_data( + Buffer_Context b, + i64 section_index +) { + return elf_section(b, elf_find_related_section_index(b, section_index)).data; } Symbol_Entry elf_symbol( @@ -1960,14 +1967,6 @@ void elf_checks(Buffer_Context b) { BX_LAX( read_u16(LE, begin + 58, end) == ELF_SECTION_HEADER_SIZE, "Invalid section header size"); } -void elf_apply_relocations( - Buffer_Context b, - i64 sec_index, - i64 dst_address -) { - //BX_LOG(WARNING, "TODO"); -} - void elf_dump(u32 log_level, Buffer_Context b) { Offset_Num headers = elf_section_headers(b); Offset_Size strtab = elf_find_section_by_name(b, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; @@ -2286,12 +2285,13 @@ 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 sec_index = sec_index_global + sym.section - 1; + i64 sym_address = base_address + data_offset + pool->section_offsets[sec_index] + sym.value.offset; u8 *begin = buf.begin + tab.data.offset + sym_index * ELF_SYMBOL_ENTRY_SIZE; u8 *end = begin + tab.data.size; - write_i64(LE, pool->section_offsets[sec_index] + sym.value.offset, begin + 8, end); + write_i64(LE, sym_address, begin + 8, end); } } @@ -2406,7 +2406,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data 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; @@ -2419,7 +2419,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data if (found) break; - + sec_index += elf_section_headers(search_buf).num - 1; } @@ -2447,13 +2447,294 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data 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); + Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index); + i64 num_sections = elf_section_headers(buf).num; - Offset_Num headers = elf_section_headers(buf); + Offset_Size strtab = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + 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); + if (src_sec.type != SEC_REL && src_sec.type != SEC_RELA) + continue; - for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++sec_index_global) - if (elf_section(buf, sec_index).alloc) - elf_apply_relocations(buf, sec_index, base_address + pool->section_offsets[sec_index_global]); + i64 dst_index = elf_find_related_section_index(buf, sec_index); + Offset_Size dst = elf_section(buf, dst_index).data; + + BX_CHECK(dst_index >= 0 && dst_index < pool->max_num_sections, "Buffer overflow",); + + i64 dst_address = base_address + data_offset + pool->section_offsets[dst_index]; + + 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: { + 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; + } + } } // ============================================================== @@ -2469,7 +2750,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data Section_Header section = elf_section(buf, sec_index); if (section.type != SEC_SYMTAB) continue; - + for (i64 sym_index = 1; sym_index < section.num_entries; ++sym_index) { Symbol_Entry sym = elf_symbol(buf, section.data, strtab, (u16) sym_index); -- cgit v1.2.3