summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-17 19:05:51 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-17 19:05:51 +0200
commitf6e0b59f79fc413b9556b25eceb05b24608fc415 (patch)
tree25fc5900c3fbf7976c9dad2cd304f53c50ecbbe1
parent71b727868d62f8a77285d6d04ee08df0b6a93376 (diff)
downloadbxgen-f6e0b59f79fc413b9556b25eceb05b24608fc415.zip
Read symbols
-rwxr-xr-xbxgen.c502
1 files changed, 292 insertions, 210 deletions
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);