diff --git a/.gitignore b/.gitignore index 1c7b3d7..2fc0943 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ # download cosmo amalgamation /libcosmo/* !/libcosmo/README.md +!/libcosmo/compile-stubs.bash +!/libcosmo/stubs.c # Generated by Cargo # will have compiled files and executables diff --git a/README.md b/README.md index 8eee2a0..822570e 100644 --- a/README.md +++ b/README.md @@ -51,63 +51,21 @@ objcopy -SO binary ./target/x86_64-unknown-linux-cosmo/debug/hello_world.com.dbg ## What about the `std` crate? -The `std` crate compiles successfully, but fails at the linker stage. Here's how -that can be tested: +1. It needs a few stubs functions so the linker doesn't complain. I wrote them + out in `stubs.c`. -1. Change the source code in `src/main.rs` to use the commented out `main` - function and `#![restricted_std]`. - -2. In the source code for Rust's `std` crate, change a `cfg_if` in - `$HOME/.rustup/toolchains//lib/rustlib/src/rust/library/backtrace/src/backtrace/mod.rs` - to use the `noop` trace instead of depending on `libunwind`. - -```diff ---- mod.rs 2022-06-21 12:52:21.724053459 +0530 -+++ mod.rs 2022-06-21 13:05:50.948777093 +0530 -@@ -132,7 +132,7 @@ - pub(crate) mod miri; - use self::miri::trace as trace_imp; - pub(crate) use self::miri::Frame as FrameImp; -- } else if #[cfg( -+ } /* else if #[cfg( - any( - all( - unix, -@@ -154,7 +154,7 @@ - pub(crate) use self::dbghelp::Frame as FrameImp; - #[cfg(target_env = "msvc")] // only used in dbghelp symbolize - pub(crate) use self::dbghelp::StackFrame; -- } else { -+ } */ else { - mod noop; - use self::noop::trace as trace_imp; - pub(crate) use self::noop::Frame as FrameImp; +```bash +cd ./libcosmo/ +# compiling a simple stub file via cosmopolitan.h +./compile-stubs.bash ``` -I haven't figured out what config I should give to `cargo` so I don't need to do -this. I find it surprising that `std` cannot be built without relying on -`libunwind`. - -3. The build command now changes to +2. The build command now changes to ```bash cargo +nightly build -Zbuild-std=core,alloc,panic_abort,libc,std -Zbuild-std-features= --target=./x86_64-unknown-linux-cosmo.json ``` -4. At the linker stage you might find some of the following symbols are missing: - - - If `Unwind_Backtrace` or similar is missing, you need to check if step 2 is - done properly. - - - `open64`, `stat64`, `fstat64`, `__xpg_strerror_r`: these can be added to - Cosmopolitan Libc via aliases of the existing functions. - - - `pthread_key_create`,`pthread_setspecific`,`pthread_key_delete`,`pthread_getspecific` - -- these functions should not be needed in a single-threaded program, but - somehow they are still linked. Support for threads is currently being added - to Cosmopolitan Libc, but possibly the related code in the `std` crate can - be changed to avoid this issue. - [rust]: https://rust-lang.org [cosmo]: https://github.com/jart/cosmopolitan [amalg-download]: https://justine.lol/cosmopolitan/download.html diff --git a/libcosmo/compile-stubs.bash b/libcosmo/compile-stubs.bash new file mode 100755 index 0000000..aa53e4a --- /dev/null +++ b/libcosmo/compile-stubs.bash @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -eux + +gcc -g -Os -static -nostdlib -nostdinc \ + -fno-pie -no-pie -mno-red-zone \ + -fno-omit-frame-pointer -pg -mnop-mcount \ + -o ./stubs.o -c ./stubs.c diff --git a/libcosmo/stubs.c b/libcosmo/stubs.c new file mode 100644 index 0000000..adb9b75 --- /dev/null +++ b/libcosmo/stubs.c @@ -0,0 +1,98 @@ +#include "cosmopolitan.h" + +typedef enum { + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 +} _Unwind_Reason_Code; + +#define UNW_TDEP_CURSOR_LEN 127 + +typedef uint64_t unw_word_t; + +typedef struct unw_cursor { + unw_word_t opaque[UNW_TDEP_CURSOR_LEN]; +} unw_cursor_t; + +struct _Unwind_Context { + unw_cursor_t cursor; + int end_of_stack; +}; + +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, + void *); + +uintptr_t _Unwind_GetCFA(struct _Unwind_Context *ctx) { + return 0; +} + +uintptr_t _Unwind_GetIP(struct _Unwind_Context *ctx) { + return 0; +} + +_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn fn, void *arg) { + return _URC_NORMAL_STOP; +} + +void *_Unwind_FindEnclosingFunction(void *arg) { + return NULL; +} + +#define MAX_KEYS 64 + +typedef unsigned pthread_key_t; +typedef void (*dtor)(void*); + +typedef struct { + pthread_key_t kval; + dtor d; + void *value; +} tls_t; + +static tls_t my_tls[MAX_KEYS] = {0}; +static unsigned thread_avail = 0; + +int pthread_key_create(pthread_key_t *k, dtor destructor) { + for(pthread_key_t i=1; i isize { fn my_panic(_info: &core::panic::PanicInfo) -> ! { loop {} } - -/* std crate requires some external changes +*/ #![feature(restricted_std)] pub fn main() { println!("hello pls cosmo rust APE"); } -*/ diff --git a/x86_64-unknown-linux-cosmo.json b/x86_64-unknown-linux-cosmo.json index 63a9a7a..62e5ae2 100644 --- a/x86_64-unknown-linux-cosmo.json +++ b/x86_64-unknown-linux-cosmo.json @@ -49,6 +49,7 @@ "-fuse-ld=bfd", "-Wl,-T,./libcosmo/ape.lds", "./libcosmo/crt.o", + "./libcosmo/stubs.o", "./libcosmo/ape-no-modify-self.o", "./libcosmo/cosmopolitan.a" ]