diff options
-rwxr-xr-x | bxgen.c | 195 | ||||
-rw-r--r-- | compile_flags.txt | 2 |
2 files changed, 118 insertions, 79 deletions
@@ -1,77 +1,92 @@ -#if 0 -SRC=${0##*/} +#if 0 /* +#/ ================================================================ +#/ +#/ bxgen.c +#/ +#/ Binary executable code generation and linking. +#/ Compiler backend. +#/ +#/ ================================================================ +#/ +#/ Qualities +#/ +#/ - Single source file (for now) +#/ - Simple and flexible API +#/ - No external dependencies +#/ - No configuration required +#/ - No dynamic memory management +#/ - Easy cross-compilation +#/ - Platform-independent host +#/ +#/ Inspirations +#/ +#/ - Cuik https://github.com/RealNeGate/Cuik +#/ - tinycc https://repo.or.cz/w/tinycc.git +#/ - QBE https://c9x.me/compile/ +#/ +#/ To-Do list +#/ +#/ - ELF + x86_64 executable +#/ - x86_64 object file +#/ - Linking libraries +#/ - String table for names and arrays +#/ - Proper error handling +#/ - Proper prefixes for identifiers +#/ - Correct serialization for endianness +#/ - Effective entity allocation +#/ - Implicit procedure prototypes +#/ - Implicit exit after ret from entry point +#/ - Static single-assignment +#/ - Sea of Nodes +#/ - Optimization layers +#/ - Multithreading +#/ - Memory reallocation when necessary +#/ - JIT +#/ - COFF, PE, OMF, Mach-O +#/ - i386, RISC-V, ARM, WebAssembly +#/ - Built-in standard library +#/ +#/ Bugs +#/ +#/ - ... +#/ +#/ Done features +#/ +#/ - ELF header +#/ - IO static dispatch +#/ +#/ ================================================================ +#/ +#/ Self-compilation shell script +#/ +#/ ================================================================ +SRC=${0##*./} BIN=${SRC%.*} gcc \ - -Wno-old-style-declaration \ - -Wno-missing-field-initializers -Wno-missing-braces \ + -Wno-old-style-declaration -Wno-missing-braces \ -Wall -Wextra -Werror -pedantic \ -O0 -fsanitize=undefined,address,leak -mshstk \ - -o $BIN $SRC && \ + -o $BIN $SRC && \ ./$BIN $@ -exit $? +exit $? # */ #endif - -// ================================================================ -// -// bxgen.c -// Binary executable code generation - compiler backend -// -// Qualities -// -// - Single source file (for now) -// - Simple and flexible API -// - No external dependencies -// - No configuration required -// - No dynamic memory management -// - Easy cross-compilation -// - Platform-independent host -// -// Inspirations -// -// - Cuik https://github.com/RealNeGate/Cuik -// - tinycc https://repo.or.cz/w/tinycc.git -// - QBE https://c9x.me/compile/ -// -// To-Do list -// -// - ELF + x86_64 executable -// - x86_64 object file -// - Linking libraries -// - String table for names and arrays -// - Proper error handling -// - Proper prefixes for identifiers -// - Correct serialization for endianness -// - Effective entity allocation -// - Implicit procedure prototypes -// - Implicit exit after ret from entry point -// - Static single-assignment -// - Sea of Nodes -// - Optimization layers -// - Multithreading -// - Memory reallocation when necessary -// - JIT -// - COFF, PE, OMF, Mach-O -// - i386, RISC-V, ARM, WebAssembly -// - Built-in standard library -// -// Bugs -// -// - ... -// -// Done features -// -// - ELF header -// - IO static dispatch -// // ================================================================ // // Compilation options // // ================================================================ -//#define DISABLE_IMPLEMENTATION -//#define DISABLE_HELPERS -//#define DISABLE_TESTING +#ifndef IMPLEMENTATION +#define IMPLEMENTATION 1 +#endif + +#ifndef HELPERS +#define HELPERS 1 +#endif + +#ifndef TESTING +#define TESTING 1 +#endif // ================================================================ // @@ -99,6 +114,27 @@ typedef char c8; // 8-bit character // ================================================================ enum { + HOST_Unknown = 0, + HOST_Unix, + HOST_Linux, + HOST_Windows, + HOST_macOS, + HOST_Cygwin, + + #if defined(__CYGWIN__) + HOST = HOST_Cygwin, + #elif defined(_WIN32) + HOST = HOST_Windows, + #elif defined(__linux__) + HOST = HOST_Linux, + #elif defined(__APPLE__) + HOST = HOST_macOS, + #elif defined(__unix__) + HOST = HOST_Unix, + #else + HOST = HOST_Unknown, + #endif + // For indices UNDEFINED = -1, @@ -383,7 +419,7 @@ void l_static(i64 unit, c8 *static_library); // // ================================================================ -#ifndef DISABLE_IMPLEMENTATION +#if IMPLEMENTATION #ifdef __cplusplus #error Implementation code should be compiled with a C compiler! @@ -399,12 +435,12 @@ void l_static(i64 unit, c8 *static_library); #define BX_ASSERT(condition) \ bx_assert((condition), #condition, __LINE__, __FILE__) -static i64 bx_align(i64 x, i64 a) { +i64 bx_align(i64 x, i64 a) { BX_ASSERT(a > 0); return x + ((a - (x % a)) % a); } -static void bx_mem_cpy(void *dst, void const *src, i64 size) { +void bx_mem_cpy(void *dst, void const *src, i64 size) { BX_ASSERT(dst != NULL); BX_ASSERT(src != NULL); BX_ASSERT(size > 0); @@ -413,7 +449,7 @@ static void bx_mem_cpy(void *dst, void const *src, i64 size) { ((u8 *)dst)[i] = ((u8 const *)src)[i]; } -static b8 bx_mem_eq(void const *a, void const *b, i64 size) { +b8 bx_mem_eq(void const *a, void const *b, i64 size) { BX_ASSERT(a != NULL); BX_ASSERT(b != NULL); BX_ASSERT(size > 0); @@ -428,7 +464,7 @@ static b8 bx_mem_eq(void const *a, void const *b, i64 size) { return 1; } -static b8 bx_str_eq( +b8 bx_str_eq( c8 const *a, c8 const *a_end, c8 const *b, c8 const *b_end ) { @@ -443,7 +479,7 @@ static b8 bx_str_eq( return a == a_end && b == b_end; } -static c8 *bx_find_char(c8 *s, c8 *s_end, c8 c) { +c8 *bx_find_char(c8 *s, c8 *s_end, c8 c) { BX_ASSERT(s != NULL); BX_ASSERT(s_end != NULL); @@ -1007,6 +1043,9 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // LLVM impl https://github.com/llvm/llvm-project/blob/main/lld/ELF/Driver.cpp#L2822 // https://github.com/llvm/llvm-project/blob/main/lld/ELF/Writer.cpp#L304 // https://github.com/llvm/llvm-project/blob/main/lld/ELF/OutputSections.cpp#L469 + // + // Online assembler + // https://defuse.ca/online-x86-assembler.htm BX_ASSERT(pool != NULL && pool->entities != NULL); BX_ASSERT(pool->entities[unit].is_enabled); @@ -1051,10 +1090,10 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data #define WRITE_8(x) io_write( io_out, 8, &(u64) { x }, io_user_data ) u8 code[16] = { - 0xb8, // mov rax - 0x3c, 0, 0, 0, // 60 // exit - 0x48, 0x31, 0xff, // xor rdx, rdx // rdx = 0 - 0x0f, 0x05, // syscall + 0xb8, // mov rax + 0x3c, 0, 0, 0, // 60 // exit + 0x48, 0x31, 0xff, // xor rdx, rdx // rdx = 0 + 0x0f, 0x05, // syscall }; u64 code_offset = bx_align(ELF_HEADER_SIZE + ELF_PROGRAM_HEADER_SIZE, X86_64_ALIGNMENT); @@ -1127,8 +1166,8 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data // Intermediate buffer // - static u8 in_buffer[1024 * 1024 * 300]; // 300 MB - static i64 ar_offsets[128]; + u8 static in_buffer[1024 * 1024 * 300]; // 300 MB + i64 static ar_offsets[128]; i64 ar_count = 0; // Read all dependency files into the memory @@ -1917,7 +1956,7 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data if (size > 0) { io_seek(f, begin_offset + offset + rela_offset, IO_SEEK_BEGIN, io_user_data); - static u8 buf[4]; + u8 static buf[4]; if (sym_size > 4) sym_size = 4; io_read(f, sym_size, buf, io_user_data); @@ -2019,7 +2058,7 @@ void io_chmod_exe(i64 f, void *user_data) { // // ================================================================ -#ifndef DISABLE_HELPERS +#if HELPERS #include <stdio.h> #include <stdlib.h> @@ -2135,7 +2174,7 @@ void io_dispatch(i16 op, i64 *id, i64 *size, void *data, void *user_data) { // Global state // -static Pool g_pool = { +Pool g_pool = { // Statically allocate a large memory block. // // TODO @@ -2219,7 +2258,7 @@ void l_static(i64 unit, c8 *static_library) { // // ================================================================ -#if !defined(DISABLE_HELPERS) && !defined(DISABLE_TESTING) +#if HELPERS && TESTING int main(int argc, char **argv) { (void) argc; diff --git a/compile_flags.txt b/compile_flags.txt index 5e93f58..1c01682 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1 +1 @@ --Wall -Wextra -Werror -pedantic -Isource +-Wall -Wextra -Werror -pedantic |