Skip to content

Commit

Permalink
✨ Add a project example from @willemolding's Cannon-rs project
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Nov 11, 2023
1 parent 87fcea0 commit fffb4c2
Show file tree
Hide file tree
Showing 10 changed files with 401 additions and 0 deletions.
32 changes: 32 additions & 0 deletions crates/mipsevm/src/mips/instrumented.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,38 @@ mod test {
}
}

#[test]
fn test_hello_rs_willem() {
let elf_bytes = include_bytes!("../../../../example/bin/hello-willem-rs.elf");
let mut state = load_elf(elf_bytes).unwrap();
patch::patch_go(elf_bytes, &mut state).unwrap();
patch::patch_stack(&mut state).unwrap();

let out = BufWriter::new(Vec::default());
let err = BufWriter::new(Vec::default());
let mut ins =
InstrumentedState::new(state, StaticOracle::new(b"hello world".to_vec()), out, err);

for _ in 0..400_000 {
if ins.state.exited {
break;
}
ins.step(false).unwrap();
}

assert!(ins.state.exited, "must exit");
assert_eq!(ins.state.exit_code, 0, "must exit with 0");

assert_eq!(
String::from_utf8(ins.std_out.buffer().to_vec()).unwrap(),
"hello world!\n"
);
assert_eq!(
String::from_utf8(ins.std_err.buffer().to_vec()).unwrap(),
""
);
}

#[test]
fn test_hello() {
let elf_bytes = include_bytes!("../../../../example/bin/hello.elf");
Expand Down
7 changes: 7 additions & 0 deletions example/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ elf: $(patsubst %/go.mod,bin/%.elf,$(wildcard */go.mod))
.PHONY: dump
dump: $(patsubst %/go.mod,bin/%.dump,$(wildcard */go.mod))

# .PHONY: ex-rs
# ex-rs:
# cd hello-rs && \
# RUSTFLAGS='-C link-arg=-no-pie -C target-cpu=mips32 -C target-feature=-mips32r2,-fpxx,-nooddspreg,+mips32,+crt-static,+soft-float' \
# cross build --release --target ../mips-unknown-linux-gnu.json -Z build-std -Z build-std-features=panic-unwind && \
# cp ../../target/mips-unknown-linux-gnu/release/hello-rs ../bin/hello-rs.elf

bin:
mkdir bin

Expand Down
Binary file added example/bin/hello-willem-rs.elf
Binary file not shown.
2 changes: 2 additions & 0 deletions example/hello-rs-willem/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Rust target dir
target
50 changes: 50 additions & 0 deletions example/hello-rs-willem/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions example/hello-rs-willem/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "hello-rs-willem"
edition = "2021"
version = "0.0.1"
authors = ["Willem Olding"]

[dependencies]
linked_list_allocator = "0.10.5"

[profile.release]
panic = "abort"
14 changes: 14 additions & 0 deletions example/hello-rs-willem/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# [`Cannon-rs`][cannon-rs-willem] example program

This is an example Rust program for Cannon that uses Willem Olding's [program template][program-template-willem].

## Building

The program can be built using Badboilabs' provided container:

```sh
docker run --rm --platform linux/amd64 -v `pwd`/:/code -w="/code" ghcr.io/badboilabs/cannon-rs/builder:main cargo build --release -Zbuild-std
```

[cannon-rs-willem]: https://github.com/BadBoiLabs/Cannon-rs
[program-template-willem]: https://github.com/BadBoiLabs/Cannon-rs/tree/main/project-template
29 changes: 29 additions & 0 deletions example/hello-rs-willem/mips-unknown-linux-gnu.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"arch": "mips",
"cpu": "mips32",
"crt-objects-fallback": "false",
"crt-static-respected": true,
"data-layout": "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64",
"dynamic-linking": true,
"env": "gnu",
"features": "-mips32r2,-fpxx,-nooddspreg,+mips32,+crt-static,+soft-float",
"has-rpath": true,
"has-thread-local": true,
"linker-flavor": "gnu-cc",
"llvm-target": "mips-unknown-linux-gnu",
"max-atomic-width": 32,
"os": "linux",
"position-independent-executables": true,
"relro-level": "full",
"supported-split-debuginfo": [
"packed",
"unpacked",
"off"
],
"target-endian": "big",
"target-family": [
"unix"
],
"target-mcount": "_mcount",
"target-pointer-width": "32"
}
52 changes: 52 additions & 0 deletions example/hello-rs-willem/src/heap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
///! This is actually just a wrapper around linked_list_allocator that allows it to work in our environment
///! Different allocator can be used if desired
use core::alloc::{GlobalAlloc, Layout};
use core::cell::RefCell;
use core::mem::MaybeUninit;
use core::ptr::{self, NonNull};
struct Alloc {
heap: RefCell<linked_list_allocator::Heap>,
}

impl Alloc {
const fn new() -> Self {
Self {
heap: RefCell::new(linked_list_allocator::Heap::empty()),
}
}
}

unsafe impl GlobalAlloc for Alloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
self.heap
.borrow_mut()
.allocate_first_fit(layout)
.ok()
.map_or(ptr::null_mut(), |allocation| allocation.as_ptr())
}

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
self.heap
.borrow_mut()
.deallocate(NonNull::new_unchecked(ptr), layout)
}
}

#[global_allocator]
static mut ALLOCATOR: Alloc = Alloc::new();

pub unsafe fn init(heap: &mut [MaybeUninit<u8>]) {
ALLOCATOR
.heap
.borrow_mut()
.init(heap.as_mut_ptr() as *mut u8, heap.len())
}

#[macro_export]
macro_rules! init_heap {
( $x:expr ) => {{
use core::mem::MaybeUninit;
static mut HEAP: [MaybeUninit<u8>; $x] = [MaybeUninit::uninit(); $x];
unsafe { crate::heap::init(&mut HEAP) }
}};
}
Loading

0 comments on commit fffb4c2

Please sign in to comment.