Skip to content
Merged
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
72 changes: 54 additions & 18 deletions lib/wasix/src/state/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,8 @@ pub enum LinkError {
#[error("Failed to allocate function table indices: {0}")]
TableAllocationError(RuntimeError),

#[error("File system error: {0}")]
FileSystemError(#[from] FsError),
#[error("Failed to find shared library {0}: {1}")]
SharedLibraryMissing(String, LocateModuleError),

#[error("Module is not a dynamic library")]
NotDynamicLibrary,
Expand Down Expand Up @@ -519,6 +519,26 @@ pub enum LinkError {
MissingTlsInitializer,
}

#[derive(Debug)]
pub enum LocateModuleError {
Single(FsError),
Multiple(Vec<(PathBuf, FsError)>),
}

impl std::fmt::Display for LocateModuleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
LocateModuleError::Single(e) => std::fmt::Display::fmt(&e, f),
LocateModuleError::Multiple(errors) => {
for (path, error) in errors {
write!(f, "\n {}: {}", path.display(), error)?;
}
Ok(())
}
}
}
}

#[derive(Debug)]
enum PartiallyResolvedExport {
Function(Function),
Expand Down Expand Up @@ -3566,14 +3586,25 @@ async fn locate_module(

if module_path.is_absolute() {
trace!(?module_path, "Locating module with absolute path");
Ok(try_load(&fs.root_fs, module_path).await?)
try_load(&fs.root_fs, module_path).await.map_err(|e| {
LinkError::SharedLibraryMissing(
module_path.to_string_lossy().into_owned(),
LocateModuleError::Single(e),
)
})
} else if module_path.components().count() > 1 {
trace!(?module_path, "Locating module with relative path");
Ok(try_load(
try_load(
&fs.root_fs,
fs.relative_path_to_absolute(module_path.to_string_lossy().into_owned()),
)
.await?)
.await
.map_err(|e| {
LinkError::SharedLibraryMissing(
module_path.to_string_lossy().into_owned(),
LocateModuleError::Single(e),
)
})
} else {
// Go through all dynamic library lookup paths
// Note: a path without a slash does *not* look at the current directory. This is by design.
Expand All @@ -3585,25 +3616,30 @@ async fn locate_module(
?module_path,
"Locating module by name in default runtime path"
);

if let Some(library_path) = library_path {
for path in library_path {
if let Ok(ret) = try_load(&fs.root_fs, path.as_ref().join(module_path)).await {
let search_paths = library_path
.iter()
.flat_map(|paths| paths.iter().map(AsRef::as_ref))
// Add default runtime paths
.chain(DEFAULT_RUNTIME_PATH.iter().map(|path| Path::new(path)));

let mut errors: Vec<(PathBuf, FsError)> = Vec::new();
for path in search_paths {
let full_path = path.join(module_path);
trace!(?module_path, full_path = ?full_path, "Searching module");
match try_load(&fs.root_fs, &full_path).await {
Ok(ret) => {
trace!(?module_path, full_path = ?ret.0, "Located module");
return Ok(ret);
}
}
}

for path in DEFAULT_RUNTIME_PATH {
if let Ok(ret) = try_load(&fs.root_fs, Path::new(path).join(module_path)).await {
trace!(?module_path, full_path = ?ret.0, "Located module");
return Ok(ret);
}
Err(e) => errors.push((full_path, e)),
};
}

trace!(?module_path, "Failed to locate module");
Err(FsError::EntryNotFound.into())
Err(LinkError::SharedLibraryMissing(
module_path.to_string_lossy().into_owned(),
LocateModuleError::Multiple(errors),
))
}
}

Expand Down
Loading