elf_runner/
vdso_vmo.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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))
    }
}

/// Returns an owned VMO handle to the stable vDSO, duplicated from the handle
/// provided to this process through its processargs bootstrap message.
pub fn get_stable_vdso_vmo() -> Result<zx::Vmo, VdsoError> {
    get_vdso_vmo(&zx::Name::new_lossy("vdso/stable"))
}

/// Returns an owned VMO handle to the next vDSO, duplicated from the handle
/// provided to this process through its processargs bootstrap message.
pub fn get_next_vdso_vmo() -> Result<zx::Vmo, VdsoError> {
    get_vdso_vmo(&zx::Name::new_lossy("vdso/next"))
}