diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-07-30 07:44:34 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-07-30 07:44:34 +0200 |
commit | bddbecbe96a00f96db0b1e796e2314328d5f230b (patch) | |
tree | a0755aad1ddc2f620d0a0f749a99004b7ab2005e | |
parent | bf90ea7800231d1d9ebe3f38f3aa716721fc29fa (diff) | |
download | bxgen-bddbecbe96a00f96db0b1e796e2314328d5f230b.zip |
Fix offsets
-rwxr-xr-x | bxgen.c | 93 |
1 files changed, 57 insertions, 36 deletions
@@ -443,6 +443,7 @@ typedef struct { u8 * obj_file_buffer; u8 * dependencies_buffer; i64 * obj_file_offsets; + i64 * section_offsets; i64 * section_addresses; Symbol_Entry *symbols; c8 * not_found_buffer; @@ -2214,7 +2215,7 @@ void elf_checks(Buffer_Context b) { BX_LAX( read_u16(LE, begin + 58, end) == ELF_SECTION_HEADER_SIZE, "Invalid section header size"); } -void elf_dump(u32 log_level, Buffer_Context b) { +void elf_dump(u32 log_level, Buffer_Context b, b8 term_color) { Offset_Num headers = elf_section_headers(b); Offset_Size strtab = elf_find_section_by_name(b, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; Offset_Size symtab = elf_find_section_by_name(b, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data; @@ -2226,7 +2227,8 @@ void elf_dump(u32 log_level, Buffer_Context b) { BX_LOG( log_level, - "\"%s%s\x1b[37m\"%*s%-14s%s%s%s%s%lld%s", + "\"%s%s%s\"%*s%-14s%s%s%s%s%lld%s", + !term_color ? "" : section.type == SEC_SYMTAB || section.type == SEC_RELA || section.type == SEC_REL ? "\x1b[32m" : @@ -2234,6 +2236,7 @@ void elf_dump(u32 log_level, Buffer_Context b) { section.type == SEC_STRTAB ? "\x1b[33m" : "\x1b[31m", name, + !term_color ? "" : "\x1b[37m", (i32) (section.name.size < 30 ? 30 - section.name.size : 1), "", SEC_TYPE_NAMES[section.type], @@ -2258,15 +2261,20 @@ void elf_dump(u32 log_level, Buffer_Context b) { BX_LOG( log_level, - " %s%s%s\x1b[37m%s %.*s %s%-7s %s\x1b[37m", + " %08llx %-04llx %s%s%s%s%s %.*s %s%-7s %s%s", + section.data.offset + sym.value.offset, + sym.value.size, *name != '\0' ? "\"" : "", + !term_color ? "" : sym.bind == BIND_GLOBAL ? "\x1b[32m" : sym.bind == BIND_WEAK ? "\x1b[35m" : "\x1b[31m", *name != '\0' ? name : "<NONE>", + !term_color ? "" : "\x1b[37m", *name != '\0' ? "\"" : "", 31 < len ? 1 : 32 - len, 31 < len ? " " : "........................................", + !term_color ? "" : sym.type == SYM_PROC ? "\x1b[32m" : sym.type == SYM_DATA ? "\x1b[32m" : sym.type == SYM_COMMON ? "\x1b[33m" : @@ -2275,9 +2283,11 @@ void elf_dump(u32 log_level, Buffer_Context b) { sym.type == SYM_SPECIFIC ? "\x1b[31m" : "", SYM_TYPE_NAMES[sym.type], + !term_color ? (sym.section == 0 ? "undefined" : "") : sym.section == 0 ? ( sym.bind == BIND_GLOBAL || sym.bind == BIND_WEAK ? - "\x1b[33mundefined" : "\x1b[31mundefined") : "" + "\x1b[33mundefined" : "\x1b[31mundefined") : "", + !term_color ? "" : "\x1b[37m" ); } @@ -2293,12 +2303,15 @@ void elf_dump(u32 log_level, Buffer_Context b) { BX_LOG( log_level, - " %-16s %08llx %-+5lld <= %s%08llx\x1b[37m%s\x1b[37m \"%s\"", + " %-16s %08llx %-+5lld <= %s%08llx%s%s%s \"%s\"", REL_NAMES[relx.type], relx.offset, relx.addent, + !term_color ? "" : relx.symbol.bind == BIND_WEAK ? "\x1b[33m" : "\x1b[32m", relx.symbol.value.offset + elf_section(b, relx.symbol.section).data.offset, + !term_color ? "" : "\x1b[37m", + !term_color ? "" : relx.symbol.type == SYM_DATA ? " \x1b[34mdata" : relx.symbol.type == SYM_COMMON ? " \x1b[32mdata" : relx.symbol.type == SYM_TLS ? " \x1b[34mdata" : @@ -2306,6 +2319,7 @@ void elf_dump(u32 log_level, Buffer_Context b) { relx.symbol.type == SYM_SECTION ? " \x1b[36msect" : relx.symbol.type == SYM_SPECIFIC ? " \x1b[34mspec" : " \x1b[33mnone", + !term_color ? "" : "\x1b[37m", elf_name_from_offset(b, relx.symbol.name) ); } @@ -2346,6 +2360,8 @@ 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); + i64 rotext_size = codegen->offset_code; i64 rwzval_size = 0; i64 rwdata_size = 0; @@ -2363,30 +2379,31 @@ i64 unit_write_in_memory( Buffer_Context buf = elf_buffer_context(pool, linker, linker->num_obj_files, elf_index); elf_checks(buf); - // elf_dump(VERBOSE, buf); + // elf_dump(VERBOSE, buf, 1); 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",); - linker->section_addresses[num_sections] = 0; - Elf_Section_Header section = elf_section(buf, sec_index); - if (!section.alloc) + if (!section.alloc || section.data.size == 0) continue; if (section.exec) { + linker->section_offsets[num_sections] = rotext_size; linker->section_addresses[num_sections] = rotext_size; - rotext_size += bx_align(section.data.size, X86_64_ALIGNMENT); + 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; - rwzval_size += bx_align(section.data.size, X86_64_ALIGNMENT); + 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; - rwdata_size += bx_align(section.data.size, X86_64_ALIGNMENT); + 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; rodata_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else { @@ -2405,6 +2422,10 @@ i64 unit_write_in_memory( i64 rwdata_address = rwzval_address + rwzval_size; i64 rodata_address = rwdata_address + rwdata_size; + i64 rotext_offset = program_offset; + i64 rwdata_offset = rotext_offset + rotext_size; + i64 rodata_offset = rwdata_offset + rwdata_size; + for (i64 elf_index = 0, sec_index_global = 0; elf_index < linker->num_obj_files; ++elf_index) { Buffer_Context buf = elf_buffer_context(pool, linker, linker->num_obj_files, elf_index); Offset_Num headers = elf_section_headers(buf); @@ -2412,21 +2433,23 @@ i64 unit_write_in_memory( for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++sec_index_global) { BX_CHECK(sec_index_global < num_sections, "Buffer overflow",); - linker->section_addresses[sec_index_global] = 0; - Elf_Section_Header section = elf_section(buf, sec_index); - if (!section.alloc) + if (!section.alloc || section.data.size == 0) continue; - if (section.exec) + if (section.exec) { + linker->section_offsets[sec_index_global] += rotext_offset + codegen->offset_code; linker->section_addresses[sec_index_global] += rotext_address + codegen->offset_code; - else if (section.write && section.type == SEC_NOBITS) + } else if (section.write && section.type == SEC_NOBITS) { linker->section_addresses[sec_index_global] += rwzval_address; - else if (section.write) + } else if (section.write) { + linker->section_offsets[sec_index_global] += rwdata_offset; linker->section_addresses[sec_index_global] += rwdata_address; - else if (section.data.size > 0) + } else if (section.data.size > 0) { + linker->section_offsets[sec_index_global] += rodata_offset + codegen->offset_rodata; linker->section_addresses[sec_index_global] += rodata_address + codegen->offset_rodata; + } } } @@ -2447,7 +2470,7 @@ i64 unit_write_in_memory( for (i64 sym_index = 1; sym_index < tab.num_entries; ++sym_index) { Elf_Symbol_Entry sym = elf_symbol(buf, tab.data, strtab, sym_index); - c8 * sym_name = elf_name_from_offset(buf, sym.name); + c8 * sym_name = elf_name_from_offset(buf, sym.name); if (sym.section == 0) // undefined symbol continue; @@ -2457,9 +2480,10 @@ i64 unit_write_in_memory( i64 sym_section = 0; i64 sym_address = sym.value.offset; - if (sym.section != 65521) { + 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(linker->section_addresses[sym_section] != 0, "Sanity",); sym_address = linker->section_addresses[sym_section] + sym.value.offset; } @@ -2775,13 +2799,7 @@ i64 unit_write_in_memory( // Program headers // - i64 rotext_offset = program_offset; - i64 rwzval_offset = rotext_offset + rotext_size; - i64 rwdata_offset = rwzval_offset; - i64 rodata_offset = rwdata_offset + rwdata_size; - BX_CHECK(rotext_offset % X86_64_PAGE_SIZE == rotext_address % X86_64_PAGE_SIZE, "Invalid alignment",); - BX_CHECK(rwzval_offset % X86_64_PAGE_SIZE == rwzval_address % X86_64_PAGE_SIZE, "Invalid alignment",); BX_CHECK(rwdata_offset % X86_64_PAGE_SIZE == rwdata_address % X86_64_PAGE_SIZE, "Invalid alignment",); BX_CHECK(rodata_offset % X86_64_PAGE_SIZE == rodata_address % X86_64_PAGE_SIZE, "Invalid alignment",); @@ -2798,7 +2816,7 @@ i64 unit_write_in_memory( // .rwzval write_u32(LE, 1, o + 120, o_end); // type (PT_LOAD) write_u32(LE, 6, o + 124, o_end); // flags (PF_R | PF_W) - write_i64(LE, rwzval_offset, o + 128, o_end); + write_i64(LE, rwdata_offset, o + 128, o_end); write_i64(LE, rwzval_address, o + 136, o_end); // virtual address write_i64(LE, rwzval_address, o + 144, o_end); // phisical address write_i64(LE, 0, o + 152, o_end); // size in file @@ -2830,26 +2848,27 @@ i64 unit_write_in_memory( // Code // - bx_mem_cpy(o + rotext_offset, codegen->buffer_code, codegen->offset_code); + bx_mem_cpy(o + rotext_offset, codegen->buffer_code, codegen->offset_code); bx_mem_cpy(o + rodata_offset, codegen->buffer_rodata, codegen->offset_rodata); // ============================================================== // // Write sections into the output buffer - for (i64 elf_index = 0; elf_index < linker->num_obj_files; ++elf_index) { + for (i64 elf_index = 0, sec_index_global = 0; elf_index < linker->num_obj_files; ++elf_index) { Buffer_Context buf = elf_buffer_context(pool, linker, linker->num_obj_files, elf_index); Offset_Num headers = elf_section_headers(buf); - for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++num_sections) { + for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++sec_index_global) { Elf_Section_Header section = elf_section(buf, sec_index); - if (linker->section_addresses[sec_index] == 0 || - !section.alloc || + i64 offset = linker->section_offsets[sec_index_global]; + if (offset == 0 || + !section.alloc || section.data.size == 0) continue; - u8 *p = o + (linker->section_addresses[sec_index] - base_address); - BX_CHECK(p >= linker->output_buffer + program_offset + codegen->offset_code, "Buffer overflow",); - BX_CHECK(p + section.data.size <= linker->output_buffer + output_size, "Buffer overflow",); + u8 *p = o + offset; + BX_CHECK(p >= o + program_offset + codegen->offset_code, "Buffer overflow",); + BX_CHECK(p + section.data.size <= o + output_size, "Buffer overflow",); bx_mem_cpy(p, buf.begin + section.data.offset, section.data.size); } } @@ -2967,6 +2986,7 @@ void unit_write( bx_mem_set(linker->obj_file_buffer, 0, linker->max_obj_file_size); bx_mem_set(linker->dependencies_buffer, 0, linker->max_dependencies_size); bx_mem_set(linker->obj_file_offsets, 0, linker->max_num_obj_files * sizeof *linker->obj_file_offsets); + bx_mem_set(linker->section_offsets, 0, linker->max_num_sections * sizeof *linker->section_offsets); bx_mem_set(linker->section_addresses, 0, linker->max_num_sections * sizeof *linker->section_addresses); bx_mem_set(linker->symbols, 0, linker->max_num_symbols * sizeof *linker->symbols); bx_mem_set(linker->not_found_buffer, 0, linker->max_not_found_size); @@ -3246,6 +3266,7 @@ Linker_Context g_linker = { .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}, .section_addresses = (i64[MAX_NUM_SECTIONS]) {0}, .symbols = (Symbol_Entry[MAX_NUM_SYMBOLS]) {0}, .not_found_buffer = (c8[MAX_NOT_FOUND_SIZE]) {0}, |