1use crate::error::VdsoError;
6use fuchsia_runtime::{HandleInfo, HandleType, take_startup_handle};
7use std::collections::HashMap;
8use std::sync::LazyLock;
9
10fn take_vdso_vmos() -> Result<HashMap<zx::Name, zx::Vmo>, VdsoError> {
11 let mut vmos = HashMap::new();
12 let mut i = 0;
13 while let Some(handle) = take_startup_handle(HandleInfo::new(HandleType::VdsoVmo, i)) {
14 let vmo = zx::Vmo::from(handle);
15 let name = vmo.get_name().map_err(VdsoError::GetName)?;
16 vmos.insert(name, vmo);
17 i += 1;
18 }
19 Ok(vmos)
20}
21
22pub fn get_vdso_vmo(name: &zx::Name) -> Result<zx::Vmo, VdsoError> {
23 static VMOS: LazyLock<HashMap<zx::Name, zx::Vmo>> =
24 LazyLock::new(|| take_vdso_vmos().expect("Failed to take vDSO VMOs"));
25 if let Some(vmo) = VMOS.get(name) {
26 vmo.duplicate_handle(zx::Rights::SAME_RIGHTS)
27 .map_err(|status| VdsoError::CouldNotDuplicate { name: *name, status })
28 } else {
29 Err(VdsoError::NotFound(*name))
30 }
31}
32
33pub fn get_stable_vdso_vmo() -> Result<zx::Vmo, VdsoError> {
36 get_vdso_vmo(&zx::Name::new_lossy("vdso/stable"))
37}
38
39pub fn get_next_vdso_vmo() -> Result<zx::Vmo, VdsoError> {
42 get_vdso_vmo(&zx::Name::new_lossy("vdso/next"))
43}