#include "sanitizer_platform.h"
#if SANITIZER_LINUX && \
(defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \
defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \
defined(__arm__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64)
#include "sanitizer_stoptheworld.h"
#include "sanitizer_platform_limits_posix.h"
#include "sanitizer_atomic.h"
#include <errno.h>
#include <sched.h>
#include <stddef.h>
#include <sys/prctl.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <elf.h>
#if (defined(__aarch64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) && \
!SANITIZER_ANDROID
# include <asm/ptrace.h>
#endif
#include <sys/user.h>
#if SANITIZER_ANDROID && SANITIZER_MIPS
# include <asm/reg.h>
#endif
#include <sys/wait.h>
#ifdef sa_handler
# undef sa_handler
#endif
#ifdef sa_sigaction
# undef sa_sigaction
#endif
#include "sanitizer_common.h"
#include "sanitizer_flags.h"
#include "sanitizer_libc.h"
#include "sanitizer_linux.h"
#include "sanitizer_mutex.h"
#include "sanitizer_placement_new.h"
#ifndef PR_SET_PTRACER
#define PR_SET_PTRACER …
#endif
namespace __sanitizer {
class SuspendedThreadsListLinux final : public SuspendedThreadsList { … };
struct TracerThreadArgument { … };
class ThreadSuspender { … };
bool ThreadSuspender::SuspendThread(tid_t tid) { … }
void ThreadSuspender::ResumeAllThreads() { … }
void ThreadSuspender::KillAllThreads() { … }
bool ThreadSuspender::SuspendAllThreads() { … }
static ThreadSuspender *thread_suspender_instance = …;
static const int kSyncSignals[] = …;
static void TracerThreadDieCallback() { … }
static void TracerThreadSignalHandler(int signum, __sanitizer_siginfo *siginfo,
void *uctx) { … }
static const int kHandlerStackSize = …;
static int TracerThread(void* argument) { … }
class ScopedStackSpaceWithGuard { … };
static __sanitizer_sigset_t blocked_sigset;
static __sanitizer_sigset_t old_sigset;
class StopTheWorldScope { … };
struct ScopedSetTracerPID { … };
void StopTheWorld(StopTheWorldCallback callback, void *argument) { … }
#if SANITIZER_ANDROID && defined(__arm__)
typedef pt_regs regs_struct;
#define REG_SP …
#elif SANITIZER_LINUX && defined(__arm__)
typedef user_regs regs_struct;
#define REG_SP …
#elif defined(__i386__) || defined(__x86_64__)
regs_struct;
#if defined(__i386__)
#define REG_SP …
#else
#define REG_SP …
#endif
#define ARCH_IOVEC_FOR_GETREGSET
#ifndef NT_X86_XSTATE
#define NT_X86_XSTATE …
#endif
#ifndef PTRACE_GETREGSET
#define PTRACE_GETREGSET …
#endif
static constexpr uptr kExtraRegs[] = …;
#elif defined(__powerpc__) || defined(__powerpc64__)
typedef pt_regs regs_struct;
#define REG_SP …
#elif defined(__mips__)
typedef struct user regs_struct;
# if SANITIZER_ANDROID
#define REG_SP …
# else
#define REG_SP …
# endif
#elif defined(__aarch64__)
typedef struct user_pt_regs regs_struct;
#define REG_SP …
static constexpr uptr kExtraRegs[] = {0};
#define ARCH_IOVEC_FOR_GETREGSET
#elif defined(__loongarch__)
typedef struct user_pt_regs regs_struct;
#define REG_SP …
static constexpr uptr kExtraRegs[] = {0};
#define ARCH_IOVEC_FOR_GETREGSET
#elif SANITIZER_RISCV64
typedef struct user_regs_struct regs_struct;
#undef REG_SP
#define REG_SP …
static constexpr uptr kExtraRegs[] = {0};
#define ARCH_IOVEC_FOR_GETREGSET
#elif defined(__s390__)
typedef _user_regs_struct regs_struct;
#define REG_SP …
static constexpr uptr kExtraRegs[] = {0};
#define ARCH_IOVEC_FOR_GETREGSET
#else
#error "Unsupported architecture"
#endif
tid_t SuspendedThreadsListLinux::GetThreadID(uptr index) const { … }
uptr SuspendedThreadsListLinux::ThreadCount() const { … }
bool SuspendedThreadsListLinux::ContainsTid(tid_t thread_id) const { … }
void SuspendedThreadsListLinux::Append(tid_t tid) { … }
PtraceRegistersStatus SuspendedThreadsListLinux::GetRegistersAndSP(
uptr index, InternalMmapVector<uptr> *buffer, uptr *sp) const { … }
}
#endif