From f6e0b59f79fc413b9556b25eceb05b24608fc415 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Wed, 17 Jul 2024 19:05:51 +0200 Subject: Read symbols --- bxgen.c | 502 +++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 292 insertions(+), 210 deletions(-) (limited to 'bxgen.c') diff --git a/bxgen.c b/bxgen.c index 7bee369..30f2b9f 100755 --- a/bxgen.c +++ b/bxgen.c @@ -74,6 +74,7 @@ SRC=${0##*./} BIN=${SRC%.*} gcc \ -Wno-old-style-declaration -Wno-missing-braces \ + -Wno-unused-variable \ -Wall -Wextra -Werror -pedantic \ -O0 -fsanitize=undefined,address,leak -mshstk \ -o $BIN $SRC && \ @@ -184,11 +185,11 @@ enum { MAX_LITERAL_SIZE = 400, MAX_NAME_SIZE = 80, - MAX_PROC_COUNT = 40, - MAX_NODE_COUNT = 60, - MAX_LINK_COUNT = 20, - MAX_ARG_COUNT = 20, - MAX_ENTITY_COUNT = 16384, + MAX_NUM_PROCS = 40, + MAX_NUM_NODES = 60, + MAX_NUM_LINKS = 20, + MAX_NUM_ARGS = 20, + MAX_NUM_ENTITIES = 16384, // IO dispatch operations // @@ -228,8 +229,8 @@ typedef struct { } Var; typedef struct { - i16 val_count; - Var vals[MAX_ARG_COUNT]; + i16 num_vals; + Var vals[MAX_NUM_ARGS]; } Ret; typedef struct { @@ -241,8 +242,8 @@ typedef struct { i64 target_proc; i64 target_name_size; c8 target_name[MAX_NAME_SIZE]; // TODO use string table - i64 arg_count; - Var args[MAX_ARG_COUNT]; + i64 num_args; + Var args[MAX_NUM_ARGS]; } Call; // A semantic node is an operation with optional data @@ -267,8 +268,8 @@ typedef struct { i16 convention; i64 name_size; c8 name[MAX_NAME_SIZE]; // TODO use string table - i64 node_count; - i64 nodes[MAX_NODE_COUNT]; + i64 num_nodes; + i64 nodes[MAX_NUM_NODES]; i64 ret_index; i64 unit; i64 index_in_unit; @@ -282,10 +283,10 @@ typedef struct { i64 entry_point_index; i64 name_size; c8 name[MAX_NAME_SIZE]; // TODO use string table - i64 proc_count; - i64 procs[MAX_PROC_COUNT]; - i64 link_count; - i64 links[MAX_LINK_COUNT]; + i64 num_procs; + i64 procs[MAX_NUM_PROCS]; + i64 num_links; + i64 links[MAX_NUM_LINKS]; } Unit; // An entity can be any of: @@ -312,7 +313,7 @@ typedef struct { // We use one single large memory block for *everything*. typedef struct { - i64 entity_count; + i64 num_entities; i64 capacity; Entity *entities; } Pool; @@ -333,9 +334,9 @@ void pool_remove(Pool *pool, i64 entity, i16 type); i64 node_init(Pool *pool, Node data); void node_destroy(Pool *pool, i64 node); i64 node_data_i64(Pool *pool, i64 value); -i64 node_ctrl_call(Pool *pool, i16 convention, i64 target_proc, i64 arg_count, Var *args); -i64 node_ctrl_call_by_name(Pool *pool, i16 convention, i64 name_size, c8 *name, i64 arg_count, Var *args); -i64 node_ctrl_ret(Pool *pool, i64 value_count, Var *values); +i64 node_ctrl_call(Pool *pool, i16 convention, i64 target_proc, i64 num_args, Var *args); +i64 node_ctrl_call_by_name(Pool *pool, i16 convention, i64 name_size, c8 *name, i64 num_args, Var *args); +i64 node_ctrl_ret(Pool *pool, i64 num_values, Var *values); i64 proc_init(Pool *pool); void proc_destroy(Pool *pool, i64 proc); @@ -369,9 +370,9 @@ void io_dispatch(i16 op, i64 *id, i64 *size, void *data, void *user_data); #ifndef DISABLE_HELPERS i64 n_i64(i64 value); -i64 n_call(i16 convention, i64 target_proc, i64 arg_count, Var *args); -i64 n_call_by_name(i16 convention, c8 *name, i64 arg_count, Var *args); -i64 n_ret(i64 val_count, Var *vals); +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); +i64 n_ret(i64 num_vals, Var *vals); i64 p_new(c8 *name); void p_add(i64 proc, i64 node); i64 u_new(); @@ -421,22 +422,12 @@ void l_static(i64 unit, c8 *static_library); bx_assert((condition), error_string, __LINE__, __FILE__) #endif -#ifdef NDEBUG -# define BX_LAX(condition, error_string, fail_result) \ - do { \ - if (!(condition)) { \ - bx_log(WARNING, error_string, __LINE__, __FILE__); \ - } \ - } while (0) -#else -# define BX_LAX(condition, error_string, fail_result) \ - do { \ - if (!(condition)) { \ - bx_log(WARNING, error_string, __LINE__, __FILE__); \ - return fail_result; \ - } \ - } while (0) -#endif +#define BX_LAX(condition, error_string) \ + do { \ + if (!(condition)) { \ + bx_log(WARNING, error_string, __LINE__, __FILE__); \ + } \ + } while (0) #ifdef NDEBUG # define BX_FAIL(error_string, fail_result) \ @@ -449,6 +440,7 @@ void l_static(i64 unit, c8 *static_library); #endif #define BX_LOG(log_level, message) bx_log(log_level, message, __LINE__, __FILE__) +#define BX_TRACE BX_LOG(TRACE,"") i64 bx_align(i64 x, i64 a) { BX_CHECK(a > 0, "Invalid arguments", 0); @@ -480,6 +472,8 @@ b8 bx_mem_eq(void *a, void *b, i64 size) { } i64 bx_str_len(c8 *s, c8 *s_max) { + BX_CHECK(s < s_max, "Buffer overflow", 0); + for (i64 len = 0; s + len < s_max; ++len) if (s[len] == '\0') return len; @@ -516,9 +510,9 @@ c8 *bx_find_char(c8 *s, c8 *s_end, c8 c) { i64 pool_add(Pool *pool, Entity data) { BX_CHECK(pool != NULL && pool->entities != NULL, "Invalid arguments", UNDEFINED); - BX_CHECK(pool->entity_count < pool->capacity, "Out of memory", UNDEFINED); + BX_CHECK(pool->num_entities < pool->capacity, "Out of memory", UNDEFINED); - i64 id = pool->entity_count++; + i64 id = pool->num_entities++; data.is_enabled = 1, pool->entities[id] = data; @@ -553,17 +547,17 @@ i64 node_data_i64(Pool *pool, i64 value) { }); } -i64 node_ctrl_call(Pool *pool, i16 convention, i64 target_proc, i64 arg_count, Var *args) { - BX_CHECK(arg_count <= MAX_ARG_COUNT, "Array too big", UNDEFINED); +i64 node_ctrl_call(Pool *pool, i16 convention, i64 target_proc, i64 num_args, Var *args) { + BX_CHECK(num_args <= MAX_NUM_ARGS, "Array too big", UNDEFINED); Call call = { .convention = convention, .target_proc = target_proc, - .arg_count = arg_count, + .num_args = num_args, }; - if (arg_count > 0) - bx_mem_cpy(call.args, args, arg_count * sizeof *args); + if (num_args > 0) + bx_mem_cpy(call.args, args, num_args * sizeof *args); return node_init(pool, (Node) { .op = CTRL_CALL, @@ -571,19 +565,19 @@ i64 node_ctrl_call(Pool *pool, i16 convention, i64 target_proc, i64 arg_count, V }); } -i64 node_ctrl_call_by_name(Pool *pool, i16 convention, i64 name_size, c8 *name, i64 arg_count, Var *args) { - BX_CHECK(arg_count <= MAX_ARG_COUNT, "Array too big", UNDEFINED); +i64 node_ctrl_call_by_name(Pool *pool, i16 convention, i64 name_size, c8 *name, i64 num_args, Var *args) { + BX_CHECK(num_args <= MAX_NUM_ARGS, "Array too big", UNDEFINED); Call call = { .convention = convention, .target_name_size = name_size, - .arg_count = arg_count, + .num_args = num_args, }; if (name_size > 0) bx_mem_cpy(call.target_name, name, name_size); - if (arg_count > 0) - bx_mem_cpy(call.args, args, arg_count * sizeof *args); + if (num_args > 0) + bx_mem_cpy(call.args, args, num_args * sizeof *args); return node_init(pool, (Node) { .op = CTRL_CALL, @@ -591,13 +585,13 @@ i64 node_ctrl_call_by_name(Pool *pool, i16 convention, i64 name_size, c8 *name, }); } -i64 node_ctrl_ret(Pool *pool, i64 value_count, Var *values) { - BX_CHECK(value_count <= MAX_ARG_COUNT, "Array too big", UNDEFINED); +i64 node_ctrl_ret(Pool *pool, i64 num_values, Var *values) { + BX_CHECK(num_values <= MAX_NUM_ARGS, "Array too big", UNDEFINED); - Ret ret = { .val_count = value_count, }; + Ret ret = { .num_vals = num_values, }; - if (value_count > 0) - bx_mem_cpy(ret.vals, values, value_count * sizeof *values); + if (num_values > 0) + bx_mem_cpy(ret.vals, values, num_values * sizeof *values); return node_init(pool, (Node) { .op = CTRL_RET, @@ -654,7 +648,7 @@ void proc_node_add(Pool *pool, i64 proc, i64 node) { BX_CHECK(n->index_in_proc == UNDEFINED, "Internal",); - i64 index = p->node_count; + i64 index = p->num_nodes; if (n->op == CTRL_RET) { @@ -665,11 +659,11 @@ void proc_node_add(Pool *pool, i64 proc, i64 node) { p->ret_index = index; } - BX_CHECK(index < MAX_NODE_COUNT, "Out of memory",); + BX_CHECK(index < MAX_NUM_NODES, "Out of memory",); n->index_in_proc = index; p->nodes[index] = node; - ++p->node_count; + ++p->num_nodes; } void proc_node_remove(Pool *pool, i64 proc, i64 node) { @@ -719,13 +713,13 @@ void unit_proc_add(Pool *pool, i64 unit, i64 proc) { BX_CHECK(p->index_in_unit == UNDEFINED, "Internal",); - i64 index = u->proc_count; + i64 index = u->num_procs; - BX_CHECK(index < MAX_PROC_COUNT, "Out of memory",); + BX_CHECK(index < MAX_NUM_PROCS, "Out of memory",); p->index_in_unit = index; u->procs[index] = proc; - ++u->proc_count; + ++u->num_procs; } void unit_proc_remove(Pool *pool, i64 unit, i64 proc) { @@ -756,12 +750,12 @@ void unit_link_add(Pool *pool, i64 unit, i64 link_unit) { Unit *u = &pool->entities[unit].unit; - for (i64 i = 0; i < u->link_count; ++i) + for (i64 i = 0; i < u->num_links; ++i) if (u->links[i] == link_unit) return; - BX_CHECK(u->link_count < MAX_LINK_COUNT, "Internal",); - u->links[u->link_count++] = link_unit; + BX_CHECK(u->num_links < MAX_NUM_LINKS, "Internal",); + u->links[u->num_links++] = link_unit; } void unit_link_remove(Pool *pool, i64 unit, i64 link_unit) { @@ -772,7 +766,7 @@ void unit_link_remove(Pool *pool, i64 unit, i64 link_unit) { Unit *u = &pool->entities[unit].unit; - for (i64 i = 0; i < u->link_count; ++i) + for (i64 i = 0; i < u->num_links; ++i) if (u->links[i] == link_unit) { u->links[i] = UNDEFINED; return; @@ -909,7 +903,7 @@ u32 host_data_ordering() { u8 read_u8(u32 ordering, u8 *v, u8 *v_end) { BX_CHECK(v != NULL, "Invalid arguments", 0); - BX_CHECK(v < v_end, "Invalid arguments", 0); + BX_CHECK(v < v_end, "Buffer overflow", 0); if ((ordering & BIT_ORDER_MASK) == host_bit_order()) return *v; @@ -927,7 +921,7 @@ u8 read_u8(u32 ordering, u8 *v, u8 *v_end) { u16 read_u16(u32 ordering, u8 *v, u8 *v_end) { BX_CHECK(v != NULL, "Invalid arguments", 0); - BX_CHECK(v + 2 <= v_end, "Invalid arguments", 0); + BX_CHECK(v + 2 <= v_end, "Buffer overflow", 0); u16 x; @@ -946,7 +940,7 @@ u16 read_u16(u32 ordering, u8 *v, u8 *v_end) { u32 read_u32(u32 ordering, u8 *v, u8 *v_end) { BX_CHECK(v != NULL, "Invalid arguments", 0); - BX_CHECK(v + 4 <= v_end, "Invalid arguments", 0); + BX_CHECK(v + 4 <= v_end, "Buffer overflow", 0); u32 x; @@ -966,7 +960,7 @@ u32 read_u32(u32 ordering, u8 *v, u8 *v_end) { u64 read_u64(u32 ordering, u8 *v, u8 *v_end) { BX_CHECK(v != NULL, "Invalid arguments", 0); - BX_CHECK(v + 8 <= v_end, "Invalid arguments", 0); + BX_CHECK(v + 8 <= v_end, "Buffer overflow", 0); u64 x; @@ -987,7 +981,7 @@ u64 read_u64(u32 ordering, u8 *v, u8 *v_end) { void write_u8(u8 ordering, u8 x, u8 *v, u8 *v_end) { BX_CHECK(v != NULL, "Invalid arguments",); - BX_CHECK(v < v_end, "Invalid arguments",); + BX_CHECK(v < v_end, "Buffer overflow",); if ((ordering & BIT_ORDER_MASK) == host_bit_order()) *v = x; @@ -1005,7 +999,7 @@ void write_u8(u8 ordering, u8 x, u8 *v, u8 *v_end) { void write_u16(u32 ordering, u16 x, u8 *v, u8 *v_end) { BX_CHECK(v != NULL, "Invalid arguments",); - BX_CHECK(v + 2 <= v_end, "Invalid arguments",); + BX_CHECK(v + 2 <= v_end, "Buffer overflow",); if ((ordering & BIT_ORDER_MASK) == host_bit_order() && (ordering & BYTE_ORDER_MASK) == host_byte_order()) @@ -1021,7 +1015,7 @@ void write_u16(u32 ordering, u16 x, u8 *v, u8 *v_end) { void write_u32(u32 ordering, u32 x, u8 *v, u8 *v_end) { BX_CHECK(v != NULL, "Invalid arguments",); - BX_CHECK(v + 4 <= v_end, "Invalid arguments",); + BX_CHECK(v + 4 <= v_end, "Buffer overflow",); if ((ordering & BIT_ORDER_MASK) == host_bit_order() && (ordering & BYTE_ORDER_MASK) == host_byte_order() && @@ -1038,7 +1032,7 @@ void write_u32(u32 ordering, u32 x, u8 *v, u8 *v_end) { void write_u64(u32 ordering, u64 x, u8 *v, u8 *v_end) { BX_CHECK(v != NULL, "Invalid arguments",); - BX_CHECK(v + 8 <= v_end, "Invalid arguments",); + BX_CHECK(v + 8 <= v_end, "Buffer overflow",); if ((ordering & BIT_ORDER_MASK) == host_bit_order() && (ordering & BYTE_ORDER_MASK) == host_byte_order() && @@ -1253,8 +1247,8 @@ typedef struct { typedef struct { u64 offset; - u16 count; -} Offset_Count; + u16 num; +} Offset_Num; typedef struct { Offset_Size name; @@ -1262,6 +1256,7 @@ typedef struct { u64 flags; u64 alignment; u64 entry_size; + u32 num_entries; Offset_Size data; } Section_Header; @@ -1292,14 +1287,14 @@ u32 ar_find_symbol_offset_by_name(u8 *ar_symbol_table, u8 *ar_end, c8 *name, c8 BX_CHECK(name != NULL, "Invalid arguments", -1); BX_CHECK(name_end > name, "Invalid arguments", -1); - u32 count = read_u32((LE & ~BYTE_ORDER_MASK) | BYTE_BE, ar_symbol_table, ar_end); + u32 num = read_u32((LE & ~BYTE_ORDER_MASK) | BYTE_BE, ar_symbol_table, ar_end); i64 len = name_end - name; - c8 *s = (c8 *) (ar_symbol_table + 4 * (count + 1)); + c8 *s = (c8 *) (ar_symbol_table + 4 * (num + 1)); u32 index = 0; - for (; index < count; ++index) { + for (; index < num; ++index) { BX_CHECK(s + len <= (c8 *) ar_end, "Buffer overflow", -1); if (s[len] == '\0' && bx_mem_eq(s, name, len)) return read_u32((LE & ~BYTE_ORDER_MASK) | BYTE_BE, ar_symbol_table + 4 * (index + 1), ar_end); @@ -1313,17 +1308,17 @@ u32 ar_find_symbol_offset_by_name(u8 *ar_symbol_table, u8 *ar_end, c8 *name, c8 BX_FAIL("Symbol not found", 0); } -Offset_Count elf_section_headers( +Offset_Num elf_section_headers( Buffer_Context b ) { u8 *begin = b.begin + b.elf.offset; u8 *end = begin + b.elf.size; - BX_CHECK(end <= b.end, "Buffer overflow", (Offset_Count) {0}); + BX_CHECK(end <= b.end, "Buffer overflow", (Offset_Num) {0}); - return (Offset_Count) { + return (Offset_Num) { .offset = b.elf.offset + read_u64(LE, begin + 40, end), - .count = read_u16(LE, begin + 60, end), + .num = read_u16(LE, begin + 60, end), }; } @@ -1343,7 +1338,7 @@ Offset_Size elf_section_names_data( u16 string_table_index = read_u16(LE, elf_begin + 62, elf_end); - u8 *begin = elf_begin + elf_section_header_offset(b, string_table_index); + u8 *begin = b.begin + elf_section_header_offset(b, string_table_index); return (Offset_Size) { .offset = b.elf.offset + read_u64(LE, begin + 24, elf_end), @@ -1356,18 +1351,17 @@ Offset_Size elf_name_in_string_table( Offset_Size string_table, u32 name_offset ) { - u8 *elf_begin = b.begin + b.elf.offset; - u8 *elf_end = elf_begin + b.elf.size; - BX_CHECK(elf_end <= b.end, "Buffer overflow", (Offset_Size) {0}); - - u64 offset = string_table.offset + name_offset; - c8 *begin = (c8 *) (b.begin + offset); - c8 *end = begin + string_table.size; + if (name_offset == 0 || name_offset >= string_table.size) + return (Offset_Size) { + .offset = 0, + .size = 0, + }; - BX_CHECK(end <= (c8 *) elf_end, "Buffer overflow", (Offset_Size) {0}); + c8 *begin = (c8 *) b.begin + string_table.offset + name_offset; + c8 *end = (c8 *) b.begin + string_table.offset + string_table.size; return (Offset_Size) { - .offset = offset, + .offset = string_table.offset + name_offset, .size = bx_str_len(begin, end), }; } @@ -1377,23 +1371,28 @@ u16 elf_find_section_index_by_name( c8 * name, u32 name_size ) { - u8 *elf_begin = b.begin + b.elf.offset; - u8 *elf_end = elf_begin + b.elf.size; - BX_CHECK(elf_end <= b.end, "Buffer overflow", 0); + BX_CHECK(name != NULL, "Invalid arguments", 0); + + if (name_size == 0) + return 0; - Offset_Count headers = elf_section_headers(b); - Offset_Size names = elf_section_names_data(b); + Offset_Num headers = elf_section_headers(b); + Offset_Size names = elf_section_names_data(b); - for (u16 i = 0; i < headers.count; ++i) { - u8 *begin = b.begin + headers.offset + i * ELF_SECTION_HEADER_SIZE; - u32 name_offset = read_u32(LE, begin, elf_end); + for (u16 i = 0; i < headers.num; ++i) { + u8 *begin = b.begin + headers.offset + i * ELF_SECTION_HEADER_SIZE; + u32 name_index = read_u32(LE, begin, b.end); + Offset_Size s = elf_name_in_string_table(b, names, name_index); - if (name_offset + name_size <= names.size && - bx_mem_eq(elf_begin + names.offset + name_offset, name, name_size)) + if (s.size == name_size && + bx_mem_eq(b.begin + s.offset, name, name_size)) return i; } - BX_FAIL("Not found", 0); + BX_LOG(TRACE, name); + BX_LAX(0, "Not found"); + + return 0; } Section_Header elf_section( @@ -1405,17 +1404,21 @@ Section_Header elf_section( u8 * end = b.begin + b.elf.offset + b.elf.size; BX_CHECK(end <= b.end, "Buffer overflow", (Section_Header) {0}); - u32 name_index = read_u32(LE, begin, end); + u32 name_index = read_u32(LE, begin, end); + u64 size = read_u64(LE, begin + 32, end); + u64 entry_size = read_u64(LE, begin + 56, end); + u32 num_entries = entry_size > 0 ? size / entry_size : 0; return (Section_Header) { - .name = elf_name_in_string_table(b, names, name_index), - .type = read_u32(LE, begin + 4, end), - .flags = read_u64(LE, begin + 8, end), - .alignment = read_u64(LE, begin + 48, end), - .entry_size = read_u64(LE, begin + 56, end), + .name = elf_name_in_string_table(b, names, name_index), + .type = read_u32(LE, begin + 4, end), + .flags = read_u64(LE, begin + 8, end), + .alignment = read_u64(LE, begin + 48, end), + .entry_size = entry_size, + .num_entries = num_entries, .data = { .offset = b.elf.offset + read_u64(LE, begin + 24, end), - .size = read_u64(LE, begin + 32, end), + .size = size, }, }; } @@ -1459,18 +1462,10 @@ u16 elf_find_related_section_index( return elf_find_section_index_by_name(b, begin, (u32) (end - begin)); } -u16 elf_num_entries( - Buffer_Context b, - u8 section_index -) { - Section_Header h = elf_section(b, section_index); - return h.data.size / h.entry_size; -} - Symbol_Entry elf_symbol( Buffer_Context b, - Offset_Size string_table, Offset_Size symbol_table, + Offset_Size string_table, u16 symbol_index ) { u8 *begin = b.begin + symbol_table.offset + symbol_index * ELF_SYMBOL_ENTRY_SIZE; @@ -1485,9 +1480,11 @@ Symbol_Entry elf_symbol( u64 sym_value = read_u64(LE, begin + 8, end); u64 sym_size = read_u64(LE, begin + 16, end); - Offset_Size dst = elf_section(b, sym_shndx).data; + Offset_Size dst = + sym_shndx < elf_section_headers(b).num ? elf_section(b, sym_shndx).data + : (Offset_Size) {0}; - BX_CHECK(sym_value + sym_size <= dst.size, "Buffer overflow", (Symbol_Entry) {0}); + BX_CHECK(dst.size == 0 || sym_value + sym_size <= dst.size, "Buffer overflow", (Symbol_Entry) {0}); u8 type = (sym_info & 0xf) == 1 ? SYM_DATA : (sym_info & 0xf) == 2 ? SYM_PROC : @@ -1512,8 +1509,8 @@ Symbol_Entry elf_symbol( Rel_Entry elf_rel( Buffer_Context b, - Offset_Size string_table, Offset_Size symbol_table, + Offset_Size string_table, u16 section_index, u16 rel_index ) { @@ -1528,7 +1525,7 @@ Rel_Entry elf_rel( u32 rel_type = read_u32(LE, begin + 8, end); u32 rel_sym = read_u32(LE, begin + 12, end); - Symbol_Entry sym = elf_symbol(b, string_table, symbol_table, rel_sym); + Symbol_Entry sym = elf_symbol(b, symbol_table, string_table, rel_sym); return (Rel_Entry) { .name = sym.name, @@ -1539,8 +1536,8 @@ Rel_Entry elf_rel( Rela_Entry elf_rela( Buffer_Context b, - Offset_Size string_table, Offset_Size symbol_table, + Offset_Size string_table, u16 section_index, u16 rela_index ) { @@ -1556,7 +1553,7 @@ Rela_Entry elf_rela( u32 rela_sym = read_u32(LE, begin + 12, end); i64 rela_addent = read_i64(LE, begin + 16, end); - Symbol_Entry sym = elf_symbol(b, string_table, symbol_table, rela_sym); + Symbol_Entry sym = elf_symbol(b, symbol_table, string_table, rela_sym); return (Rela_Entry) { .name = sym.name, @@ -1568,16 +1565,15 @@ Rela_Entry elf_rela( Symbol_Entry elf_find_symbol_by_name( Buffer_Context b, - Offset_Size string_table, u32 symbol_table_index, + Offset_Size string_table, c8 * name, u32 name_size ) { - u32 num_symbols = elf_num_entries(b, symbol_table_index); + Section_Header symbol_table = elf_section(b, symbol_table_index); - for (u32 i = 0; i < num_symbols; ++i) { - Offset_Size symbol_table = elf_section(b, symbol_table_index).data; - Symbol_Entry sym = elf_symbol(b, string_table, symbol_table, i); + for (u32 i = 0; i < symbol_table.num_entries; ++i) { + Symbol_Entry sym = elf_symbol(b, symbol_table.data, string_table, i); BX_CHECK(b.begin + sym.name.offset + name_size <= b.end, "Buffer overflow", (Symbol_Entry) {0}); BX_CHECK(sym.name.offset + name_size <= b.elf.size, "Buffer overflow", (Symbol_Entry) {0}); @@ -1589,6 +1585,20 @@ Symbol_Entry elf_find_symbol_by_name( BX_FAIL("Not found", (Symbol_Entry) {0}); } +c8 *elf_name_from_offset( + Buffer_Context b, + Offset_Size name +) { + if (name.size == 0) + return ""; + + c8 *begin = (c8 *) (b.begin + name.offset); + i64 len = bx_str_len(begin, (c8 *) b.end); + + BX_CHECK((i64) name.size == len, "Buffer overflow", ""); + return begin; +} + 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",); BX_CHECK(pool->entities[unit].is_enabled, "Unit does not exist",); @@ -1643,9 +1653,9 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data WRITE_4( 0 ); // flags WRITE_2( ELF_HEADER_SIZE ); WRITE_2( ELF_PROGRAM_HEADER_SIZE ); - WRITE_2( 1 ); // program header count + WRITE_2( 1 ); // num program headers WRITE_2( 0 ); // section header size - WRITE_2( 0 ); // section header count + WRITE_2( 0 ); // num section headers WRITE_2( 0 ); // string table section header index // Program header @@ -1693,7 +1703,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data Unit *u = &pool->entities[unit].unit; - for (i64 link_index = 0; link_index < u->link_count; ++link_index) { + for (i64 link_index = 0; link_index < u->num_links; ++link_index) { i64 id = u->links[link_index]; if (id == UNDEFINED) continue; @@ -1754,9 +1764,9 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data bx_mem_cpy(im_buffer + im_size, f_data, fn_size); - im_offsets[im_num++] = im_size; - im_size += delta_size; im_offsets[im_num] = im_size; + im_size += delta_size; + im_offsets[++im_num] = im_size; } f_begin = f_data + fn_size; @@ -1787,15 +1797,101 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data 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",); - // We can ignore this - BX_CHECK( read_u64(LE, elf_begin + 24, elf_end) == 0, "Invalid ELF file",); // entry - BX_CHECK( read_u64(LE, elf_begin + 32, elf_end) == 0, "Invalid ELF file",); // program header offset - BX_CHECK( read_u32(LE, elf_begin + 48, elf_end) == 0, "Invalid ELF file",); // flags - BX_CHECK( read_u16(LE, elf_begin + 52, elf_end) == ELF_HEADER_SIZE, "Invalid ELF file",); - BX_CHECK( read_u16(LE, elf_begin + 54, elf_end) == 0, "Invalid ELF file",); // program header size - BX_CHECK( read_u16(LE, elf_begin + 56, elf_end) == 0, "Invalid ELF file",); // program header count - BX_CHECK( read_u16(LE, elf_begin + 58, elf_end) == ELF_SECTION_HEADER_SIZE, "Invalid ELF file",); + BX_LAX( read_u64(LE, elf_begin + 24, elf_end) == 0, "Invalid ELF file"); // entry + BX_LAX( read_u64(LE, elf_begin + 32, elf_end) == 0, "Invalid ELF file"); // program header offset + BX_LAX( read_u32(LE, elf_begin + 48, elf_end) == 0, "Invalid ELF file"); // flags + BX_LAX( read_u16(LE, elf_begin + 52, elf_end) == ELF_HEADER_SIZE, "Invalid ELF file"); + BX_LAX( read_u16(LE, elf_begin + 54, elf_end) == 0, "Invalid ELF file"); // program header size + BX_LAX( read_u16(LE, elf_begin + 56, elf_end) == 0, "Invalid ELF file"); // num program headers + BX_LAX( read_u16(LE, elf_begin + 58, elf_end) == ELF_SECTION_HEADER_SIZE, "Invalid ELF file"); + + Buffer_Context buf = { + .begin = im_buffer, + .end = im_buffer + im_offsets[im_num], + .elf = { + .offset = im_offsets[elf_index], + .size = im_offsets[elf_index + 1] - im_offsets[elf_index], + }, + }; + + Offset_Num section_headers = elf_section_headers(buf); + // Offset_Size section_names = elf_section_names_data(buf); + Offset_Size symbol_names = elf_find_section_by_name(buf, SECTION_STRTAB, sizeof SECTION_STRTAB - 1).data; + + for (u16 sec_index = 0; sec_index < section_headers.num; ++sec_index) { + Section_Header section = elf_section(buf, sec_index); + + if (section.type == 2 || section.type == 4 || section.type == 9) // sym/rela/rel + printf("\"%s", "\x1b[32m"); + else if ((section.flags & 2) != 0) // alloc + printf("\"%s", "\x1b[34m"); + else if (section.type == 3) // string table + 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( + "%-10s", + section.type >= 1 && section.type <= 9 ? + (c8 *[]) { + "Program", + "Symbols", + "Strings", + "Rel add", + "Hash", + "Dynamic", + "Note", + "Zeros", + "Rel", + }[section.type - 1] : + section.type == 17 ? + "Group" : + "" + ); + + if ((section.flags & 2) == 2) + printf("R"); + else + printf("_"); + if ((section.flags & 1) == 1) + printf("W"); + else + printf("_"); + if ((section.flags & 4) == 4) + printf("X"); + else + printf("_"); + + if (section.data.size > 0) + printf(" - %lld bytes", section.data.size); + printf("\n"); + + switch (section.type) { + case 2: { // sym + for (u32 sym_index = 0; sym_index < section.num_entries; ++sym_index) { + Symbol_Entry sym = elf_symbol(buf, section.data, symbol_names, (u16) sym_index); + printf(" %s\n", elf_name_from_offset(buf, sym.name)); + } + } break; + + case 4: { // rela + } break; + + case 9: { // rel + } break; + + default:; + } + } + + printf("\n"); } // ========================================================== @@ -1811,7 +1907,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data { Unit *u = &pool->entities[unit].unit; - for (i64 i = 0; i < u->link_count; ++i) { + for (i64 i = 0; i < u->num_links; ++i) { if (u->links[i] == UNDEFINED) continue; @@ -1879,15 +1975,15 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // AR symbol table // - u32 count_be; - n = io_read(f, 4, &count_be, io_user_data); if (n == 0) break; + u32 num_be; + n = io_read(f, 4, &num_be, io_user_data); if (n == 0) break; current_offset += n; num_symbols = - (( count_be & 0xffu) << 24) | - (((count_be >> 8) & 0xffu) << 16) | - (((count_be >> 16) & 0xffu) << 8) | - ((count_be >> 24) & 0xffu); + (( num_be & 0xffu) << 24) | + (((num_be >> 8) & 0xffu) << 16) | + (((num_be >> 16) & 0xffu) << 8) | + ((num_be >> 24) & 0xffu); printf("Symbol table - %lld symbols.\n\n", num_symbols); BX_CHECK(num_symbols <= (i64) (sizeof offsets / sizeof *offsets), "",); @@ -1905,7 +2001,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data } if (n == 0) break; - i64 byte_count = 0; + i64 num_bytes = 0; for (u32 j = 0; j < num_symbols; ++j) { i64 symbol_size = 0; @@ -1913,7 +2009,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data c8 c; n = io_read(f, 1, &c, io_user_data); if (n == 0) break; current_offset += n; - ++byte_count; + ++num_bytes; if (c == '\0') break; BX_CHECK(symbol_size < 256, "",); @@ -1924,7 +2020,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data } if (n == 0) break; - if ((byte_count & 1) == 1) { + if ((num_bytes & 1) == 1) { // align io_seek(f, 1, IO_SEEK_CURSOR, io_user_data); current_offset += 1; @@ -1933,17 +2029,17 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // String table // - i64 byte_count = atoi(size); - if ((byte_count & 1) == 1) - ++byte_count; // align + i64 num_bytes = atoi(size); + if ((num_bytes & 1) == 1) + ++num_bytes; // align b8 has_line = 0; - while (byte_count > 0) { + while (num_bytes > 0) { c8 c; n = io_read(f, 1, &c, io_user_data); if (n == 0) break; current_offset += n; - byte_count -= n; + num_bytes -= n; if (c == '\0') { if (has_line) { printf("\n"); @@ -1988,16 +2084,16 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // // Decode ELF object file - i64 byte_count = atoi(size); - if ((byte_count & 1) == 1) - ++byte_count; // align + i64 num_bytes = atoi(size); + if ((num_bytes & 1) == 1) + ++num_bytes; // align i64 begin_offset = current_offset; u8 buf[16]; n = io_read(f, sizeof buf, buf, io_user_data); if (n == 0) break; current_offset += n; - byte_count -= n; + num_bytes -= n; BX_CHECK(buf[0] == 0x7f, "",); BX_CHECK(buf[1] == 'E', "",); @@ -2015,11 +2111,11 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data &(x), \ io_user_data); \ current_offset += n; \ - byte_count -= n; \ + num_bytes -= n; \ } while (0) u64 section_header_offset; - u16 section_count; + u16 num_sections; u16 strings_index; u64 strings_offset; @@ -2038,7 +2134,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data u32 flags; u16 elf_header_size; u16 program_header_size; - u16 program_header_count; + u16 num_program_headers; u16 section_header_size; READ(type); @@ -2050,9 +2146,9 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data READ(flags); READ(elf_header_size); READ(program_header_size); - READ(program_header_count); + READ(num_program_headers); READ(section_header_size); - READ(section_count); + READ(num_sections); READ(strings_index); BX_CHECK(type == ELF_RELOCATABLE, "",); @@ -2064,13 +2160,13 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data BX_CHECK(flags == 0, "",); BX_CHECK(elf_header_size == 64, "",); BX_CHECK(program_header_size == 0, "",); - BX_CHECK(program_header_count == 0, "",); + BX_CHECK(num_program_headers == 0, "",); BX_CHECK(section_header_size == 64, "",); u64 section_offset = section_header_offset - (current_offset - begin_offset); io_seek(f, section_offset, IO_SEEK_CURSOR, io_user_data); - byte_count -= section_offset; + num_bytes -= section_offset; current_offset += section_offset; // Find offset to the section name string table data @@ -2091,9 +2187,9 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // { i64 prev_offset = current_offset; - i64 prev_byte_count = byte_count; + i64 prev_num_bytes = num_bytes; - for (u16 i = 0; i < section_count; ++i) { + for (u16 i = 0; i < num_sections; ++i) { io_seek(f, begin_offset + section_header_offset + i * 64, IO_SEEK_BEGIN, io_user_data); @@ -2127,11 +2223,11 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data io_seek(f, prev_offset, IO_SEEK_BEGIN, io_user_data); current_offset = prev_offset; - byte_count = prev_byte_count; + num_bytes = prev_num_bytes; } } - for (u16 i = 0; i < section_count; ++i) { + for (u16 i = 0; i < num_sections; ++i) { u32 name; u32 type; u64 flags; @@ -2249,7 +2345,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data BX_CHECK(entsize == 24, "",); i64 prev_offset = current_offset; - i64 prev_byte_count = byte_count; + i64 prev_num_bytes = num_bytes; io_seek(f, begin_offset + offset, IO_SEEK_BEGIN, io_user_data); @@ -2257,7 +2353,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data printf("\n"); - for (byte_count = size; byte_count > 0;) { + for (num_bytes = size; num_bytes > 0;) { BX_CHECK(symbol_names_found, "",); u32 sym_name; @@ -2339,7 +2435,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data io_seek(f, prev_offset, IO_SEEK_BEGIN, io_user_data); current_offset = prev_offset; - byte_count = prev_byte_count; + num_bytes = prev_num_bytes; } break; // ================================================== @@ -2350,13 +2446,13 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data BX_CHECK(entsize == 16, "",); i64 prev_offset = current_offset; - i64 prev_byte_count = byte_count; + i64 prev_num_bytes = num_bytes; io_seek(f, begin_offset + offset, IO_SEEK_BEGIN, io_user_data); current_offset = begin_offset + offset; printf("\n"); - for (byte_count = size; byte_count > 0;) { + for (num_bytes = size; num_bytes > 0;) { u64 rel_offset; u64 rel_info; @@ -2376,7 +2472,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data io_seek(f, prev_offset, IO_SEEK_BEGIN, io_user_data); current_offset = prev_offset; - byte_count = prev_byte_count; + num_bytes = prev_num_bytes; } break; // ================================================== @@ -2397,13 +2493,13 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data BX_CHECK(entsize == 24, "",); i64 prev_offset = current_offset; - i64 prev_byte_count = byte_count; + i64 prev_num_bytes = num_bytes; io_seek(f, begin_offset + offset, IO_SEEK_BEGIN, io_user_data); current_offset = begin_offset + offset; printf("\n"); - for (byte_count = size; byte_count > 0;) { + for (num_bytes = size; num_bytes > 0;) { u64 rela_offset; u64 rela_info; i64 rela_addent; @@ -2423,12 +2519,12 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // { i64 prev_offset = current_offset; - i64 prev_byte_count = byte_count; + i64 prev_num_bytes = num_bytes; u64 sym_size = 0; // Go to the symbol table - for (u64 j = 0; j < section_count; ++j) { + for (u64 j = 0; j < num_sections; ++j) { io_seek(f, begin_offset + section_header_offset + j * 64 + 4, IO_SEEK_BEGIN, io_user_data); u32 type; READ(type); @@ -2469,7 +2565,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data io_seek(f, prev_offset, IO_SEEK_BEGIN, io_user_data); current_offset = prev_offset; - byte_count = prev_byte_count; + num_bytes = prev_num_bytes; } printf("\n"); @@ -2479,7 +2575,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data io_seek(f, prev_offset, IO_SEEK_BEGIN, io_user_data); current_offset = prev_offset; - byte_count = prev_byte_count; + num_bytes = prev_num_bytes; } break; // ================================================== @@ -2490,8 +2586,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data printf("\n"); - io_seek(f, byte_count, IO_SEEK_CURSOR, io_user_data); - current_offset += byte_count; + io_seek(f, num_bytes, IO_SEEK_CURSOR, io_user_data); + current_offset += num_bytes; #undef READ @@ -2578,7 +2674,7 @@ void io_chmod_exe(i64 f, void *user_data) { } while (0) void bx_log(i32 log_level, c8 *message, u32 line, c8 *file) { - if (*message == '\0') { + if (*message == '\0' && log_level != TRACE) { fprintf(log_level == ERROR || log_level == WARNING ? stderr : stdout, "\n"); return; } @@ -2739,8 +2835,8 @@ Pool g_pool = { // TODO // Reallocate the memory block when necessary. - .capacity = MAX_ENTITY_COUNT, - .entities = (Entity[MAX_ENTITY_COUNT]) { 0 }, + .capacity = MAX_NUM_ENTITIES, + .entities = (Entity[MAX_NUM_ENTITIES]) { 0 }, }; // Handy procedures @@ -2750,16 +2846,16 @@ i64 n_i64(i64 value) { return node_data_i64(&g_pool, value); } -i64 n_call(i16 convention, i64 target_proc, i64 arg_count, Var *args) { - return node_ctrl_call(&g_pool, convention, target_proc, arg_count, args); +i64 n_call(i16 convention, i64 target_proc, i64 num_args, Var *args) { + return node_ctrl_call(&g_pool, convention, target_proc, num_args, args); } -i64 n_call_by_name(i16 convention, c8 *name, i64 arg_count, Var *args) { - return node_ctrl_call_by_name(&g_pool, convention, strlen(name), name, arg_count, 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); } -i64 n_ret(i64 val_count, Var *vals) { - return node_ctrl_ret(&g_pool, val_count, vals); +i64 n_ret(i64 num_vals, Var *vals) { + return node_ctrl_ret(&g_pool, num_vals, vals); } i64 p_new(c8 *name) { @@ -2823,20 +2919,6 @@ int main(int argc, char **argv) { (void) argc; (void) argv; - BX_LOG(ERROR, "Error example" ); - BX_LOG(WARNING, "Warning example"); - BX_LOG(INFO, "Info example" ); - BX_LOG(VERBOSE, "Verbose example"); - BX_LOG(TRACE, "Trace example" ); - - BX_LOGF(TRACE, "host bit order: %s", host_bit_order() == BIT_LE ? "LE" : "BE"); - BX_LOGF(TRACE, "host byte order: %s", host_byte_order() == BYTE_LE ? "LE" : "BE"); - BX_LOGF(TRACE, "host word order: %s", host_word_order() == WORD_LE ? "LE" : "BE"); - BX_LOGF(TRACE, "host dword order: %s", host_dword_order() == DWORD_LE ? "LE" : "BE"); - BX_LOGF(TRACE, "host f64 dword order: %s", host_f64_dword_order() == F64_DWORD_LE ? "LE" : "BE"); - - BX_LOGF(TRACE, "entity - %d bytes", (i32) sizeof(Entity)); - i64 main = p_new("main"); i64 n0 = n_i64(42); p_add(main, n0); -- cgit v1.2.3