elf_runner/
vdso_vmo.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::error::VdsoError;
6use fuchsia_runtime::{HandleInfo, HandleType, take_startup_handle};
7use std::collections::HashMap;
8use std::sync::LazyLock;
9use zx::{self as zx, AsHandleRef, HandleBased};
10
11fn take_vdso_vmos() -> Result<HashMap<zx::Name, zx::Vmo>, VdsoError> {
12    let mut vmos = HashMap::new();
13    let mut i = 0;
14    while let Some(handle) = take_startup_handle(HandleInfo::new(HandleType::VdsoVmo, i)) {
15        let vmo = zx::Vmo::from(handle);
16        let name = vmo.get_name().map_err(VdsoError::GetName)?;
17        vmos.insert(name, vmo);
18        i += 1;
19    }
20    Ok(vmos)
21}
22
23pub fn get_vdso_vmo(name: &zx::Name) -> Result<zx::Vmo, VdsoError> {
24    static VMOS: LazyLock<HashMap<zx::Name, zx::Vmo>> =
25        LazyLock::new(|| take_vdso_vmos().expect("Failed to take vDSO VMOs"));
26    if let Some(vmo) = VMOS.get(name) {
27        vmo.duplicate_handle(zx::Rights::SAME_RIGHTS)
28            .map_err(|status| VdsoError::CouldNotDuplicate { name: *name, status })
29    } else {
30        Err(VdsoError::NotFound(*name))
31    }
32}
33
34/// Returns an owned VMO handle to the stable vDSO, duplicated from the handle
35/// provided to this process through its processargs bootstrap message.
36pub fn get_stable_vdso_vmo() -> Result<zx::Vmo, VdsoError> {
37    get_vdso_vmo(&zx::Name::new_lossy("vdso/stable"))
38}
39
40/// Returns an owned VMO handle to the next vDSO, duplicated from the handle
41/// provided to this process through its processargs bootstrap message.
42pub fn get_next_vdso_vmo() -> Result<zx::Vmo, VdsoError> {
43    get_vdso_vmo(&zx::Name::new_lossy("vdso/next"))
44}