use crate::error::VdsoError;
use fuchsia_runtime::{take_startup_handle, HandleInfo, HandleType};
use lazy_static::lazy_static;
use std::collections::HashMap;
use zx::{self as zx, AsHandleRef, HandleBased};
fn take_vdso_vmos() -> Result<HashMap<zx::Name, zx::Vmo>, VdsoError> {
let mut vmos = HashMap::new();
let mut i = 0;
while let Some(handle) = take_startup_handle(HandleInfo::new(HandleType::VdsoVmo, i)) {
let vmo = zx::Vmo::from(handle);
let name = vmo.get_name().map_err(VdsoError::GetName)?;
vmos.insert(name, vmo);
i += 1;
}
Ok(vmos)
}
pub fn get_vdso_vmo(name: &zx::Name) -> Result<zx::Vmo, VdsoError> {
lazy_static! {
static ref VMOS: HashMap<zx::Name, zx::Vmo> =
take_vdso_vmos().expect("Failed to take vDSO VMOs");
}
if let Some(vmo) = VMOS.get(name) {
vmo.duplicate_handle(zx::Rights::SAME_RIGHTS)
.map_err(|status| VdsoError::CouldNotDuplicate { name: *name, status })
} else {
Err(VdsoError::NotFound(*name))
}
}
pub fn get_stable_vdso_vmo() -> Result<zx::Vmo, VdsoError> {
get_vdso_vmo(&zx::Name::new_lossy("vdso/stable"))
}
pub fn get_next_vdso_vmo() -> Result<zx::Vmo, VdsoError> {
get_vdso_vmo(&zx::Name::new_lossy("vdso/next"))
}