Skip to content
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
4 changes: 1 addition & 3 deletions .github/workflows/playground.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ jobs:
with:
node-version: 20
- uses: ./.github/actions/install-rust
- uses: cargo-bins/[email protected]
- run: cargo binstall [email protected] -y
- run: rustup component add rustfmt # needed for cargo-component, apparently?
- run: rustup target add wasm32-wasip1
- run: rustup target add wasm32-wasip2
- run: npm ci
working-directory: playground
- run: npm run build
Expand Down
13 changes: 2 additions & 11 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ unnecessary_cast = 'warn'
# allow_attributes_without_reason = 'warn'

[workspace.package]
edition = '2021'
edition = '2024'
license = "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT"
version = "0.246.2"
# Current thinking for wasm-tools is that the minimum supported Rust version
Expand Down
160 changes: 83 additions & 77 deletions crates/wit-component/dl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,34 +51,36 @@ static mut ERROR: *const c_char = ptr::null();
static mut LIBRARIES: *const Libraries = ptr::null();

unsafe fn invalid_handle(library: *const c_void) -> bool {
if LIBRARIES.is_null() {
panic!(
"`__wasm_set_libraries` should have been called during \
unsafe {
if LIBRARIES.is_null() {
panic!(
"`__wasm_set_libraries` should have been called during \
instantiation with a non-NULL value"
);
}

let library = library as *const Library;
if (0..(*LIBRARIES).count)
.any(|index| (*LIBRARIES).libraries.add(usize::try_from(index).unwrap()) == library)
{
false
} else {
ERROR = c"invalid library handle".as_ptr();
true
);
}

let library = library as *const Library;
if (0..(*LIBRARIES).count)
.any(|index| (*LIBRARIES).libraries.add(usize::try_from(index).unwrap()) == library)
{
false
} else {
ERROR = c"invalid library handle".as_ptr();
true
}
}
}

/// # Safety
///
/// `library` must be a valid, not-yet-closed library pointer returned by
/// `dlopen`.
#[no_mangle]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn dlclose(library: *mut c_void) -> c_int {
if invalid_handle(library) { -1 } else { 0 }
unsafe { if invalid_handle(library) { -1 } else { 0 } }
}

#[no_mangle]
#[unsafe(no_mangle)]
pub extern "C" fn dlerror() -> *const c_char {
unsafe {
let value = ERROR;
Expand All @@ -90,85 +92,89 @@ pub extern "C" fn dlerror() -> *const c_char {
/// # Safety
///
/// `name` must be a valid pointer to a null-terminated string.
#[no_mangle]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn dlopen(name: *const c_char, flags: c_int) -> *const c_void {
if LIBRARIES.is_null() {
panic!(
"`__wasm_set_libraries` should have been called during \
unsafe {
if LIBRARIES.is_null() {
panic!(
"`__wasm_set_libraries` should have been called during \
instantiation with a non-NULL value"
);
}

if (flags & !(RTLD_LAZY | RTLD_NOW | RTLD_GLOBAL)) != 0 {
// TODO
ERROR = c"dlopen flags not yet supported".as_ptr();
return ptr::null();
}

let name = CStr::from_ptr(name);
let name = name.to_bytes();
let libraries = slice::from_raw_parts(
(*LIBRARIES).libraries,
usize::try_from((*LIBRARIES).count).unwrap(),
);
}

if (flags & !(RTLD_LAZY | RTLD_NOW | RTLD_GLOBAL)) != 0 {
// TODO
ERROR = c"dlopen flags not yet supported".as_ptr();
return ptr::null();
}

let name = CStr::from_ptr(name);
let name = name.to_bytes();
let libraries = slice::from_raw_parts(
(*LIBRARIES).libraries,
usize::try_from((*LIBRARIES).count).unwrap(),
);
if let Ok(index) = libraries.binary_search_by(|library| {
slice::from_raw_parts(
library.name.data,
usize::try_from(library.name.length).unwrap(),
)
.cmp(name)
}) {
&libraries[index] as *const _ as _
} else {
ERROR = c"library not found".as_ptr();
ptr::null()
if let Ok(index) = libraries.binary_search_by(|library| {
slice::from_raw_parts(
library.name.data,
usize::try_from(library.name.length).unwrap(),
)
.cmp(name)
}) {
&libraries[index] as *const _ as _
} else {
ERROR = c"library not found".as_ptr();
ptr::null()
}
}
}

/// # Safety
///
/// `library` must be a valid, not-yet-closed library pointer returned by
/// `dlopen`, and `name` must be a valid pointer to a null-terminated string.
#[no_mangle]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn dlsym(library: *const c_void, name: *const c_char) -> *const c_void {
if library as isize == RTLD_NEXT || library as isize == RTLD_DEFAULT {
// TODO
ERROR = c"dlsym RTLD_NEXT and RTLD_DEFAULT not yet supported".as_ptr();
return ptr::null();
}

if invalid_handle(library) {
return ptr::null();
}

let library = library as *const Library;
let name = CStr::from_ptr(name);
let name = name.to_bytes();
let symbols = slice::from_raw_parts(
(*library).symbols.symbols,
usize::try_from((*library).symbols.count).unwrap(),
);
if let Ok(index) = symbols.binary_search_by(|symbol| {
slice::from_raw_parts(
symbol.name.data,
usize::try_from(symbol.name.length).unwrap(),
)
.cmp(name)
}) {
symbols[index].address
} else {
ERROR = c"symbol not found".as_ptr();
ptr::null()
unsafe {
if library as isize == RTLD_NEXT || library as isize == RTLD_DEFAULT {
// TODO
ERROR = c"dlsym RTLD_NEXT and RTLD_DEFAULT not yet supported".as_ptr();
return ptr::null();
}
if invalid_handle(library) {
return ptr::null();
}
let library = library as *const Library;
let name = CStr::from_ptr(name);
let name = name.to_bytes();
let symbols = slice::from_raw_parts(
(*library).symbols.symbols,
usize::try_from((*library).symbols.count).unwrap(),
);
if let Ok(index) = symbols.binary_search_by(|symbol| {
slice::from_raw_parts(
symbol.name.data,
usize::try_from(symbol.name.length).unwrap(),
)
.cmp(name)
}) {
symbols[index].address
} else {
ERROR = c"symbol not found".as_ptr();
ptr::null()
}
}
}

/// # Safety
///
/// `libraries` must be a valid pointer to a `Libraries` object, and this
/// pointer must remain valid for the lifetime of the process.
#[no_mangle]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn __wasm_set_libraries(libraries: *const Libraries) {
LIBRARIES = libraries;
unsafe {
LIBRARIES = libraries;
}
}

#[cfg(target_arch = "wasm32")]
Expand Down
Loading
Loading