mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
linux: Collect fxsave instead of fsave in ThreadInfo
Bug: crashpad:30 Change-Id: Ib4abf0ad60b792c8241b28e6b5e47970fdfcf451 Reviewed-on: https://chromium-review.googlesource.com/537532 Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
63ccbd0e4c
commit
d3e4f09742
@ -30,6 +30,34 @@ namespace crashpad {
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
|
||||
template <typename Destination>
|
||||
bool GetRegisterSet(pid_t tid, int set, Destination* dest) {
|
||||
iovec iov;
|
||||
iov.iov_base = dest;
|
||||
iov.iov_len = sizeof(*dest);
|
||||
if (ptrace(PTRACE_GETREGSET, tid, reinterpret_cast<void*>(set), &iov) != 0) {
|
||||
PLOG(ERROR) << "ptrace";
|
||||
return false;
|
||||
}
|
||||
if (iov.iov_len != sizeof(*dest)) {
|
||||
LOG(ERROR) << "Unexpected registers size";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetFloatingPointRegisters32(pid_t tid, FloatContext* context) {
|
||||
return GetRegisterSet(tid, NT_PRXFPREG, &context->f32.fxsave);
|
||||
}
|
||||
|
||||
bool GetFloatingPointRegisters64(pid_t tid, FloatContext* context) {
|
||||
return GetRegisterSet(tid, NT_PRFPREG, &context->f64.fxsave);
|
||||
}
|
||||
|
||||
#elif defined(ARCH_CPU_ARM_FAMILY)
|
||||
|
||||
#if defined(ARCH_CPU_ARMEL)
|
||||
// PTRACE_GETREGSET, introduced in Linux 2.6.34 (2225a122ae26), requires kernel
|
||||
// support enabled by HAVE_ARCH_TRACEHOOK. This has been set for x86 (including
|
||||
@ -77,7 +105,6 @@ bool GetFloatingPointRegistersLegacy(pid_t tid, FloatContext* context) {
|
||||
}
|
||||
#endif // ARCH_CPU_ARMEL
|
||||
|
||||
#if defined(ARCH_CPU_ARM_FAMILY)
|
||||
// Normally, the Linux kernel will copy out register sets according to the size
|
||||
// of the struct that contains them. Tracing a 32-bit ARM process running in
|
||||
// compatibility mode on a 64-bit ARM cpu will only copy data for the number of
|
||||
@ -163,7 +190,9 @@ bool GetFloatingPointRegisters64(pid_t tid, FloatContext* context) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif // ARCH_CPU_ARM_FAMILY
|
||||
#else
|
||||
#error Port.
|
||||
#endif // ARCH_CPU_X86_FAMILY
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -241,31 +270,8 @@ size_t ThreadInfo::GetGeneralPurposeRegistersAndLength(ThreadContext* context) {
|
||||
bool ThreadInfo::GetFloatingPointRegisters(FloatContext* context) {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
iovec iov;
|
||||
iov.iov_base = context;
|
||||
iov.iov_len = sizeof(*context);
|
||||
if (ptrace(
|
||||
PTRACE_GETREGSET, tid_, reinterpret_cast<void*>(NT_PRFPREG), &iov) !=
|
||||
0) {
|
||||
PLOG(ERROR) << "ptrace";
|
||||
return false;
|
||||
}
|
||||
if (is_64_bit_ && iov.iov_len == sizeof(context->f64)) {
|
||||
return true;
|
||||
}
|
||||
if (!is_64_bit_ && iov.iov_len == sizeof(context->f32)) {
|
||||
return true;
|
||||
}
|
||||
LOG(ERROR) << "Unexpected registers size";
|
||||
return false;
|
||||
|
||||
#elif defined(ARCH_CPU_ARM_FAMILY)
|
||||
return is_64_bit_ ? GetFloatingPointRegisters64(tid_, context)
|
||||
: GetFloatingPointRegisters32(tid_, context);
|
||||
#else
|
||||
#error Port.
|
||||
#endif // ARCH_CPU_X86_FAMILY
|
||||
}
|
||||
|
||||
bool ThreadInfo::GetThreadArea(LinuxVMAddress* address) {
|
||||
|
@ -27,6 +27,10 @@
|
||||
#include "util/misc/initialization_state_dcheck.h"
|
||||
#include "util/numeric/int128.h"
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
#include <android/api-level.h>
|
||||
#endif
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief The set of general purpose registers for an architecture family.
|
||||
@ -140,15 +144,22 @@ union FloatContext {
|
||||
//! architecture.
|
||||
struct f32 {
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
// Reflects user_fpregs_struct in sys/user.h.
|
||||
uint32_t cwd;
|
||||
uint32_t swd;
|
||||
uint32_t twd;
|
||||
uint32_t fip;
|
||||
uint32_t fcs;
|
||||
uint32_t foo;
|
||||
uint32_t fos;
|
||||
uint32_t st_space[20];
|
||||
// Reflects user_fpxregs_struct in sys/user.h
|
||||
struct fxsave {
|
||||
uint16_t cwd;
|
||||
uint16_t swd;
|
||||
uint16_t twd;
|
||||
uint16_t fop;
|
||||
uint32_t fip;
|
||||
uint32_t fcs;
|
||||
uint32_t foo;
|
||||
uint32_t fos;
|
||||
uint32_t mxcsr;
|
||||
uint32_t reserved;
|
||||
uint32_t st_space[32];
|
||||
uint32_t xmm_space[32];
|
||||
uint32_t padding[56];
|
||||
} fxsave;
|
||||
#elif defined(ARCH_CPU_ARM_FAMILY)
|
||||
// Reflects user_fpregs in sys/user.h.
|
||||
struct fpregs {
|
||||
@ -184,17 +195,20 @@ union FloatContext {
|
||||
//! architecture.
|
||||
struct f64 {
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
uint16_t cwd;
|
||||
uint16_t swd;
|
||||
uint16_t ftw;
|
||||
uint16_t fop;
|
||||
uint64_t rip;
|
||||
uint64_t rdp;
|
||||
uint32_t mxcsr;
|
||||
uint32_t mxcr_mask;
|
||||
uint32_t st_space[32];
|
||||
uint32_t xmm_space[64];
|
||||
uint32_t padding[24];
|
||||
// Refelects user_fpregs_struct in sys/user.h
|
||||
struct fxsave {
|
||||
uint16_t cwd;
|
||||
uint16_t swd;
|
||||
uint16_t ftw;
|
||||
uint16_t fop;
|
||||
uint64_t rip;
|
||||
uint64_t rdp;
|
||||
uint32_t mxcsr;
|
||||
uint32_t mxcr_mask;
|
||||
uint32_t st_space[32];
|
||||
uint32_t xmm_space[64];
|
||||
uint32_t padding[24];
|
||||
} fxsave;
|
||||
#elif defined(ARCH_CPU_ARM_FAMILY)
|
||||
uint128_struct vregs[32];
|
||||
uint32_t fpsr;
|
||||
@ -206,9 +220,15 @@ union FloatContext {
|
||||
} f64;
|
||||
|
||||
#if defined(ARCH_CPU_X86)
|
||||
static_assert(sizeof(f32) == sizeof(user_fpregs_struct), "Size mismatch");
|
||||
#if defined(OS_ANDROID) && __ANDROID_API__ <= 19
|
||||
using NativeFpxregs = user_fxsr_struct;
|
||||
#else
|
||||
using NativeFpxregs = user_fpxregs_struct;
|
||||
#endif // OS_ANDROID
|
||||
static_assert(sizeof(f32::fxsave) == sizeof(NativeFpxregs), "Size mismatch");
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
static_assert(sizeof(f64) == sizeof(user_fpregs_struct), "Size mismatch");
|
||||
static_assert(sizeof(f64::fxsave) == sizeof(user_fpregs_struct),
|
||||
"Size mismatch");
|
||||
#elif defined(ARCH_CPU_ARMEL)
|
||||
static_assert(sizeof(f32::fpregs) == sizeof(user_fpregs), "Size mismatch");
|
||||
static_assert(sizeof(f32::vfp) == sizeof(user_vfp), "Size mismatch");
|
||||
|
Loading…
x
Reference in New Issue
Block a user