diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-07-24 14:06:09 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-07-24 14:06:09 +0200 |
commit | 9b62cc97013793eb69d8afdc7e5cb8398b52bfc5 (patch) | |
tree | 848149c4d4171f781a098aa815cc1501ae9aad8f | |
parent | aa36c50a6b89d36ce7edefd23a833de141f5d2cc (diff) | |
download | bxgen-9b62cc97013793eb69d8afdc7e5cb8398b52bfc5.zip |
Not found buffer
-rwxr-xr-x | bxgen.c | 80 |
1 files changed, 39 insertions, 41 deletions
@@ -41,6 +41,7 @@ #/ - Optimization layers #/ - Multithreading #/ - Memory reallocation when necessary +#/ - C compiler and self-compilation #/ - JIT #/ - COFF, PE, OMF, Mach-O #/ - i386, RISC-V, ARM, WebAssembly @@ -160,10 +161,11 @@ enum { // TEMP MAX_NUM_OBJECT_FILES = 10 * 1024, - MAX_NUM_SECTIONS = 100 * 1024, - MAX_NUM_SYMBOLS = 200 * 1024, + MAX_NUM_SECTIONS = 2 * 1024 * 1024, + MAX_NUM_SYMBOLS = 2 * 1024 * 1024, MAX_OBJECT_FILE_SIZE = 10 * 1024 * 1024, // 10 MB MAX_DEPENDENCIES_SIZE = 50 * 1024 * 1024, // 50 MB + MAX_NOT_FOUND_SIZE = 10 * 1024, // 10 KB MAX_PATH_SIZE = 10 * 1024, MAX_LITERAL_SIZE = 400, @@ -377,12 +379,14 @@ typedef struct { i64 max_num_obj_files; i64 max_num_sections; i64 max_num_symbols; + i64 max_not_found_size; u8 * obj_file_buffer; u8 * dependencies_buffer; i64 * obj_file_offsets; i64 * section_addresses; Internal_Symbol_Entry *symbols; + c8 * not_found_buffer; } Pool; // ================================================================ @@ -2136,7 +2140,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data i64 code_address = base_address + data_offset; i64 entry = code_address + entry_offset; - Symbol_Entry sym_printf = {0}; + Internal_Symbol_Entry sym_printf = {0}; i64 text_size = code_size; i64 data_size = 0; @@ -2149,7 +2153,9 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data i64 num_obj_files = 0; i64 obj_files_size = 0; + i64 num_sections = 0; i64 num_symbols = 0; + i64 not_found_size = 0; // Read all dependency files into the memory // @@ -2226,7 +2232,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // // Calculate section offsets - for (i64 elf_index = 0, sec_index_global = 0; elf_index < num_obj_files; ++elf_index) { + for (i64 elf_index = 0; elf_index < num_obj_files; ++elf_index) { Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index); elf_checks(buf); @@ -2234,8 +2240,10 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data Offset_Num headers = elf_section_headers(buf); - for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++sec_index_global) { - pool->section_addresses[sec_index_global] = 0; + for (i64 sec_index = 1; sec_index < headers.num; ++sec_index, ++num_sections) { + BX_CHECK(num_sections < pool->max_num_sections, "Too many sections",); + + pool->section_addresses[num_sections] = 0; Section_Header section = elf_section(buf, sec_index); @@ -2243,16 +2251,16 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data continue; if (section.exec) { - pool->section_addresses[sec_index_global] = base_address + data_offset + text_size; + pool->section_addresses[num_sections] = base_address + data_offset + text_size; text_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else if (section.write && section.type == SEC_NOBITS) { - pool->section_addresses[sec_index_global] = base_address + data_offset + bss_size; + pool->section_addresses[num_sections] = base_address + data_offset + bss_size; bss_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else if (section.write) { - pool->section_addresses[sec_index_global] = base_address + data_offset + data_size; + pool->section_addresses[num_sections] = base_address + data_offset + data_size; data_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else if (section.data.size > 0) { - pool->section_addresses[sec_index_global] = base_address + data_offset + rodata_size; + pool->section_addresses[num_sections] = base_address + data_offset + rodata_size; rodata_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else { BX_LAX(0, "Unsupported section type"); @@ -2285,7 +2293,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data i64 sym_section = sec_index_global + sym.section - 1; - BX_CHECK(sym_section < pool->max_num_sections, "Too many sections",); + BX_CHECK(sym_section < pool->max_num_sections, "Buffer overflow",); i64 sym_address = pool->section_addresses[sym_section] + sym.value.offset; @@ -2395,8 +2403,12 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data symbol = pool->symbols[i]; break; } - if (symbol.name_size == 0) + if (symbol.name_size == 0 && bx_find_str_in_table(pool->not_found_buffer, pool->not_found_buffer + not_found_size, sym_name, sym_name + relx.symbol.name.size) == NULL) { BX_LOG(WARNING, "Symbol not found: %s", sym_name); + BX_CHECK(not_found_size + relx.symbol.name.size + 1 <= pool->max_not_found_size, "Out of memory",); + bx_mem_cpy(pool->not_found_buffer + not_found_size, sym_name, relx.symbol.name.size); + not_found_size += relx.symbol.name.size + 1; + } } else symbol = (Internal_Symbol_Entry) { .section = sec_index_global, @@ -2558,34 +2570,11 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // // TODO Search symbols - for (i64 elf_index = 0; elf_index < num_obj_files; ++elf_index) { - Buffer_Context buf = elf_buffer_context(pool, num_obj_files, elf_index); - Offset_Size strtab = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; - i64 num_sections = elf_section_headers(buf).num; - - for (i64 sec_index = 1; sec_index < num_sections; ++sec_index) { - 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); - - if (sym.bind == BIND_LOCAL || - sym.section == 0 || - sym.name.size != 6) - continue; - - if (bx_mem_eq(elf_name_from_offset(buf, sym.name), "printf", 6)) { - sym_printf = sym; - break; - } - } - - if (sym_printf.section != 0) - break; + for (i64 i = 0; i < num_symbols; ++i) + if (pool->symbols[i].name_size == 6 && bx_mem_eq(pool->symbols[i].name, "printf", 6)) { + sym_printf = pool->symbols[i]; + break; } - } // ============================================================== // @@ -2597,14 +2586,17 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // // TODO Write into memory. + BX_LOG(VERBOSE, "Total %lld sections", num_sections); + BX_LOG(VERBOSE, "Total %lld symbols", num_symbols); + BX_LOG(VERBOSE, "Total size"); BX_LOG(VERBOSE, ".text - %lld bytes", text_size); BX_LOG(VERBOSE, ".bss - %lld bytes", bss_size); BX_LOG(VERBOSE, ".data - %lld bytes", data_size); BX_LOG(VERBOSE, ".rodata - %lld bytes", rodata_size); - BX_CHECK(sym_printf.section != 0, "Symbol not found: printf",); - BX_LOG(VERBOSE, "Found printf: %08llx", sym_printf.value.offset); + BX_CHECK(sym_printf.name_size != 0, "Symbol not found: printf",); + BX_LOG(VERBOSE, "Found printf: %08llx", sym_printf.address); BX_LOG(VERBOSE, "Writing ELF x86_64 executable"); @@ -2928,12 +2920,14 @@ Pool g_pool = { .max_num_obj_files = MAX_NUM_OBJECT_FILES, .max_num_sections = MAX_NUM_SECTIONS, .max_num_symbols = MAX_NUM_SYMBOLS, + .max_not_found_size = MAX_NOT_FOUND_SIZE, .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_addresses = (i64[MAX_NUM_SECTIONS]) {0}, .symbols = (Internal_Symbol_Entry[MAX_NUM_SYMBOLS]) {0}, + .not_found_buffer = (c8[MAX_NOT_FOUND_SIZE]) {0}, }; // Handy procedures @@ -3048,6 +3042,10 @@ int main(int argc, char **argv) { // Set the `main` as the entry point of the compilation unit. u_entry_point(u, main); + // NOTE + // Codegen is not implemented so the example above won't be compiled into binary. + // Instead, some dummy binary will be generated. + // Link a static library. l_static(u, "/lib/x86_64-linux-gnu/libc.a"); // l_static(u, "libtest.a"); |