Skip to content

Commit b620e3e

Browse files
committed
move libc from hl-guest-bin to hl-libc
Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com>
1 parent 43118b2 commit b620e3e

21 files changed

Lines changed: 620 additions & 82 deletions

File tree

.gitmodules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[submodule "src/hyperlight_guest_bin/third_party/picolibc"]
2-
path = src/hyperlight_guest_bin/third_party/picolibc
1+
[submodule "src/hyperlight_libc/third_party/picolibc"]
2+
path = src/hyperlight_libc/third_party/picolibc
33
url = https://github.com/hyperlight-dev/picolibc-bsd.git
44
shallow = true

Cargo.lock

Lines changed: 32 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ members = [
1515
"fuzz",
1616
"src/hyperlight_guest_bin",
1717
"src/hyperlight_guest_macro",
18+
"src/hyperlight_libc",
1819
"src/hyperlight_component_util",
1920
"src/hyperlight_component_macro",
2021
"src/trace_dump",
@@ -43,6 +44,7 @@ hyperlight-guest-bin = { path = "src/hyperlight_guest_bin", version = "0.14.0",
4344
hyperlight-guest-macro = { path = "src/hyperlight_guest_macro", version = "0.14.0", default-features = false }
4445
hyperlight-testing = { path = "src/hyperlight_testing", default-features = false }
4546
hyperlight-guest-tracing = { path = "src/hyperlight_guest_tracing", version = "0.14.0", default-features = false }
47+
hyperlight-libc = { path = "src/hyperlight_libc", version = "0.14.0", default-features = false }
4648
hyperlight-component-util = { path = "src/hyperlight_component_util", version = "0.14.0", default-features = false }
4749
hyperlight-component-macro = { path = "src/hyperlight_component_macro", version = "0.14.0", default-features = false }
4850

NOTICE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Copyright © 2020 The Newlib Project
5353
Newlib code is licensed under a collection of BSD-compatible and
5454
permissive licenses. The full license details for all files are
5555
documented in the COPYING.picolibc and COPYING.NEWLIB files in the
56-
picolibc submodule at src/hyperlight_guest_bin/third_party/picolibc/.
56+
picolibc submodule at src/hyperlight_libc/third_party/picolibc/.
5757

5858
Note: The picolibc submodule uses the picolibc-bsd fork
5959
(https://github.com/hyperlight-dev/picolibc-bsd), which is a redistribution

c.just

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ mkdir := if os() == "windows" { "mkdir -f -p" } else { "mkdir -p"}
33
# Elf options
44
# We don't support stack protectors at the moment, but Arch Linux clang auto-enables them for -linux platforms, so explicitly disable them.
55
c-compile-options-elf := '-nostdlibinc -H --target=x86_64-unknown-linux-none -fno-stack-protector -fstack-clash-protection -mstack-probe-size=4096 -fPIC'
6-
c-include-flags-elf := "-I " + root / "src/hyperlight_guest_capi/include/" + " -I " + root / "src/hyperlight_guest_bin/third_party/picolibc/libc/include/" + " -I " + root / "src/hyperlight_guest_bin/third_party/picolibc/libc/stdio/" + " -I " + root / "src/hyperlight_guest_bin/include/"
6+
c-include-flags-elf := "-I " + root / "src/hyperlight_guest_capi/include/" + " -I " + root / "src/hyperlight_libc/third_party/picolibc/libc/include/" + " -I " + root / "src/hyperlight_libc/third_party/picolibc/libc/stdio/" + " -I " + root / "src/hyperlight_libc/include/"
77
c-linker-options-elf := '--entry "entrypoint" --nostdlib -pie --no-dynamic-linker'
88
c-flags-debug-elf := '-O0'
99
c-flags-release-elf := '-O3'

docs/picolibc.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ for embedded systems, making it well-suited for Hyperlight's micro-VM environmen
88

99
The picolibc integration is controlled by the `libc` feature flag on the `hyperlight-guest-bin`
1010
crate (enabled by default). When enabled, the build script compiles picolibc from source using the
11-
vendored submodule at `src/hyperlight_guest_bin/third_party/picolibc`.
11+
vendored submodule at `src/hyperlight_libc/third_party/picolibc`.
1212

1313
The submodule points to [picolibc-bsd](https://github.com/hyperlight-dev/picolibc-bsd), a
1414
redistribution of picolibc with all copyleft-licensed files (GPL/AGPL) removed from the tree and
@@ -66,11 +66,11 @@ To update picolibc to a new version:
6666
2. Update the submodule in hyperlight:
6767

6868
```bash
69-
cd src/hyperlight_guest_bin/third_party/picolibc
69+
cd src/hyperlight_libc/third_party/picolibc
7070
git fetch origin
7171
git checkout <new-fork-tag>
7272
cd ../../../..
73-
git add src/hyperlight_guest_bin/third_party/picolibc
73+
git add src/hyperlight_libc/third_party/picolibc
7474
```
7575

7676
3. Verify licensing: The fork's CI runs scancode-toolkit to ensure no copyleft files are present.

src/hyperlight_guest_bin/Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[package]
22
name = "hyperlight-guest-bin"
3-
links = "c"
43
version.workspace = true
54
edition.workspace = true
65
rust-version.workspace = true
@@ -15,7 +14,7 @@ and third-party code used by our C-API needed to build a native hyperlight-guest
1514

1615
[features]
1716
default = ["libc", "macros"]
18-
libc = [] # compile libc from picolibc
17+
libc = ["dep:hyperlight-libc"] # compile libc from picolibc
1918
trace_guest = ["hyperlight-common/trace_guest", "hyperlight-guest/trace_guest", "hyperlight-guest-tracing/trace"]
2019
mem_profile = ["hyperlight-common/mem_profile"]
2120
macros = ["dep:hyperlight-guest-macro", "dep:linkme"]
@@ -25,6 +24,7 @@ hyperlight-guest = { workspace = true, default-features = false }
2524
hyperlight-common = { workspace = true, default-features = false }
2625
hyperlight-guest-tracing = { workspace = true, default-features = false }
2726
hyperlight-guest-macro = { workspace = true, default-features = false, optional = true }
27+
hyperlight-libc = { workspace = true, default-features = false, optional = true }
2828
buddy_system_allocator = "0.13.0"
2929
log = { version = "0.4", default-features = false }
3030
linkme = { version = "0.3.36", optional = true }
@@ -37,6 +37,4 @@ workspace = true
3737

3838
[build-dependencies]
3939
anyhow = "1"
40-
cc = "1.2"
4140
cfg-if = "1.0"
42-
glob = "0.3.3"

src/hyperlight_guest_bin/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,13 @@ pub mod memory;
5555
pub mod paging;
5656

5757
/// Bridge between picolibc's POSIX expectations and the Hyperlight host.
58+
/// cbindgen:ignore
5859
#[cfg(feature = "libc")]
59-
mod libc;
60+
mod libc_stubs;
61+
62+
/// Re-export the libc bindings from hyperlight-libc when the libc feature is enabled.
63+
#[cfg(feature = "libc")]
64+
pub use hyperlight_libc as libc;
6065

6166
// Globals
6267
#[cfg(all(feature = "mem_profile", target_arch = "x86_64"))]

src/hyperlight_guest_bin/src/libc.rs renamed to src/hyperlight_guest_bin/src/libc_stubs.rs

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,48 +16,25 @@ limitations under the License.
1616

1717
use alloc::string::String;
1818
use alloc::vec;
19-
use core::ffi::*;
19+
use core::ffi::{c_int, c_long, c_void};
2020
use core::sync::atomic::{AtomicU64, Ordering};
2121

2222
use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnType};
2323

2424
use crate::host_comm::call_host_function;
25+
use crate::libc::{
26+
CLOCK_MONOTONIC, CLOCK_REALTIME, EBADF, EINVAL, EIO, ENOSYS, clockid_t, errno, timespec,
27+
timeval,
28+
};
2529

26-
unsafe extern "C" {
27-
static mut errno: c_int;
28-
}
29-
30-
fn set_errno(val: c_int) {
30+
fn set_errno(val: u32) {
3131
// SAFETY: single-threaded guest, errno is a global int (__GLOBAL_ERRNO)
32-
unsafe { errno = val };
32+
// Bindgen uses u32 for the errno definitions, so we convert it to the expected c_int type here
33+
unsafe { errno = val as _ };
3334
}
3435

35-
// POSIX errno values (matching picolibc sys/errno.h)
36-
const EINVAL: c_int = 22;
37-
const EIO: c_int = 5;
38-
const EBADF: c_int = 9;
39-
const ENOSYS: c_int = 88;
40-
41-
// picolibc clock IDs (from time.h)
42-
const CLOCK_REALTIME: c_ulong = 1;
43-
const CLOCK_MONOTONIC: c_ulong = 4;
44-
4536
static CURRENT_TIME: AtomicU64 = AtomicU64::new(0);
4637

47-
/// Matches picolibc `struct timespec` layout for x86_64 and aarch64.
48-
#[repr(C)]
49-
pub(crate) struct Timespec {
50-
tv_sec: c_long,
51-
tv_nsec: c_long,
52-
}
53-
54-
/// Matches picolibc `struct timeval` layout for x86_64 and aarch64.
55-
#[repr(C)]
56-
pub(crate) struct Timeval {
57-
tv_sec: c_long,
58-
tv_usec: c_long,
59-
}
60-
6138
/// Returns a synthetic monotonically-increasing time starting at Unix epoch
6239
/// increasing 1s each call.
6340
fn current_time() -> (u64, u64) {
@@ -66,7 +43,7 @@ fn current_time() -> (u64, u64) {
6643
}
6744

6845
#[unsafe(no_mangle)]
69-
pub extern "C" fn read(fd: c_int, buf: *mut c_void, count: usize) -> isize {
46+
extern "C" fn read(fd: c_int, buf: *mut c_void, count: usize) -> isize {
7047
if buf.is_null() && count > 0 {
7148
set_errno(EINVAL);
7249
return -1;
@@ -81,7 +58,7 @@ pub extern "C" fn read(fd: c_int, buf: *mut c_void, count: usize) -> isize {
8158
}
8259

8360
#[unsafe(no_mangle)]
84-
pub extern "C" fn write(fd: c_int, buf: *const c_void, count: usize) -> isize {
61+
extern "C" fn write(fd: c_int, buf: *const c_void, count: usize) -> isize {
8562
if buf.is_null() && count > 0 {
8663
set_errno(EINVAL);
8764
return -1;
@@ -108,14 +85,19 @@ pub extern "C" fn write(fd: c_int, buf: *const c_void, count: usize) -> isize {
10885
}
10986

11087
#[unsafe(no_mangle)]
111-
pub extern "C" fn clock_gettime(clk_id: c_ulong, tp: *mut Timespec) -> c_int {
88+
extern "C" fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int {
89+
// The libc bindings generated by bindgen are u32, but we expect them to be clockid_t,
90+
// so we convert the constants to the expected type here for comparison.
91+
const CLOCK_ID_REALTIME: clockid_t = CLOCK_REALTIME as _;
92+
const CLOCK_ID_MONOTONIC: clockid_t = CLOCK_MONOTONIC as _;
93+
11294
if tp.is_null() {
11395
set_errno(EINVAL);
11496
return -1;
11597
}
11698

11799
match clk_id {
118-
CLOCK_REALTIME | CLOCK_MONOTONIC => {
100+
CLOCK_ID_REALTIME | CLOCK_ID_MONOTONIC => {
119101
let (secs, nanos) = current_time();
120102
unsafe {
121103
(*tp).tv_sec = secs as c_long;
@@ -131,7 +113,7 @@ pub extern "C" fn clock_gettime(clk_id: c_ulong, tp: *mut Timespec) -> c_int {
131113
}
132114

133115
#[unsafe(no_mangle)]
134-
pub extern "C" fn gettimeofday(tv: *mut Timeval, _tz: *mut c_void) -> c_int {
116+
extern "C" fn gettimeofday(tv: *mut timeval, _tz: *mut c_void) -> c_int {
135117
if tv.is_null() {
136118
set_errno(EINVAL);
137119
return -1;
@@ -146,17 +128,17 @@ pub extern "C" fn gettimeofday(tv: *mut Timeval, _tz: *mut c_void) -> c_int {
146128
}
147129

148130
#[unsafe(no_mangle)]
149-
pub extern "C" fn _exit(ec: c_int) -> ! {
131+
extern "C" fn _exit(ec: c_int) -> ! {
150132
hyperlight_guest::exit::abort_with_code(&[ec as u8]);
151133
}
152134

153135
#[unsafe(no_mangle)]
154-
pub extern "C" fn lseek(_fd: c_int, _offset: c_long, _whence: c_int) -> c_long {
136+
extern "C" fn lseek(_fd: c_int, _offset: c_long, _whence: c_int) -> c_long {
155137
set_errno(ENOSYS);
156138
-1
157139
}
158140

159141
#[unsafe(no_mangle)]
160-
pub extern "C" fn close(_fd: c_int) -> c_int {
142+
extern "C" fn close(_fd: c_int) -> c_int {
161143
0
162144
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build]
2+
target = "x86_64-unknown-none"

0 commit comments

Comments
 (0)