summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-24 14:06:09 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-24 14:06:09 +0200
commit9b62cc97013793eb69d8afdc7e5cb8398b52bfc5 (patch)
tree848149c4d4171f781a098aa815cc1501ae9aad8f
parentaa36c50a6b89d36ce7edefd23a833de141f5d2cc (diff)
downloadbxgen-9b62cc97013793eb69d8afdc7e5cb8398b52bfc5.zip
Not found buffer
-rwxr-xr-xbxgen.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/bxgen.c b/bxgen.c
index 6640ba7..64d5145 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -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");