#include "partition_alloc/stack/stack.h"
#include <cstdint>
#include <limits>
#include "partition_alloc/build_config.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/partition_alloc_base/compiler_specific.h"
#include "partition_alloc/partition_alloc_check.h"
#if PA_BUILDFLAG(IS_WIN)
#include <windows.h>
#else
#include <pthread.h>
#endif
#if PA_BUILDFLAG(PA_LIBC_GLIBC)
extern "C" void* __libc_stack_end;
#endif
namespace partition_alloc::internal {
#if PA_BUILDFLAG(IS_WIN)
void* GetStackTop() {
#if PA_BUILDFLAG(PA_ARCH_CPU_X86_64)
return reinterpret_cast<void*>(
reinterpret_cast<NT_TIB64*>(NtCurrentTeb())->StackBase);
#elif PA_BUILDFLAG(PA_ARCH_CPU_32_BITS)
return reinterpret_cast<void*>(
reinterpret_cast<NT_TIB*>(NtCurrentTeb())->StackBase);
#elif PA_BUILDFLAG(PA_ARCH_CPU_ARM64)
ULONG_PTR lowLimit, highLimit;
::GetCurrentThreadStackLimits(&lowLimit, &highLimit);
return reinterpret_cast<void*>(highLimit);
#else
#error "Unsupported GetStackStart"
#endif
}
#elif PA_BUILDFLAG(IS_APPLE)
void* GetStackTop() {
return pthread_get_stackaddr_np(pthread_self());
}
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
void* GetStackTop() { … }
#else
#error "Unsupported GetStackTop"
#endif
IterateStackCallback;
extern "C" void PAPushAllRegistersAndIterateStack(const Stack*,
StackVisitor*,
IterateStackCallback);
Stack::Stack(void* stack_top) : … { … }
PA_NOINLINE uintptr_t* GetStackPointer() { … }
namespace {
[[maybe_unused]] void IterateSafeStackIfNecessary(StackVisitor* visitor) { … }
[[maybe_unused]] PA_NOINLINE PA_NO_SANITIZE("address") void IteratePointersImpl(
const Stack* stack,
StackVisitor* visitor,
uintptr_t* stack_ptr) { … }
}
void Stack::IteratePointers(StackVisitor* visitor) const { … }
StackTopRegistry::StackTopRegistry() = default;
StackTopRegistry::~StackTopRegistry() = default;
StackTopRegistry& StackTopRegistry::Get() { … }
void StackTopRegistry::NotifyThreadCreated(void* stack_top) { … }
void StackTopRegistry::NotifyThreadDestroyed() { … }
void* StackTopRegistry::GetCurrentThreadStackTop() const { … }
}