update for fat APE

This commit is contained in:
Gautham 2023-10-10 13:15:47 +00:00
parent 3856d18fdf
commit 6b540df45d
5 changed files with 104 additions and 57 deletions

View file

@ -1,3 +1,7 @@
[unstable]
build-std-features = [""]
build-std = ["libc", "panic_abort", "std"]
[profile.dev] [profile.dev]
panic = "abort" panic = "abort"
opt-level = "s" opt-level = "s"

View file

@ -10,9 +10,8 @@ and it builds around 175 example programs, including those that use Rust's
> [here](https://github.com/ahgamut/ripgrep/tree/cosmopolitan). > [here](https://github.com/ahgamut/ripgrep/tree/cosmopolitan).
To build this repo you need a recent version of `gcc` (9 or 10 ought to be To build this repo you need a recent version of the Cosmopolitan Libc monorepo,
good), a recent version of `binutils` (`ld.bfd` and `objcopy`), and `bash` and `bash` because I wrote a simple filter script.
because I wrote a simple filter script.
I created a [custom compilation target][custom-target] for Rust, called I created a [custom compilation target][custom-target] for Rust, called
`x86_64-unknown-linux-cosmo`, to provide a build process that uses the `x86_64-unknown-linux-cosmo`, to provide a build process that uses the
@ -26,17 +25,23 @@ this method.
## Building a Rust APE with the `std` crate ## Building a Rust APE with the `std` crate
1. Download the Cosmopolitan Libc [amalgamation][amalg-download] into the `libcosmo` folder: 1. Download the Cosmopolitan Libc repo and build the toolchain:
```bash ```bash
cd libcosmo git clone https://github.com/jart/cosmopolitan
wget https://justine.lol/cosmopolitan/cosmopolitan.zip cd cosmopolitan
unzip cosmopolitan.zip make -j MODE= toolchain
cd ../ make -j MODE=aarch64 toolchain
export COSMO=$(realpath ./)
cd ..
``` ```
For reference, I used the nightly version of `cosmopolitan.a` from September 12 Then clone this repo
2022, which can be built from source if needed from [this commit][cosmo-nightly].
```bash
git clone https://github.com/ahgamut/rust-ape-example
cd rust-ape-example
```
2. Download the necessary host toolchain and source code for Rust: 2. Download the necessary host toolchain and source code for Rust:
@ -51,49 +56,47 @@ rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-musl
For reference, this worked when I tried it for `nightly-x86_64-linux-gnu` and: For reference, this worked when I tried it for `nightly-x86_64-linux-gnu` and:
* the Rust binaries on June 22 2022 (5750a6aa2 2022-06-20) * the Rust binaries on October 10 2023
* the Rust binaries on June 25 2022 (fdca237d5 2022-06-24)
* the Rust binaries on June 26 2022 (20a6f3a8a 2022-06-25)
* the Rust binaries on June 30 2022 (ddcbba036 2022-06-29)
* the Rust binaries on July 27 2022 (4d6d601c8 2022-07-26)
* the Rust binaries on September 6 2022 (78a891d36 2022-09-06)
3. run `cargo build` to get the debug executable. This uses a bash script that 3. run `cargo build` to get the debug executables. This uses a bash script that
removes unnecessary linker arguments. A recent version of `gcc` and `ld.bfd` removes unnecessary linker arguments.
is required.
```bash ```bash
cargo +nightly build -Zbuild-std=libc,panic_abort,std -Zbuild-std-features="" --target=./x86_64-unknown-linux-cosmo.json export ARCH=x86_64
cargo +nightly build --target=./x86_64-unknown-linux-cosmo.json
export ARCH=aarch64
cargo +nightly build --target=./aarch64-unknown-linux-cosmo.json
``` ```
For reference, I used the below versions of `gcc` and `ld.bfd`
``` 4. run `apelink` on the debug binaries to obtain the fat APE:
gcc (Debian 10.2.1-6) 10.2.1 20210110
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```
```
GNU ld (GNU Binutils for Debian) 2.35.2
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
```
4. run `objcopy` on the debug binary to obtain the APE:
```bash ```bash
# look at the built debug binaries # look at the built debug binaries
ls ./target/x86_64-unknown-linux-cosmo/debug/*.com.dbg ls ./target/x86_64-unknown-linux-cosmo/debug/*.com.dbg
# objcopy is the same version as ld.bfd above
objcopy -SO binary ./target/x86_64-unknown-linux-cosmo/debug/hello_world.com.dbg ./hello_world.com # apelink
MODE=
MODE_AARCH64=aarch64
APELINK=$COSMO/o/tool/build/apelink.com
apelinkpls () {
OUTPUT="$1"
OUTPUT_X86_64="$2"
OUTPUT_AARCH64="$3"
"$APELINK" -l "$COSMO/o/$MODE/ape/ape.elf" \
-l "$COSMO/o/$MODE_AARCH64/ape/ape.elf" \
-M "$COSMO/ape/ape-m1.c" \
-o "$OUTPUT" \
"$OUTPUT_X86_64" \
"$OUTPUT_AARCH64"
}
apelinkpls ./hello.com\
./target/x86_64-unknown-linux-cosmo/debug/hello_world.com.dbg\
./target/aarch64-unknown-linux-cosmo/debug/hello_world.com.dbg
# run the APE # run the APE
./hello_world.com ./hello.com
# see syscalls made by the APE
./hello_world.com --strace
``` ```
Now we have Actually Portable Executables built with Rust! I also built a few Now we have Actually Portable Executables built with Rust! I also built a few

View file

@ -0,0 +1,51 @@
{
"llvm-target": "aarch64-unknown-linux-musl",
"target-pointer-width": "64",
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"os":"linux",
"env": "musl",
"panic-strategy":"abort",
"requires-uwtable":false,
"dynamic-linking": false,
"executables": true,
"exe-suffix": ".com.dbg",
"emit-debug-gdb-scripts":false,
"crt-static-default": true,
"crt-static-respected": false,
"linker-is-gnu":true,
"allows-weak-linkage":true,
"has-rpath": false,
"has-thread-local": false,
"is-builtin": false,
"trap-unreachable":true,
"position-independent-executables": false,
"static-position-independent-executables": false,
"relocation-model": "static",
"disable-redzone":true,
"frame-pointer":"always",
"requires-lto":false,
"eh-frame-header":false,
"no-default-libraries":true,
"max-atomic-width":64,
"linker-flavor":"gcc",
"linker": "./gcc-linker-wrapper.bash",
"late-link-args": {
"gcc": []
},
"pre-link-args": {
"gcc": [
"-static"
]
},
"post-link-args": {
"gcc": [
]
},
"stack-probes": {
"kind": "none"
},
"target-family": [
"unix"
]
}

View file

@ -1,21 +1,18 @@
#!/bin/bash #!/bin/bash
set -eu set -eu
COSMO="${COSMO:-/opt/cosmo}"
ARCH="${ARCH:-x86_64}"
declare -a args declare -a args
args=() args=()
for o in "$@" ; do for o in "$@" ; do
case $o in case $o in
"-lunwind") continue;; "-lunwind") continue;;
"-lutil") continue;;
"-lrt") continue;;
"-lc") continue;;
"-lm") continue;;
"-lpthread") continue;;
"-lgcc") continue;;
"-Wl,-Bdynamic") continue;; "-Wl,-Bdynamic") continue;;
"-Wl,-Bstatic") continue;; "-Wl,-Bstatic") continue;;
esac esac
args+=("$o") args+=("$o")
done done
gcc "${args[@]}" $COSMO/bin/$ARCH-unknown-cosmo-cc "${args[@]}"

View file

@ -37,20 +37,12 @@
"pre-link-args": { "pre-link-args": {
"gcc": [ "gcc": [
"-static", "-static",
"-nostdinc",
"-nostdlib",
"-pg", "-pg",
"-mnop-mcount" "-mnop-mcount"
] ]
}, },
"post-link-args": { "post-link-args": {
"gcc": [ "gcc": [
"-Wl,--gc-sections",
"-fuse-ld=bfd",
"-Wl,-T,./libcosmo/ape.lds",
"./libcosmo/crt.o",
"./libcosmo/ape-no-modify-self.o",
"./libcosmo/cosmopolitan.a"
] ]
}, },
"stack-probes": { "stack-probes": {