mirror of
https://github.com/ahgamut/rust-ape-example.git
synced 2024-11-21 15:30:59 +00:00
std crate builds with stubs
This commit is contained in:
parent
26c4c14d96
commit
f6ae82160c
6 changed files with 117 additions and 52 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,6 +4,8 @@
|
||||||
# download cosmo amalgamation
|
# download cosmo amalgamation
|
||||||
/libcosmo/*
|
/libcosmo/*
|
||||||
!/libcosmo/README.md
|
!/libcosmo/README.md
|
||||||
|
!/libcosmo/compile-stubs.bash
|
||||||
|
!/libcosmo/stubs.c
|
||||||
|
|
||||||
# Generated by Cargo
|
# Generated by Cargo
|
||||||
# will have compiled files and executables
|
# will have compiled files and executables
|
||||||
|
|
56
README.md
56
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?
|
## What about the `std` crate?
|
||||||
|
|
||||||
The `std` crate compiles successfully, but fails at the linker stage. Here's how
|
1. It needs a few stubs functions so the linker doesn't complain. I wrote them
|
||||||
that can be tested:
|
out in `stubs.c`.
|
||||||
|
|
||||||
1. Change the source code in `src/main.rs` to use the commented out `main`
|
```bash
|
||||||
function and `#![restricted_std]`.
|
cd ./libcosmo/
|
||||||
|
# compiling a simple stub file via cosmopolitan.h
|
||||||
2. In the source code for Rust's `std` crate, change a `cfg_if` in
|
./compile-stubs.bash
|
||||||
`$HOME/.rustup/toolchains/<your-host-nightly-toolchain>/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;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
I haven't figured out what config I should give to `cargo` so I don't need to do
|
2. The build command now changes to
|
||||||
this. I find it surprising that `std` cannot be built without relying on
|
|
||||||
`libunwind`.
|
|
||||||
|
|
||||||
3. The build command now changes to
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo +nightly build -Zbuild-std=core,alloc,panic_abort,libc,std -Zbuild-std-features= --target=./x86_64-unknown-linux-cosmo.json
|
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
|
[rust]: https://rust-lang.org
|
||||||
[cosmo]: https://github.com/jart/cosmopolitan
|
[cosmo]: https://github.com/jart/cosmopolitan
|
||||||
[amalg-download]: https://justine.lol/cosmopolitan/download.html
|
[amalg-download]: https://justine.lol/cosmopolitan/download.html
|
||||||
|
|
7
libcosmo/compile-stubs.bash
Executable file
7
libcosmo/compile-stubs.bash
Executable file
|
@ -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
|
98
libcosmo/stubs.c
Normal file
98
libcosmo/stubs.c
Normal file
|
@ -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<MAX_KEYS; i++) {
|
||||||
|
if(my_tls[i].kval == 0) {
|
||||||
|
*k = i;
|
||||||
|
my_tls[i].kval = i;
|
||||||
|
my_tls[i].d = destructor;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* pthread_getspecific(pthread_key_t k) {
|
||||||
|
if(k < MAX_KEYS) {
|
||||||
|
return my_tls[k].value;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_setspecific(pthread_key_t k, const void* value) {
|
||||||
|
if(k < MAX_KEYS) {
|
||||||
|
my_tls[k].value = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_key_delete(pthread_key_t k) {
|
||||||
|
if (k < MAX_KEYS) {
|
||||||
|
my_tls[k].kval = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __xpg_strerror_r(int a, char *b, size_t c) {
|
||||||
|
return strerror_r(a, b, c);
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
|
@ -20,12 +21,10 @@ pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
fn my_panic(_info: &core::panic::PanicInfo) -> ! {
|
fn my_panic(_info: &core::panic::PanicInfo) -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/* std crate requires some external changes
|
|
||||||
|
|
||||||
#![feature(restricted_std)]
|
#![feature(restricted_std)]
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
println!("hello pls cosmo rust APE");
|
println!("hello pls cosmo rust APE");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
"-fuse-ld=bfd",
|
"-fuse-ld=bfd",
|
||||||
"-Wl,-T,./libcosmo/ape.lds",
|
"-Wl,-T,./libcosmo/ape.lds",
|
||||||
"./libcosmo/crt.o",
|
"./libcosmo/crt.o",
|
||||||
|
"./libcosmo/stubs.o",
|
||||||
"./libcosmo/ape-no-modify-self.o",
|
"./libcosmo/ape-no-modify-self.o",
|
||||||
"./libcosmo/cosmopolitan.a"
|
"./libcosmo/cosmopolitan.a"
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue