diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-07-19 13:54:37 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-07-19 13:54:37 +0200 |
commit | d37f496059bba635eeb4ecd4262b9a05f088d09d (patch) | |
tree | 8eecfb4751c1d769f11499913a2624728cc9bec1 | |
parent | ebd61b71171889b908de20d973e0a17c1f4e5149 (diff) | |
download | bxgen-d37f496059bba635eeb4ecd4262b9a05f088d09d.zip |
Separate ELF dump function
-rwxr-xr-x | bxgen.c | 776 |
1 files changed, 417 insertions, 359 deletions
@@ -75,7 +75,7 @@ SRC=${0##*./} BIN=${SRC%.*} gcc \ -Wno-old-style-declaration -Wno-missing-braces \ - -Wno-unused-variable \ + -Wno-unused-variable -Wno-unused-but-set-variable \ -Wall -Wextra -Werror -pedantic \ -O0 -fsanitize=undefined,address,leak -mshstk \ -o $BIN $SRC && \ @@ -108,6 +108,10 @@ exit $? # */ #define LOG_BLOCKING 1 #endif +#ifndef TRACE_BLOCKING +#define TRACE_BLOCKING 1 +#endif + // ================================================================ // // Basic declarations @@ -141,6 +145,22 @@ enum { VERBOSE, TRACE, + // Limits + // + + MAX_OBJECT_FILE_SIZE = 10 * 1024 * 1024, + MAX_NUM_OBJECT_FILES = 10 * 1024, + MAX_DEPENDENCIES_SIZE = 300 * 1024 * 1024, + STRING_TABLE_ALIGNMENT = 16, // TODO + MAX_PATH_SIZE = 10 * 1024, + MAX_LITERAL_SIZE = 400, + MAX_NAME_SIZE = 80, + MAX_NUM_PROCS = 40, + MAX_NUM_NODES = 60, + MAX_NUM_LINKS = 20, + MAX_NUM_ARGS = 20, + MAX_NUM_ENTITIES = 16 * 1024, + // For indices UNDEFINED = -1, @@ -177,14 +197,6 @@ enum { UNIT_LIBRARY_STATIC, UNIT_LIBRARY_DYNAMIC, - // Buffers - // - - MAX_OBJECT_FILE_SIZE = 10 * 1024 * 1024, - MAX_NUM_OBJECT_FILES = 10 * 1024, - MAX_DEPENDENCIES_SIZE = 300 * 1024 * 1024, - STRING_TABLE_ALIGNMENT = 16, // TODO - // Entity types // @@ -192,17 +204,6 @@ enum { ENTITY_PROC, ENTITY_UNIT, - // Limits - // - - MAX_LITERAL_SIZE = 400, - MAX_NAME_SIZE = 80, - MAX_NUM_PROCS = 40, - MAX_NUM_NODES = 60, - MAX_NUM_LINKS = 20, - MAX_NUM_ARGS = 20, - MAX_NUM_ENTITIES = 16 * 1024, - // IO dispatch operations // @@ -498,6 +499,8 @@ i64 bx_align(i64 x, i64 a) { return x + ((a - (x % a)) % a); } +#define BX_TRACE BX_LOG(TRACE, "") + void bx_mem_cpy(void *dst, void *src, i64 size) { BX_CHECK(dst != NULL, "Invalid arguments",); BX_CHECK(src != NULL, "Invalid arguments",); @@ -1291,8 +1294,8 @@ enum { SYM_NONE = 0, SYM_PROC, SYM_DATA, - SYM_DATA_COMMON, - SYM_DATA_THREAD_LOCAL, + SYM_COMMON, + SYM_TLS, SYM_SECTION, SYM_SPECIFIC, @@ -1710,12 +1713,12 @@ Symbol_Entry elf_symbol( BX_CHECK(dst.size == 0 || sym_value + sym_size <= dst.size, "Buffer overflow", (Symbol_Entry) {0}); - u8 type = (sym_info & 0xf) == 0 ? SYM_NONE : - (sym_info & 0xf) == 1 ? SYM_DATA : - (sym_info & 0xf) == 2 ? SYM_PROC : - (sym_info & 0xf) == 3 ? SYM_SECTION : - (sym_info & 0xf) == 5 ? SYM_DATA_COMMON : - (sym_info & 0xf) == 6 ? SYM_DATA_THREAD_LOCAL : + u8 type = (sym_info & 0xf) == 0 ? SYM_NONE : + (sym_info & 0xf) == 1 ? SYM_DATA : + (sym_info & 0xf) == 2 ? SYM_PROC : + (sym_info & 0xf) == 3 ? SYM_SECTION : + (sym_info & 0xf) == 5 ? SYM_COMMON : + (sym_info & 0xf) == 6 ? SYM_TLS : SYM_SPECIFIC; BX_CHECK(type != SYM_NONE || (sym_info & 0xf) == 0, "Unknown symbol type", (Symbol_Entry) {0}); @@ -1815,8 +1818,153 @@ Symbol_Entry elf_find_symbol_by_name( BX_FAIL("Not found", (Symbol_Entry) {0}); } -#include <stdio.h> // TEMP -#include <stdlib.h> // TEMP +void elf_dump(u32 log_level, Buffer_Context b) { + Offset_Num section_headers = elf_section_headers(b); + Offset_Size symbol_names = {0}; + Offset_Size symbols = {0}; + + for (i64 sec_index = 0; sec_index < section_headers.num; ++sec_index) { + Section_Header section = elf_section(b, sec_index); + + c8 *name = elf_name_from_offset(b, section.name); + + BX_LOG( + log_level, + "\"%s%s\x1b[37m\"%*s%-14s%s%s%s%s%lld%s", + section.type == SEC_SYMTAB || + section.type == SEC_RELA || + section.type == SEC_REL ? "\x1b[32m" : + section.alloc ? "\x1b[34m" : + section.type == SEC_STRTAB ? "\x1b[33m" : + "\x1b[31m", + name, + (i32) (section.name.size < 30 ? 30 - section.name.size : 1), + "", + SEC_TYPE_NAMES[section.type], + section.alloc ? "R" : "_", + section.write ? "W" : "_", + section.exec ? "X" : "_", + section.data.size > 0 ? " - " : "", + section.data.size, + section.data.size > 0 ? " bytes" : "\b " + ); + + switch (section.type) { + case SEC_SYMTAB: + if (symbols.offset == 0) + symbols = section.data; + + if (symbol_names.offset == 0) + symbol_names = elf_find_section_by_name(b, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + + BX_LOG(log_level, " - -"); + + for (i64 sym_index = 0; sym_index < section.num_entries; ++sym_index) { + Symbol_Entry sym = elf_symbol(b, section.data, symbol_names, (u16) sym_index); + + c8 *name = elf_name_from_offset(b, sym.name); + + i32 len = (sym.name.size == 0) ? 4 : (i32) sym.name.size; + + BX_LOG( + log_level, + " %s%s%s\x1b[37m%s %.*s %s\x1b[37m", + *name != '\0' ? "\"" : "", + sym.bind == BIND_GLOBAL ? "\x1b[32m" : + sym.bind == BIND_WEAK ? "\x1b[35m" : + "\x1b[31m", + *name != '\0' ? name : "<NONE>", + *name != '\0' ? "\"" : "", + 31 < len ? 1 : 32 - len, + 31 < len ? " " : "........................................", + sym.type == SYM_PROC ? "\x1b[32mproc " : + sym.type == SYM_DATA ? "\x1b[32mdata " : + sym.type == SYM_COMMON ? "\x1b[33mcommon " : + sym.type == SYM_TLS ? "\x1b[35mtls " : + sym.type == SYM_SECTION ? "\x1b[31msection" : + sym.type == SYM_SPECIFIC ? "\x1b[31mspec " : + " " + ); + } + + BX_LOG(log_level, " - -"); + break; + + case SEC_RELA: { + if (symbol_names.offset == 0) + symbol_names = elf_find_section_by_name(b, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + if (symbols.offset == 0) + symbols = elf_find_section_by_name(b, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data; + + Offset_Size dst = elf_find_related_data(b, sec_index); + + BX_LOG(log_level, " - -"); + + for (i64 rela_index = 0; rela_index < section.num_entries; ++rela_index) { + Rela_Entry rela = elf_rela(b, symbols, symbol_names, section.data, dst, rela_index); + + BX_LOG( + log_level, + " %-16s %08llx %-+5lld <= %s%08llx\x1b[37m%s\x1b[37m \"%s\"", + REL_NAMES[rela.type], + rela.dst, + rela.addent, + rela.symbol.bind == BIND_WEAK ? "\x1b[33m" : "\x1b[32m", + rela.symbol.value.offset, + rela.symbol.type == SYM_DATA || + rela.symbol.type == SYM_COMMON || + rela.symbol.type == SYM_TLS ? " \x1b[34mdata" : + rela.symbol.type == SYM_PROC ? " \x1b[34mproc" : + rela.symbol.type == SYM_SECTION ? " \x1b[36msect" : + rela.symbol.type == SYM_SPECIFIC ? " \x1b[34mspec" : + " \x1b[33mnone", + elf_name_from_offset(b, rela.symbol.name) + ); + } + + BX_LOG(log_level, " - -"); + } break; + + case SEC_REL: { + if (symbol_names.offset == 0) + symbol_names = elf_find_section_by_name(b, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + if (symbols.offset == 0) + symbols = elf_find_section_by_name(b, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data; + + Offset_Size dst = elf_find_related_data(b, sec_index); + + BX_LOG(log_level, " - -"); + + for (i64 rel_index = 0; rel_index < section.num_entries; ++rel_index) { + Rel_Entry rel = elf_rel(b, symbols, symbol_names, section.data, dst, rel_index); + + BX_LOG( + log_level, + " %-16s %08llx <= %s%08llx\x1b[37m%s\x1b[37m \"%s\"", + REL_NAMES[rel.type], + rel.dst, + rel.symbol.bind == BIND_WEAK ? "\x1b[33m" : "\x1b[32m", + rel.symbol.value.offset, + rel.symbol.type == SYM_DATA || + rel.symbol.type == SYM_COMMON || + rel.symbol.type == SYM_TLS ? " \x1b[34mdata" : + rel.symbol.type == SYM_PROC ? " \x1b[34mproc" : + rel.symbol.type == SYM_SECTION ? " \x1b[36msect" : + rel.symbol.type == SYM_SPECIFIC ? " \x1b[34mspec" : + " \x1b[33mnone", + elf_name_from_offset(b, rel.symbol.name) + ); + } + + BX_LOG(log_level, " - -"); + } break; + + default:; + } + } + + BX_LOG(log_level, ""); +} void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data) { BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments",); @@ -1829,13 +1977,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data BX_CHECK(pool->obj_file_offsets != NULL, "No object file offsets buffer",); // ============================================================== - - #define WRITE(x, n) io_write( io_out, n, x, io_user_data ) - #define WRITE_V(...) io_write( io_out, sizeof((u8[]) {__VA_ARGS__}), (u8[]) {__VA_ARGS__}, io_user_data ) - #define WRITE_DUP(x, n) io_write( io_out, n, (u8[n]) { 0 }, io_user_data ) - #define WRITE_2(x) io_write( io_out, 2, &(u16) { x }, io_user_data ) - #define WRITE_4(x) io_write( io_out, 4, &(u32) { x }, io_user_data ) - #define WRITE_8(x) io_write( io_out, 8, &(u64) { x }, io_user_data ) + // + // Our program u8 code[32] = { 0xb8, 0x3c, 0x00, 0x00, 0x00, // mov eax, 60 @@ -1851,8 +1994,236 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data i64 code_address = base_address + code_offset; i64 entry = code_address + entry_offset; - BX_CHECK((code_offset % X86_64_ALIGNMENT) == 0, "Invalid alignment",); - BX_CHECK((code_size % X86_64_ALIGNMENT) == 0, "Invalid alignment",); + Symbol_Entry sym_printf = {0}; + + i64 text_size = code_size; + i64 data_size = 0; + i64 bss_size = 0; + i64 rodata_size = 0; + + // ============================================================== + // + // Reading dependencies + + i64 im_num = 0; + i64 im_size = 0; + + // Read all dependency files into the memory + // + + Unit *u = &pool->entities[unit].unit; + + for (i64 link_index = 0; link_index < u->num_links; ++link_index) { + i64 id = u->links[link_index]; + if (id == UNDEFINED) + continue; + Unit *l = &pool->entities[id].unit; + BX_CHECK(pool->entities[id].is_enabled, "Internal",); + BX_CHECK(l->type == UNIT_LIBRARY_STATIC, "Link type not supported",); + BX_CHECK(l->name_size > 0 && l->name_size <= MAX_NAME_SIZE, "Link name too big",); + + i64 f = io_open_read(l->name_size, l->name, io_user_data); + io_seek(f, 0, IO_SEEK_END, io_user_data); + + i64 in_size = io_tell(f, io_user_data); + BX_CHECK(in_size <= pool->max_obj_file_size, "AR file too big",); + + io_seek(f, 0, IO_SEEK_BEGIN, io_user_data); + i64 n = io_read(f, in_size, pool->obj_file_buffer, io_user_data); + BX_CHECK(n == in_size, "Read failed",); + + io_close(f, io_user_data); + + // ======================================================== + // + // Read AR library + + u8 *ar_begin = pool->obj_file_buffer; + u8 *ar_end = pool->obj_file_buffer + in_size; + + BX_CHECK(bx_mem_eq(ar_begin, AR_MAGIC, 8), "Invalid AR file",); + + u8 *f_begin = ar_begin + 8; + + while (f_begin + 60 < ar_end) { + u8 *f_id = f_begin; + u8 *f_size = f_begin + 48; + u8 *f_end = f_begin + 58; + u8 *f_data = f_begin + 60; + + i64 size = bx_i64_from_str((c8 *) f_size, (c8 *) f_size + 10); + + size = bx_align(size, 2); + + BX_CHECK(bx_mem_eq(f_end, "\x60\x0a", 2), "Invalid AR file",); + BX_CHECK(f_begin + size <= ar_end, "Buffer overflow",); + + if (!bx_mem_eq(f_id, AR_SYMBOL_TABLE, 16) && + !bx_mem_eq(f_id, AR_STRING_TABLE, 16)) { + // Read ELF object file + + i64 delta_size = bx_align(size, X86_64_ALIGNMENT); + + BX_CHECK(im_size + delta_size < pool->max_dependencies_size, "Out of memory",); + BX_CHECK(im_num + 1 < pool->max_num_obj_files, "Out of memory",); + + bx_mem_cpy(pool->dependencies_buffer + im_size, f_data, size); + + pool->obj_file_offsets[im_num] = im_size; + im_size += delta_size; + pool->obj_file_offsets[++im_num] = im_size; + } + + f_begin = f_data + size; + } + } + + // ========================================================== + // + // Process ELF object files + + for (i64 elf_index = 0; elf_index < im_num; ++elf_index) { + u8 *elf_begin = pool->dependencies_buffer + pool->obj_file_offsets[elf_index]; + u8 *elf_end = pool->dependencies_buffer + pool->obj_file_offsets[elf_index + 1]; + + u8 osabi = read_u8(LE, elf_begin + 7, elf_end); + + BX_CHECK( read_u8 (LE, elf_begin, elf_end) == ELF_MAGIC[0], "Invalid ELF file",); + BX_CHECK( read_u8 (LE, elf_begin + 1, elf_end) == ELF_MAGIC[1], "Invalid ELF file",); + BX_CHECK( read_u8 (LE, elf_begin + 2, elf_end) == ELF_MAGIC[2], "Invalid ELF file",); + BX_CHECK( read_u8 (LE, elf_begin + 3, elf_end) == ELF_MAGIC[3], "Invalid ELF file",); + + BX_CHECK( read_u8 (LE, elf_begin + 4, elf_end) == ELF_64, "Unsupported ELF file",); + BX_CHECK( read_u8 (LE, elf_begin + 5, elf_end) == ELF_2_LE, "Unsupported ELF file",); + BX_CHECK( read_u8 (LE, elf_begin + 6, elf_end) == ELF_VERSION, "Unsupported ELF file",); + BX_CHECK( osabi == ELF_SYS_V || osabi == ELF_LINUX, "Unsupported ELF file",); + BX_CHECK( read_u8 (LE, elf_begin + 8, elf_end) == ELF_ABI_VERSION, "Unsupported ELF file",); + BX_CHECK( read_u16(LE, elf_begin + 16, elf_end) == ELF_RELOCATABLE, "Unsupported ELF file",); + BX_CHECK( read_u16(LE, elf_begin + 18, elf_end) == ELF_X86_64, "Unsupported ELF file",); + BX_CHECK( read_u32(LE, elf_begin + 20, elf_end) == ELF_VERSION, "Unsupported ELF file",); + + BX_LAX( read_u64(LE, elf_begin + 24, elf_end) == 0, "Invalid entry point"); + BX_LAX( read_u64(LE, elf_begin + 32, elf_end) == 0, "Invalid program header offset"); + BX_LAX( read_u32(LE, elf_begin + 48, elf_end) == 0, "Invalid flags"); + BX_LAX( read_u16(LE, elf_begin + 52, elf_end) == ELF_HEADER_SIZE, "Invalid ELF header size"); + BX_LAX( read_u16(LE, elf_begin + 54, elf_end) == 0, "Invalid program header size"); + BX_LAX( read_u16(LE, elf_begin + 56, elf_end) == 0, "Invalid num program headers"); + BX_LAX( read_u16(LE, elf_begin + 58, elf_end) == ELF_SECTION_HEADER_SIZE, "Invalid section header size"); + + Buffer_Context buf = { + .begin = pool->dependencies_buffer, + .end = pool->dependencies_buffer + pool->obj_file_offsets[im_num], + .elf = { + .offset = pool->obj_file_offsets[elf_index], + .size = pool->obj_file_offsets[elf_index + 1] - pool->obj_file_offsets[elf_index], + }, + }; + + elf_dump(VERBOSE, buf); + + Offset_Num section_headers = elf_section_headers(buf); + Offset_Size symbol_names = {0}; + Offset_Size symbols = {0}; + + for (i64 sec_index = 0; sec_index < section_headers.num; ++sec_index) { + Section_Header section = elf_section(buf, sec_index); + + i64 offset = 0; + + if (section.alloc) { + if (section.exec) { + offset = text_size; + text_size += bx_align(section.data.size, X86_64_ALIGNMENT); + } else if (section.write && section.type == SEC_NOBITS) { + offset = bss_size; + bss_size += bx_align(section.data.size, X86_64_ALIGNMENT); + } else if (section.write) { + offset = data_size; + data_size += bx_align(section.data.size, X86_64_ALIGNMENT); + } else if (section.data.size > 0) { + offset = rodata_size; + rodata_size += bx_align(section.data.size, X86_64_ALIGNMENT); + } else + BX_LAX(0, "Unsupported section type"); + } + + switch (section.type) { + case SEC_SYMTAB: + if (symbols.offset == 0) + symbols = section.data; + if (symbol_names.offset == 0) + symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + + for (i64 sym_index = 0; sym_index < section.num_entries; ++sym_index) { + Symbol_Entry sym = elf_symbol(buf, section.data, symbol_names, (u16) sym_index); + + if (sym.name.size == 6 && bx_mem_eq(elf_name_from_offset(buf, sym.name), "printf", 6)) { + if (sym_printf.value.offset != 0) + BX_LAX(0, "Symbol redefinition"); + sym_printf = sym; + } + } + + break; + + case SEC_RELA: { + if (symbol_names.offset == 0) + symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + if (symbols.offset == 0) + symbols = elf_find_section_by_name(buf, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data; + + Offset_Size dst = elf_find_related_data(buf, sec_index); + + for (i64 rela_index = 0; rela_index < section.num_entries; ++rela_index) { + Rela_Entry rela = elf_rela(buf, symbols, symbol_names, section.data, dst, rela_index); + } + + } break; + + case SEC_REL: { + if (symbol_names.offset == 0) + symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + if (symbols.offset == 0) + symbols = elf_find_section_by_name(buf, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data; + + Offset_Size dst = elf_find_related_data(buf, sec_index); + + for (i64 rel_index = 0; rel_index < section.num_entries; ++rel_index) { + Rel_Entry rel = elf_rel(buf, symbols, symbol_names, section.data, dst, rel_index); + } + + } break; + + default:; + } + } + } + + // ============================================================== + + // TODO Write sections into the output buffer. + // + + // ============================================================== + // + // Writing the ELF executable + + BX_LOG(VERBOSE, "Total size"); + BX_LOG(VERBOSE, ".text: %lld", text_size); + BX_LOG(VERBOSE, ".bss: %lld", bss_size); + BX_LOG(VERBOSE, ".data: %lld", data_size); + BX_LOG(VERBOSE, ".rodata: %lld", rodata_size); + + BX_LOG(VERBOSE, ""); + + BX_LOG(VERBOSE, "Found printf: %d", sym_printf.value.offset); + + #define WRITE(x, n) io_write( io_out, n, x, io_user_data ) + #define WRITE_V(...) io_write( io_out, sizeof((u8[]) {__VA_ARGS__}), (u8[]) {__VA_ARGS__}, io_user_data ) + #define WRITE_DUP(x, n) io_write( io_out, n, (u8[n]) { 0 }, io_user_data ) + #define WRITE_2(x) io_write( io_out, 2, &(u16) { x }, io_user_data ) + #define WRITE_4(x) io_write( io_out, 4, &(u32) { x }, io_user_data ) + #define WRITE_8(x) io_write( io_out, 8, &(u64) { x }, io_user_data ) // ELF header // @@ -1907,321 +2278,6 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data #undef WRITE_64 #undef WRITE - - // ============================================================== - - // Intermediate buffer - // - - i64 im_num = 0; - i64 im_size = 0; - - // Read all dependency files into the memory - // - { - Unit *u = &pool->entities[unit].unit; - - for (i64 link_index = 0; link_index < u->num_links; ++link_index) { - i64 id = u->links[link_index]; - if (id == UNDEFINED) - continue; - Unit *l = &pool->entities[id].unit; - BX_CHECK(pool->entities[id].is_enabled, "Internal",); - BX_CHECK(l->type == UNIT_LIBRARY_STATIC, "Link type not supported",); - BX_CHECK(l->name_size > 0 && l->name_size <= MAX_NAME_SIZE, "Link name too big",); - - i64 f = io_open_read(l->name_size, l->name, io_user_data); - io_seek(f, 0, IO_SEEK_END, io_user_data); - - i64 in_size = io_tell(f, io_user_data); - BX_CHECK(in_size <= pool->max_obj_file_size, "AR file too big",); - - io_seek(f, 0, IO_SEEK_BEGIN, io_user_data); - i64 n = io_read(f, in_size, pool->obj_file_buffer, io_user_data); - BX_CHECK(n == in_size, "Read failed",); - - io_close(f, io_user_data); - - // ======================================================== - // - // Read AR library - - u8 *ar_begin = pool->obj_file_buffer; - u8 *ar_end = pool->obj_file_buffer + in_size; - - BX_CHECK(bx_mem_eq(ar_begin, AR_MAGIC, 8), "Invalid AR file",); - - u8 *f_begin = ar_begin + 8; - - while (f_begin + 60 < ar_end) { - u8 *f_id = f_begin; - u8 *f_size = f_begin + 48; - u8 *f_end = f_begin + 58; - u8 *f_data = f_begin + 60; - - i64 size = bx_i64_from_str((c8 *) f_size, (c8 *) f_size + 10); - - size = bx_align(size, 2); - - BX_CHECK(bx_mem_eq(f_end, "\x60\x0a", 2), "Invalid AR file",); - BX_CHECK(f_begin + size <= ar_end, "Buffer overflow",); - - if (!bx_mem_eq(f_id, AR_SYMBOL_TABLE, 16) && - !bx_mem_eq(f_id, AR_STRING_TABLE, 16)) { - // Read ELF object file - - i64 delta_size = bx_align(size, X86_64_ALIGNMENT); - - BX_CHECK(im_size + delta_size < pool->max_dependencies_size, "Out of memory",); - BX_CHECK(im_num + 1 < pool->max_num_obj_files, "Out of memory",); - - bx_mem_cpy(pool->dependencies_buffer + im_size, f_data, size); - - pool->obj_file_offsets[im_num] = im_size; - im_size += delta_size; - pool->obj_file_offsets[++im_num] = im_size; - } - - f_begin = f_data + size; - } - } - - // ========================================================== - // - // Process ELF object files - - for (i64 elf_index = 0; elf_index < im_num; ++elf_index) { - u8 *elf_begin = pool->dependencies_buffer + pool->obj_file_offsets[elf_index]; - u8 *elf_end = pool->dependencies_buffer + pool->obj_file_offsets[elf_index + 1]; - - u8 osabi = read_u8(LE, elf_begin + 7, elf_end); - - BX_CHECK( read_u8 (LE, elf_begin, elf_end) == ELF_MAGIC[0], "Invalid ELF file",); - BX_CHECK( read_u8 (LE, elf_begin + 1, elf_end) == ELF_MAGIC[1], "Invalid ELF file",); - BX_CHECK( read_u8 (LE, elf_begin + 2, elf_end) == ELF_MAGIC[2], "Invalid ELF file",); - BX_CHECK( read_u8 (LE, elf_begin + 3, elf_end) == ELF_MAGIC[3], "Invalid ELF file",); - - BX_CHECK( read_u8 (LE, elf_begin + 4, elf_end) == ELF_64, "Unsupported ELF file",); - BX_CHECK( read_u8 (LE, elf_begin + 5, elf_end) == ELF_2_LE, "Unsupported ELF file",); - BX_CHECK( read_u8 (LE, elf_begin + 6, elf_end) == ELF_VERSION, "Unsupported ELF file",); - BX_CHECK( osabi == ELF_SYS_V || osabi == ELF_LINUX, "Unsupported ELF file",); - BX_CHECK( read_u8 (LE, elf_begin + 8, elf_end) == ELF_ABI_VERSION, "Unsupported ELF file",); - BX_CHECK( read_u16(LE, elf_begin + 16, elf_end) == ELF_RELOCATABLE, "Unsupported ELF file",); - BX_CHECK( read_u16(LE, elf_begin + 18, elf_end) == ELF_X86_64, "Unsupported ELF file",); - BX_CHECK( read_u32(LE, elf_begin + 20, elf_end) == ELF_VERSION, "Unsupported ELF file",); - - BX_LAX( read_u64(LE, elf_begin + 24, elf_end) == 0, "Invalid entry point"); - BX_LAX( read_u64(LE, elf_begin + 32, elf_end) == 0, "Invalid program header offset"); - BX_LAX( read_u32(LE, elf_begin + 48, elf_end) == 0, "Invalid flags"); - BX_LAX( read_u16(LE, elf_begin + 52, elf_end) == ELF_HEADER_SIZE, "Invalid ELF header size"); - BX_LAX( read_u16(LE, elf_begin + 54, elf_end) == 0, "Invalid program header size"); - BX_LAX( read_u16(LE, elf_begin + 56, elf_end) == 0, "Invalid num program headers"); - BX_LAX( read_u16(LE, elf_begin + 58, elf_end) == ELF_SECTION_HEADER_SIZE, "Invalid section header size"); - - Buffer_Context buf = { - .begin = pool->dependencies_buffer, - .end = pool->dependencies_buffer + pool->obj_file_offsets[im_num], - .elf = { - .offset = pool->obj_file_offsets[elf_index], - .size = pool->obj_file_offsets[elf_index + 1] - pool->obj_file_offsets[elf_index], - }, - }; - - Offset_Num section_headers = elf_section_headers(buf); - Offset_Size symbol_names = {0}; - Offset_Size symbols = {0}; - - for (i64 sec_index = 0; sec_index < section_headers.num; ++sec_index) { - Section_Header section = elf_section(buf, sec_index); - - 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_STRTAB) - printf("\"%s", "\x1b[33m"); - else - printf("\"%s", "\x1b[31m"); - - c8 *name = elf_name_from_offset(buf, section.name); - printf("%s", name); - printf("%s\"", "\x1b[37m"); - printf("%*s", - (i32) (section.name.size < 30 ? 30 - section.name.size : 1), ""); - - printf("%-14s", SEC_TYPE_NAMES[section.type]); - - if (section.alloc) - printf("R"); - else - printf("_"); - if (section.write) - printf("W"); - else - printf("_"); - if (section.exec) - printf("X"); - else - printf("_"); - - if (section.data.size > 0) - printf(" - %lld bytes", section.data.size); - - printf("\n"); - - switch (section.type) { - case SEC_SYMTAB: - if (symbols.offset == 0) - symbols = section.data; - - if (symbol_names.offset == 0) - symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; - - printf("\n"); - - for (i64 sym_index = 0; sym_index < section.num_entries; ++sym_index) { - Symbol_Entry sym = elf_symbol(buf, section.data, symbol_names, (u16) sym_index); - - c8 *name = elf_name_from_offset(buf, sym.name); - - i32 len = *name == '\0' ? 4 : (i32) sym.name.size; - - printf(" "); - if (*name != '\0') - printf("\""); - - if (sym.bind == BIND_GLOBAL) - printf("\x1b[32m"); - else if (sym.bind == BIND_WEAK) - printf("\x1b[35m"); - else - printf("\x1b[31m"); - - if (*name != '\0') - printf("%s", name); - else - printf("<NONE>"); - printf("\x1b[37m"); - - if (*name != '\0') - printf("\""); - - printf(" "); - if (len < 32) - printf("%.*s ", 32 - len, "........................................"); - printf(" "); - - switch (sym.type) { - case SYM_PROC: printf("\x1b[32mproc "); break; - case SYM_DATA: printf("\x1b[32mdata "); break; - case SYM_DATA_COMMON: printf("\x1b[33mdata "); break; - case SYM_DATA_THREAD_LOCAL: printf("\x1b[35mdata "); break; - case SYM_SECTION: printf("\x1b[31msection"); break; - case SYM_SPECIFIC: printf("\x1b[31mspec "); break; - default: printf(" "); - } - printf("\x1b[37m"); - printf("\n"); - } - - printf("\n"); - break; - - case SEC_RELA: { - if (symbol_names.offset == 0) - symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; - if (symbols.offset == 0) - symbols = elf_find_section_by_name(buf, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data; - - Offset_Size dst = elf_find_related_data(buf, sec_index); - - printf("\n"); - - for (i64 rela_index = 0; rela_index < section.num_entries; ++rela_index) { - Rela_Entry rela = elf_rela(buf, symbols, symbol_names, section.data, dst, rela_index); - - printf(" %-16s", REL_NAMES[rela.type]); - printf( - " %08llx %-+5lld <= ", - rela.dst, - rela.addent - ); - if (rela.symbol.bind == BIND_WEAK) - printf("\x1b[33m"); - else - printf("\x1b[32m"); - printf("%08llx", rela.symbol.value.offset); - printf("\x1b[37m"); - if (rela.symbol.type == SYM_DATA || - rela.symbol.type == SYM_DATA_COMMON || - rela.symbol.type == SYM_DATA_THREAD_LOCAL) - printf(" \x1b[34mdata"); - else if (rela.symbol.type == SYM_PROC) - printf(" \x1b[34mproc"); - else if (rela.symbol.type == SYM_SECTION) - printf(" \x1b[36msect"); - else if (rela.symbol.type == SYM_SPECIFIC) - printf(" \x1b[34mspec"); - else - printf(" \x1b[33mnone"); - printf("\x1b[37m"); - printf(" \"%s\"", elf_name_from_offset(buf, rela.symbol.name)); - printf("\n"); - } - - printf("\n"); - } break; - - case SEC_REL: { - if (symbol_names.offset == 0) - symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; - if (symbols.offset == 0) - symbols = elf_find_section_by_name(buf, SECTION_SYMTAB, sizeof SECTION_SYMTAB - 1).data; - - Offset_Size dst = elf_find_related_data(buf, sec_index); - - printf("\n"); - - for (i64 rel_index = 0; rel_index < section.num_entries; ++rel_index) { - Rel_Entry rel = elf_rel(buf, symbols, symbol_names, section.data, dst, rel_index); - - printf(" %-16s", REL_NAMES[rel.type]); - printf(" %08llx <= ", rel.dst); - if (rel.symbol.bind == BIND_WEAK) - printf("\x1b[33m"); - else - printf("\x1b[32m"); - printf("%08llx", rel.symbol.value.offset); - printf("\x1b[37m"); - if (rel.symbol.type == SYM_DATA || - rel.symbol.type == SYM_DATA_COMMON || - rel.symbol.type == SYM_DATA_THREAD_LOCAL) - printf(" \x1b[34mdata"); - else if (rel.symbol.type == SYM_PROC) - printf(" \x1b[34mproc"); - else if (rel.symbol.type == SYM_SECTION) - printf(" \x1b[36msect"); - else if (rel.symbol.type == SYM_SPECIFIC) - printf(" \x1b[31mspec"); - else - printf(" \x1b[33mnone"); - printf("\x1b[37m"); - printf(" \"%s\"", elf_name_from_offset(buf, rel.symbol.name)); - printf("\n"); - } - - printf("\n"); - } break; - - default:; - } - } - - printf("\n"); - } - } } i64 io_open_read(i64 name_size, c8 *name, void *user_data) { @@ -2348,6 +2404,8 @@ void bx_log(i32 log_level, u32 line, c8 *file, c8 *format, ...) { message, len, "................................................................", file, line); + if (TRACE_BLOCKING) + wait_any_input(); break; default:; @@ -2485,7 +2543,7 @@ i64 n_call(i16 convention, i64 target_proc, i64 num_args, Var *args) { } i64 n_call_by_name(i16 convention, c8 *name, i64 num_args, Var *args) { - return node_ctrl_call_by_name(&g_pool, convention, strlen(name), name, num_args, args); + return node_ctrl_call_by_name(&g_pool, convention, bx_str_len(name, name + MAX_NAME_SIZE), name, num_args, args); } i64 n_ret(i64 num_vals, Var *vals) { @@ -2494,7 +2552,7 @@ i64 n_ret(i64 num_vals, Var *vals) { i64 p_new(c8 *name) { i64 p = proc_init(&g_pool); - proc_set_name(&g_pool, p, strlen(name), name); + proc_set_name(&g_pool, p, bx_str_len(name, name + MAX_NAME_SIZE), name); return p; } @@ -2515,7 +2573,7 @@ void u_entry_point(i64 unit, i64 proc) { } void u_elf_x86_64(i64 unit, c8 *output_file_name) { - i64 out = io_open_write(strlen(output_file_name), output_file_name, NULL); + i64 out = io_open_write(bx_str_len(output_file_name, output_file_name + MAX_PATH_SIZE), output_file_name, NULL); unit_write(&g_pool, unit, FORMAT_ELF | ARCH_X86_64, out, NULL); @@ -2529,13 +2587,13 @@ void l_code(i64 unit, i64 link_unit) { void l_object(i64 unit, c8 *object_library) { i64 l = unit_init(&g_pool, UNIT_LIBRARY_OBJECT); - unit_set_name(&g_pool, l, strlen(object_library), object_library); + unit_set_name(&g_pool, l, bx_str_len(object_library, object_library + MAX_PATH_SIZE), object_library); unit_link_add(&g_pool, unit, l); } void l_static(i64 unit, c8 *static_library) { i64 l = unit_init(&g_pool, UNIT_LIBRARY_STATIC); - unit_set_name(&g_pool, l, strlen(static_library), static_library); + unit_set_name(&g_pool, l, bx_str_len(static_library, static_library + MAX_PATH_SIZE), static_library); unit_link_add(&g_pool, unit, l); } |