21 #ifdef ABSL_HAVE_VDSO_SUPPORT // defined in vdso_support.h 25 #include <sys/syscall.h> 28 #if __GLIBC_PREREQ(2, 16) // GLIBC-2.16 implements getauxval. 36 #ifndef AT_SYSINFO_EHDR 37 #define AT_SYSINFO_EHDR 33 // for crosstoolv10 41 namespace debugging_internal {
44 std::atomic<const void *> VDSOSupport::vdso_base_(
45 debugging_internal::ElfMemImage::kInvalidBase);
47 std::atomic<VDSOSupport::GetCpuFn> VDSOSupport::getcpu_fn_(&InitAndGetCPU);
48 VDSOSupport::VDSOSupport()
51 : image_(vdso_base_.load(
std::memory_order_relaxed) ==
52 debugging_internal::ElfMemImage::kInvalidBase
54 : vdso_base_.load(
std::memory_order_relaxed)) {}
65 const void *VDSOSupport::Init() {
66 const auto kInvalidBase = debugging_internal::ElfMemImage::kInvalidBase;
67 #if __GLIBC_PREREQ(2, 16) 68 if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) {
70 const void *
const sysinfo_ehdr =
71 reinterpret_cast<const void *
>(getauxval(AT_SYSINFO_EHDR));
73 vdso_base_.store(sysinfo_ehdr, std::memory_order_relaxed);
76 #endif // __GLIBC_PREREQ(2, 16) 77 if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) {
83 vdso_base_.store(
nullptr, std::memory_order_relaxed);
84 getcpu_fn_.store(&GetCPUViaSyscall, std::memory_order_relaxed);
87 int fd = open(
"/proc/self/auxv", O_RDONLY);
90 vdso_base_.store(
nullptr, std::memory_order_relaxed);
91 getcpu_fn_.store(&GetCPUViaSyscall, std::memory_order_relaxed);
95 while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) {
96 if (aux.a_type == AT_SYSINFO_EHDR) {
97 vdso_base_.store(reinterpret_cast<void *>(aux.a_un.a_val),
98 std::memory_order_relaxed);
103 if (vdso_base_.load(std::memory_order_relaxed) == kInvalidBase) {
105 vdso_base_.store(
nullptr, std::memory_order_relaxed);
108 GetCpuFn fn = &GetCPUViaSyscall;
109 if (vdso_base_.load(std::memory_order_relaxed)) {
112 if (vdso.LookupSymbol(
"__vdso_getcpu",
"LINUX_2.6", STT_FUNC, &info)) {
113 fn =
reinterpret_cast<GetCpuFn
>(
const_cast<void *
>(info.address));
118 getcpu_fn_.store(fn, std::memory_order_relaxed);
119 return vdso_base_.load(std::memory_order_relaxed);
122 const void *VDSOSupport::SetBase(
const void *base) {
123 ABSL_RAW_CHECK(base != debugging_internal::ElfMemImage::kInvalidBase,
125 const void *old_base = vdso_base_.load(std::memory_order_relaxed);
126 vdso_base_.store(base, std::memory_order_relaxed);
129 getcpu_fn_.store(&InitAndGetCPU, std::memory_order_relaxed);
133 bool VDSOSupport::LookupSymbol(
const char *
name,
136 SymbolInfo *info)
const {
137 return image_.LookupSymbol(name, version, type, info);
140 bool VDSOSupport::LookupSymbolByAddress(
const void *address,
141 SymbolInfo *info_out)
const {
142 return image_.LookupSymbolByAddress(address, info_out);
146 long VDSOSupport::GetCPUViaSyscall(
unsigned *cpu,
149 return syscall(SYS_getcpu, cpu,
nullptr,
nullptr);
152 static_cast<void>(cpu);
159 long VDSOSupport::InitAndGetCPU(
unsigned *cpu,
162 GetCpuFn fn = getcpu_fn_.load(std::memory_order_relaxed);
163 ABSL_RAW_CHECK(fn != &InitAndGetCPU,
"Init() did not set getcpu_fn_");
164 return (*fn)(cpu, x, y);
173 int ret_code = (*VDSOSupport::getcpu_fn_)(&cpu,
nullptr,
nullptr);
174 return ret_code == 0 ? cpu : ret_code;
184 static class VDSOInitHelper {
186 VDSOInitHelper() { VDSOSupport::Init(); }
192 #endif // ABSL_HAVE_VDSO_SUPPORT
#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY
#define ABSL_RAW_CHECK(condition, message)
int RunningOnValgrind(void)