#ifndef ABSL_DEBUGGING_INTERNAL_VDSO_SUPPORT_H_
#define ABSL_DEBUGGING_INTERNAL_VDSO_SUPPORT_H_
#include <atomic>
#include "absl/base/attributes.h"
#include "absl/debugging/internal/elf_mem_image.h"
#ifdef ABSL_HAVE_ELF_MEM_IMAGE
#ifdef ABSL_HAVE_VDSO_SUPPORT
#error ABSL_HAVE_VDSO_SUPPORT cannot be directly set
#else
#define ABSL_HAVE_VDSO_SUPPORT 1
#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
class VDSOSupport {
public:
VDSOSupport();
typedef ElfMemImage::SymbolInfo SymbolInfo;
typedef ElfMemImage::SymbolIterator SymbolIterator;
#ifdef __powerpc64__
enum { kVDSOSymbolType = STT_NOTYPE };
#else
enum { kVDSOSymbolType = STT_FUNC };
#endif
bool IsPresent() const { return image_.IsPresent(); }
SymbolIterator begin() const { return image_.begin(); }
SymbolIterator end() const { return image_.end(); }
bool LookupSymbol(const char *name, const char *version,
int symbol_type, SymbolInfo *info_out) const;
bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const;
const void *SetBase(const void *s);
static const void *Init();
private:
ElfMemImage image_;
static std::atomic<const void *> vdso_base_;
static long InitAndGetCPU(unsigned *cpu, void *cache, void *unused);
static long GetCPUViaSyscall(unsigned *cpu, void *cache, void *unused);
typedef long (*GetCpuFn)(unsigned *cpu, void *cache, void *unused);
ABSL_CONST_INIT static std::atomic<GetCpuFn> getcpu_fn_;
friend int GetCPU(void);
VDSOSupport(const VDSOSupport&) = delete;
VDSOSupport& operator=(const VDSOSupport&) = delete;
};
int GetCPU();
} ABSL_NAMESPACE_END
}
#endif
#endif