From ebd61b71171889b908de20d973e0a17c1f4e5149 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Fri, 19 Jul 2024 09:39:11 +0200 Subject: Cleanup --- bxgen.c | 139 +++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 86 insertions(+), 53 deletions(-) (limited to 'bxgen.c') diff --git a/bxgen.c b/bxgen.c index 8ee878f..f293b87 100755 --- a/bxgen.c +++ b/bxgen.c @@ -180,10 +180,10 @@ enum { // Buffers // - MAX_OBJECT_FILE_SIZE = 10 * 1024 * 1024, - MAX_NUM_OBJECT_FILES = 10 * 1024, + MAX_OBJECT_FILE_SIZE = 10 * 1024 * 1024, + MAX_NUM_OBJECT_FILES = 10 * 1024, MAX_DEPENDENCIES_SIZE = 300 * 1024 * 1024, - STRING_TABLE_ALIGNMENT = 16, // TODO + STRING_TABLE_ALIGNMENT = 16, // TODO // Entity types // @@ -201,7 +201,7 @@ enum { MAX_NUM_NODES = 60, MAX_NUM_LINKS = 20, MAX_NUM_ARGS = 20, - MAX_NUM_ENTITIES = 16384, + MAX_NUM_ENTITIES = 16 * 1024, // IO dispatch operations // @@ -241,7 +241,7 @@ enum { // TODO typedef struct { i64 size; - i64 index; + i64 offset; } String_Handle; // TODO @@ -253,7 +253,7 @@ typedef struct { } Strint_Table; typedef struct { - i16 size; + i16 num; i16 type; i64 node; } Var; @@ -1271,16 +1271,22 @@ enum { ELF_RELA_ENTRY_SIZE = 24, SEC_NONE = 0, - SEC_PROGRAM, - SEC_SYMBOLS, - SEC_STRINGS, + SEC_PROGBITS, + SEC_SYMTAB, + SEC_STRTAB, SEC_RELA, SEC_HASH, SEC_DYNAMIC, SEC_NOTE, - SEC_ZEROS, + SEC_NOBITS, SEC_REL, + SEC_SHLIB, + SEC_DYNSYM, + SEC_INIT_ARRAY = 14, + SEC_FINI_ARRAY, + SEC_PREINIT_ARRAY, SEC_GROUP, + SEC_SYMTAB_SHNDX, SYM_NONE = 0, SYM_PROC, @@ -1340,6 +1346,28 @@ enum { R_X86_64_REX_GOTPCRELX, }; +c8 *SEC_TYPE_NAMES[] = { + [SEC_NONE] = "none", + [SEC_PROGBITS] = "progbits", + [SEC_SYMTAB] = "symtab", + [SEC_STRTAB] = "strtab", + [SEC_RELA] = "rela", + [SEC_HASH] = "hash", + [SEC_DYNAMIC] = "dynamic", + [SEC_NOTE] = "note", + [SEC_NOBITS] = "nobits", + [SEC_REL] = "rel", + [SEC_SHLIB] = "shlib", + [SEC_DYNSYM] = "dynsym", + [12] = "", + [13] = "", + [SEC_INIT_ARRAY] = "init array", + [SEC_FINI_ARRAY] = "fini array", + [SEC_PREINIT_ARRAY] = "preinit array", + [SEC_GROUP] = "group", + [SEC_SYMTAB_SHNDX] = "symtab shndx", +}; + c8 *REL_NAMES[] = { [R_X86_64_NONE] = "none", [R_X86_64_64] = "64", @@ -1569,9 +1597,9 @@ Section_Header elf_section( Buffer_Context b, i64 index ) { - Offset_Size names = elf_section_names_data(b); - u8 * begin = b.begin + elf_section_header_offset(b, index); - u8 * end = b.begin + b.elf.offset + b.elf.size; + Offset_Size names = elf_section_names_data(b); + u8 * begin = b.begin + elf_section_header_offset(b, index); + u8 * end = b.begin + b.elf.offset + b.elf.size; BX_CHECK(end <= b.end, "Buffer overflow", (Section_Header) {0}); i64 name_index = (i64) read_u32(LE, begin, end); @@ -1581,19 +1609,14 @@ Section_Header elf_section( u32 type = read_u32(LE, begin + 4, end); u64 flags = read_u64(LE, begin + 8, end); + if (type > SEC_SYMTAB_SHNDX || type == 12 || type == 13) { + BX_LOG(WARNING, "Unknown section type: %d", type); + type = SEC_NONE; + } + return (Section_Header) { .name = elf_name_in_string_table(b, names, name_index), - .type = type == 1 ? SEC_PROGRAM : - type == 2 ? SEC_SYMBOLS : - type == 3 ? SEC_STRINGS : - type == 4 ? SEC_RELA : - type == 5 ? SEC_HASH : - type == 6 ? SEC_DYNAMIC : - type == 7 ? SEC_NOTE : - type == 8 ? SEC_ZEROS : - type == 9 ? SEC_REL : - type == 10 ? SEC_GROUP : - SEC_NONE, + .type = type, .alloc = (flags & 2) == 2, .write = (flags & 1) == 1, .exec = (flags & 4) == 4, @@ -1674,13 +1697,14 @@ Symbol_Entry elf_symbol( BX_CHECK(end <= b.end, "Buffer overflow", (Symbol_Entry) {0}); BX_CHECK(end <= b.begin + b.elf.offset + b.elf.size, "Buffer overflow", (Symbol_Entry) {0}); - i64 sym_name = (i64) read_u32(LE, begin, end); - u8 sym_info = read_u8 (LE, begin + 4, end); - i64 sym_shndx = (i64) read_u16(LE, begin + 6, end); - i64 sym_value = read_i64(LE, begin + 8, end); - i64 sym_size = read_i64(LE, begin + 16, end); + i64 sym_name = (i64) read_u32(LE, begin, end); + u8 sym_info = read_u8 (LE, begin + 4, end); + i64 sym_shndx = (i64) read_u16(LE, begin + 6, end); + i64 sym_value = read_i64(LE, begin + 8, end); + i64 sym_size = read_i64(LE, begin + 16, end); Offset_Size dst = + sym_shndx >= 0 && sym_shndx < elf_section_headers(b).num ? elf_section(b, sym_shndx).data : (Offset_Size) {0}; @@ -2010,13 +2034,13 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data for (i64 sec_index = 0; sec_index < section_headers.num; ++sec_index) { Section_Header section = elf_section(buf, sec_index); - if (section.type == SEC_SYMBOLS || + if (section.type == SEC_SYMTAB || section.type == SEC_RELA || section.type == SEC_REL) printf("\"%s", "\x1b[32m"); else if (section.alloc) printf("\"%s", "\x1b[34m"); - else if (section.type == SEC_STRINGS) + else if (section.type == SEC_STRTAB) printf("\"%s", "\x1b[33m"); else printf("\"%s", "\x1b[31m"); @@ -2027,22 +2051,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data printf("%*s", (i32) (section.name.size < 30 ? 30 - section.name.size : 1), ""); - printf( - "%-10s", - (c8 *[]) { - "", - "Program", - "Symbols", - "Strings", - "Rel add", - "Hash", - "Dynamic", - "Note", - "Zeros", - "Rel", - "Group", - }[section.type] - ); + printf("%-14s", SEC_TYPE_NAMES[section.type]); if (section.alloc) printf("R"); @@ -2063,7 +2072,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data printf("\n"); switch (section.type) { - case SEC_SYMBOLS: + case SEC_SYMTAB: if (symbols.offset == 0) symbols = section.data; @@ -2451,9 +2460,7 @@ void io_dispatch(i16 op, i64 *id, i64 *size, void *data, void *user_data) { Pool g_pool = { // Statically allocate a large memory block. - // - // TODO - // Reallocate the memory block when necessary. + // TODO Reallocate the memory block when necessary. .capacity = MAX_NUM_ENTITIES, .entities = (Entity[MAX_NUM_ENTITIES]) {0}, @@ -2546,22 +2553,48 @@ int main(int argc, char **argv) { (void) argc; (void) argv; + // Add the `main` procedure. i64 main = p_new("main"); + + // Create `42` i64 data node and add it into the `main`. i64 n0 = n_i64(42); p_add(main, n0); - p_add(main, n_ret(1, (Var[]) { {.size = 4, .type = TYPE_I32, .node = n0, } })); + // Add a return statement into the `main`. + // The return statement will point at the previously + // created node `42`. + p_add(main, + // Create a ret node. + n_ret( 1, // number of returned values + (Var[]) {{ + // the return value + .num = 1, // number of elements + .type = TYPE_I32, // type + .node = n0, // source to get the value from + }} + )); + + // Add a compilation unit. i64 u = u_new(); + + // Add the `main` procedure to the compilation unit. u_add(u, main); + + // Set the `main` as the entry point of the compilation unit. u_entry_point(u, main); + + // Link a static library. l_static(u, "/lib/x86_64-linux-gnu/libc.a"); // l_static(u, "libtest.a"); + // Write the compilation unit into an executable file. BX_LOG(VERBOSE, "Writing ELF x86_64 executable..."); u_elf_x86_64(u, "test_foo"); - BX_CHECK(HO == LE, "Host data ordering is not compatible", -1); + BX_CHECK(HOST == HOST_Linux, "Host system is not compatible", -1); + BX_CHECK(HO == LE, "Host data ordering is not compatible", -1); + // Run the created executable file. i32 ret = system("./test_foo"); BX_CHECK(WEXITSTATUS(ret) == 42, "Failure", -1); -- cgit v1.2.3