82 lines · c
1//===------------- Linux VDSO Header ----------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_VDSO_H9#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_VDSO_H10#include "src/__support/CPP/array.h"11#include "src/__support/common.h"12#include "src/__support/macros/attributes.h"13#include "src/__support/macros/properties/architectures.h"14#include "src/__support/threads/callonce.h"15 16#if defined(LIBC_TARGET_ARCH_IS_X86)17#include "x86_64/vdso.h"18#elif defined(LIBC_TARGET_ARCH_IS_AARCH64)19#include "aarch64/vdso.h"20#elif defined(LIBC_TARGET_ARCH_IS_ARM)21#include "arm/vdso.h"22#elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)23#include "riscv/vdso.h"24#else25#error "unknown arch"26#endif27 28namespace LIBC_NAMESPACE_DECL {29namespace vdso {30 31class Symbol {32 VDSOSym sym;33 34public:35 LIBC_INLINE_VAR static constexpr size_t COUNT =36 static_cast<size_t>(VDSOSym::VDSOSymCount);37 LIBC_INLINE constexpr explicit Symbol(VDSOSym sym) : sym(sym) {}38 LIBC_INLINE constexpr Symbol(size_t idx) : sym(static_cast<VDSOSym>(idx)) {}39 LIBC_INLINE constexpr cpp::string_view name() const {40 return symbol_name(sym);41 }42 LIBC_INLINE constexpr cpp::string_view version() const {43 return symbol_version(sym);44 }45 LIBC_INLINE constexpr operator size_t() const {46 return static_cast<size_t>(sym);47 }48 LIBC_INLINE constexpr bool is_valid() const {49 return *this < Symbol::global_cache.size();50 }51 using VDSOArray = cpp::array<void *, Symbol::COUNT>;52 53private:54 static CallOnceFlag once_flag;55 static VDSOArray global_cache;56 static void initialize_vdso_global_cache();57 58 LIBC_INLINE void *get() const {59 if (name().empty() || !is_valid())60 return nullptr;61 62 callonce(&once_flag, Symbol::initialize_vdso_global_cache);63 return (global_cache[*this]);64 }65 template <VDSOSym sym> friend struct TypedSymbol;66};67 68template <VDSOSym sym> struct TypedSymbol {69 LIBC_INLINE constexpr operator VDSOSymType<sym>() const {70 return cpp::bit_cast<VDSOSymType<sym>>(Symbol{sym}.get());71 }72 template <typename... Args>73 LIBC_INLINE auto operator()(Args &&...args) const {74 return this->operator VDSOSymType<sym>()(cpp::forward<Args>(args)...);75 }76};77 78} // namespace vdso79 80} // namespace LIBC_NAMESPACE_DECL81#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_VDSO_H82