diff --git a/snapshot/linux/cpu_context_linux.cc b/snapshot/linux/cpu_context_linux.cc new file mode 100644 index 00000000..d4b09a70 --- /dev/null +++ b/snapshot/linux/cpu_context_linux.cc @@ -0,0 +1,108 @@ +// Copyright 2017 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "snapshot/linux/cpu_context_linux.h" + +#include +#include + +#include "base/logging.h" + +namespace crashpad { +namespace internal { + +#if defined(ARCH_CPU_X86_FAMILY) + +void InitializeCPUContextX86(const ThreadContext::t32_t& thread_context, + const FloatContext::f32_t& float_context, + CPUContextX86* context) { + context->eax = thread_context.eax; + context->ebx = thread_context.ebx; + context->ecx = thread_context.ecx; + context->edx = thread_context.edx; + context->edi = thread_context.edi; + context->esi = thread_context.esi; + context->ebp = thread_context.ebp; + context->esp = thread_context.esp; + context->eip = thread_context.eip; + context->eflags = thread_context.eflags; + context->cs = thread_context.xcs; + context->ds = thread_context.xds; + context->es = thread_context.xes; + context->fs = thread_context.xfs; + context->gs = thread_context.xgs; + context->ss = thread_context.xss; + + static_assert(sizeof(context->fxsave) == sizeof(float_context.fxsave), + "fxsave size mismatch"); + memcpy(&context->fxsave, &float_context.fxsave, sizeof(context->fxsave)); + + // TODO(jperaza): debug registers + context->dr0 = 0; + context->dr1 = 0; + context->dr2 = 0; + context->dr3 = 0; + context->dr4 = 0; + context->dr5 = 0; + context->dr6 = 0; + context->dr7 = 0; + +} + +void InitializeCPUContextX86_64(const ThreadContext::t64_t& thread_context, + const FloatContext::f64_t& float_context, + CPUContextX86_64* context) { + context->rax = thread_context.rax; + context->rbx = thread_context.rbx; + context->rcx = thread_context.rcx; + context->rdx = thread_context.rdx; + context->rdi = thread_context.rdi; + context->rsi = thread_context.rsi; + context->rbp = thread_context.rbp; + context->rsp = thread_context.rsp; + context->r8 = thread_context.r8; + context->r9 = thread_context.r9; + context->r10 = thread_context.r10; + context->r11 = thread_context.r11; + context->r12 = thread_context.r12; + context->r13 = thread_context.r13; + context->r14 = thread_context.r14; + context->r15 = thread_context.r15; + context->rip = thread_context.rip; + context->rflags = thread_context.eflags; + context->cs = thread_context.cs; + context->fs = thread_context.fs; + context->gs = thread_context.gs; + + static_assert(sizeof(context->fxsave) == sizeof(float_context.fxsave), + "fxsave size mismatch"); + memcpy(&context->fxsave, &float_context.fxsave, sizeof(context->fxsave)); + + // TODO(jperaza): debug registers. + context->dr0 = 0; + context->dr1 = 0; + context->dr2 = 0; + context->dr3 = 0; + context->dr4 = 0; + context->dr5 = 0; + context->dr6 = 0; + context->dr7 = 0; +} + +#else +#error Port. +#endif // ARCH_CPU_X86_FAMILY || DOXYGEN + +} // namespace internal +} // namespace crashpad diff --git a/snapshot/linux/cpu_context_linux.h b/snapshot/linux/cpu_context_linux.h new file mode 100644 index 00000000..0ce5d5f4 --- /dev/null +++ b/snapshot/linux/cpu_context_linux.h @@ -0,0 +1,53 @@ +// Copyright 2017 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_SNAPSHOT_LINUX_SNAPSHOT_CPU_CONTEXT_LINUX_H_ +#define CRASHPAD_SNAPSHOT_LINUX_SNAPSHOT_CPU_CONTEXT_LINUX_H_ + +#include "build/build_config.h" +#include "snapshot/cpu_context.h" +#include "util/linux/thread_info.h" + +namespace crashpad { +namespace internal { + +#if defined(ARCH_CPU_X86_FAMILY) || DOXYGEN + +//! \brief Initializes a CPUContextX86 structure from native context structures +//! on Linux. +//! +//! \param[in] thread_context The native thread context. +//! \param[in] float_context The native float context. +//! \param[out] context The CPUContextX86 structure to initialize. +void InitializeCPUContextX86(const ThreadContext::t32_t& thread_context, + const FloatContext::f32_t& float_context, + CPUContextX86* context); + +//! \brief Initializes a CPUContextX86_64 structure from native context +//! structures on Linux. +//! +//! \param[in] thread_context The native thread context. +//! \param[in] float_context The native float context. +//! \param[out] context The CPUContextX86_64 structure to initialize. +void InitializeCPUContextX86_64(const ThreadContext::t64_t& thread_context, + const FloatContext::f64_t& float_context, + CPUContextX86_64* context); +#else +#error Port. // TODO(jperaza): ARM +#endif // ARCH_CPU_X86_FAMILY || DOXYGEN + +} // namespace internal +} // namespace crashpad + +#endif // CRASHPAD_SNAPSHOT_LINUX_SNAPSHOT_CPU_CONTEXT_LINUX_H_ diff --git a/snapshot/snapshot.gyp b/snapshot/snapshot.gyp index d816c075..a85f6a27 100644 --- a/snapshot/snapshot.gyp +++ b/snapshot/snapshot.gyp @@ -40,6 +40,8 @@ 'exception_snapshot.h', 'handle_snapshot.cc', 'handle_snapshot.h', + 'linux/cpu_context_linux.cc', + 'linux/cpu_context_linux.h', 'linux/debug_rendezvous.cc', 'linux/debug_rendezvous.h', 'linux/elf_dynamic_array_reader.cc', diff --git a/util/linux/thread_info.h b/util/linux/thread_info.h index 9cb77d06..f8b97514 100644 --- a/util/linux/thread_info.h +++ b/util/linux/thread_info.h @@ -40,7 +40,7 @@ union ThreadContext { //! \brief The general purpose registers used by the 32-bit variant of the //! architecture. - struct t32 { + struct t32_t { #if defined(ARCH_CPU_X86_FAMILY) // Reflects user_regs_struct in sys/user.h. uint32_t ebx; @@ -77,7 +77,7 @@ union ThreadContext { //! \brief The general purpose registers used by the 64-bit variant of the //! architecture. - struct t64 { + struct t64_t { #if defined(ARCH_CPU_X86_FAMILY) // Reflects user_regs_struct in sys/user.h. uint64_t r15; @@ -127,9 +127,9 @@ union ThreadContext { #endif // ARCH_CPU_X86_FAMILY || ARCH_CPU_ARM64 #if defined(ARCH_CPU_32_BITS) - static_assert(sizeof(t32) == sizeof(NativeThreadContext), "Size mismatch"); + static_assert(sizeof(t32_t) == sizeof(NativeThreadContext), "Size mismatch"); #else // ARCH_CPU_64_BITS - static_assert(sizeof(t64) == sizeof(NativeThreadContext), "Size mismatch"); + static_assert(sizeof(t64_t) == sizeof(NativeThreadContext), "Size mismatch"); #endif // ARCH_CPU_32_BITS }; static_assert(std::is_standard_layout::value, @@ -142,7 +142,7 @@ union FloatContext { //! \brief The floating point registers used by the 32-bit variant of the //! architecture. - struct f32 { + struct f32_t { #if defined(ARCH_CPU_X86_FAMILY) // Reflects user_fpxregs_struct in sys/user.h struct fxsave { @@ -193,7 +193,7 @@ union FloatContext { //! \brief The floating point registers used by the 64-bit variant of the //! architecture. - struct f64 { + struct f64_t { #if defined(ARCH_CPU_X86_FAMILY) // Refelects user_fpregs_struct in sys/user.h struct fxsave { @@ -228,13 +228,14 @@ union FloatContext { #else using NativeFpxregs = user_fpxregs_struct; #endif // OS_ANDROID - static_assert(sizeof(f32::fxsave) == sizeof(NativeFpxregs), "Size mismatch"); + static_assert(sizeof(f32_t::fxsave) == sizeof(NativeFpxregs), + "Size mismatch"); #elif defined(ARCH_CPU_X86_64) - static_assert(sizeof(f64::fxsave) == sizeof(user_fpregs_struct), + static_assert(sizeof(f64_t::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"); + static_assert(sizeof(f32_t::fpregs) == sizeof(user_fpregs), "Size mismatch"); + static_assert(sizeof(f32_t::vfp) == sizeof(user_vfp), "Size mismatch"); #elif defined(ARCH_CPU_ARM64) static_assert(sizeof(f64) == sizeof(user_fpsimd_struct), "Size mismatch"); #else