crashpad/minidump/minidump_context.h
Mark Mentovai 5906513e30 MinidumpContext: fix some problems in AMD64 (x86_64) context enums.
This fixes a sloppy compliation error: “Redefinition of enumerator
'kMinidumpContextX86Xstate'”. It also fixes CONTEXT_FULL, which should
contain floating-point registers but not segment registers unlike the
its 32-bit x86 equivalent.

Some comments are revised to provide better, um, context.

R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/620663002
2014-09-30 17:22:35 -04:00

368 lines
12 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. 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_MINIDUMP_MINIDUMP_CONTEXT_H_
#define CRASHPAD_MINIDUMP_MINIDUMP_CONTEXT_H_
#include <stdint.h>
#include "util/numeric/int128.h"
namespace crashpad {
//! \brief Architecture-independent flags for `context_flags` fields in Minidump
//! context structures.
//
// http://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
//! 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 `float_save` field is valid.
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. This structure is used instead of `CONTEXT` to make it available
//! when targeting other architectures.
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;
struct {
uint32_t control_word;
uint32_t status_word;
uint32_t tag_word;
uint32_t error_offset;
uint32_t error_selector;
uint32_t data_offset;
uint32_t data_selector;
uint8_t register_area[80];
uint32_t spare_0;
} 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;
uint8_t extended_registers[512];
};
//! \brief x86_64-specifc 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 not currently defined here.
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.
struct __attribute__((aligned(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;
union {
struct {
uint16_t control_word;
uint16_t status_word;
uint8_t tag_word;
uint8_t reserved_1;
uint16_t error_opcode;
uint32_t error_offset;
uint16_t error_selector;
uint16_t reserved_2;
uint32_t data_offset;
uint16_t data_selector;
uint16_t reserved_3;
uint32_t mx_csr;
uint32_t mx_csr_mask;
uint128_struct float_registers[8];
uint128_struct xmm_registers[16];
uint8_t reserved_4[96];
} float_save;
struct {
uint128_struct header[2];
uint128_struct legacy[8];
uint128_struct xmm0;
uint128_struct xmm1;
uint128_struct xmm2;
uint128_struct xmm3;
uint128_struct xmm4;
uint128_struct xmm5;
uint128_struct xmm6;
uint128_struct xmm7;
uint128_struct xmm8;
uint128_struct xmm9;
uint128_struct xmm10;
uint128_struct xmm11;
uint128_struct xmm12;
uint128_struct xmm13;
uint128_struct xmm14;
uint128_struct xmm15;
};
};
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;
//! \}
};
} // namespace crashpad
#endif // CRASHPAD_MINIDUMP_MINIDUMP_CONTEXT_H_