kicad/thirdparty/sentry-native/external/crashpad/minidump/minidump_context.h

643 lines
21 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2014 The Crashpad Authors
//
// 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_MINIDUMP_MINIDUMP_CONTEXT_H_
#define CRASHPAD_MINIDUMP_MINIDUMP_CONTEXT_H_
#include <stdint.h>
#include "base/compiler_specific.h"
#include "snapshot/cpu_context.h"
#include "util/numeric/int128.h"
namespace crashpad {
//! \brief Architecture-independent flags for `context_flags` fields in Minidump
//! context structures.
//
// https://zachsaw.blogspot.com/2010/11/wow64-bug-getthreadcontext-may-return.html#c5639760895973344002
enum MinidumpContextFlags : uint32_t {
//! \brief The thread was executing a trap handler in kernel mode
//! (`CONTEXT_EXCEPTION_ACTIVE`).
//!
//! If this bit is set, it indicates that the context is from a thread that
//! was executing a trap handler in the kernel. This bit is only valid when
//! ::kMinidumpContextExceptionReporting is also set. This bit is only used on
//! Windows.
kMinidumpContextExceptionActive = 0x08000000,
//! \brief The thread was executing a system call in kernel mode
//! (`CONTEXT_SERVICE_ACTIVE`).
//!
//! If this bit is set, it indicates that the context is from a thread that
//! was executing a system call in the kernel. This bit is only valid when
//! ::kMinidumpContextExceptionReporting is also set. This bit is only used on
//! Windows.
kMinidumpContextServiceActive = 0x10000000,
//! \brief Kernel-mode state reporting is desired
//! (`CONTEXT_EXCEPTION_REQUEST`).
//!
//! This bit is not used in context structures containing snapshots of thread
//! CPU context. It used when calling `GetThreadContext()` on Windows to
//! specify that kernel-mode state reporting
//! (::kMinidumpContextExceptionReporting) is desired in the returned context
//! structure.
kMinidumpContextExceptionRequest = 0x40000000,
//! \brief Kernel-mode state reporting is provided
//! (`CONTEXT_EXCEPTION_REPORTING`).
//!
//! If this bit is set, it indicates that the bits indicating how the thread
//! had entered kernel mode (::kMinidumpContextExceptionActive and
//! ::kMinidumpContextServiceActive) are valid. This bit is only used on
//! Windows.
kMinidumpContextExceptionReporting = 0x80000000,
};
//! \brief 32-bit x86-specifc flags for MinidumpContextX86::context_flags.
enum MinidumpContextX86Flags : uint32_t {
//! \brief Identifies the context structure as 32-bit x86. This is the same as
//! `CONTEXT_i386` and `CONTEXT_i486` on Windows for this architecture.
kMinidumpContextX86 = 0x00010000,
//! \brief Indicates the validity of control registers (`CONTEXT_CONTROL`).
//!
//! The `ebp`, `eip`, `cs`, `eflags`, `esp`, and `ss` fields are valid.
kMinidumpContextX86Control = kMinidumpContextX86 | 0x00000001,
//! \brief Indicates the validity of non-control integer registers
//! (`CONTEXT_INTEGER`).
//!
//! The `edi`, `esi`, `ebx`, `edx`, `ecx, and `eax` fields are valid.
kMinidumpContextX86Integer = kMinidumpContextX86 | 0x00000002,
//! \brief Indicates the validity of non-control segment registers
//! (`CONTEXT_SEGMENTS`).
//!
//! The `gs`, `fs`, `es`, and `ds` fields are valid.
kMinidumpContextX86Segment = kMinidumpContextX86 | 0x00000004,
//! \brief Indicates the validity of floating-point state
//! (`CONTEXT_FLOATING_POINT`).
//!
//! The `fsave` field is valid. The `float_save` field is included in this
//! definition, but its members have no practical use asdie from `fsave`.
kMinidumpContextX86FloatingPoint = kMinidumpContextX86 | 0x00000008,
//! \brief Indicates the validity of debug registers
//! (`CONTEXT_DEBUG_REGISTERS`).
//!
//! The `dr0` through `dr3`, `dr6`, and `dr7` fields are valid.
kMinidumpContextX86Debug = kMinidumpContextX86 | 0x00000010,
//! \brief Indicates the validity of extended registers in `fxsave` format
//! (`CONTEXT_EXTENDED_REGISTERS`).
//!
//! The `extended_registers` field is valid and contains `fxsave` data.
kMinidumpContextX86Extended = kMinidumpContextX86 | 0x00000020,
//! \brief Indicates the validity of `xsave` data (`CONTEXT_XSTATE`).
//!
//! The context contains `xsave` data. This is used with an extended context
//! structure not currently defined here.
kMinidumpContextX86Xstate = kMinidumpContextX86 | 0x00000040,
//! \brief Indicates the validity of control, integer, and segment registers.
//! (`CONTEXT_FULL`).
kMinidumpContextX86Full = kMinidumpContextX86Control |
kMinidumpContextX86Integer |
kMinidumpContextX86Segment,
//! \brief Indicates the validity of all registers except `xsave` data.
//! (`CONTEXT_ALL`).
kMinidumpContextX86All = kMinidumpContextX86Full |
kMinidumpContextX86FloatingPoint |
kMinidumpContextX86Debug |
kMinidumpContextX86Extended,
};
//! \brief A 32-bit x86 CPU context (register state) carried in a minidump file.
//!
//! This is analogous to the `CONTEXT` structure on Windows when targeting
//! 32-bit x86, and the `WOW64_CONTEXT` structure when targeting an x86-family
//! CPU, either 32- or 64-bit. This structure is used instead of `CONTEXT` or
//! `WOW64_CONTEXT` to make it available when targeting other architectures.
//!
//! \note This structure doesnt carry `dr4` or `dr5`, which are obsolete and
//! normally alias `dr6` and `dr7`, respectively. See Intel Software
//! Developers Manual, Volume 3B: System Programming, Part 2 (253669-052),
//! 17.2.2 “Debug Registers DR4 and DR5”.
struct MinidumpContextX86 {
//! \brief A bitfield composed of values of #MinidumpContextFlags and
//! #MinidumpContextX86Flags.
//!
//! This field identifies the context structure as a 32-bit x86 CPU context,
//! and indicates which other fields in the structure are valid.
uint32_t context_flags;
uint32_t dr0;
uint32_t dr1;
uint32_t dr2;
uint32_t dr3;
uint32_t dr6;
uint32_t dr7;
// CPUContextX86::Fsave has identical layout to what the x86 CONTEXT structure
// places here.
CPUContextX86::Fsave fsave;
union {
uint32_t spare_0; // As in the native x86 CONTEXT structure since Windows 8
uint32_t cr0_npx_state; // As in WOW64_CONTEXT and older SDKs x86 CONTEXT
} float_save;
uint32_t gs;
uint32_t fs;
uint32_t es;
uint32_t ds;
uint32_t edi;
uint32_t esi;
uint32_t ebx;
uint32_t edx;
uint32_t ecx;
uint32_t eax;
uint32_t ebp;
uint32_t eip;
uint32_t cs;
uint32_t eflags;
uint32_t esp;
uint32_t ss;
// CPUContextX86::Fxsave has identical layout to what the x86 CONTEXT
// structure places here.
CPUContextX86::Fxsave fxsave;
};
//! \brief x86_64-specific flags for MinidumpContextAMD64::context_flags.
enum MinidumpContextAMD64Flags : uint32_t {
//! \brief Identifies the context structure as x86_64. This is the same as
//! `CONTEXT_AMD64` on Windows for this architecture.
kMinidumpContextAMD64 = 0x00100000,
//! \brief Indicates the validity of control registers (`CONTEXT_CONTROL`).
//!
//! The `cs`, `ss`, `eflags`, `rsp`, and `rip` fields are valid.
kMinidumpContextAMD64Control = kMinidumpContextAMD64 | 0x00000001,
//! \brief Indicates the validity of non-control integer registers
//! (`CONTEXT_INTEGER`).
//!
//! The `rax`, `rcx`, `rdx`, `rbx`, `rbp`, `rsi`, `rdi`, and `r8` through
//! `r15` fields are valid.
kMinidumpContextAMD64Integer = kMinidumpContextAMD64 | 0x00000002,
//! \brief Indicates the validity of non-control segment registers
//! (`CONTEXT_SEGMENTS`).
//!
//! The `ds`, `es`, `fs`, and `gs` fields are valid.
kMinidumpContextAMD64Segment = kMinidumpContextAMD64 | 0x00000004,
//! \brief Indicates the validity of floating-point state
//! (`CONTEXT_FLOATING_POINT`).
//!
//! The `xmm0` through `xmm15` fields are valid.
kMinidumpContextAMD64FloatingPoint = kMinidumpContextAMD64 | 0x00000008,
//! \brief Indicates the validity of debug registers
//! (`CONTEXT_DEBUG_REGISTERS`).
//!
//! The `dr0` through `dr3`, `dr6`, and `dr7` fields are valid.
kMinidumpContextAMD64Debug = kMinidumpContextAMD64 | 0x00000010,
//! \brief Indicates the validity of `xsave` data (`CONTEXT_XSTATE`).
//!
//! The context contains `xsave` data. This is used with an extended context
//! structure which is partly implemented for CET state only.
kMinidumpContextAMD64Xstate = kMinidumpContextAMD64 | 0x00000040,
//! \brief Indicates the validity of control, integer, and floating-point
//! registers (`CONTEXT_FULL`).
kMinidumpContextAMD64Full = kMinidumpContextAMD64Control |
kMinidumpContextAMD64Integer |
kMinidumpContextAMD64FloatingPoint,
//! \brief Indicates the validity of all registers except `xsave` data
//! (`CONTEXT_ALL`).
kMinidumpContextAMD64All = kMinidumpContextAMD64Full |
kMinidumpContextAMD64Segment |
kMinidumpContextAMD64Debug,
};
//! \brief An x86_64 (AMD64) CPU context (register state) carried in a minidump
//! file.
//!
//! This is analogous to the `CONTEXT` structure on Windows when targeting
//! x86_64. This structure is used instead of `CONTEXT` to make it available
//! when targeting other architectures.
//!
//! \note This structure doesnt carry `dr4` or `dr5`, which are obsolete and
//! normally alias `dr6` and `dr7`, respectively. See Intel Software
//! Developers Manual, Volume 3B: System Programming, Part 2 (253669-052),
//! 17.2.2 “Debug Registers DR4 and DR5”.
struct alignas(16) MinidumpContextAMD64 {
//! \brief Register parameter home address.
//!
//! On Windows, this field may contain the “home” address (on-stack, in the
//! shadow area) of a parameter passed by register. This field is present for
//! convenience but is not necessarily populated, even if a corresponding
//! parameter was passed by register.
//!
//! \{
uint64_t p1_home;
uint64_t p2_home;
uint64_t p3_home;
uint64_t p4_home;
uint64_t p5_home;
uint64_t p6_home;
//! \}
//! \brief A bitfield composed of values of #MinidumpContextFlags and
//! #MinidumpContextAMD64Flags.
//!
//! This field identifies the context structure as an x86_64 CPU context, and
//! indicates which other fields in the structure are valid.
uint32_t context_flags;
uint32_t mx_csr;
uint16_t cs;
uint16_t ds;
uint16_t es;
uint16_t fs;
uint16_t gs;
uint16_t ss;
uint32_t eflags;
uint64_t dr0;
uint64_t dr1;
uint64_t dr2;
uint64_t dr3;
uint64_t dr6;
uint64_t dr7;
uint64_t rax;
uint64_t rcx;
uint64_t rdx;
uint64_t rbx;
uint64_t rsp;
uint64_t rbp;
uint64_t rsi;
uint64_t rdi;
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t rip;
// CPUContextX86_64::Fxsave has identical layout to what the x86_64 CONTEXT
// structure places here.
CPUContextX86_64::Fxsave fxsave;
uint128_struct vector_register[26];
uint64_t vector_control;
//! \brief Model-specific debug extension register.
//!
//! See Intel Software Developers Manual, Volume 3B: System Programming, Part
//! 2 (253669-051), 17.4 “Last Branch, Interrupt, and Exception Recording
//! Overview”, and AMD Architecture Programmers Manual, Volume 2: System
//! Programming (24593-3.24), 13.1.6 “Control-Transfer Breakpoint Features”.
//!
//! \{
uint64_t debug_control;
uint64_t last_branch_to_rip;
uint64_t last_branch_from_rip;
uint64_t last_exception_to_rip;
uint64_t last_exception_from_rip;
//! \}
};
//! \brief 32-bit ARM-specifc flags for MinidumpContextARM::context_flags.
enum MinidumpContextARMFlags : uint32_t {
//! \brief Identifies the context structure as 32-bit ARM.
kMinidumpContextARM = 0x40000000,
//! \brief Indicates the validity of integer regsiters.
//!
//! Regsiters `r0`-`r15` and `cpsr` are valid.
kMinidumpContextARMInteger = kMinidumpContextARM | 0x00000002,
//! \brief Inidicates the validity of VFP regsiters.
//!
//! Registers `d0`-`d31` and `fpscr` are valid.
kMinidumpContextARMVFP = kMinidumpContextARM | 0x00000004,
//! \brief Indicates the validity of all registers.
kMinidumpContextARMAll = kMinidumpContextARMInteger | kMinidumpContextARMVFP,
};
//! \brief A 32-bit ARM CPU context (register state) carried in a minidump file.
struct MinidumpContextARM {
//! \brief A bitfield composed of values of #MinidumpContextFlags and
//! #MinidumpContextARMFlags.
//!
//! This field identifies the context structure as a 32-bit ARM CPU context,
//! and indicates which other fields in the structure are valid.
uint32_t context_flags;
//! \brief General-purpose registers `r0`-`r15`.
uint32_t regs[11];
uint32_t fp; // r11
uint32_t ip; // r12
uint32_t sp; // r13
uint32_t lr; // r14
uint32_t pc; // r15
//! \brief Current program status register.
uint32_t cpsr;
//! \brief Floating-point status and control register.
uint32_t fpscr;
//! \brief VFP registers `d0`-`d31`.
uint64_t vfp[32];
//! \brief This space is unused. It is included for compatibility with
//! breakpad (which also doesn't use it).
uint32_t extra[8];
};
//! \brief CONTEXT_CHUNK
struct MinidumpContextChunk {
int32_t offset;
uint32_t size;
};
//! \brief CONTEXT_EX
struct MinidumpContextExHeader {
MinidumpContextChunk all;
MinidumpContextChunk legacy;
MinidumpContextChunk xstate;
};
//! \brief XSAVE_AREA_HEADER
struct MinidumpXSaveAreaHeader {
uint64_t mask;
uint64_t compaction_mask;
uint64_t xsave_header_reserved[6];
};
//! \brief Offset of first xsave feature in the full extended context.
//!
//! This is used to calculate the final size of the extended context, and
//! can be validated by calling InitializeContext2 with one XSTATE feature,
//! and LocateXStateFeature to determine the first offset.
//! Also see "MANAGING STATE USING THE XSAVE FEATURE SET", Ch. 13, Intel SDM.
constexpr uint32_t kMinidumpAMD64XSaveOffset = 0x550;
//! \brief Offset of first xsave feature within the extended context area.
//!
//! 0x240 is the size of the legacy area (512) + the xsave header(64 bytes)
//! Intel SDM 13.4.1. This is not where the item is in the extended compacted
//! context, but is the offset recorded in the minidump. It needs to be correct
//! there. See https://windows-internals.com/cet-on-windows/ for some discussion
//! "CONTEXT_XSTATE: Extended processor state chunk. The state is stored in the
//! same format the XSAVE operation stores it with exception of the first 512
//! bytes, i.e. starting from XSAVE_AREA_HEADER." This may vary by cpuid.
constexpr uint32_t kXSaveAreaFirstOffset = 0x240;
//! \brief XSAVE_CET_U_FORMAT
struct MinidumpAMD64XSaveFormatCetU {
uint64_t cetmsr;
uint64_t ssp;
};
//! \brief 64-bit ARM-specifc flags for MinidumpContextARM64::context_flags.
enum MinidumpContextARM64Flags : uint32_t {
//! \brief Identifies the context structure as 64-bit ARM.
kMinidumpContextARM64 = 0x00400000,
//! \brief Indicates the validity of control registers.
//!
//! Registers `fp`, `lr`, `sp`, `pc`, and `cpsr`.
kMinidumpContextARM64Control = kMinidumpContextARM64 | 0x00000001,
//! \brief Indicates the validty of integer registers.
//!
//! Registers `x0`-`x28`.
kMinidumpContextARM64Integer = kMinidumpContextARM64 | 0x00000002,
//! \brief Indicates the validity of fpsimd registers.
//!
//! Registers `v0`-`v31`, `fpsr`, and `fpcr` are valid.
kMinidumpContextARM64Fpsimd = kMinidumpContextARM64 | 0x00000004,
//! \brief Indicates the validity of debug registers.
//!
//! `bcr`, `bvr`, `wcr`, and `wvr` are valid.
kMinidumpContextARM64Debug = kMinidumpContextARM64 | 0x00000008,
//! \brief Indicates the validity of control, integer and floating point
//! registers.
kMinidumpContextARM64Full = kMinidumpContextARM64Control |
kMinidumpContextARM64Integer |
kMinidumpContextARM64Fpsimd,
//! \brief Indicates the validity of all registers.
kMinidumpContextARM64All =
kMinidumpContextARM64Full | kMinidumpContextARM64Debug,
};
//! \brief A 64-bit ARM CPU context (register state) carried in a minidump file.
struct MinidumpContextARM64 {
uint32_t context_flags;
//! \brief Current program status register.
uint32_t cpsr;
//! \brief General-purpose registers `x0`-`x28`.
uint64_t regs[29];
//! \brief Frame pointer or `x29`.
uint64_t fp;
//! \brief Link register or `x30`.
uint64_t lr;
//! \brief Stack pointer or `x31`.
uint64_t sp;
//! \brief Program counter.
uint64_t pc;
//! \brief NEON registers `v0`-`v31`.
uint128_struct fpsimd[32];
//! \brief Floating-point control register.
uint32_t fpcr;
//! \brief Floating-point status register.
uint32_t fpsr;
//! \brief Debug registers.
uint32_t bcr[8];
uint64_t bvr[8];
uint32_t wcr[2];
uint64_t wvr[2];
};
//! \brief 32bit MIPS-specifc flags for MinidumpContextMIPS::context_flags.
//! Based on minidump_cpu_mips.h from breakpad
enum MinidumpContextMIPSFlags : uint32_t {
//! \brief Identifies the context structure as MIPSEL.
kMinidumpContextMIPS = 0x00040000,
//! \brief Indicates the validity of integer registers.
//!
//! Registers `0`-`31`, `mdhi`, `mdlo`, `epc`, `badvaddr`, `status` and
//! `cause` are valid.
kMinidumpContextMIPSInteger = kMinidumpContextMIPS | 0x00000002,
//! \brief Indicates the validity of floating point registers.
//!
//! Floating point registers `0`-`31`, `fpcsr` and `fir` are valid
kMinidumpContextMIPSFloatingPoint = kMinidumpContextMIPS | 0x00000004,
//! \brief Indicates the validity of DSP registers.
//!
//! Registers `hi0`-`hi2`, `lo0`-`lo2` and `dsp_control` are valid
kMinidumpContextMIPSDSP = kMinidumpContextMIPS | 0x00000008,
//! \brief Indicates the validity of all registers.
kMinidumpContextMIPSAll = kMinidumpContextMIPSInteger |
kMinidumpContextMIPSFloatingPoint |
kMinidumpContextMIPSDSP,
};
//! \brief A 32bit MIPS CPU context (register state) carried in a minidump file.
struct MinidumpContextMIPS {
uint32_t context_flags;
//! \brief This padding field is included for breakpad compatibility.
uint32_t _pad0;
//! \brief General purpose registers `0`-`31`.
uint64_t regs[32];
//! \brief Multiply/divide result.
uint64_t mdhi, mdlo;
//! \brief DSP registers.
uint32_t hi[3];
uint32_t lo[3];
uint32_t dsp_control;
//! \brief This padding field is included for breakpad compatibility.
uint32_t _pad1;
// \brief cp0 registers.
uint64_t epc;
uint64_t badvaddr;
uint32_t status;
uint32_t cause;
//! \brief FPU registers.
union {
struct {
float _fp_fregs;
uint32_t _fp_pad;
} fregs[32];
double dregs[32];
} fpregs;
//! \brief FPU status register.
uint32_t fpcsr;
//! \brief FPU implementation register.
uint32_t fir;
};
//! \brief 64bit MIPS-specifc flags for MinidumpContextMIPS64::context_flags.
//! Based on minidump_cpu_mips.h from breakpad
enum MinidumpContextMIPS64Flags : uint32_t {
//! \brief Identifies the context structure as MIPS64EL.
kMinidumpContextMIPS64 = 0x00080000,
//! \brief Indicates the validity of integer registers.
//!
//! Registers `0`-`31`, `mdhi`, `mdlo`, `epc`, `badvaddr`, `status` and
//! `cause` are valid.
kMinidumpContextMIPS64Integer = kMinidumpContextMIPS64 | 0x00000002,
//! \brief Indicates the validity of floating point registers.
//!
//! Floating point registers `0`-`31`, `fpcsr` and `fir` are valid
kMinidumpContextMIPS64FloatingPoint = kMinidumpContextMIPS64 | 0x00000004,
//! \brief Indicates the validity of DSP registers.
//!
//! Registers `hi0`-`hi2`, `lo0`-`lo2` and `dsp_control` are valid.
kMinidumpContextMIPS64DSP = kMinidumpContextMIPS64 | 0x00000008,
//! \brief Indicates the validity of all registers.
kMinidumpContextMIPS64All = kMinidumpContextMIPS64Integer |
kMinidumpContextMIPS64FloatingPoint |
kMinidumpContextMIPS64DSP,
};
//! \brief A 32bit MIPS CPU context (register state) carried in a minidump file.
struct MinidumpContextMIPS64 {
uint64_t context_flags;
//! \brief General purpose registers.
uint64_t regs[32];
//! \brief Multiply/divide result.
uint64_t mdhi, mdlo;
//! \brief DSP registers.
uint64_t hi[3];
uint64_t lo[3];
uint64_t dsp_control;
//! \brief cp0 registers.
uint64_t epc;
uint64_t badvaddr;
uint64_t status;
uint64_t cause;
//! \brief FPU registers.
union {
struct {
float _fp_fregs;
uint32_t _fp_pad;
} fregs[32];
double dregs[32];
} fpregs;
//! \brief FPU status register.
uint64_t fpcsr;
//! \brief FPU implementation register.
uint64_t fir;
};
} // namespace crashpad
#endif // CRASHPAD_MINIDUMP_MINIDUMP_CONTEXT_H_