diff --git a/.gitignore b/.gitignore index efbdc99..9d3f7ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ /bin /lib /a -/src/ciabatta.c -/src/include/conf.h a.out *.a *.so @@ -16,7 +14,5 @@ a.out *.4coder *.rdbg /.venv -tinyrt-iface.h test/ -test_folder/ vgcore.* \ No newline at end of file diff --git a/src/windows/chkstk.asm b/arch/x86-64/chkstk.asm similarity index 100% rename from src/windows/chkstk.asm rename to arch/x86-64/chkstk.asm diff --git a/src/loader/loader-entry.asm b/arch/x86-64/loader-entry.asm similarity index 100% rename from src/loader/loader-entry.asm rename to arch/x86-64/loader-entry.asm diff --git a/build.py b/build.py index 97326d9..d05b757 100755 --- a/build.py +++ b/build.py @@ -1,14 +1,12 @@ #!/usr/bin/env python3 -import argparse # Parsing command-line args +import importlib import platform # Checking current OS -import shutil import os import sys -import pyjson5 import re -# Colors + class colors: grey='\033[38;5;243m' cyan='\033[38;5;80m' @@ -21,219 +19,16 @@ class colors: def print_step(step): print(f'{colors.green}==>{colors.reset} {step}', end='') -# Parse command line arguments -arg_parser = argparse.ArgumentParser('build.py') -arg_parser.add_argument('--clean', action='store_true', help='Remove all object files and binaries') -arg_parser.add_argument('--test', help='Compile ciabatta executable with given file') -arg_parser.add_argument('--mode', '-m', choices=['debug', 'release'], default='debug', help='Select build configuration') -arg_parser.add_argument('--target', '-t', help='Select target OS (default=host)') -arg_parser.add_argument('--compiler', '-c', choices=['clang', 'cuik'], default='clang', help='Select compiler') -arg_parser.add_argument('--cflags', nargs='*', default=[], help='Pass additional compiler flags') -args = arg_parser.parse_args() -compiler = args.compiler - - -# Perform cleaning if required -def rm(path): - if os.path.exists(path): - os.remove(path) -if args.clean: - if os.path.exists('bin'): - shutil.rmtree('bin') - if os.path.exists('lib'): - shutil.rmtree('lib') - rm(os.path.join('src', 'ciabatta.c')) - rm('a') - rm('a.exe') - rm('a.ilk') - rm('a.pdb') - sys.exit(0) - -# Check host OS -print_step('Performing basic checks\n') -target = args.target -if target is None: - target = platform.system().lower() -target_colored = f'{colors.cyan}{target}{colors.reset}' -print(f" * Compiling for host OS: '{target_colored}'") -if not os.path.exists(os.path.join('src', target)): - print(colors.red, f" ERROR: OS '{colors.cyan}{target}{colors.red}' isn't implemented.", colors.reset) - sys.exit(1) - -# Add compiler to dependencies -dependencies = [ - 'nasm', - 'llvm-ar' -] -dependencies.append(args.compiler) - - -# Figure out the flags -includes = ['src/include'] -cc = args.compiler -cc_defines = [] -cc_flags = ['-nostdlib', '-fno-stack-protector'] -crt_file = 'crt.lib' -lib_file = 'cia.lib' -dl_file = 'ld-cia.so' -if args.mode == 'release': - cc_flags.append('-O2') - cc_defines.append('NDEBUG') -else: # 'debug' - cc_flags.append('-g') - cc_flags.append('-O0') - cc_defines.append('_DEBUG') -if target != 'windows': - cc_flags.append('-fpic') - -if target == 'linux': - includes.append('src/include/linux') - -# Check dependencies -print_step('Checking dependencies... ') -for dependency in dependencies: - if shutil.which(dependency) is None: - print(colors.red, f"\n -> [ERROR] Missing dependency: '{dependency}'", colors.reset) - sys.exit(1) -print(colors.green, 'OK', colors.reset) - -# Generate TinyRT headers for the target platform -print_step(f'Generating TinyRT header for: {target_colored}... ') -tinyrt_config_path = os.path.join('src', target, 'tinyrt.json') -tinyrt_apis = [] -try: - with open(tinyrt_config_path, 'r') as tinyrt_config_file: - string = tinyrt_config_file.read() - json = '{' + string + '}' - tinyrt_config = pyjson5.loads(json) -except Exception as error: - print(colors.red, f"\n -> [ERROR] reading file '{tinyrt_config_path}'") - print(f" * {error}", colors.reset) - sys.exit(1) -tinyrt_header_path = os.path.join('src', target, 'tinyrt-iface.h') -try: - with open(tinyrt_header_path, 'w') as tinyrt_header_file: - tinyrt_header_file.write('\n') - tinyrt_header_file.write(f'// This file is AUTO-GENERATED from {tinyrt_config_path}\n') - tinyrt_header_file.write('\n') - for tinyrt_api in tinyrt_config: - api_name = tinyrt_api - is_defined = tinyrt_config[tinyrt_api] - if is_defined: - tinyrt_apis.append(api_name) - is_defined_int = 1 if is_defined else 0 - tinyrt_header_file.write(f'#define _{api_name.upper()} {is_defined_int}\n') -except Exception as error: - print(colors.red, f" -> [ERROR] writing to file '{tinyrt_header_path}'") - print(f" * {error}", colors.reset) - sys.exit(1) -print(colors.green, 'OK', colors.reset) - -# Generate ciabatta header for the target platform and configuration -print_step('Generating ciabatta.c\n') -library_config_path = os.path.join('src', 'library.json') -try: - with open(library_config_path, 'r') as library_config_file: - string = library_config_file.read() - json = '{' + string + '}' - library_config = pyjson5.loads(json) -except Exception as error: - print(colors.red, f" ERROR when reading file '{library_config_path}':") - print(f" {error}", colors.reset) - sys.exit(1) -ciabatta_header_path = os.path.join('src', 'ciabatta.c') -try: - with open(ciabatta_header_path, 'w') as ciabatta_header: - # Write heading - ciabatta_header.write('\n') - ciabatta_header.write('// This file is AUTO-GENERATED by library.json\n') - ciabatta_header.write('\n') - # Write main include - ciabatta_header.write('#include \n') - ciabatta_header.write('\n') - # Write platform includes - ciabatta_header.write('// Platform-dependent sources\n') - platform_config = None - for platform in library_config['platforms']: - if platform['name'] == target: - platform_config = platform - if platform_config is None: - print(colors.red, f" ERROR: library config doesn't contain configuration for platform {target}", colors.reset, sep='') - for include in platform_config['includes']: - include_path = platform_config['path'] - ciabatta_header.write(f'#include <{include}>\n') - for source in platform_config['sources']: - source_path = platform_config['path'] - ciabatta_header.write(f'#include "{source_path}/{source}"\n') - ciabatta_header.write(f'#include "{target}/tinyrt-iface.h"\n') - ciabatta_header.write(f'#include \n') - for tinyrt_source in platform_config['tinyrt']: - ciabatta_header.write(f'#include "{target}/{tinyrt_source}"\n') - ciabatta_header.write('\n') - # Write module includes - ciabatta_header.write('// Forward declarations') - for include in library_config['includes']: - ciabatta_header.write(f'#include <{include}>\n') - ciabatta_header.write('\n') - # Write module sources - mod_exports = [] - requirements_satisfied = True - for api in library_config['apis']: - api_name = api['name'] - api_path = api['path'] - if api_name in library_config['export']: - reqs_satisfied = True - # Check API dependencies - for req in api['reqs']: - if req in tinyrt_apis: - continue - elif req in mod_exports: - continue - reqs_satisfied = False - break - if not reqs_satisfied: - print(colors.red, f" * Not exporting API '{api_name}'", colors.reset, sep='') - requirements_satisfied = False - else: - print(colors.green, f" * Exporting API '{api_name}'", colors.reset, sep='') - ciabatta_header.write(f'// Module {api_name}\n') - mod_exports.append(api_name) - for include in api['includes']: - ciabatta_header.write(f'#include "{api_path}/{include}"\n') - if not requirements_satisfied: - sys.exit(1) -except Exception as error: - print(colors.red, f" ERROR writing file '{ciabatta_header_path}':", sep='') - print(f" {error}", colors.reset) - sys.exit(1) -print_step('Generating cia-conf.h\n') - def path(str): l = str.split('/') return os.path.join(*l) + def quote(s): return '"' + s + '"' + def prefix(prefix): return (lambda s: prefix + s) -cc_flags_str = ' '.join( - cc_flags + - list(map(prefix('-D '), cc_defines)) + - list(map(prefix('-I '), map(quote, includes)))) - -try: - with open(os.path.join('src', 'include', 'cia-conf.h'), 'w') as conf_file: - os_config = open(os.path.join('src', target, 'conf.h')) - conf_file.write('\n') - conf_file.write('// This file is AUTO-GENERATED\n') - conf_file.write('// See os folder (e.g. src/linux) for conf.h file\n') - conf_file.write(os_config.read()) - os_config.close() -except Exception as error: - print(colors.red, f" ERROR writing file '{ciabatta_header_path}':", sep='') - print(f" {error}", colors.reset) - sys.exit(1) - def run(cmdline): cmdline_colored = re.sub(r'"(.+?)"', f'{colors.grey}"\\1"{colors.reset}', cmdline) cmdline_colored = re.sub(r'^([a-zA-Z0-9-_]*)', f'{colors.yellow}\\1{colors.reset}', cmdline_colored) @@ -242,24 +37,36 @@ def run(cmdline): if code != 0: sys.exit(code) -def assemble(src, out): - format = 'elf64' - if target == 'windows': - format = 'win64' - cmdline = f'nasm -f "{format}" "{path(src)}" -o "{path(out)}"' +cc_flags = [] +cc_defines = [] +cc_includes = [] + +def compile(output, inputs, additional_flags=[]): + flags_cmdline = ' '.join(cc_flags + additional_flags) + defines_cmdline = ' '.join(map(prefix('-D '), map(quote, cc_defines))) + includes_cmdline = ' '.join(map(prefix('-I '), map(quote, cc_includes))) + inputs_cmdline = ' '.join(inputs) + cmdline = f'clang {flags_cmdline} {includes_cmdline} {defines_cmdline} {inputs_cmdline} -o {output}' run(cmdline) -def compile(srcs, out, extra_flags = ''): - if cc == 'cuik' and out.endswith('.o'): - out = out[:-2] - flags = cc_flags_str + ' ' + extra_flags + ' ' + ' '.join(args.cflags) - inputs = ' '.join(map(quote, map(path, srcs))) - cmdline = f'{cc} {flags} {inputs} -o {quote(path(out))}' +def compile_obj(output, inputs, additional_flags=[]): + compile(output, inputs, ['-c -fpic'] + additional_flags) + +def compile_exe(output, inputs, additional_flags=[]): + compile(output, inputs, ['-pie'] + additional_flags) + +def compile_shared(output, inputs, additional_flags=[]): + compile(output, inputs, ['-shared'] + additional_flags) + +def assemble_obj(output, inputs, flags=[]): + flags_cmdline = ' '.join(flags) + inputs_cmdline = ' '.join(inputs) + cmdline = f'nasm {flags_cmdline} {inputs_cmdline} -o {output}' run(cmdline) -def archive(srcs, out): - inputs = ' '.join(map(quote, srcs)) - cmdline = f'llvm-ar -rcs {quote(out)} {inputs}' +def archive(output, inputs): + inputs_cmdline = ' '.join(inputs) + cmdline = f'llvm-ar -rcs {output} {inputs_cmdline}' run(cmdline) # Ciabatta build spec @@ -268,46 +75,35 @@ if not os.path.exists('lib'): if not os.path.exists('bin'): os.mkdir('bin') -cia_lib = f'lib/{lib_file}' -crt_lib = f'lib/{crt_file}' -dl_lib = f'lib/{dl_file}' - -dl_flags = [ - '-shared', - '-nostdlib', - # '-mno-sse', - '-ffreestanding', - '-fno-stack-protector', +loader_flags = [ '-Wl,-e,_dlstart', '-Wl,--sort-section,alignment', '-Wl,--sort-common', '-Wl,--gc-sections', '-Wl,--hash-style=both', '-Wl,--no-undefined', - '-Wl,--exclude-libs=ALL', + '-Wl,--exclude-libs=ALL' ] -if target == 'linux': - print_step(f'Compiling {dl_lib}\n') - assemble('src/loader/loader-entry.asm', 'bin/loader-entry.o') - compile(['bin/loader-entry.o', 'src/loader/loader-self-reloc.c', 'src/loader/loader.c'], dl_lib, - ' '.join(dl_flags)) +target_arch = 'x86-64' +target_os = 'linux' -print_step(f'Compiling {crt_file}\n') -if target == 'linux': - compile(['src/linux/crt-ctors.c'], 'bin/crt-ctors.o', '-c') - archive(['bin/crt-ctors.o'], crt_lib) -elif target == 'windows': - assemble('src/windows/chkstk.asm', 'bin/chkstk.o') - compile(['src/windows/crt-entry.c'], 'bin/crt-entry.o', '-c') - archive(['bin/crt-entry.o', 'bin/chkstk.o'], crt_lib) +cc_flags.extend(['-nostdlib', '-fno-stack-protector']) +cc_flags.extend(['-g', '-O0']) +cc_defines.append('_DEBUG') +cc_defines.append(f'_CIA_OS_CONF=\\"os/{target_os}/conf.h\\"') -print_step(f'Compiling {lib_file}\n') -compile(['src/ciabatta.c'], 'bin/ciabatta.o', '-c') -archive(['bin/ciabatta.o'], cia_lib) +cc_includes.append('include') +cc_includes.append('include/linux') -if args.test: - if target == 'linux': - compile([args.test, crt_lib, cia_lib], 'a', f'-pie -Wl,-dynamic-linker,{dl_lib} -fno-stack-protector') - elif target == 'windows': - compile([args.test, crt_lib, cia_lib], 'a.exe', '-lkernel32.lib') +# Build the dynamic loader +print_step("Building lib/ld-cia.so\n") +assemble_obj('bin/loader-entry.o', [f'arch/{target_arch}/loader-entry.asm'], ['-f "elf64"']) +compile_shared('lib/ld-cia.so', ['bin/loader-entry.o','loader/loader-self-reloc.c','loader/loader.c'], loader_flags) + +# Build the ciabatta +compile_obj('bin/cia.o', ['cia.c']) +archive('lib/cia.a', ['bin/cia.o']) + +# Build the test +compile_exe('a', ['tests/hello.c', 'lib/cia.a'], ['-Wl,-dynamic-linker,lib/ld-cia.so']) diff --git a/cia.c b/cia.c new file mode 100644 index 0000000..2117646 --- /dev/null +++ b/cia.c @@ -0,0 +1,26 @@ + +#include + +// Platform-dependent sources +#include _CIA_OS_CONF + +// Forward declarations +#include +#include +#include +#include + +// Module cia_memory +#include "src/cia-mem/util.c" +#include "src/cia-mem/allocator.c" +#include "src/cia-mem/arena.c" +#include "src/cia-mem/pool.c" + +// Module stdlib_program +#include "src/stdlib-program/program.c" + +// Module stdlib_threads +#include "src/stdlib-thread/thread.c" + +// Module stdlib_file +#include "src/stdlib-file/file.c" diff --git a/commands.sh b/commands.sh new file mode 100644 index 0000000..59d0aad --- /dev/null +++ b/commands.sh @@ -0,0 +1,10 @@ +==> Compiling lib/ld-cia.so + $ nasm -f "elf64" "loader/loader-entry.asm" -o "bin/loader-entry.o" + $ clang -nostdlib -fno-stack-protector -g -O0 -fpic -D _DEBUG -I "include" -I "include/linux" -shared -nostdlib -ffreestanding -fno-stack-protector -Wl,-e,_dlstart -Wl,--sort-section,alignment -Wl,--sort-common -Wl,--gc-sections -Wl,--hash-style=both -Wl,--no-undefined -Wl,--exclude-libs=ALL "bin/loader-entry.o" "loader/loader-self-reloc.c" "loader/loader.c" -o "lib/ld-cia.so" +==> Compiling crt.lib + $ clang -nostdlib -fno-stack-protector -g -O0 -fpic -D _DEBUG -I "include" -I "include/linux" -c "os/linux/crt-ctors.c" -o "bin/crt-ctors.o" + $ llvm-ar -rcs "lib/crt.lib" "bin/crt-ctors.o" +==> Compiling cia.lib + $ clang -nostdlib -fno-stack-protector -g -O0 -fpic -D _DEBUG -I "include" -I "include/linux" -c "include/cia.c" -o "bin/cia.o" + $ llvm-ar -rcs "lib/cia.lib" "bin/cia.o" + $ clang -nostdlib -fno-stack-protector -g -O0 -fpic -D _DEBUG -I "include" -I "include/linux" -pie -Wl,-dynamic-linker,lib/ld-cia.so -fno-stack-protector "tests/hello.c" "lib/crt.lib" "lib/cia.lib" -o "a" diff --git a/src/include/bin/elf.h b/include/bin/elf.h similarity index 100% rename from src/include/bin/elf.h rename to include/bin/elf.h diff --git a/src/include/cia-conf.h b/include/cia-conf.h similarity index 64% rename from src/include/cia-conf.h rename to include/cia-conf.h index 1f6f898..c302c1e 100644 --- a/src/include/cia-conf.h +++ b/include/cia-conf.h @@ -2,5 +2,5 @@ // This file is AUTO-GENERATED // See os folder (e.g. src/linux) for conf.h file -#define _CIA_OS_LINUX -#define _CIA_DATA_LP64 +#define CIA_OS_LINUX +#define CIA_DATA_LP64 diff --git a/src/include/cia-def.h b/include/cia-def.h similarity index 100% rename from src/include/cia-def.h rename to include/cia-def.h diff --git a/src/include/cia-mem.h b/include/cia-mem.h similarity index 100% rename from src/include/cia-mem.h rename to include/cia-mem.h diff --git a/src/include/ctype.h b/include/ctype.h similarity index 100% rename from src/include/ctype.h rename to include/ctype.h diff --git a/src/include/errno.h b/include/errno.h similarity index 100% rename from src/include/errno.h rename to include/errno.h diff --git a/src/include/linux/fcntl.h b/include/linux/fcntl.h similarity index 100% rename from src/include/linux/fcntl.h rename to include/linux/fcntl.h diff --git a/src/include/linux/sched.h b/include/linux/sched.h similarity index 100% rename from src/include/linux/sched.h rename to include/linux/sched.h diff --git a/src/include/linux/sys/mman.h b/include/linux/sys/mman.h similarity index 100% rename from src/include/linux/sys/mman.h rename to include/linux/sys/mman.h diff --git a/src/include/linux/sys/syscall.h b/include/linux/sys/syscall.h similarity index 100% rename from src/include/linux/sys/syscall.h rename to include/linux/sys/syscall.h diff --git a/src/include/stdbool.h b/include/stdbool.h similarity index 100% rename from src/include/stdbool.h rename to include/stdbool.h diff --git a/src/include/stddef.h b/include/stddef.h similarity index 100% rename from src/include/stddef.h rename to include/stddef.h diff --git a/src/include/stdint.h b/include/stdint.h similarity index 92% rename from src/include/stdint.h rename to include/stdint.h index 5ee6a51..f0b80ed 100644 --- a/src/include/stdint.h +++ b/include/stdint.h @@ -5,9 +5,9 @@ static_assert(sizeof(char) == 1, "Char isn't 1 bytes long"); static_assert(sizeof(short) == 2, "Short isn't 2 bytes long"); static_assert(sizeof(int) == 4, "Int isn't 4 bytes long"); static_assert(sizeof(long long int) == 8, "Long long isn't 8 bytes long"); -#if defined(_CIA_DATA_LP64) +#if defined(CIA_DATA_LP64) static_assert(sizeof(long) == 8, "Long on linux isn't 8 bytes"); -#elif defined(_CIA_DATA_LLP64) +#elif defined(CIA_DATA_LLP64) static_assert(sizeof(long) == 4, "Long on windows isn't 4 bytes"); #endif @@ -17,10 +17,10 @@ typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; -#if defined(_CIA_DATA_LP64) +#if defined(CIA_DATA_LP64) typedef signed long int64_t; typedef unsigned long uint64_t; -#elif defined(_CIA_DATA_LLP64) +#elif defined(CIA_DATA_LLP64) typedef signed long long int64_t; typedef unsigned long long uint64_t; #else @@ -50,12 +50,12 @@ typedef uint64_t uintptr_t; #define UINT16_C(n) (n) #define UINT32_C(n) (n) -#if defined(_CIA_DATA_LP64) +#if defined(CIA_DATA_LP64) #define INT64_C(n) (n ## L) #define INTMAX_C(n) (n ## L) #define UINT64_C(n) (n ## UL) #define UINTMAX_C(n) (n ## UL) -#elif defined(_CIA_DATA_LLP64) +#elif defined(CIA_DATA_LLP64) #define INT64_C(n) (n ## LL) #define INTMAX_C(n) (n ## LL) #define UINT64_C(n) (n ## ULL) diff --git a/src/include/stdio.h b/include/stdio.h similarity index 100% rename from src/include/stdio.h rename to include/stdio.h diff --git a/src/include/stdlib.h b/include/stdlib.h similarity index 100% rename from src/include/stdlib.h rename to include/stdlib.h diff --git a/src/include/string.h b/include/string.h similarity index 100% rename from src/include/string.h rename to include/string.h diff --git a/src/include/threads.h b/include/threads.h similarity index 100% rename from src/include/threads.h rename to include/threads.h diff --git a/src/include/tinyrt.h b/include/tinyrt.h similarity index 61% rename from src/include/tinyrt.h rename to include/tinyrt.h index 7c50a0e..7d93f9a 100644 --- a/src/include/tinyrt.h +++ b/include/tinyrt.h @@ -41,9 +41,7 @@ static _RT_Status _rt_init(); static _RT_Status _rt_deinit(); // Program API -#if _RT_API_PROGRAM == 1 - _Noreturn static void _rt_program_exit(int code); -#endif +_Noreturn static void _rt_program_exit(int code); // Thread API struct _RT_Thread typedef _RT_Thread; @@ -51,21 +49,17 @@ struct _RT_Thread { u64 tid; void *handle; }; -#if _RT_API_THREAD == 1 - static _RT_Status _rt_thread_current(_RT_Thread *thread); - static _RT_Status _rt_thread_create(_RT_Thread *thread, void (*thread_fn)(void *ctx), void *ctx); - static _RT_Status _rt_thread_join(_RT_Thread *thread); - static _RT_Status _rt_thread_detach(_RT_Thread *thread); - static _RT_Status _rt_thread_terminate(_RT_Thread *thread); - static _RT_Status _rt_thread_sleep(u64 time); - static _RT_Status _rt_thread_get_timer_freq(u64 *freq); -#endif +static _RT_Status _rt_thread_current(_RT_Thread *thread); +static _RT_Status _rt_thread_create(_RT_Thread *thread, void (*thread_fn)(void *ctx), void *ctx); +static _RT_Status _rt_thread_join(_RT_Thread *thread); +static _RT_Status _rt_thread_detach(_RT_Thread *thread); +static _RT_Status _rt_thread_terminate(_RT_Thread *thread); +static _RT_Status _rt_thread_sleep(u64 time); +static _RT_Status _rt_thread_get_timer_freq(u64 *freq); // Environment API -#if _RT_API_ENVIRONMENT == 1 - static _RT_Status _rt_shell_exec(char const *cmd); - static _RT_Status _rt_env_get(char const *name); -#endif +static _RT_Status _rt_shell_exec(char const *cmd); +static _RT_Status _rt_env_get(char const *name); // File API struct _RT_File typedef _RT_File; @@ -76,19 +70,15 @@ struct _RT_File { }; i32 flags; }; -#if _RT_API_FILE == 1 - static _RT_File _rt_file_stdin; - static _RT_File _rt_file_stdout; - static _RT_File _rt_file_stderr; - static _RT_Status _rt_file_std_handles_init(); - static _RT_Status _rt_file_open(_RT_File *file, char const *name, int flags); - static _RT_Status _rt_file_read(u64 size, void *buffer, _RT_File *from, u64 *out_bytes_read); - static _RT_Status _rt_file_write(_RT_File *to, u64 size, void *buffer, u64 *out_bytes_written); - static _RT_Status _rt_file_close(_RT_File *file); -#endif +static _RT_File _rt_file_stdin; +static _RT_File _rt_file_stdout; +static _RT_File _rt_file_stderr; +static _RT_Status _rt_file_std_handles_init(); +static _RT_Status _rt_file_open(_RT_File *file, char const *name, int flags); +static _RT_Status _rt_file_read(u64 size, void *buffer, _RT_File *from, u64 *out_bytes_read); +static _RT_Status _rt_file_write(_RT_File *to, u64 size, void *buffer, u64 *out_bytes_written); +static _RT_Status _rt_file_close(_RT_File *file); // Memory API -#if _RT_API_MEMORY == 1 - static _RT_Status _rt_mem_alloc(void *optional_desired_addr, u64 size, void **out_addr); - static _RT_Status _rt_mem_free(void *ptr, u64 size); -#endif +static _RT_Status _rt_mem_alloc(void *optional_desired_addr, u64 size, void **out_addr); +static _RT_Status _rt_mem_free(void *ptr, u64 size); diff --git a/src/loader/loader-self-reloc.c b/loader/loader-self-reloc.c similarity index 100% rename from src/loader/loader-self-reloc.c rename to loader/loader-self-reloc.c diff --git a/src/loader/loader.c b/loader/loader.c similarity index 97% rename from src/loader/loader.c rename to loader/loader.c index 165b75d..911fe43 100644 --- a/src/loader/loader.c +++ b/loader/loader.c @@ -9,15 +9,14 @@ #include #include #include -#include "../linux/tinyrt-iface.h" #include -#include "../linux/tinyrt.c" +#include "../os/linux/tinyrt.c" #include -#include "../impl/cia-mem/util.c" -#include "../impl/cia-mem/allocator.c" -#include "../impl/cia-mem/arena.c" -#include "../impl/cia-mem/pool.c" +#include "../src/cia-mem/util.c" +#include "../src/cia-mem/allocator.c" +#include "../src/cia-mem/arena.c" +#include "../src/cia-mem/pool.c" struct Elf_Image typedef Elf_Image; struct Elf_Image { diff --git a/src/loader/loader.h b/loader/loader.h similarity index 100% rename from src/loader/loader.h rename to loader/loader.h diff --git a/os/linux/build.py b/os/linux/build.py new file mode 100644 index 0000000..ab9312b --- /dev/null +++ b/os/linux/build.py @@ -0,0 +1,24 @@ + +loader_flags = [ + '-Wl,-e,_dlstart', + '-Wl,--sort-section,alignment', + '-Wl,--sort-common', + '-Wl,--gc-sections', + '-Wl,--hash-style=both', + '-Wl,--no-undefined', + '-Wl,--exclude-libs=ALL' +] + +def build(toolchain): + toolchain.compiler.flags.append('-fno-stack-protector') + toolchain.assembler.flags.append('-f "elf64"') + compiler = toolchain.compiler + assembler = toolchain.assembler + archiver = toolchain.archiver + # Build dynamic loader + toolchain.step("lib/ld-cia.so") + assembler.obj('bin/loader-entry.o', ['loader/loader-entry.asm']) + compiler.shared('lib/ld-cia.so', ['bin/loader-entry.c','loader/loader-self-reloc.c','loader/loader.c'], loader_flags) + # Build the crt + toolchain.step('crt.lib') + compiler.obj('') \ No newline at end of file diff --git a/os/linux/conf.h b/os/linux/conf.h new file mode 100644 index 0000000..482dc6b --- /dev/null +++ b/os/linux/conf.h @@ -0,0 +1,11 @@ + +#pragma once + +#include +#include +#include +#include +#include "entry.c" +#include +#include "tinyrt.c" + diff --git a/src/linux/crt-ctors.c b/os/linux/crt-ctors.c similarity index 100% rename from src/linux/crt-ctors.c rename to os/linux/crt-ctors.c diff --git a/src/linux/entry.c b/os/linux/entry.c similarity index 96% rename from src/linux/entry.c rename to os/linux/entry.c index b9dac28..fe63f79 100644 --- a/src/linux/entry.c +++ b/os/linux/entry.c @@ -14,7 +14,7 @@ void __stack_chk_fail(void) { extern int main(int argc, char **argv, char **envp); static void _fileapi_init(); -void _cia_start() { +void _start() { // Get the envp // char **envp = argv + (argc + 1); // init(argc, argv, envp); diff --git a/src/linux/tinyrt.c b/os/linux/tinyrt.c similarity index 100% rename from src/linux/tinyrt.c rename to os/linux/tinyrt.c diff --git a/src/windows/cia-init.c b/os/windows/cia-init.c similarity index 100% rename from src/windows/cia-init.c rename to os/windows/cia-init.c diff --git a/src/windows/conf.h b/os/windows/conf.h similarity index 100% rename from src/windows/conf.h rename to os/windows/conf.h diff --git a/src/windows/crt-entry.c b/os/windows/crt-entry.c similarity index 100% rename from src/windows/crt-entry.c rename to os/windows/crt-entry.c diff --git a/src/windows/tinyrt.c b/os/windows/tinyrt.c similarity index 100% rename from src/windows/tinyrt.c rename to os/windows/tinyrt.c diff --git a/src/windows/tinyrt.json b/os/windows/tinyrt.json similarity index 100% rename from src/windows/tinyrt.json rename to os/windows/tinyrt.json diff --git a/utf8/utf8.rc b/os/windows/utf8/utf8.rc similarity index 100% rename from utf8/utf8.rc rename to os/windows/utf8/utf8.rc diff --git a/utf8/utf8.xml b/os/windows/utf8/utf8.xml similarity index 100% rename from utf8/utf8.xml rename to os/windows/utf8/utf8.xml diff --git a/src/windows/windows.c b/os/windows/windows.c similarity index 100% rename from src/windows/windows.c rename to os/windows/windows.c diff --git a/readme.md b/readme.md index a17a453..668e9b2 100644 --- a/readme.md +++ b/readme.md @@ -98,22 +98,8 @@ $ pip install pyjson5 ### Building -On linux you can simply run `./build.lua` script. On windows you have to run -it like `lua build.lua`. Reference for command-line options: - -``` -Usage: build.py [-h] [--clean] [--test TEST] - [--mode {debug,release}] [--target TARGET] - [--compiler {clang,cuik}] [--cflags [CFLAGS ...]] -Options: - -h, --help show this help message and exit - --clean Remove all object files and binaries - --test TEST Compile ciabatta executable with given file - --mode, -m {debug,release} Select build configuration - --target, -t TARGET Select target OS (default=host) - --compiler, -c {clang,cuik} Select compiler - --cflags [CFLAGS ...] Pass additional compiler flags -``` +On linux you can simply run `./build.py` script. On windows can run +it with `py build.py` command. ## Usage @@ -131,7 +117,7 @@ assuming you put all files mentioned above in the `./ciabatta` folder 1. Add the following flags to your compilation command: `-nostdlib -I ./ciabatta/include utf8.obj -mfma` 2. Add the following sources to the compile command: - `./ciabatta/lib/ciabatta.lib ./ciabatta/lib/cia.lib ./ciabatta/lib/crt.lib` + `./ciabatta/lib/cia.lib` **Note:** The `include` folder refers to the folder you copied from ciabatta. Set the path to it accordingly. @@ -140,7 +126,9 @@ assuming you put all files mentioned above in the `./ciabatta` folder 1. Add the following flags to your compilation command: - `-nostdlib -I ./ciabatta/include -mfma` 2. Link to the following libraries - - `./ciabatta/lib/ciabatta.a` + - `./ciabatta/lib/cia.a` +3. Specify the ciabatta dynamic loader in linker options + - `-Wl,-dynamic-linker,lib/ld-cia.so` ## Contributing diff --git a/src/impl/cia-mem/allocator.c b/src/cia-mem/allocator.c similarity index 100% rename from src/impl/cia-mem/allocator.c rename to src/cia-mem/allocator.c diff --git a/src/impl/cia-mem/arena.c b/src/cia-mem/arena.c similarity index 100% rename from src/impl/cia-mem/arena.c rename to src/cia-mem/arena.c diff --git a/src/impl/cia-mem/pool.c b/src/cia-mem/pool.c similarity index 100% rename from src/impl/cia-mem/pool.c rename to src/cia-mem/pool.c diff --git a/src/impl/cia-mem/util.c b/src/cia-mem/util.c similarity index 100% rename from src/impl/cia-mem/util.c rename to src/cia-mem/util.c diff --git a/src/library.json b/src/library.json deleted file mode 100644 index 194d50e..0000000 --- a/src/library.json +++ /dev/null @@ -1,118 +0,0 @@ -// Manifest file for the ciabatta build. - -// Platform sections describe available platforms and -// which files they need to include to function -// API sections describe API subsets and their TinyRT -// dependencies. If an API requires TinyRT module that -// isn't implemented by the platform that API won't be included -// in the final build - -// This file is used to auto-generate ciabatta.c - -// `include` section specifies the header files that ciabatta -// implements -// `platform` sections describe platforms, the directories -// where the source code for these platforms resides and the -// files that should be included in the build for that platform -// (relative to "src" dir) as well as the location of TinyRT -// implementation. -// `api` sections describe modules, where the implementation resides, -// the source files and the TinyRT modules, on which this module -// depends. If the platform doesn't implement one of the dependencies -// this module will not be included in the final build - -includes: [ - "stdlib.h", - "stdio.h", - "threads.h", - "cia-mem.h", -], - -platforms: [ - { - name: "linux", - path: "linux", - includes: [ - "sys/mman.h", - "errno.h", - "fcntl.h", - "sched.h", - ], - sources: [ - "entry.c", - ], - tinyrt: [ - "tinyrt.c" - ] - }, - { - name: "windows", - path: "windows", - sources: [ - "windows.c" - ], - tinyrt: [ - "tinyrt.c", - "cia-init.c" - ], - }, -], - -apis: [ - { - name: "cia_memory", - path: "impl/cia-mem", - includes: [ - "util.c", - "allocator.c", - "arena.c", - "pool.c", - ], - reqs: [ - "rt_api_memory" - ] - }, - { - name: "stdlib_program", - path: "impl/stdlib-program", - includes: [ - "program.c", - ], - reqs: [ - "rt_api_program", - "cia_memory", - ] - }, - { - name: "stdlib_threads", - path: "impl/stdlib-thread", - includes: [ - "thread.c", - ], - reqs: [ - "rt_api_thread" - ] - }, - { - name: "stdlib_file", - path: "impl/stdlib-file", - includes: [ - "file.c" - ], - reqs: [ - "rt_api_file", - "cia_memory", - ] - } -], - -// Edit this part for a particular build you want -// this contains list of "name" properties for modules -// in the "apis" section - -export: [ - "cia_memory", - "stdlib_program", - "stdlib_file", - "stdlib_threads", -] \ No newline at end of file diff --git a/src/linux/conf.h b/src/linux/conf.h deleted file mode 100644 index d64652c..0000000 --- a/src/linux/conf.h +++ /dev/null @@ -1,3 +0,0 @@ - -#define _CIA_OS_LINUX -#define _CIA_DATA_LP64 diff --git a/src/linux/tinyrt.json b/src/linux/tinyrt.json deleted file mode 100644 index bfd4281..0000000 --- a/src/linux/tinyrt.json +++ /dev/null @@ -1,11 +0,0 @@ - -// This file contains TinyRT API subsets that are exported -// for this operating system, one name per line. This file -// is used in a build script to generate tinyrt_macro file -// and to resolve higher-level API dependencies - -rt_api_file: true, -rt_api_program: true, -rt_api_shell: false, -rt_api_memory: true, -rt_api_thread: true, diff --git a/src/impl/stdlib-file/file.c b/src/stdlib-file/file.c similarity index 100% rename from src/impl/stdlib-file/file.c rename to src/stdlib-file/file.c diff --git a/src/impl/stdlib-program/program.c b/src/stdlib-program/program.c similarity index 100% rename from src/impl/stdlib-program/program.c rename to src/stdlib-program/program.c diff --git a/src/impl/stdlib-thread/thread.c b/src/stdlib-thread/thread.c similarity index 100% rename from src/impl/stdlib-thread/thread.c rename to src/stdlib-thread/thread.c