summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-30 08:50:02 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-30 08:50:02 +0200
commit702dd8de2aa8341f5abf3e9f014d9c7e74ac0f63 (patch)
treeea5e7d4009aaf435c3700a43f1967411b5a4960e
parentbddbecbe96a00f96db0b1e796e2314328d5f230b (diff)
downloadbxgen-702dd8de2aa8341f5abf3e9f014d9c7e74ac0f63.zip
Fix section index in relocations
-rwxr-xr-xbxgen.c104
1 files changed, 55 insertions, 49 deletions
diff --git a/bxgen.c b/bxgen.c
index 3496802..fb07827 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -2360,16 +2360,16 @@ i64 unit_write_in_memory(
i64 rotext_address = base_address + program_offset;
i64 entry = rotext_address + codegen->entry_point;
- BX_LOG(VERBOSE, "Entry point: %08llx", entry);
+ BX_LOG(VERBOSE, "Entry point: %08llx (%lld)", entry, entry);
i64 rotext_size = codegen->offset_code;
i64 rwzval_size = 0;
i64 rwdata_size = 0;
i64 rodata_size = codegen->offset_rodata;
- i64 num_sections = 0;
- i64 num_symbols = 0;
- i64 not_found_size = 0;
+ i64 num_sections_total = 0;
+ i64 num_symbols = 0;
+ i64 not_found_size = 0;
// ==========================================================
//
@@ -2383,8 +2383,8 @@ i64 unit_write_in_memory(
Offset_Num headers = elf_section_headers(buf);
- for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++num_sections) {
- BX_CHECK(num_sections < linker->max_num_sections, "Too many sections",);
+ for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++num_sections_total) {
+ BX_CHECK(num_sections_total < linker->max_num_sections, "Too many sections",);
Elf_Section_Header section = elf_section(buf, sec_index);
@@ -2392,19 +2392,19 @@ i64 unit_write_in_memory(
continue;
if (section.exec) {
- linker->section_offsets[num_sections] = rotext_size;
- linker->section_addresses[num_sections] = rotext_size;
+ linker->section_offsets[num_sections_total] = rotext_size;
+ linker->section_addresses[num_sections_total] = rotext_size;
rotext_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else if (section.write && section.type == SEC_NOBITS) {
- linker->section_addresses[num_sections] = rwzval_size;
+ linker->section_addresses[num_sections_total] = rwzval_size;
rwzval_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else if (section.write) {
- linker->section_offsets[num_sections] = rwdata_size;
- linker->section_addresses[num_sections] = rwdata_size;
+ linker->section_offsets[num_sections_total] = rwdata_size;
+ linker->section_addresses[num_sections_total] = rwdata_size;
rwdata_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else if (section.data.size > 0) {
- linker->section_offsets[num_sections] = rodata_size;
- linker->section_addresses[num_sections] = rodata_size;
+ linker->section_offsets[num_sections_total] = rodata_size;
+ linker->section_addresses[num_sections_total] = rodata_size;
rodata_size += bx_align(section.data.size, X86_64_ALIGNMENT);
} else {
BX_LAX(0, "Unsupported section type");
@@ -2431,7 +2431,7 @@ i64 unit_write_in_memory(
Offset_Num headers = elf_section_headers(buf);
for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++sec_index_global) {
- BX_CHECK(sec_index_global < num_sections, "Buffer overflow",);
+ BX_CHECK(sec_index_global < num_sections_total, "Buffer overflow",);
Elf_Section_Header section = elf_section(buf, sec_index);
@@ -2482,7 +2482,7 @@ i64 unit_write_in_memory(
if (sym.section != 65521 && elf_section(buf, sym.section).alloc) {
sym_section = sec_index_global + sym.section - 1;
- BX_CHECK(sym_section < num_sections, "Buffer overflow",);
+ BX_CHECK(sym_section < num_sections_total, "Buffer overflow",);
BX_CHECK(linker->section_addresses[sym_section] != 0, "Sanity",);
sym_address = linker->section_addresses[sym_section] + sym.value.offset;
}
@@ -2569,14 +2569,15 @@ i64 unit_write_in_memory(
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) {
+ for (i64 sec_index = 1; sec_index < num_sections; ++sec_index) {
Elf_Section_Header src_sec = elf_section(buf, sec_index);
if (src_sec.type != SEC_REL && src_sec.type != SEC_RELA)
continue;
- i64 dst_index = elf_find_related_section_index(buf, sec_index);
+ i64 dst_index = elf_find_related_section_index(buf, sec_index);
+ i64 dst_index_global = sec_index_global + dst_index - 1;
- BX_CHECK(dst_index >= 0 && dst_index < linker->max_num_sections, "Buffer overflow",);
+ BX_CHECK(dst_index_global >= 0 && dst_index_global < linker->max_num_sections, "Buffer overflow",);
for (i64 entry_index = 0; entry_index < src_sec.num_entries; ++entry_index) {
Elf_Relx_Entry relx = elf_relx(buf, symtab, strtab, src_sec.data, entry_index, src_sec.type == SEC_RELA);
@@ -2603,7 +2604,8 @@ i64 unit_write_in_memory(
sym_name,
sym_name + relx.symbol.name.size
) == NULL) {
- BX_LOG(WARNING, "Undefined symbol: %s", sym_name);
+ // FIXME
+ // BX_LOG(WARNING, "Undefined symbol: %s", sym_name);
BX_CHECK(not_found_size + relx.symbol.name.size + 1 <= linker->max_not_found_size, "Out of memory",);
bx_mem_cpy(linker->not_found_buffer + not_found_size, sym_name, relx.symbol.name.size);
not_found_size += relx.symbol.name.size + 1;
@@ -2623,19 +2625,19 @@ i64 unit_write_in_memory(
i64 A = relx.addent;
// Represents the base address at which a shared object has been loaded into memory during execution. Generally, a shared object is built with a 0 base virtual address, but the execution address will be different.
- i64 B = linker->section_addresses[dst_index];
+ i64 B = linker->section_addresses[dst_index_global];
// Represents the offset into the global offset table at which the relocation entry's symbol will reside during execution.
- i64 G = symbol.address - base_address - program_offset;
+ i64 G = 0;
// Represents the address of the global offset table.
- i64 GOT = base_address + program_offset;
+ i64 GOT = 0;
// Represents the place (section offset or address) of the Procedure Linkage Table entry for a symbol.
- i64 L = base_address + program_offset;
+ i64 L = 0;
// Represents the place (section offset or address) of the storage unit being relocated (computed using r_offset).
- i64 P = linker->section_addresses[dst_index] + relx.offset;
+ i64 P = linker->section_addresses[dst_index_global] + relx.offset;
// Represents the value of the symbol whose index resides in the relocation entry.
i64 S = symbol.address;
@@ -2653,46 +2655,46 @@ i64 unit_write_in_memory(
#define TODO_ BX_FAIL("Not implemented", 0)
case R_X86_64_NONE: /* Do nothing */ break;
- case R_X86_64_64: ADD_(64, S + A); break;
- case R_X86_64_PC32: ADD_(32, S + A - P); break;
- case R_X86_64_GOT32: ADD_(32, G + A); break;
- case R_X86_64_PLT32: ADD_(32, L + A - P); break;
+ case R_X86_64_64: ADD_(64, 0); break; // 64, S + A
+ case R_X86_64_PC32: ADD_(32, 0); break; // 32, S + A - P
+ case R_X86_64_GOT32: TODO_; break; // 32, G + A
+ case R_X86_64_PLT32: ADD_(32, S + A - P); break; // 32, L + A - P
case R_X86_64_COPY: /* Do nothing */ break;
- case R_X86_64_GLOB_DAT: ADD_(64, S); break;
- case R_X86_64_JUMP_SLOT: ADD_(64, S); break;
- case R_X86_64_RELATIVE: ADD_(64, B + A); break;
- case R_X86_64_GOTPCREL: ADD_(32, G + GOT + A - P); break;
- case R_X86_64_32: ADD_(32, S + A); break;
- case R_X86_64_32S: ADD_(32, S + A); break;
- case R_X86_64_16: ADD_(16, S + A); break;
- case R_X86_64_PC16: ADD_(16, S + A - P); break;
- case R_X86_64_8: ADD_(8, S + A); break;
- case R_X86_64_PC8: ADD_(8, S + A - P); break;
+ case R_X86_64_GLOB_DAT: TODO_; break; // 64, S
+ case R_X86_64_JUMP_SLOT: TODO_; break; // 64, S
+ case R_X86_64_RELATIVE: TODO_; break; // 64, B + A
+ case R_X86_64_GOTPCREL: ADD_(32, 0); break; // 32, G + GOT + A - P
+ case R_X86_64_32: TODO_; break; // 32, S + A
+ case R_X86_64_32S: TODO_; break; // 32, S + A
+ case R_X86_64_16: TODO_; break; // 16, S + A
+ case R_X86_64_PC16: TODO_; break; // 16, S + A - P
+ case R_X86_64_8: TODO_; break; // 8, S + A
+ case R_X86_64_PC8: TODO_; break; // 8, S + A - P
case R_X86_64_DTPMOD64: TODO_; break;
case R_X86_64_DTPOFF64: TODO_; break;
case R_X86_64_TPOFF64: TODO_; break;
case R_X86_64_TLSGD: TODO_; break;
case R_X86_64_TLSLD: TODO_; break;
case R_X86_64_DTPOFF32: TODO_; break;
- case R_X86_64_GOTTPOFF: ADD_(32, S - GOT); break;
- case R_X86_64_TPOFF32: ADD_(32, S + A - B); break;
- case R_X86_64_PC64: ADD_(64, S + A - P); break;
+ case R_X86_64_GOTTPOFF: ADD_(32, 0); break; // 32, S - GOT
+ case R_X86_64_TPOFF32: ADD_(32, 0); break; // 32, S + A - B
+ case R_X86_64_PC64: TODO_; break; // 64, S + A - P
case R_X86_64_GOTOFF64: TODO_; break;
- case R_X86_64_GOTPC32: ADD_(32, GOT + A - P); break;
+ case R_X86_64_GOTPC32: TODO_; break; // 32, GOT + A - P
case R_X86_64_GOT64: TODO_; break;
case R_X86_64_GOTPCREL64: TODO_; break;
- case R_X86_64_GOTPC64: ADD_(64, GOT + A - P); break;
+ case R_X86_64_GOTPC64: TODO_; break; // 64, GOT + A - P
case R_X86_64_GOTPLT64: TODO_; break;
case R_X86_64_PLTOFF64: TODO_; break;
- case R_X86_64_SIZE32: ADD_(32, Z + A); break;
- case R_X86_64_SIZE64: ADD_(64, Z + A); break;
+ case R_X86_64_SIZE32: TODO_; break; // 32, Z + A
+ case R_X86_64_SIZE64: TODO_; break; // 64, Z + A
case R_X86_64_GOTPC32_TLSDESC: TODO_; break;
case R_X86_64_TLSDESC_CALL: TODO_; break;
case R_X86_64_TLSDESC: TODO_; break;
case R_X86_64_IRELATIVE: TODO_; break;
case R_X86_64_RELATIVE64: TODO_; break;
case R_X86_64_GOTPCRELX: TODO_; break;
- case R_X86_64_REX_GOTPCRELX: ADD_(32, GOT - P + G - 4); break;
+ case R_X86_64_REX_GOTPCRELX: ADD_(32, 0); break; // 32, GOT - P + G - 4
default: BX_LAX(0, "Unknown relocation type");
#undef ADD_
@@ -2700,6 +2702,8 @@ i64 unit_write_in_memory(
}
}
}
+
+ sec_index_global += num_sections - 1;
}
// ==============================================================
@@ -2741,8 +2745,10 @@ i64 unit_write_in_memory(
break;
}
- if (!found)
+ if (!found) {
BX_LOG(ERROR, "Undefined symbol: %.*s", rel.name_size, rel.name);
+ BX_FAIL("Link failed", 0);
+ }
} break;
}
}
@@ -2756,7 +2762,7 @@ i64 unit_write_in_memory(
BX_CHECK(output_size <= linker->max_output_size, "Out of memory",);
- BX_LOG(VERBOSE, "Total %lld sections", num_sections);
+ BX_LOG(VERBOSE, "Total %lld sections", num_sections_total);
BX_LOG(VERBOSE, "Total %lld symbols", num_symbols);
BX_LOG(VERBOSE, "Total size");
@@ -3422,7 +3428,7 @@ int main(int argc, char **argv) {
n_call_by_name(
mainproc,
CONV_CDECL, // calling convention
- "printf", // proc name
+ "_IO_puts", // proc name
1, // number of arguments
(Var[]) {{
.node = n_str(mainproc, "hello sailor"), // the first argument