summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-24 08:18:50 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-24 08:18:50 +0200
commit366bfa14cd2c93a8ec9b5b855bcb031c51742b6b (patch)
tree586d9c0fad244a551fce818f176302f9f7ad1faf
parente818389ae98b92ad1933549d80736d682f4dbf15 (diff)
downloadbxgen-366bfa14cd2c93a8ec9b5b855bcb031c51742b6b.zip
Relocations (incomplete)
-rwxr-xr-xbxgen.c329
1 files changed, 305 insertions, 24 deletions
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);