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