diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bf45f3ed..be8502080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). * `Sandbox` lives in the private `sandbox::initialized` module and is reached through `hyperlight_host::Sandbox` or `hyperlight_host::sandbox::Sandbox`. `sandbox::initialized_multi_use` remains as a deprecated public path. +* C guests may omit `c_guest_dispatch_function` when they do not need custom + fallback dispatch. * Support overriding the guest log level when building or restoring initialized snapshots. * `Snapshot::save` now writes the guest memory blob sparsely, skipping all-zero diff --git a/docs/how-to-build-a-hyperlight-guest-binary.md b/docs/how-to-build-a-hyperlight-guest-binary.md index b48e2ea1e..7730e690b 100644 --- a/docs/how-to-build-a-hyperlight-guest-binary.md +++ b/docs/how-to-build-a-hyperlight-guest-binary.md @@ -101,16 +101,19 @@ The macros are optional. A guest can define the underlying symbols directly, which is useful for advanced setup work or custom dispatch logic (for example the WIT-based guests in `src/tests/rust_guests/witguest`). -The host expects two guest symbols: +The runtime provides weak default definitions for two guest symbols. A guest +can override either definition: * `pub extern "C" fn hyperlight_main()` runs once at guest startup. Use it to register functions or initialize global state. -* `pub extern "Rust" fn guest_dispatch_function(function_call: FunctionCall) -> Result, HyperlightGuestError>` - is invoked when the host calls a function name that is not registered. +* `pub extern "Rust" fn guest_dispatch_function(function_call: FunctionCall) -> Result>` + handles calls that do not match a registered guest function. Its default + implementation returns `GuestFunctionNotFound`. `hyperlight-guest-bin` exposes `#[main]` and `#[dispatch]` macros that generate these symbols from a regular Rust function, so most "advanced" guests still use -the macros rather than writing the raw `extern "C"` items themselves. +the macros rather than defining the symbols directly. A generated or direct +definition overrides the runtime's weak default. If you mix the manual form with `#[guest_function]`, registrations from the macro still happen automatically. Your `hyperlight_main` only needs to do @@ -143,6 +146,19 @@ C API library. The `hyperlight_guest.h` header contains the corresponding APIs to register guest functions and call host functions from within the guest. +Registered guest functions are checked first. When no registered function +matches, the runtime calls: + +```c +hl_ReturnValue *c_guest_dispatch_function(const hl_FunctionCall *function_call); +``` + +The C API provides a weak default implementation that returns `NULL`, which the +runtime reports as `GuestFunctionNotFound`. Define this function only when the +guest needs custom dynamic dispatch. The guest definition overrides the weak +default and must return either `NULL` or a value created by an +`hl_result_from_*` function. + See [src/tests/c_guests/c_simpleguest/main.c](../src/tests/c_guests/c_simpleguest/main.c) for a complete example. diff --git a/src/hyperlight_guest_capi/src/dispatch.rs b/src/hyperlight_guest_capi/src/dispatch.rs index 6799bcf93..648ef73f7 100644 --- a/src/hyperlight_guest_capi/src/dispatch.rs +++ b/src/hyperlight_guest_capi/src/dispatch.rs @@ -26,6 +26,19 @@ static mut LAST_HOST_RESULT: Option> = None; type CGuestFunc = extern "C" fn(&FfiFunctionCall) -> *mut FfiReturnValue; +core::arch::global_asm!( + ".weak c_guest_dispatch_function", + ".set c_guest_dispatch_function, {}", + sym c_guest_dispatch_function_default, +); + +extern "C" fn c_guest_dispatch_function_default( + _function_call: &FfiFunctionCall, +) -> *mut FfiReturnValue { + // Null surfaces as ErrorCode::GuestFunctionNotFound + core::ptr::null_mut() +} + unsafe extern "C" { // The C guest supplies this fallback. Non-null results come from hl_result_from_*. fn c_guest_dispatch_function(function_call: &FfiFunctionCall) -> *mut FfiReturnValue;