summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-30 07:44:34 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-30 07:44:34 +0200
commitbddbecbe96a00f96db0b1e796e2314328d5f230b (patch)
treea0755aad1ddc2f620d0a0f749a99004b7ab2005e
parentbf90ea7800231d1d9ebe3f38f3aa716721fc29fa (diff)
downloadbxgen-bddbecbe96a00f96db0b1e796e2314328d5f230b.zip
Fix offsets
-rwxr-xr-xbxgen.c93
1 files changed, 57 insertions, 36 deletions
diff --git a/bxgen.c b/bxgen.c
index 848fd72..3496802 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -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},