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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_VDSO_H 9 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_VDSO_H 10 #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 #else 25 #error "unknown arch" 26 #endif 27 28 namespace LIBC_NAMESPACE_DECL { 29 namespace vdso { 30 31 class Symbol { 32 VDSOSym sym; 33 34 public: 35 LIBC_INLINE_VAR static constexpr size_t COUNT = 36 static_cast<size_t>(VDSOSym::VDSOSymCount); Symbol(VDSOSym sym)37 LIBC_INLINE constexpr explicit Symbol(VDSOSym sym) : sym(sym) {} Symbol(size_t idx)38 LIBC_INLINE constexpr Symbol(size_t idx) : sym(static_cast<VDSOSym>(idx)) {} name()39 LIBC_INLINE constexpr cpp::string_view name() const { 40 return symbol_name(sym); 41 } version()42 LIBC_INLINE constexpr cpp::string_view version() const { 43 return symbol_version(sym); 44 } size_t()45 LIBC_INLINE constexpr operator size_t() const { 46 return static_cast<size_t>(sym); 47 } is_valid()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 53 private: 54 static CallOnceFlag once_flag; 55 static VDSOArray global_cache; 56 static void initialize_vdso_global_cache(); 57 get()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 68 template <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> operatorTypedSymbol73 LIBC_INLINE auto operator()(Args &&...args) const { 74 return this->operator VDSOSymType<sym>()(cpp::forward<Args>(args)...); 75 } 76 }; 77 78 } // namespace vdso 79 80 } // namespace LIBC_NAMESPACE_DECL 81 #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_VDSO_H 82