Skip to content

Creates hyperlight-guest-bin crate #545

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

Merged
merged 9 commits into from
Jun 2, 2025
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ This repository requires commits to be signed you should ensure that any commits
- `fuzz` - contains the fuzzing tests for the project
- `src/hyperlight_common/` - contains the common code shared between the host and guest
- `src/hyperlight_guest/` - contains the hyperlight-guest library code
- `src/hyperlight_guest_bin/` - contains the hyperlight-guest-bin library code
- `src/hyperlight_host/` - contains the hyperlight-host library code
- `src/hyperlight_guest_capi/` - contains the hyperlight-guest C library code
- `src/hyperlight_testing/` - contains the shared code for tests
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/CargoPublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
VERSION="${{ github.ref }}"
VERSION="${VERSION#refs/heads/release/v}"
fi
./dev/verify-version.sh "$VERSION" hyperlight-common hyperlight-guest hyperlight-host
./dev/verify-version.sh "$VERSION" hyperlight-common hyperlight-guest hyperlight-guest-bin hyperlight-host

- name: Publish hyperlight-common
continue-on-error: ${{ inputs.dry_run }}
Expand All @@ -59,6 +59,12 @@ jobs:
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_PUBLISH_TOKEN }}

- name: Publish hyperlight-guest-bin
continue-on-error: ${{ inputs.dry_run }}
run: cargo publish --manifest-path ./src/hyperlight_guest_bin/Cargo.toml ${{ inputs.dry_run && '--dry-run' || '' }}
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_PUBLISH_TOKEN }}

- name: Publish hyperlight-host
continue-on-error: ${{ inputs.dry_run }}
run: cargo publish --manifest-path ./src/hyperlight_host/Cargo.toml ${{ inputs.dry_run && '--dry-run' || '' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dep_rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ jobs:
run: just build ${{ matrix.config }}

- name: Verify MSRV
run: ./dev/verify-msrv.sh hyperlight-host hyperlight-guest hyperlight-common
run: ./dev/verify-msrv.sh hyperlight-host hyperlight-guest hyperlight-guest-bin hyperlight-common

- name: Run Rust tests
env:
Expand Down
11 changes: 10 additions & 1 deletion Cargo.lock

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

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ members = [
"src/hyperlight_host",
"src/hyperlight_guest_capi",
"src/hyperlight_testing",
"fuzz",
"fuzz",
"src/hyperlight_guest_bin",
]
# Guests have custom linker flags, so we need to exclude them from the workspace
exclude = [
Expand All @@ -33,6 +34,7 @@ readme = "README.md"
hyperlight-common = { path = "src/hyperlight_common", version = "0.5.0", default-features = false }
hyperlight-host = { path = "src/hyperlight_host", version = "0.5.0", default-features = false }
hyperlight-guest = { path = "src/hyperlight_guest", version = "0.5.0", default-features = false }
hyperlight-guest-bin = { path = "src/hyperlight_guest_bin", version = "0.5.0", default-features = false }
hyperlight-testing = { path = "src/hyperlight_testing", default-features = false }

[workspace.lints.rust]
Expand Down
4 changes: 2 additions & 2 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ clippy-apply-fix-windows:

# Verify Minimum Supported Rust Version
verify-msrv:
./dev/verify-msrv.sh hyperlight-host hyperlight-guest hyperlight-common
./dev/verify-msrv.sh hyperlight-host hyperlight-guest hyperlight-guest-lib hyperlight-common

#####################
### RUST EXAMPLES ###
Expand All @@ -175,7 +175,7 @@ run-rust-examples-linux target=default-target features="": (run-rust-examples ta
#########################

tar-headers: (build-rust-capi) # build-rust-capi is a dependency because we need the hyperlight_guest.h to be built
tar -zcvf include.tar.gz -C {{root}}/src/hyperlight_guest/third_party/ musl/include musl/arch/x86_64 printf/printf.h -C {{root}}/src/hyperlight_guest_capi include
tar -zcvf include.tar.gz -C {{root}}/src/hyperlight_guest_bin/third_party/ musl/include musl/arch/x86_64 printf/printf.h -C {{root}}/src/hyperlight_guest_capi include

tar-static-lib: (build-rust-capi "release") (build-rust-capi "debug")
tar -zcvf hyperlight-guest-c-api-linux.tar.gz -C {{root}}/target/x86_64-unknown-none/ release/libhyperlight_guest_capi.a -C {{root}}/target/x86_64-unknown-none/ debug/libhyperlight_guest_capi.a
Expand Down
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,9 @@ use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
use hyperlight_common::flatbuffer_wrappers::util::get_flatbuffer_result_from_int;

use hyperlight_guest::error::{HyperlightGuestError, Result};
use hyperlight_guest::guest_function_definition::GuestFunctionDefinition;
use hyperlight_guest::guest_function_register::register_function;
use hyperlight_guest::host_function_call::{
call_host_function, get_host_value_return_as_int,
};
use hyperlight_guest_bin::guest_function::definition::GuestFunctionDefinition;
use hyperlight_guest_bin::guest_function::register::register_function;
use hyperlight_guest_bin::host_comm::{call_host_function, call_host_function_without_returning_result};

fn print_output(function_call: &FunctionCall) -> Result<Vec<u8>> {
if let ParameterValue::String(message) = function_call.parameters.clone().unwrap()[0].clone() {
Expand Down Expand Up @@ -145,9 +143,9 @@ the [./src/tests/rust_guests](./src/tests/rust_guests) directory for Rust guests
- [src/hyperlight_host](./src/hyperlight_host) - This is the Rust Hyperlight host library.

- Hyperlight Guest Libraries (i.e., the ones to make it easier to create guests that run inside the VMs)
- [src/hyperlight_guest](./src/hyperlight_guest) - This is the Rust Hyperlight guest library.
- [src/hyperlight_guest_capi](./src/hyperlight_guest_capi) - This is the C compatible wrapper for the Hyperlight
guest library.
- [src/hyperlight_guest](./src/hyperlight_guest) - The core Rust library for Hyperlight guests. It provides only the essential building blocks for interacting with the host environment, including the VM exit mechanism (`outb`), abstractions for calling host functions and receiving return values, and the input/output stacks used for guest-host communication.
- [src/hyperlight_guest_bin](./src/hyperlight_guest_bin/) - An extension to the core Rust library for Hyperlight guests. It contains more opinionated components (e.g., panic handler, heap initialization, musl-specific imports, logging, and exception handling).
- [src/hyperlight_guest_capi](./src/hyperlight_guest_capi) - A C-compatible wrapper around `hyperlight_guest_bin`, exposing its core functionality for use in C programs and other languages via FFI.

- Hyperlight Common (functionality used by both the host and the guest)
- [src/hyperlight_common](./src/hyperlight_common)
Expand Down
2 changes: 1 addition & 1 deletion c.just
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mkdir := if os() == "windows" { "mkdir -f -p" } else { "mkdir -p"}
# Elf options
# We don't support stack protectors at the moment, but Arch Linux clang auto-enables them for -linux platforms, so explicitly disable them.
c-compile-options-elf := '-nobuiltininc -H --target=x86_64-unknown-linux-none -fno-stack-protector -fstack-clash-protection -mstack-probe-size=4096 -fPIC'
c-include-flags-elf := "-I " + root / "src/hyperlight_guest_capi/include/" + " -I " + root / "src/hyperlight_guest/third_party/musl/include/" + " -I " + root / "src/hyperlight_guest/third_party/musl/arch/x86_64" + " -I " + root / "src/hyperlight_guest/third_party/printf"
c-include-flags-elf := "-I " + root / "src/hyperlight_guest_capi/include/" + " -I " + root / "src/hyperlight_guest_bin/third_party/musl/include/" + " -I " + root / "src/hyperlight_guest_bin/third_party/musl/arch/x86_64" + " -I " + root / "src/hyperlight_guest_bin/third_party/printf"
c-linker-options-elf := '--entry "entrypoint" --nostdlib -pie'
c-flags-debug-elf := '-O0'
c-flags-release-elf := '-O3'
Expand Down
2 changes: 1 addition & 1 deletion dev/verify-msrv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ for CRATE in "$@"; do
if ! rustup toolchain list | grep -q "$VERSION"; then
rustup --quiet toolchain install "$VERSION" --no-self-update --profile minimal
fi
if [[ "$CRATE" == "hyperlight-guest" ]]; then
if [[ "$CRATE" == "hyperlight-guest" || "$CRATE" == "hyperlight-guest-bin" ]]; then
TARGET="x86_64-unknown-none"
rustup target add "$TARGET" --toolchain "$VERSION" >/dev/null
if cargo +"$VERSION" check --quiet -p "$CRATE" --target "$TARGET"; then
Expand Down
2 changes: 1 addition & 1 deletion docs/how-to-build-a-hyperlight-guest-binary.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ binary can be used with Hyperlight:
## Rust guest binary

In the case of a binary that is written in Rust, one needs to make use of the
Hyperlight crate, `hyperlight_guest` that contains the types and APIs that enable
Hyperlight crate, `hyperlight_guest` and `hyperlight_guest_bin` that contains the types and APIs that enable
the guest to:
- register functions that can be called by the host application
- call host functions that have been registered by the host.
Expand Down
1 change: 1 addition & 0 deletions docs/how-to-make-releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ After the previous CI job runs to create the new release branch, go to the ["Cre
When this job is done, a new [GitHub release](https://github.com/hyperlight-dev/hyperlight/releases) will be created for you. This job also publishes the following rust packages to the crates.io:
- `hyperlight-common`
- `hyperlight-guest`
- `hyperlight-guest-bin`
- `hyperlight-host`

## Patching a release
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/guest_call.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/host_call.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion src/hyperlight_common/src/flatbuffer_wrappers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion src/hyperlight_common/src/flatbuffer_wrappers/util.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion src/hyperlight_common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion src/hyperlight_common/src/mem.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
14 changes: 0 additions & 14 deletions src/hyperlight_guest/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[package]
name = "hyperlight-guest"
links = "c"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
Expand All @@ -12,20 +11,7 @@ description = """
Library to build guest applications for hyperlight.
"""

[features]
default = ["libc", "printf"]
libc = [] # compile musl libc
printf = [] # compile printf

[dependencies]
anyhow = { version = "1.0.98", default-features = false }
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
buddy_system_allocator = "0.11.0"
hyperlight-common = { workspace = true }
spin = "0.10.0"
log = { version = "0.4", default-features = false }

[build-dependencies]
cc = "1.2"
cfg-if = "1.0"
glob = "0.3.2"
2 changes: 1 addition & 1 deletion src/hyperlight_guest/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2024 The Hyperlight Authors.
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
100 changes: 100 additions & 0 deletions src/hyperlight_guest/src/exit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
Copyright 2025 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

use core::arch::asm;
use core::ffi::{c_char, CStr};

use hyperlight_common::outb::OutBAction;

/// Halt the execution of the guest and returns control to the host.
#[inline(never)]
pub fn halt() {
unsafe { asm!("hlt", options(nostack)) }
}

/// Exits the VM with an Abort OUT action and code 0.
#[unsafe(no_mangle)]
pub extern "C" fn abort() -> ! {
abort_with_code(&[0, 0xFF])
}

/// Exits the VM with an Abort OUT action and a specific code.
pub fn abort_with_code(code: &[u8]) -> ! {
outb(OutBAction::Abort as u16, code);
outb(OutBAction::Abort as u16, &[0xFF]); // send abort terminator (if not included in code)
unreachable!()
}

/// Aborts the program with a code and a message.
///
/// # Safety
/// This function is unsafe because it dereferences a raw pointer.
pub unsafe fn abort_with_code_and_message(code: &[u8], message_ptr: *const c_char) -> ! {
unsafe {
// Step 1: Send abort code (typically 1 byte, but `code` allows flexibility)
outb(OutBAction::Abort as u16, code);

// Step 2: Convert the C string to bytes
let message_bytes = CStr::from_ptr(message_ptr).to_bytes(); // excludes null terminator

// Step 3: Send the message itself in chunks
outb(OutBAction::Abort as u16, message_bytes);

// Step 4: Send abort terminator to signal completion (e.g., 0xFF)
outb(OutBAction::Abort as u16, &[0xFF]);

// This function never returns
unreachable!()
}
}

/// OUT bytes to the host through multiple exits.
pub(crate) fn outb(port: u16, data: &[u8]) {
unsafe {
let mut i = 0;
while i < data.len() {
let remaining = data.len() - i;
let chunk_len = remaining.min(3);
let mut chunk = [0u8; 4];
chunk[0] = chunk_len as u8;
chunk[1..1 + chunk_len].copy_from_slice(&data[i..i + chunk_len]);
let val = u32::from_le_bytes(chunk);
out32(port, val);
i += chunk_len;
}
}
}

/// OUT function for sending a 32-bit value to the host.
pub(crate) unsafe fn out32(port: u16, val: u32) {
unsafe {
asm!("out dx, eax", in("dx") port, in("eax") val, options(preserves_flags, nomem, nostack));
}
}

/// Prints a message using `OutBAction::DebugPrint`. It transmits bytes of a message
/// through several VMExists and, with such, it is slower than
/// `print_output_with_host_print`.
///
/// This function should be used in debug mode only. This function does not
/// require memory to be setup to be used.
pub fn debug_print(msg: &str) {
for byte in msg.bytes() {
unsafe {
out32(OutBAction::DebugPrint as u16, byte as u32);
}
}
}
Loading