[fuchsia] Add fp registers to x86 context

This lays groundwork for floating point registers to also be included in
RISC-V CPU context.

Bug: fuchsia:5496

Tested: `fx test crashpad`
Change-Id: I6230f146f955ac27f053f670f7f45dfff3560d02
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/4594586
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Thomas Gales 2023-06-06 22:48:28 +00:00 committed by Mark Mentovai
parent 788b72f922
commit 25f724d783
6 changed files with 38 additions and 9 deletions

View File

@ -21,8 +21,9 @@ namespace internal {
#if defined(ARCH_CPU_X86_64) #if defined(ARCH_CPU_X86_64)
void InitializeCPUContextX86_64_NoFloatingPoint( void InitializeCPUContextX86_64(
const zx_thread_state_general_regs_t& thread_context, const zx_thread_state_general_regs_t& thread_context,
const zx_thread_state_fp_regs_t& float_context,
CPUContextX86_64* context) { CPUContextX86_64* context) {
memset(context, 0, sizeof(*context)); memset(context, 0, sizeof(*context));
context->rax = thread_context.rax; context->rax = thread_context.rax;
@ -43,6 +44,19 @@ void InitializeCPUContextX86_64_NoFloatingPoint(
context->r15 = thread_context.r15; context->r15 = thread_context.r15;
context->rip = thread_context.rip; context->rip = thread_context.rip;
context->rflags = thread_context.rflags; context->rflags = thread_context.rflags;
context->fxsave.fcw = float_context.fcw;
context->fxsave.fsw = float_context.fsw;
context->fxsave.ftw = float_context.ftw;
context->fxsave.fop = float_context.fop;
context->fxsave.fpu_ip_64 = float_context.fip;
context->fxsave.fpu_dp_64 = float_context.fdp;
for (size_t i = 0; i < std::size(float_context.st); ++i) {
memcpy(&context->fxsave.st_mm[i],
&float_context.st[i],
sizeof(float_context.st[i]));
}
} }
#elif defined(ARCH_CPU_ARM64) #elif defined(ARCH_CPU_ARM64)

View File

@ -29,13 +29,14 @@ namespace internal {
//! \brief Initializes a CPUContextX86_64 structure from native context //! \brief Initializes a CPUContextX86_64 structure from native context
//! structures on Fuchsia. //! structures on Fuchsia.
//! //!
//! Floating point registers are currently initialized to zero.
//! Segment registers are currently initialized to zero. //! Segment registers are currently initialized to zero.
//! //!
//! \param[in] thread_context The native thread context. //! \param[in] thread_context The native thread context.
//! \param[in] float_context The native floating point context.
//! \param[out] context The CPUContextX86_64 structure to initialize. //! \param[out] context The CPUContextX86_64 structure to initialize.
void InitializeCPUContextX86_64_NoFloatingPoint( void InitializeCPUContextX86_64(
const zx_thread_state_general_regs_t& thread_context, const zx_thread_state_general_regs_t& thread_context,
const zx_thread_state_fp_regs_t& float_context,
CPUContextX86_64* context); CPUContextX86_64* context);
#endif // ARCH_CPU_X86_64 || DOXYGEN #endif // ARCH_CPU_X86_64 || DOXYGEN

View File

@ -70,9 +70,9 @@ bool ExceptionSnapshotFuchsia::Initialize(
#if defined(ARCH_CPU_X86_64) #if defined(ARCH_CPU_X86_64)
context_.architecture = kCPUArchitectureX86_64; context_.architecture = kCPUArchitectureX86_64;
context_.x86_64 = &context_arch_; context_.x86_64 = &context_arch_;
// TODO(fxbug.dev/5496): Add float context once saved in |t|. // TODO(fxbug.dev/5496): Add vector context.
InitializeCPUContextX86_64_NoFloatingPoint(t->general_registers, InitializeCPUContextX86_64(
context_.x86_64); t->general_registers, t->fp_registers, context_.x86_64);
#elif defined(ARCH_CPU_ARM64) #elif defined(ARCH_CPU_ARM64)
context_.architecture = kCPUArchitectureARM64; context_.architecture = kCPUArchitectureARM64;
context_.arm64 = &context_arch_; context_.arm64 = &context_arch_;

View File

@ -346,6 +346,16 @@ void ProcessReaderFuchsia::InitializeThreads() {
} }
} }
zx_thread_state_fp_regs_t fp_regs;
status = thread_handles[i].read_state(
ZX_THREAD_STATE_FP_REGS, &fp_regs, sizeof(fp_regs));
if (status != ZX_OK) {
ZX_LOG(WARNING, status)
<< "zx_thread_read_state(ZX_THREAD_STATE_FP_REGS)";
} else {
thread.fp_registers = fp_regs;
}
zx_thread_state_vector_regs_t vector_regs; zx_thread_state_vector_regs_t vector_regs;
status = thread_handles[i].read_state( status = thread_handles[i].read_state(
ZX_THREAD_STATE_VECTOR_REGS, &vector_regs, sizeof(vector_regs)); ZX_THREAD_STATE_VECTOR_REGS, &vector_regs, sizeof(vector_regs));

View File

@ -76,6 +76,10 @@ class ProcessReaderFuchsia {
//! returned by `zx_thread_read_state()`. //! returned by `zx_thread_read_state()`.
zx_thread_state_general_regs_t general_registers = {}; zx_thread_state_general_regs_t general_registers = {};
//! \brief The raw architecture-specific `zx_thread_state_fp_regs_t` as
//! returned by `zx_thread_read_state()`.
zx_thread_state_fp_regs_t fp_registers = {};
//! \brief The raw architecture-specific `zx_thread_state_vector_regs_t` as //! \brief The raw architecture-specific `zx_thread_state_vector_regs_t` as
//! returned by `zx_thread_read_state()`. //! returned by `zx_thread_read_state()`.
zx_thread_state_vector_regs_t vector_registers = {}; zx_thread_state_vector_regs_t vector_registers = {};

View File

@ -40,9 +40,9 @@ bool ThreadSnapshotFuchsia::Initialize(
#if defined(ARCH_CPU_X86_64) #if defined(ARCH_CPU_X86_64)
context_.architecture = kCPUArchitectureX86_64; context_.architecture = kCPUArchitectureX86_64;
context_.x86_64 = &context_arch_; context_.x86_64 = &context_arch_;
// TODO(fuchsia/DX-642): Add float context once saved in |thread|. // TODO(fxbug.dev/5496): Add vector context.
InitializeCPUContextX86_64_NoFloatingPoint(thread.general_registers, InitializeCPUContextX86_64(
context_.x86_64); thread.general_registers, thread.fp_registers, context_.x86_64);
#elif defined(ARCH_CPU_ARM64) #elif defined(ARCH_CPU_ARM64)
context_.architecture = kCPUArchitectureARM64; context_.architecture = kCPUArchitectureARM64;
context_.arm64 = &context_arch_; context_.arm64 = &context_arch_;