Skip to content

Commit

Permalink
assembly: Add helloworld program and tooling
Browse files Browse the repository at this point in the history
  • Loading branch information
joncinque committed Sep 10, 2024
1 parent c560f35 commit 8429202
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 1 deletion.
33 changes: 33 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ env:
SOLANA_ZIG_VERSION: v1.43.0
SOLANA_ZIG_DIR: solana-zig
SOLANA_C_DIR: solana-c-sdk
SOLANA_LLVM_DIR: solana-llvm

jobs:
zig-test:
Expand Down Expand Up @@ -111,3 +112,35 @@ jobs:

- name: Build and test program
run: ./test-c.sh ${{ matrix.program }}

asm-test:
name: Run tests against assembly implementations
strategy:
matrix:
program: [helloworld]
fail-fast: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
~/.cache/solana
$SOLANA_LLVM_DIR
key: asm-${{ hashFiles('./Cargo.lock') }}

- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.78.0

- name: Install Rust build deps
run: ./install-rust-build-deps.sh

- name: Install LLVM
run: ./install-solana-llvm.sh $SOLANA_LLVM_DIR

- name: Build and test program
run: ./test-asm.sh ${{ matrix.program }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
target/
.zig-cache/
zig-out/
solana-llvm/
solana-zig/
solana-c-sdk/
out/
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# solana-program-rosetta

Multiple implementations of Solana programs across languages
Multiple implementations of Solana programs across languages: Rust, Zig, C, and
even assembly.

More programs will be added over time!

Expand Down Expand Up @@ -108,6 +109,39 @@ SBF_OUT_DIR="./c/out" cargo test
./test-c.sh helloworld
```

### Assembly

* Install Solana LLVM tools

```console
./install-solana-llvm.sh
```

* Go to a program directory

```console
cd helloworld/asm
```

* Build a program

```console
make
```

* Test it

```console
cd ..
SBF_OUT_DIR="./asm/out" cargo test
```

* OR use the helper from the root of this repo to build and test

```console
./test-asm.sh helloworld
```

## Current Programs

* Helloworld: logs a static string using the `sol_log_` syscall
29 changes: 29 additions & 0 deletions helloworld/asm/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.PHONY: all clean

OUT_DIR ?= ./out

all: $(OUT_DIR)/solana_program_rosetta_helloworld.so

clean:
rm -rf $(OUT_DIR)

LLVM_DIR := ../../solana-llvm
STD_LIB_DIRS := $(LLVM_DIR)/lib

LLVM_MC := $(LLVM_DIR)/bin/llvm-mc
LLD := $(LLVM_DIR)/bin/ld.lld

SBF_LLD_FLAGS := \
-z notext \
-shared \
--Bdynamic \
$(LLVM_DIR)/sbf.ld \
--entry entrypoint \
-L $(STD_LIB_DIRS) \

$(OUT_DIR)/main.o: ./main.s
mkdir -p $(OUT_DIR)
$(LLVM_MC) -triple sbf -filetype=obj -o $(OUT_DIR)/main.o main.s

$(OUT_DIR)/solana_program_rosetta_helloworld.so: $(OUT_DIR)/main.o
$(LLD) $(SBF_LLD_FLAGS) -o $(OUT_DIR)/solana_program_rosetta_helloworld.so $(OUT_DIR)/main.o
10 changes: 10 additions & 0 deletions helloworld/asm/main.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.text
.globl entrypoint
entrypoint:
lddw r1, .message
mov64 r2, 12
call sol_log_
exit
.section .rodata
.message:
.asciz "Hello world!"
76 changes: 76 additions & 0 deletions install-solana-llvm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env bash

if [[ -n $SOLANA_TOOLS_VERSION ]]; then
solana_tools_version="$SOLANA_TOOLS_VERSION"
else
solana_tools_version="v1.43.1"
fi
release_url="https://github.com/joncinque/solana-zig-bootstrap/releases/download/solana-$solana_tools_version"

output_dir="$1"
if [[ -z $output_dir ]]; then
output_dir="solana-llvm"
fi
output_dir="$(mkdir -p "$output_dir"; cd "$output_dir"; pwd)"
cd $output_dir

arch=$(uname -m)
if [[ "$arch" == "arm64" ]]; then
arch="aarch64"
fi
case $(uname -s | cut -c1-7) in
"Linux")
os="linux"
abi="musl"
;;
"Darwin")
os="macos"
abi="none"
;;
"Windows" | "MINGW64")
os="windows"
abi="gnu"
;;
*)
echo "install-solana-llvm.sh: Unknown OS $(uname -s)" >&2
exit 1
;;
esac

solana_llvm_tar=llvm-$arch-$os-$abi.tar.bz2
url="$release_url/$solana_llvm_tar"
echo "Downloading $url"
curl --proto '=https' --tlsv1.2 -SfOL "$url"
echo "Unpacking $solana_llvm_tar"
tar -xjf $solana_llvm_tar
rm $solana_llvm_tar

solana_llvm_dir="llvm-$arch-$os-$abi-baseline"
mv "$solana_llvm_dir"/* .
rmdir $solana_llvm_dir

echo "PHDRS
{
text PT_LOAD ;
rodata PT_LOAD ;
data PT_LOAD ;
dynamic PT_DYNAMIC ;
}
SECTIONS
{
. = SIZEOF_HEADERS;
.text : { *(.text*) } :text
.rodata : { *(.rodata*) } :rodata
.data.rel.ro : { *(.data.rel.ro*) } :rodata
.dynamic : { *(.dynamic) } :dynamic
.dynsym : { *(.dynsym) } :data
.dynstr : { *(.dynstr) } :data
.rel.dyn : { *(.rel.dyn) } :data
/DISCARD/ : {
*(.eh_frame*)
*(.gnu.hash*)
*(.hash*)
}
}" > sbf.ld
echo "solana-llvm tools available at $output_dir"
10 changes: 10 additions & 0 deletions test-asm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

PROGRAM_NAME="$1"
ROOT_DIR="$(cd "$(dirname "$0")"; pwd)"
set -e
PROGRAM_DIR=$ROOT_DIR/$PROGRAM_NAME
cd $PROGRAM_DIR/asm
make
SBF_OUT_DIR="$PROGRAM_DIR/asm/out" cargo test --manifest-path "$PROGRAM_DIR/Cargo.toml"

0 comments on commit 8429202

Please sign in to comment.