Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add generic sandbox, better DWARF handling, add DOOM #53

Merged
merged 20 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,22 @@ jobs:
run: sudo apt-get install -y lld
- name: Install target -- i686-unknown-linux-musl
run: rustup target add i686-unknown-linux-musl
- name: Install target -- x86_64-unknown-freebsd
run: rustup target add x86_64-unknown-freebsd
- name: Build and test (generic)
run: ./ci/jobs/build-and-test.sh
- name: Build and test (Linux-only)
run: ./ci/jobs/build-and-test-linux.sh
- name: Check (FreeBSD)
run: ./ci/jobs/check-freebsd.sh
build-and-test-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Build and test
run: ./ci/jobs/build-and-test.sh
- name: Build and test (macOS-only)
run: ./ci/jobs/build-and-test-macos.sh
build-and-test-windows:
runs-on: windows-latest
steps:
Expand Down
62 changes: 50 additions & 12 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ members = [
"crates/polkavm-assembler",
"crates/polkavm-common",
"crates/polkavm-linux-raw",
"crates/polkavm-linux-sandbox",
"crates/polkavm",

"tools/polkatool",
"tools/polkavm-linux-raw-generate",

"examples/hosts/hello-world",
"examples/hosts/doom",
]

[workspace.package]
Expand All @@ -31,13 +31,13 @@ polkavm-derive = { version = "0.2.0", path = "crates/polkavm-derive" }
polkavm-derive-impl = { version = "0.2.0", path = "crates/polkavm-derive-impl" }
polkavm-linker = { version = "0.2.0", path = "crates/polkavm-linker" }
polkavm-linux-raw = { version = "0.2.0", path = "crates/polkavm-linux-raw" }
polkavm-linux-sandbox = { version = "0.2.0", path = "crates/polkavm-linux-sandbox" }

clap = "4.4.1"
env_logger = { version = "0.10.0", default-features = false }
gimli = { version = "0.28.0", default-features = false }
hashbrown = { version = "0.14.0", default-features = false }
iced-x86 = "1.19.0"
libc = "0.2.146"
log = "0.4.20"
object = { version = "0.32.0", default-features = false }
proc-macro2 = "1.0.63"
Expand Down
13 changes: 11 additions & 2 deletions ci/jobs/build-and-test-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,14 @@ cd crates/polkavm-zygote
cargo build --release
cd ../..

echo ">> cargo run (examples, musl)"
POLKAVM_TRACE_EXECUTION=1 POLKAVM_ALLOW_INSECURE=1 cargo run --target=i686-unknown-linux-musl -p hello-world-host
echo ">> cargo run (examples, interpreter, i686-unknown-linux-musl)"
POLKAVM_TRACE_EXECUTION=1 POLKAVM_ALLOW_INSECURE=1 POLKAVM_BACKEND=interpreter cargo run --target=i686-unknown-linux-musl -p hello-world-host

echo ">> cargo run (examples, interpreter, x86_64-unknown-linux-gnu)"
POLKAVM_TRACE_EXECUTION=1 POLKAVM_ALLOW_INSECURE=1 POLKAVM_BACKEND=interpreter cargo run --target=x86_64-unknown-linux-gnu -p hello-world-host

echo ">> cargo run (examples, compiler, linux, x86_64-unknown-linux-gnu)"
POLKAVM_TRACE_EXECUTION=1 POLKAVM_ALLOW_INSECURE=1 POLKAVM_BACKEND=compiler POLKAVM_SANDBOX=linux cargo run --target=x86_64-unknown-linux-gnu -p hello-world-host

echo ">> cargo run (examples, compiler, generic, x86_64-unknown-linux-gnu)"
POLKAVM_TRACE_EXECUTION=1 POLKAVM_ALLOW_INSECURE=1 POLKAVM_BACKEND=compiler POLKAVM_SANDBOX=generic cargo run --target=x86_64-unknown-linux-gnu -p hello-world-host
11 changes: 11 additions & 0 deletions ci/jobs/build-and-test-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

set -euo pipefail
cd -- "$(dirname -- "${BASH_SOURCE[0]}")"
cd ../..

echo ">> cargo run (examples, interpreter, x86_64-apple-darwin)"
POLKAVM_TRACE_EXECUTION=1 POLKAVM_ALLOW_INSECURE=1 POLKAVM_BACKEND=interpreter cargo run --target=x86_64-apple-darwin -p hello-world-host

echo ">> cargo run (examples, compiler, generic, x86_64-apple-darwin)"
POLKAVM_TRACE_EXECUTION=1 POLKAVM_ALLOW_INSECURE=1 POLKAVM_BACKEND=compiler POLKAVM_SANDBOX=generic cargo run --target=x86_64-apple-darwin -p hello-world-host
10 changes: 10 additions & 0 deletions ci/jobs/check-freebsd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

set -euo pipefail
cd -- "$(dirname -- "${BASH_SOURCE[0]}")"
cd ../..

echo ">> cargo check (freebsd)"
cd crates/polkavm
cargo check --target=x86_64-unknown-freebsd
cd ../..
7 changes: 7 additions & 0 deletions ci/run-all-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ fi
case "$OSTYPE" in
linux*)
./ci/jobs/build-and-test-linux.sh
;;
darwin*)
./ci/jobs/build-and-test-macos.sh
;;
esac

./ci/jobs/check-freebsd.sh

./ci/jobs/clippy.sh
./ci/jobs/rustfmt.sh

Expand Down
45 changes: 45 additions & 0 deletions crates/polkavm-assembler/src/amd64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,30 @@ pub mod inst {
Some((self.1, 2, 4))
}
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct lea_rip_label(pub Reg, pub Label);
impl lea_rip_label {
const fn encode_const(self) -> EncInst {
lea_rip(RegSize::R64, self.0, 0).encode_const()
}
}

impl core::fmt::Display for lea_rip_label {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
fmt.write_fmt(core::format_args!("lea {}, [{}]", self.0, self.1))
}
}

impl crate::Instruction for lea_rip_label {
fn encode(self) -> EncInst {
self.encode_const()
}

fn target_fixup(self) -> Option<(Label, u8, u8)> {
Some((self.1, 3, 4))
}
}
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -1693,4 +1717,25 @@ mod tests {
);
});
}

#[test]
fn lea_rip_label_infinite_loop() {
use super::inst::*;
let mut asm = crate::Assembler::new();
let label = asm.forward_declare_label();
asm.push_with_label(label, lea_rip_label(super::Reg::rax, label));
let disassembly = disassemble(asm.finalize());
assert_eq!(disassembly, "00000000 488d05f9ffffff lea rax, [rip-0x7]");
}

#[test]
fn lea_rip_label_next_instruction() {
use super::inst::*;
let mut asm = crate::Assembler::new();
let label = asm.forward_declare_label();
asm.push(lea_rip_label(super::Reg::rax, label));
asm.push_with_label(label, nop());
let disassembly = disassemble(asm.finalize());
assert_eq!(disassembly, "00000000 488d0500000000 lea rax, [rip]\n00000007 90 nop");
}
}
26 changes: 17 additions & 9 deletions crates/polkavm-assembler/src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct Fixup {
pub struct Assembler {
origin: u64,
code: Vec<u8>,
labels: Vec<usize>,
labels: Vec<isize>,
fixups: Vec<Fixup>,
}

Expand Down Expand Up @@ -41,19 +41,19 @@ impl Assembler {

pub fn forward_declare_label(&mut self) -> Label {
let label = self.labels.len();
self.labels.push(usize::MAX);
self.labels.push(isize::MAX);
Label(label)
}

pub fn create_label(&mut self) -> Label {
let label = self.labels.len();
self.labels.push(self.code.len());
self.labels.push(self.code.len() as isize);
Label(label)
}

pub fn define_label(&mut self, label: Label) -> &mut Self {
assert_eq!(self.labels[label.0], usize::MAX, "tried to redefine an already defined label");
self.labels[label.0] = self.code.len();
assert_eq!(self.labels[label.0], isize::MAX, "tried to redefine an already defined label");
self.labels[label.0] = self.code.len() as isize;
self
}

Expand All @@ -62,12 +62,16 @@ impl Assembler {
self.push(inst)
}

pub fn get_label_offset(&self, label: Label) -> usize {
pub fn get_label_offset(&self, label: Label) -> isize {
let offset = self.labels[label.0];
assert_ne!(offset, usize::MAX, "tried to fetch a label offset for a label that was not defined");
assert_ne!(offset, isize::MAX, "tried to fetch a label offset for a label that was not defined");
offset
}

pub fn set_label_offset(&mut self, label: Label, offset: isize) {
self.labels[label.0] = offset;
}

fn add_fixup_if_necessary(&mut self, bytes: &[u8], inst: impl Instruction) {
let (target_label, fixup_offset, fixup_length) = match inst.target_fixup() {
Some(fixup) => fixup,
Expand Down Expand Up @@ -106,8 +110,8 @@ impl Assembler {
for fixup in self.fixups.drain(..) {
let origin = fixup.instruction_offset + fixup.instruction_length as usize;
let target_absolute = self.labels[fixup.target_label.0];
assert_ne!(target_absolute, usize::MAX);
let offset = target_absolute as isize - origin as isize;
assert_ne!(target_absolute, isize::MAX);
let offset = target_absolute - origin as isize;
let p = fixup.instruction_offset + fixup.fixup_offset as usize;
if fixup.fixup_length == 1 {
if offset > i8::MAX as isize || offset < i8::MIN as isize {
Expand All @@ -134,6 +138,10 @@ impl Assembler {
self.code.len()
}

pub fn resize(&mut self, size: usize, fill_with: u8) {
self.code.resize(size, fill_with)
}

pub fn clear(&mut self) {
self.origin = 0;
self.code.clear();
Expand Down
16 changes: 9 additions & 7 deletions crates/polkavm-common/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,19 +143,21 @@ impl GuestMemoryConfig {

/// The address at where the program memory starts inside of the VM.
#[inline]
pub const fn user_memory_address(self) -> u32 {
pub const fn user_memory_region_address(self) -> u32 {
VM_ADDR_USER_MEMORY
}

/// The size of the program memory inside of the VM, excluding the stack.
/// The size of the region in which the program memory resides inside of the VM, excluding the stack.
///
/// This also includes the guard page between the read-only data and read-write data.
#[inline]
pub const fn user_memory_size(self) -> u32 {
self.ro_data_size + self.rw_data_size + self.bss_size
pub const fn user_memory_region_size(self) -> u32 {
(self.bss_address() + self.bss_size()) - self.user_memory_region_address()
}

/// Resets the size of the program memory to zero, excluding the stack.
#[inline]
pub fn clear_user_memory_size(&mut self) {
pub fn clear_user_memory_sizes(&mut self) {
self.ro_data_size = 0;
self.rw_data_size = 0;
self.bss_size = 0;
Expand All @@ -164,7 +166,7 @@ impl GuestMemoryConfig {
/// The address at where the program's read-only data starts inside of the VM.
#[inline]
pub const fn ro_data_address(self) -> u32 {
self.user_memory_address()
self.user_memory_region_address()
}

/// The size of the program's read-only data.
Expand Down Expand Up @@ -199,7 +201,7 @@ impl GuestMemoryConfig {
#[inline]
pub const fn rw_data_address(self) -> u32 {
if self.ro_data_size == 0 {
self.user_memory_address()
self.user_memory_region_address()
} else {
self.ro_data_address() + self.ro_data_size + VM_PAGE_SIZE
}
Expand Down
2 changes: 1 addition & 1 deletion crates/polkavm-common/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1625,7 +1625,7 @@ impl<'a> LineProgram<'a> {
}

// Put an upper limit to how many instructions we'll process.
const INSTRUCTION_LIMIT_PER_REGION: usize = 128;
const INSTRUCTION_LIMIT_PER_REGION: usize = 256;

let mark_as_finished_on_drop = SetTrueOnDrop(&mut self.is_finished);
for _ in 0..INSTRUCTION_LIMIT_PER_REGION {
Expand Down
Loading