diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-07-30 08:50:02 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-07-30 08:50:02 +0200 |
commit | 702dd8de2aa8341f5abf3e9f014d9c7e74ac0f63 (patch) | |
tree | ea5e7d4009aaf435c3700a43f1967411b5a4960e | |
parent | bddbecbe96a00f96db0b1e796e2314328d5f230b (diff) | |
download | bxgen-702dd8de2aa8341f5abf3e9f014d9c7e74ac0f63.zip |
Fix section index in relocations
-rwxr-xr-x | bxgen.c | 104 |
1 files changed, 55 insertions, 49 deletions
@@ -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 |