summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbxgen.c195
-rw-r--r--compile_flags.txt2
2 files changed, 118 insertions, 79 deletions
diff --git a/bxgen.c b/bxgen.c
index 3efa7e3..95a3e03 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -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