summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-11-16 05:12:21 +0100
committerMitya Selivanov <automainint@guattari.tech>2024-11-16 05:12:21 +0100
commit896066dfbf1a5cbfd235565d1f770ee5eac9930d (patch)
tree42d7ff93505f2446385e8cef511361ab865ce6fa
parent8c99b5df10b644de003b6e26e270272504200df9 (diff)
downloadbxgen-896066dfbf1a5cbfd235565d1f770ee5eac9930d.zip
two plus two test
-rwxr-xr-xbxgen.c393
1 files changed, 255 insertions, 138 deletions
diff --git a/bxgen.c b/bxgen.c
index e024e5e..09e76f9 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -109,17 +109,17 @@
#/
SRC=${0##*./}
BIN=${SRC%.*}
-gcc \
- -Wall -Wextra -Werror -pedantic \
- -Wno-old-style-declaration \
- -Wno-missing-braces \
- -Wno-unused-variable \
- -Wno-unused-but-set-variable \
- -Wno-unused-parameter \
- -O0 \
- -fsanitize=undefined,address,leak -mshstk \
- -o $BIN $SRC && \
- ./$BIN $@ && \
+gcc \
+ -Wall -Wextra -Werror -pedantic \
+ -Wno-old-style-declaration \
+ -Wno-missing-braces \
+ -Wno-unused-variable \
+ -Wno-unused-but-set-variable \
+ -Wno-unused-parameter \
+ -O0 \
+ -fsanitize=undefined,address,leak \
+ -o $BIN $SRC && \
+ ./$BIN $@ && \
rm $BIN
exit $? # */
#endif
@@ -232,6 +232,7 @@ enum {
DATA_I64,
DATA_F32,
DATA_F64,
+ DATA_ADD,
DATA_REFERENCE,
CTRL_CALL,
CTRL_RET,
@@ -364,6 +365,7 @@ typedef struct {
Var ref;
Ret ret;
Call call;
+ Var add[2];
};
} Node;
@@ -532,6 +534,7 @@ i64 node_data_array_c8(Pool *pool, i64 size, c8 *data);
i64 node_data_ptr(Pool *pool, u64 address);
i64 node_data_i32(Pool *pool, i32 value);
i64 node_data_i64(Pool *pool, i64 value);
+i64 node_data_add(Pool *pool, Var x, Var y);
i64 node_ctrl_call(Pool *pool, i64 target_proc, i64 num_args, Var *args);
i64 node_ctrl_call_by_name(Pool *pool, i64 name_size, c8 *name, i64 num_args, Var *args);
i64 node_ctrl_ret(Pool *pool, i64 num_values, Var *values);
@@ -575,6 +578,7 @@ i64 n_i32(i64 proc, i32 value);
i64 n_i64(i64 proc, i64 value);
i64 n_call(i64 proc, i64 target_proc, i64 num_args, Var *args);
i64 n_call_by_name(i64 proc, c8 *name, i64 num_args, Var *args);
+i64 n_add(i64 proc, Var x, Var y);
i64 n_ret(i64 proc, i64 num_vals, Var *vals);
i64 p_new(i64 unit, c8 *name);
@@ -870,6 +874,16 @@ i64 node_data_i64(Pool *pool, i64 value) {
});
}
+i64 node_data_add(Pool *pool, Var x, Var y) {
+ return node_init(pool, (Node) {
+ .op = DATA_ADD,
+ .add = {
+ x,
+ y,
+ },
+ });
+}
+
u16 resolve_calling_convention(Pool *pool, i64 proc) {
CHECK(pool != NULL, "Invalid arguments",);
CHECK(proc != UNDEFINED, "Invalid arguments",);
@@ -1521,25 +1535,25 @@ void write_f64(u32 ordering, f64 x, void *v, void *v_end) {
// ================================================================
enum {
- HOST_Unknown = 0,
- HOST_Unix,
- HOST_Linux,
- HOST_Windows,
- HOST_macOS,
- HOST_Cygwin,
+ OS_Unknown = 0,
+ OS_Unix,
+ OS_Linux,
+ OS_Windows,
+ OS_macOS,
+ OS_Cygwin,
#if defined(__CYGWIN__)
- HOST = HOST_Cygwin,
+ HOST_OS = OS_Cygwin,
#elif defined(_WIN32)
- HOST = HOST_Windows,
+ HOST_OS = OS_Windows,
#elif defined(__linux__)
- HOST = HOST_Linux,
+ HOST_OS = OS_Linux,
#elif defined(__APPLE__)
- HOST = HOST_macOS,
+ HOST_OS = OS_macOS,
#elif defined(__unix__)
- HOST = HOST_Unix,
+ HOST_OS = OS_Unix,
#else
- HOST = HOST_Unknown,
+ HOST_OS = OS_Unknown,
#endif
// x86_64 constants
@@ -1825,6 +1839,30 @@ void x86_64_emit_node(
// Do nothing
break;
+ case DATA_ADD:
+ CHECK_NODE_(n->add[0]);
+ CHECK_NODE_(n->add[1]);
+
+ Node *x = &pool->entities[n->add[0]].node;
+ Node *y = &pool->entities[n->add[1]].node;
+
+ if (x->op == DATA_I32) {
+ write_u8 (LE, 0xb8, begin, end); // mov eax
+ write_u32(LE, x->lit.as_u32[0], begin + 1, end);
+ } else {
+ FAIL("Not implemented",);
+ }
+
+ if (y->op == DATA_I32) {
+ write_u8 (LE, 0x05, begin + 5, end); // add eax
+ write_u32(LE, y->lit.as_u32[0], begin + 6, end);
+ } else {
+ FAIL("Not implemented",);
+ }
+
+ codegen->offset_code += 10;
+ break;
+
case CTRL_CALL: {
CHECK(n->call.convention == CONV_CDECL, "Not implemented", 0);
CHECK(n->call.target_proc == UNDEFINED, "Not implemented", 0);
@@ -2081,13 +2119,17 @@ void x86_64_emit_node(
case CTRL_RET: {
if ((context & EMIT_ENTRY_PROC) != 0) {
- write_u8 (LE, 0xb8, begin, end); // mov eax
- write_u32(LE, 60, begin + 1, end); // 60
-
if (n->ret.num_vals == 0) {
+ write_u8 (LE, 0xb8, begin, end); // mov eax
+ write_u32(LE, 60, begin + 1, end); // 60
+
write_u8 (LE, 0xbf, begin + 5, end); // mov edi
write_u32(LE, 0, begin + 6, end); // 0
+ write_u8 (LE, 0x0f, begin + 10, end); // syscall
+ write_u8 (LE, 0x05, begin + 11, end);
+
+ codegen->offset_code += 12;
} else {
if (n->ret.num_vals > 1)
LOG(WARNING, "Some return values are ignored for node %lld", node);
@@ -2098,17 +2140,40 @@ void x86_64_emit_node(
CHECK(pool->entities[n_val].type == ENTITY_NODE, "Internal", 0);
Node *val = &pool->entities[n_val].node;
- CHECK(val->op == DATA_I64, "Not implemented", 0);
- CHECK(val->lit.num_bytes == 8, "Not implemented", 0);
- write_u8 (LE, 0xbf, begin + 5, end); // mov edi
- write_u32(LE, *val->lit.as_u32, begin + 6, end); // <- literal
- }
+ switch (val->op) {
+ case DATA_I64: {
+ CHECK(val->lit.num_bytes == 8, "Not implemented", 0);
+
+ write_u8 (LE, 0xb8, begin, end); // mov eax
+ write_u32(LE, 60, begin + 1, end); // 60
+
+ write_u8 (LE, 0xbf, begin + 5, end); // mov edi
+ write_u32(LE, *val->lit.as_u32, begin + 6, end); // <- literal
+
+ write_u8 (LE, 0x0f, begin + 10, end); // syscall
+ write_u8 (LE, 0x05, begin + 11, end);
+
+ codegen->offset_code += 12;
+ } break;
+
+ case DATA_ADD: {
+ write_u8 (LE, 0x89, begin, end); // mov edi
+ write_u32(LE, 0xc7, begin + 1, end); // eax
- write_u8 (LE, 0x0f, begin + 10, end); // syscall
- write_u8 (LE, 0x05, begin + 11, end);
+ write_u8 (LE, 0xb8, begin + 2, end); // mov eax
+ write_u32(LE, 60, begin + 3, end); // 60
- codegen->offset_code += 12;
+ write_u8 (LE, 0x0f, begin + 7, end); // syscall
+ write_u8 (LE, 0x05, begin + 8, end);
+
+ codegen->offset_code += 9;
+ } break;
+
+ default:
+ FAIL("Not implemented",);
+ }
+ }
} else {
CHECK(n->ret.num_vals == 1, "Not implemented", 0);
@@ -2118,14 +2183,27 @@ void x86_64_emit_node(
CHECK(pool->entities[n_val].type == ENTITY_NODE, "Internal", 0);
Node *val = &pool->entities[n_val].node;
- CHECK(val->op == DATA_I32, "Not implemented", 0);
- CHECK(val->lit.num_bytes == 4, "Not implemented", 0);
- write_u8 (LE, 0xb8, begin, end); // mov eax
- write_u32(LE, val->lit.as_u32[0], begin + 1, end);
- write_u8 (LE, 0xc3, begin + 5, end); // ret
+ switch (val->op) {
+ case DATA_I32: {
+ CHECK(val->lit.num_bytes == 4, "Not implemented", 0);
+
+ write_u8 (LE, 0xb8, begin, end); // mov eax
+ write_u32(LE, val->lit.as_u32[0], begin + 1, end);
+ write_u8 (LE, 0xc3, begin + 5, end); // ret
+
+ codegen->offset_code += 6;
+ } break;
+
+ case DATA_ADD: {
+ write_u8(LE, 0xc3, begin + 5, end); // ret
+
+ codegen->offset_code += 1;
+ } break;
- codegen->offset_code += 6;
+ default:
+ FAIL("Not implemented",);
+ }
}
} break;
@@ -3413,7 +3491,7 @@ i64 unit_write_in_memory(
// 4 bytes - flags o + 48
write_u16(LE, ELF_HEADER_SIZE, o + 52, o_end);
write_u16(LE, ELF_PROGRAM_HEADER_SIZE, o + 54, o_end);
- write_u16(LE, num_program_headers, o + 56, o_end);
+ // write_u16(LE, num_program_headers, o + 56, o_end);
// 2 bytes - section header size o + 58
// 2 bytes - num section headers o + 60
// 2 bytes - string table section o + 62
@@ -3431,117 +3509,121 @@ i64 unit_write_in_memory(
u8 *h = o + ELF_HEADER_SIZE;
- // r/o elf header
- write_u32(LE, 1, h, o_end); // type (PT_LOAD)
- write_u32(LE, 4, h + 4, o_end); // flags (PF_R)
- write_i64(LE, 0, h + 8, o_end);
- write_i64(LE, base_address, h + 16, o_end); // virtual address
- write_i64(LE, base_address, h + 24, o_end); // phisical address
- write_i64(LE, ELF_HEADER_SIZE, h + 32, o_end); // size in file
- write_i64(LE, ELF_HEADER_SIZE, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
+ num_program_headers = 0;
// r/x code
- write_u32(LE, 1, h, o_end); // type (PT_LOAD)
- write_u32(LE, 5, h + 4, o_end); // flags (PF_X | PF_R)
- write_i64(LE, rx_code_offset, h + 8, o_end);
- write_i64(LE, rx_code_address, h + 16, o_end); // virtual address
- write_i64(LE, rx_code_address, h + 24, o_end); // phisical address
- write_i64(LE, rx_code_size, h + 32, o_end); // size in file
- write_i64(LE, rx_code_size, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
+ if (rx_code_size > 0) {
+ write_u32(LE, 1, h, o_end); // type (PT_LOAD)
+ write_u32(LE, 5, h + 4, o_end); // flags (PF_X | PF_R)
+ write_i64(LE, rx_code_offset, h + 8, o_end);
+ write_i64(LE, rx_code_address, h + 16, o_end); // virtual address
+ write_i64(LE, rx_code_address, h + 24, o_end); // phisical address
+ write_i64(LE, rx_code_size, h + 32, o_end); // size in file
+ write_i64(LE, rx_code_size, h + 40, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
+ h += ELF_PROGRAM_HEADER_SIZE;
+ ++num_program_headers;
+ }
// r/o data
- write_u32(LE, 1, h, o_end); // type (PT_LOAD)
- write_u32(LE, 4, h + 4, o_end); // flags (PF_R)
- write_i64(LE, ro_data_offset, h + 8, o_end);
- write_i64(LE, ro_data_address, h + 16, o_end); // virtual address
- write_i64(LE, ro_data_address, h + 24, o_end); // phisical address
- write_i64(LE, ro_data_size, h + 32, o_end); // size in file
- write_i64(LE, ro_data_size, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
+ if (ro_data_size > 0) {
+ write_u32(LE, 1, h, o_end); // type (PT_LOAD)
+ write_u32(LE, 4, h + 4, o_end); // flags (PF_R)
+ write_i64(LE, ro_data_offset, h + 8, o_end);
+ write_i64(LE, ro_data_address, h + 16, o_end); // virtual address
+ write_i64(LE, ro_data_address, h + 24, o_end); // phisical address
+ write_i64(LE, ro_data_size, h + 32, o_end); // size in file
+ write_i64(LE, ro_data_size, h + 40, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
+ h += ELF_PROGRAM_HEADER_SIZE;
+ ++num_program_headers;
+ }
// r/w data
- write_u32(LE, 1, h, o_end); // type (PT_LOAD)
- write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
- write_i64(LE, rw_data_offset, h + 8, o_end);
- write_i64(LE, rw_data_address, h + 16, o_end); // virtual address
- write_i64(LE, rw_data_address, h + 24, o_end); // phisical address
- write_i64(LE, rw_data_size, h + 32, o_end); // size in file
- write_i64(LE, rw_data_size, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
+ if (rw_data_size > 0) {
+ write_u32(LE, 1, h, o_end); // type (PT_LOAD)
+ write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
+ write_i64(LE, rw_data_offset, h + 8, o_end);
+ write_i64(LE, rw_data_address, h + 16, o_end); // virtual address
+ write_i64(LE, rw_data_address, h + 24, o_end); // phisical address
+ write_i64(LE, rw_data_size, h + 32, o_end); // size in file
+ write_i64(LE, rw_data_size, h + 40, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
+ h += ELF_PROGRAM_HEADER_SIZE;
+ ++num_program_headers;
+ }
// r/w zero values
- write_u32(LE, 1, h, o_end); // type (PT_LOAD)
- write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
- write_i64(LE, rw_got_offset, h + 8, o_end);
- write_i64(LE, rw_zval_address, h + 16, o_end); // virtual address
- write_i64(LE, rw_zval_address, h + 24, o_end); // phisical address
- write_i64(LE, 0, h + 32, o_end); // size in file
- write_i64(LE, rw_zval_size, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
+ if (rw_zval_size > 0) {
+ write_u32(LE, 1, h, o_end); // type (PT_LOAD)
+ write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
+ write_i64(LE, rw_got_offset, h + 8, o_end);
+ write_i64(LE, rw_zval_address, h + 16, o_end); // virtual address
+ write_i64(LE, rw_zval_address, h + 24, o_end); // phisical address
+ write_i64(LE, 0, h + 32, o_end); // size in file
+ write_i64(LE, rw_zval_size, h + 40, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
+ h += ELF_PROGRAM_HEADER_SIZE;
+ ++num_program_headers;
+ }
// r/w GOT
- write_u32(LE, 1, h, o_end); // type (PT_LOAD)
- write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
- write_i64(LE, rw_got_offset, h + 8, o_end);
- write_i64(LE, rw_got_address, h + 16, o_end); // virtual address
- write_i64(LE, rw_got_address, h + 24, o_end); // phisical address
- write_i64(LE, rw_got_size, h + 32, o_end); // size in file
- write_i64(LE, rw_got_size, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
+ if (rw_got_size > 0) {
+ write_u32(LE, 1, h, o_end); // type (PT_LOAD)
+ write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
+ write_i64(LE, rw_got_offset, h + 8, o_end);
+ write_i64(LE, rw_got_address, h + 16, o_end); // virtual address
+ write_i64(LE, rw_got_address, h + 24, o_end); // phisical address
+ write_i64(LE, rw_got_size, h + 32, o_end); // size in file
+ write_i64(LE, rw_got_size, h + 40, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
+ h += ELF_PROGRAM_HEADER_SIZE;
+ ++num_program_headers;
+ }
// r/w dynamic
- write_u32(LE, 2, h, o_end); // type (PT_DYNAMIC)
- write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
- write_i64(LE, rw_dynamic_offset, h + 8, o_end);
- write_i64(LE, rw_dynamic_address, h + 16, o_end); // virtual address
- write_i64(LE, rw_dynamic_address, h + 24, o_end); // phisical address
- write_i64(LE, rw_dynamic_size, h + 32, o_end); // size in file
- write_i64(LE, rw_dynamic_size, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
-
- // TLS segment
- i64 tls_size_total = align(rw_tls_data_size, X86_64_PAGE_SIZE) + rw_tls_zval_size;
-
- write_u32(LE, 1, h, o_end); // type (PT_LOAD)
- write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
- write_i64(LE, rw_tls_data_offset, h + 8, o_end);
- write_i64(LE, rw_tls_data_address, h + 16, o_end); // virtual address
- write_i64(LE, rw_tls_data_address, h + 24, o_end); // phisical address
- write_i64(LE, rw_tls_data_size, h + 32, o_end); // size in file
- write_i64(LE, tls_size_total, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
+ if (rw_dynamic_size) {
+ write_u32(LE, 2, h, o_end); // type (PT_DYNAMIC)
+ write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
+ write_i64(LE, rw_dynamic_offset, h + 8, o_end);
+ write_i64(LE, rw_dynamic_address, h + 16, o_end); // virtual address
+ write_i64(LE, rw_dynamic_address, h + 24, o_end); // phisical address
+ write_i64(LE, rw_dynamic_size, h + 32, o_end); // size in file
+ write_i64(LE, rw_dynamic_size, h + 40, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
+ h += ELF_PROGRAM_HEADER_SIZE;
+ ++num_program_headers;
+ }
// r/w TLS data
- write_u32(LE, 7, h, o_end); // type (PT_TLS)
- write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
- write_i64(LE, rw_tls_data_offset, h + 8, o_end);
- write_i64(LE, rw_tls_data_address, h + 16, o_end); // virtual address
- write_i64(LE, rw_tls_data_address, h + 24, o_end); // phisical address
- write_i64(LE, rw_tls_data_size, h + 32, o_end); // size in file
- write_i64(LE, rw_tls_data_size, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
+ if (rw_tls_data_size > 0) {
+ write_u32(LE, 7, h, o_end); // type (PT_TLS)
+ write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
+ write_i64(LE, rw_tls_data_offset, h + 8, o_end);
+ write_i64(LE, rw_tls_data_address, h + 16, o_end); // virtual address
+ write_i64(LE, rw_tls_data_address, h + 24, o_end); // phisical address
+ write_i64(LE, rw_tls_data_size, h + 32, o_end); // size in file
+ write_i64(LE, rw_tls_data_size, h + 40, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
+ h += ELF_PROGRAM_HEADER_SIZE;
+ ++num_program_headers;
+ }
// r/w TLS zero values
- write_u32(LE, 7, h, o_end); // type (PT_TLS)
- write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
- write_i64(LE, output_size, h + 8, o_end);
- write_i64(LE, rw_tls_zval_address, h + 16, o_end); // virtual address
- write_i64(LE, rw_tls_zval_address, h + 24, o_end); // phisical address
- write_i64(LE, 0, h + 32, o_end); // size in file
- write_i64(LE, rw_tls_zval_size, h + 40, o_end); // size in memory
- write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
- h += ELF_PROGRAM_HEADER_SIZE;
+ if (rw_tls_zval_size > 0) {
+ write_u32(LE, 7, h, o_end); // type (PT_TLS)
+ write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W)
+ write_i64(LE, output_size, h + 8, o_end);
+ write_i64(LE, rw_tls_zval_address, h + 16, o_end); // virtual address
+ write_i64(LE, rw_tls_zval_address, h + 24, o_end); // phisical address
+ write_i64(LE, 0, h + 32, o_end); // size in file
+ write_i64(LE, rw_tls_zval_size, h + 40, o_end); // size in memory
+ write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end);
+ h += ELF_PROGRAM_HEADER_SIZE;
+ ++num_program_headers;
+ }
+
+ write_u16(LE, num_program_headers, o + 56, o_end);
CHECK(h == o + ELF_HEADER_SIZE + num_program_headers * ELF_PROGRAM_HEADER_SIZE, "Invalid num program headers",);
CHECK(rx_code_offset >= h - o, "Sanity",);
@@ -4062,6 +4144,12 @@ i64 n_call_by_name(i64 proc, c8 *name, i64 num_args, Var *args) {
return n;
}
+i64 n_add(i64 proc, Var x, Var y) {
+ i64 n = node_data_add(&g_pool, x, y);
+ p_add(proc, n);
+ return n;
+}
+
i64 n_ret(i64 proc, i64 num_vals, Var *vals) {
i64 n = node_ctrl_ret(&g_pool, num_vals, vals);
p_add(proc, n);
@@ -4215,7 +4303,7 @@ b8 link_with_libc(void) {
// ============================================================
- if (HOST != HOST_Linux) {
+ if (HOST_OS != OS_Linux) {
LOG(INFO, "Skip running the executable. Host system is not compatible.");
} else if (HO != LE) {
LOG(INFO, "Skip running the executable. Host data ordering is not compatible.");
@@ -4231,6 +4319,34 @@ b8 link_with_libc(void) {
return 1;
}
+b8 two_plus_two(void) {
+ i64 u = u_new();
+
+ i64 mainproc = p_new_entry(u);
+
+ N_RET(
+ mainproc,
+ n_add(mainproc, n_i32(mainproc, 2), n_i32(mainproc, 2))
+ );
+
+ u_elf_x86_64(u, "test_two_plus_two");
+
+ if (HOST_OS != OS_Linux) {
+ LOG(INFO, "Skip running the executable. Host system is not compatible.");
+ } else if (HO != LE) {
+ LOG(INFO, "Skip running the executable. Host data ordering is not compatible.");
+ } else {
+ LOG(VERBOSE, "Running the executable");
+
+ i32 ret = system("./test_two_plus_two");
+
+ if (WEXITSTATUS(ret) != 4)
+ return 0;
+ }
+
+ return 1;
+}
+
#endif // HELPERS
i32 main(i32 argc, c8 **argv) {
@@ -4250,7 +4366,8 @@ i32 main(i32 argc, c8 **argv) {
} while (0)
#if HELPERS
- RUN_TEST_(link_with_libc);
+ // RUN_TEST_(link_with_libc);
+ RUN_TEST_(two_plus_two);
#endif
#undef RUN_TEST_