blob: 3b8a957af513d39910fff0812c5250d4c1c662f7 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
#include <lib/userabi/rodso.h>
#include <lib/userabi/userboot.h>
#include <vm/vm_object.h>
class VmMapping;
class VDso : public RoDso {
// This is called only once, at boot time.
// The created VDso will retain RefPtrs to the created VmObjectDispatchers,
// but ownership of the wrapping handles are given to the caller.
// The RoDso VMO is created in vmo_kernel_handles[0], with the VDso variants
// following.
static const VDso* Create(KernelHandle<VmObjectDispatcher>* vmo_kernel_handles);
static bool vmo_is_vdso(const fbl::RefPtr<VmObject>& vmo) {
return likely(instance_) && instance_->vmo_is_vdso_impl(vmo);
static bool valid_code_mapping(uint64_t vmo_offset, size_t size) {
return instance_->RoDso::valid_code_mapping(vmo_offset, size);
// Given VmAspace::vdso_code_mapping_, return the vDSO base address or 0.
static uintptr_t base_address(const fbl::RefPtr<VmMapping>& code_mapping);
// Forward declaration of generated class.
// This class is defined in the file vdso-valid-sysret.h,
// which is generated by scripts/
// It has a static method named after each syscall:
// static bool <syscall-name>(uintptr_t offset);
// This tests whether <start of vDSO code>+offset is a valid PC
// for entering the kernel with <syscall-name>'s syscall number.
struct ValidSyscallPC;
using Variant = userboot::VdsoVariant;
VDso(KernelHandle<VmObjectDispatcher>* vmo_kernel_handles);
void CreateVariant(Variant, KernelHandle<VmObjectDispatcher>* vmo_kernel_handle);
bool vmo_is_vdso_impl(const fbl::RefPtr<VmObject>& vmo_ref) const {
if (vmo_ref == vmo()->vmo())
return true;
for (const auto& v : variant_vmo_) {
if (vmo_ref == v->vmo())
return true;
return false;
static constexpr size_t variant_index(Variant v) {
DEBUG_ASSERT(v > Variant::FULL);
return static_cast<size_t>(v) - 1;
fbl::RefPtr<VmObjectDispatcher> variant_vmo_[static_cast<size_t>(Variant::COUNT) - 1];
static const VDso* instance_;