Skip to content

Cleanup of win64 and alike ABI usage and MSVC legacy #499

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 12 commits into from
May 16, 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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
&& rustup default ${RUST_TOOLCHAIN} \
&& rustup target add x86_64-unknown-linux-gnu \
&& rustup target add x86_64-unknown-none \
&& rustup target add x86_64-pc-windows-msvc \
&& rustup toolchain add nightly-x86_64-unknown-linux-gnu \
&& cargo install just

7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,10 @@ After having an environment with a hypervisor setup, running the example has the
Azure Linux, run `sudo dnf install build-essential`.
2. [Rust](https://www.rust-lang.org/tools/install). Install toolchain v1.81 or later.

Also, install the `x86_64-pc-windows-msvc` and `x86_64-unknown-none` targets, these are needed to build the test
guest binaries. (Note: install both targets on either Linux or Windows: Hyperlight can load ELF or PE files on either
OS, and the tests/examples are built for both):

Also, install the `x86_64-unknown-none` target, it is needed to build the test
guest binaries.
```sh
rustup target add x86_64-unknown-none
rustup target add x86_64-pc-windows-msvc
```

3. [just](https://github.com/casey/just). `cargo install just` On Windows you also need [pwsh](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4).
Expand Down
19 changes: 15 additions & 4 deletions dev/verify-msrv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,21 @@ for CRATE in "$@"; do
if ! rustup toolchain list | grep -q "$VERSION"; then
rustup --quiet toolchain install "$VERSION" --no-self-update --profile minimal
fi
if cargo +$VERSION check --quiet -p $CRATE; then
echo -e " \u001b[1;32m✓\u001b[0m Crate \u001b[1m$CRATE\u001b[0m builds with rust \u001b[1m$VERSION\u001b[0m"
if [[ "$CRATE" == "hyperlight-guest" ]]; then
TARGET="x86_64-unknown-none"
rustup target add "$TARGET" --toolchain "$VERSION" >/dev/null
if cargo +"$VERSION" check --quiet -p "$CRATE" --target "$TARGET"; then
echo -e " \u001b[1;32m✓\u001b[0m Crate \u001b[1m$CRATE\u001b[0m builds with rust \u001b[1m$VERSION\u001b[0m and target \u001b[1m$TARGET\u001b[0m"
else
echo -e " \u001b[1;31m✗\u001b[0m Crate \u001b[1m$CRATE\u001b[0m fails with rust \u001b[1m$VERSION\u001b[0m and target \u001b[1m$TARGET\u001b[0m"
exit 1
fi
else
echo -e " \u001b[1;31m✗\u001b[0m Crate \u001b[1m$CRATE\u001b[0m fails with rust \u001b[1m$VERSION\u001b[0m"
exit 1
if cargo +"$VERSION" check --quiet -p "$CRATE"; then
echo -e " \u001b[1;32m✓\u001b[0m Crate \u001b[1m$CRATE\u001b[0m builds with rust \u001b[1m$VERSION\u001b[0m"
else
echo -e " \u001b[1;31m✗\u001b[0m Crate \u001b[1m$CRATE\u001b[0m fails with rust \u001b[1m$VERSION\u001b[0m"
exit 1
fi
fi
done
1 change: 0 additions & 1 deletion src/hyperlight_guest/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ fn cargo_main() {
copy_includes(&include_dir, "third_party/printf/");
}
if cfg!(feature = "libc") {
copy_includes(&include_dir, "include");
copy_includes(&include_dir, "third_party/musl/include");
copy_includes(&include_dir, "third_party/musl/arch/generic");
copy_includes(&include_dir, "third_party/musl/arch/x86_64");
Expand Down
47 changes: 0 additions & 47 deletions src/hyperlight_guest/include/setjmp.h

This file was deleted.

64 changes: 0 additions & 64 deletions src/hyperlight_guest/src/chkstk.rs

This file was deleted.

20 changes: 10 additions & 10 deletions src/hyperlight_guest/src/entrypoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ use hyperlight_common::outb::OutBAction;
use log::LevelFilter;
use spin::Once;

use crate::gdt::load_gdt;
#[cfg(target_arch = "x86_64")]
use crate::exceptions::{gdt::load_gdt, idtr::load_idt};
use crate::guest_function_call::dispatch_function;
use crate::guest_logger::init_logger;
use crate::host_function_call::outb;
use crate::idtr::load_idt;
use crate::{__security_cookie, HEAP_ALLOCATOR, MIN_STACK_ADDRESS, OS_PAGE_SIZE, P_PEB};
use crate::{HEAP_ALLOCATOR, MIN_STACK_ADDRESS, OS_PAGE_SIZE, P_PEB};

#[inline(never)]
pub fn halt() {
Expand Down Expand Up @@ -73,10 +73,8 @@ extern "C" {

static INIT: Once = Once::new();

// Note: entrypoint cannot currently have a stackframe >4KB, as that will invoke __chkstk on msvc
// target without first having setup global `RUNNING_MODE` variable, which __chkstk relies on.
#[no_mangle]
pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_level: u64) {
pub extern "C" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_level: u64) {
if peb_address == 0 {
panic!("PEB address is null");
}
Expand All @@ -85,7 +83,6 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_
unsafe {
P_PEB = Some(peb_address as *mut HyperlightPEB);
let peb_ptr = P_PEB.unwrap();
__security_cookie = peb_address ^ seed;

let srand_seed = ((peb_address << 8 ^ seed >> 4) >> 32) as u32;

Expand All @@ -103,9 +100,12 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_
// don't have to change the assembly code.
MIN_STACK_ADDRESS = (*peb_ptr).gueststackData.minUserStackAddress;

// Setup GDT and IDT
load_gdt();
load_idt();
#[cfg(target_arch = "x86_64")]
{
// Setup GDT and IDT
load_gdt();
load_idt();
}

let heap_start = (*peb_ptr).guestheapData.guestHeapBuffer as usize;
let heap_size = (*peb_ptr).guestheapData.guestHeapSize as usize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::entrypoint::abort_with_code_and_message;

/// Exception handler
#[no_mangle]
pub extern "sysv64" fn hl_exception_handler(
pub extern "C" fn hl_exception_handler(
stack_pointer: u64,
exception_number: u64,
page_fault_address: u64,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

use hyperlight_common::outb::Exception;

use crate::interrupt_entry::{
use crate::exceptions::interrupt_entry::{
_do_excp0, _do_excp1, _do_excp10, _do_excp11, _do_excp12, _do_excp13, _do_excp14, _do_excp15,
_do_excp16, _do_excp17, _do_excp18, _do_excp19, _do_excp2, _do_excp20, _do_excp3, _do_excp30,
_do_excp4, _do_excp5, _do_excp6, _do_excp7, _do_excp8, _do_excp9,
Expand Down Expand Up @@ -96,7 +96,7 @@ pub(crate) fn init_idt() {
set_idt_entry(Exception::SecurityException as usize, _do_excp30); // Security Exception
}

fn set_idt_entry(index: usize, handler: unsafe extern "sysv64" fn()) {
fn set_idt_entry(index: usize, handler: unsafe extern "C" fn()) {
let handler_addr = handler as *const () as u64;
unsafe {
IDT[index] = IdtEntry::new(handler_addr);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::ptr::addr_of;

use crate::idt::{init_idt, IdtEntry, IDT};
use crate::exceptions::idt::{init_idt, IdtEntry, IDT};

#[repr(C, packed)]
pub struct Idtr {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ limitations under the License.

use core::arch::global_asm;

use crate::interrupt_handlers::hl_exception_handler;
use crate::exceptions::handlers::hl_exception_handler;

extern "sysv64" {
extern "C" {
// Exception handlers
pub(crate) fn _do_excp0();
pub(crate) fn _do_excp1();
Expand Down Expand Up @@ -119,7 +119,6 @@ macro_rules! generate_exceptions {
// Common exception handler
".global _do_excp_common\n",
"_do_excp_common:\n",
// In SysV ABI, the first argument is passed in rdi
// rdi is the stack pointer.
" mov rdi, rsp\n",
" call {hl_exception_handler}\n",
Expand Down Expand Up @@ -173,12 +172,10 @@ macro_rules! generate_excp {
stringify!($num),
":\n",
context_save!(),
// In SysV ABI, the second argument is passed in rsi
// rsi is the exception number.
" mov rsi, ",
stringify!($num),
"\n",
// In SysV ABI, the third argument is passed in rdx
// rdx is only used for pagefault exception and
// contains the address that caused the pagefault.
" mov rdx, 0\n",
Expand All @@ -198,12 +195,10 @@ macro_rules! generate_excp {
// stack aligned.
" push 0\n",
context_save!(),
// In SysV ABI, the second argument is passed in rsi
// rsi is the exception number.
" mov rsi, ",
stringify!($num),
"\n",
// In SysV ABI, the third argument is passed in rdx
// rdx is only used for pagefault exception and
// contains the address that caused the pagefault.
" mov rdx, 0\n",
Expand Down
12 changes: 0 additions & 12 deletions src/hyperlight_guest/src/guest_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ use alloc::vec::Vec;
use core::ffi::{c_char, CStr};

use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError};
use hyperlight_common::outb::OutBAction;

use crate::entrypoint::halt;
use crate::host_function_call::outb;
use crate::shared_output_data::push_shared_output_data;

pub(crate) fn write_error(error_code: ErrorCode, message: Option<&str>) {
Expand All @@ -42,16 +40,6 @@ pub(crate) fn set_error(error_code: ErrorCode, message: &str) {
write_error(error_code, Some(message));
}

pub(crate) fn set_error_and_halt(error_code: ErrorCode, message: &str) {
set_error(error_code, message);
halt();
}

#[no_mangle]
pub(crate) extern "win64" fn set_stack_allocate_error() {
outb(OutBAction::Abort as u16, &[ErrorCode::StackOverflow as u8]);
}

/// Exposes a C API to allow the guest to set an error
///
/// # Safety
Expand Down
2 changes: 1 addition & 1 deletion src/hyperlight_guest/src/guest_function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ fn internal_dispatch_function() -> Result<()> {
// This is implemented as a separate function to make sure that epilogue in the internal_dispatch_function is called before the halt()
// which if it were included in the internal_dispatch_function cause the epilogue to not be called because the halt() would not return
// when running in the hypervisor.
pub(crate) extern "win64" fn dispatch_function() {
pub(crate) extern "C" fn dispatch_function() {
let _ = internal_dispatch_function();
halt();
}
30 changes: 8 additions & 22 deletions src/hyperlight_guest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,18 @@ pub mod host_function_call;
pub(crate) mod guest_logger;
pub mod memory;
pub mod print;
pub(crate) mod security_check;
pub mod setjmp;

pub mod chkstk;
pub mod error;
pub mod gdt;
pub mod idt;
pub mod idtr;
pub mod interrupt_entry;
pub mod interrupt_handlers;
#[cfg(target_arch = "x86_64")]
pub mod exceptions {
pub mod gdt;
pub mod handlers;
pub mod idt;
pub mod idtr;
pub mod interrupt_entry;
}
pub mod logging;

// Unresolved symbols
///cbindgen:ignore
#[no_mangle]
pub(crate) extern "C" fn __CxxFrameHandler3() {}
///cbindgen:ignore
#[no_mangle]
#[clippy::allow(clippy::non_upper_case_globals)]
pub(crate) static _fltused: i32 = 0;

// It looks like rust-analyzer doesn't correctly manage no_std crates,
// and so it displays an error about a duplicate panic_handler.
// See more here: https://github.com/rust-lang/rust-analyzer/issues/4490
Expand All @@ -82,11 +73,6 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
#[global_allocator]
pub(crate) static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::empty();

///cbindgen:ignore
#[no_mangle]
#[clippy::allow(clippy::non_upper_case_globals)]
pub(crate) static mut __security_cookie: u64 = 0;

pub(crate) static mut P_PEB: Option<*mut HyperlightPEB> = None;
pub static mut MIN_STACK_ADDRESS: u64 = 0;

Expand Down
Loading