From 8eb7111814953cb64ec0569b91ea99804b2d5b85 Mon Sep 17 00:00:00 2001 From: "ted.mielczarek" Date: Wed, 31 Oct 2007 19:20:31 +0000 Subject: Issue 196 - Breakpad processor support for x86-64. r=mento git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@227 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/google_breakpad/common/minidump_format.h | 154 ++++++++++++++++++++++++ src/google_breakpad/processor/minidump.h | 15 ++- src/google_breakpad/processor/stack_frame_cpu.h | 26 ++++ 3 files changed, 190 insertions(+), 5 deletions(-) (limited to 'src/google_breakpad') diff --git a/src/google_breakpad/common/minidump_format.h b/src/google_breakpad/common/minidump_format.h index cb6811e0..229bb9b2 100644 --- a/src/google_breakpad/common/minidump_format.h +++ b/src/google_breakpad/common/minidump_format.h @@ -215,6 +215,160 @@ typedef struct { #define MD_CONTEXT_CPU_MASK 0xffffffc0 +/* + * AMD64 support, see WINNT.H + */ + +typedef struct { + u_int16_t control_word; + u_int16_t status_word; + u_int8_t tag_word; + u_int8_t reserved1; + u_int16_t error_opcode; + u_int32_t error_offset; + u_int16_t error_selector; + u_int16_t reserved2; + u_int32_t data_offset; + u_int16_t data_selector; + u_int16_t reserved3; + u_int32_t mx_csr; + u_int32_t mx_csr_mask; + u_int128_t float_registers[8]; + u_int128_t xmm_registers[16]; + u_int8_t reserved4[96]; +} MDXmmSaveArea32AMD64; /* XMM_SAVE_AREA32 */ + +#define MD_CONTEXT_AMD64_VR_COUNT 26 + +typedef struct { + /* + * Register parameter home addresses. + */ + u_int64_t p1_home; + u_int64_t p2_home; + u_int64_t p3_home; + u_int64_t p4_home; + u_int64_t p5_home; + u_int64_t p6_home; + + /* The next field determines the layout of the structure, and which parts + * of it are populated */ + u_int32_t context_flags; + u_int32_t mx_csr; + + /* The next register is included with MD_CONTEXT_AMD64_CONTROL */ + u_int16_t cs; + + /* The next 4 registers are included with MD_CONTEXT_AMD64_SEGMENTS */ + u_int16_t ds; + u_int16_t es; + u_int16_t fs; + u_int16_t gs; + + /* The next 2 registers are included with MD_CONTEXT_AMD64_CONTROL */ + u_int16_t ss; + u_int32_t eflags; + + /* The next 6 registers are included with MD_CONTEXT_AMD64_DEBUG_REGISTERS */ + u_int64_t dr0; + u_int64_t dr1; + u_int64_t dr2; + u_int64_t dr3; + u_int64_t dr6; + u_int64_t dr7; + + /* The next 4 registers are included with MD_CONTEXT_AMD64_INTEGER */ + u_int64_t rax; + u_int64_t rcx; + u_int64_t rdx; + u_int64_t rbx; + + /* The next register is included with MD_CONTEXT_AMD64_CONTROL */ + u_int64_t rsp; + + /* The next 11 registers are included with MD_CONTEXT_AMD64_INTEGER */ + u_int64_t rbp; + u_int64_t rsi; + u_int64_t rdi; + u_int64_t r8; + u_int64_t r9; + u_int64_t r10; + u_int64_t r11; + u_int64_t r12; + u_int64_t r13; + u_int64_t r14; + u_int64_t r15; + + /* The next register is included with MD_CONTEXT_AMD64_CONTROL */ + u_int64_t rip; + + /* The next set of registers are included with + * MD_CONTEXT_AMD64_FLOATING_POINT + */ + union { + MDXmmSaveArea32AMD64 flt_save; + struct { + u_int128_t header[2]; + u_int128_t legacy[8]; + u_int128_t xmm0; + u_int128_t xmm1; + u_int128_t xmm2; + u_int128_t xmm3; + u_int128_t xmm4; + u_int128_t xmm5; + u_int128_t xmm6; + u_int128_t xmm7; + u_int128_t xmm8; + u_int128_t xmm9; + u_int128_t xmm10; + u_int128_t xmm11; + u_int128_t xmm12; + u_int128_t xmm13; + u_int128_t xmm14; + u_int128_t xmm15; + } sse_registers; + }; + + u_int128_t vector_register[MD_CONTEXT_AMD64_VR_COUNT]; + u_int64_t vector_control; + + /* The next 5 registers are included with MD_CONTEXT_AMD64_DEBUG_REGISTERS */ + u_int64_t debug_control; + u_int64_t last_branch_to_rip; + u_int64_t last_branch_from_rip; + u_int64_t last_exception_to_rip; + u_int64_t last_exception_from_rip; + +} MDRawContextAMD64; /* CONTEXT */ + +/* For (MDRawContextAMD64).context_flags. These values indicate the type of + * context stored in the structure. The high 26 bits identify the CPU, the + * low 6 bits identify the type of context saved. */ +#define MD_CONTEXT_AMD64_CONTROL (MD_CONTEXT_AMD64 | 0x00000001) + /* CONTEXT_CONTROL */ +#define MD_CONTEXT_AMD64_INTEGER (MD_CONTEXT_AMD64 | 0x00000002) + /* CONTEXT_INTEGER */ +#define MD_CONTEXT_AMD64_SEGMENTS (MD_CONTEXT_AMD64 | 0x00000004) + /* CONTEXT_SEGMENTS */ +#define MD_CONTEXT_AMD64_FLOATING_POINT (MD_CONTEXT_AMD64 | 0x00000008) + /* CONTEXT_FLOATING_POINT */ +#define MD_CONTEXT_AMD64_DEBUG_REGISTERS (MD_CONTEXT_AMD64 | 0x00000010) + /* CONTEXT_DEBUG_REGISTERS */ +/* WinNT.h refers to CONTEXT_MMX_REGISTERS but doesn't appear to define it + * I think it really means CONTEXT_FLOATING_POINT. + */ + +#define MD_CONTEXT_AMD64_FULL (MD_CONTEXT_AMD64_CONTROL | \ + MD_CONTEXT_AMD64_INTEGER | \ + MD_CONTEXT_AMD64_FLOATING_POINT) + /* CONTEXT_FULL */ + +#define MD_CONTEXT_AMD64_ALL (MD_CONTEXT_AMD64_FULL | \ + MD_CONTEXT_AMD64_SEGMENTS | \ + MD_CONTEXT_X86_DEBUG_REGISTERS) + /* CONTEXT_ALL */ + + /* * SPARC support, see (solaris)sys/procfs_isa.h also */ diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h index 474382b9..4e900fb1 100644 --- a/src/google_breakpad/processor/minidump.h +++ b/src/google_breakpad/processor/minidump.h @@ -175,8 +175,9 @@ class MinidumpContext : public MinidumpStream { // Returns raw CPU-specific context data for the named CPU type. If the // context data does not match the CPU type or does not exist, returns // NULL. - const MDRawContextX86* GetContextX86() const; - const MDRawContextPPC* GetContextPPC() const; + const MDRawContextX86* GetContextX86() const; + const MDRawContextPPC* GetContextPPC() const; + const MDRawContextAMD64* GetContextAMD64() const; const MDRawContextSPARC* GetContextSPARC() const; // Print a human-readable representation of the object to stdout. @@ -200,11 +201,15 @@ class MinidumpContext : public MinidumpStream { // not contain a system info stream. bool CheckAgainstSystemInfo(u_int32_t context_cpu_type); + // Store this separately because of the weirdo AMD64 context + u_int32_t context_flags_; + // The CPU-specific context structure. union { - MDRawContextBase* base; - MDRawContextX86* x86; - MDRawContextPPC* ppc; + MDRawContextBase* base; + MDRawContextX86* x86; + MDRawContextPPC* ppc; + MDRawContextAMD64* amd64; // on Solaris SPARC, sparc is defined as a numeric constant, // so variables can NOT be named as sparc MDRawContextSPARC* ctx_sparc; diff --git a/src/google_breakpad/processor/stack_frame_cpu.h b/src/google_breakpad/processor/stack_frame_cpu.h index 567c1b7e..a8840278 100644 --- a/src/google_breakpad/processor/stack_frame_cpu.h +++ b/src/google_breakpad/processor/stack_frame_cpu.h @@ -98,6 +98,32 @@ struct StackFramePPC : public StackFrame { int context_validity; }; +struct StackFrameAMD64 : public StackFrame { + // ContextValidity has one entry for each relevant hardware pointer register + // (%rip and %rsp) and one entry for each nonvolatile (callee-save) register. + //FIXME: validate this list + enum ContextValidity { + CONTEXT_VALID_NONE = 0, + CONTEXT_VALID_RIP = 1 << 0, + CONTEXT_VALID_RSP = 1 << 1, + CONTEXT_VALID_RBP = 1 << 2, + CONTEXT_VALID_ALL = -1 + }; + + StackFrameAMD64() : context(), context_validity(CONTEXT_VALID_NONE) {} + + // Register state. This is only fully valid for the topmost frame in a + // stack. In other frames, the values of nonvolatile registers may be + // present, given sufficient debugging information. Refer to + // context_validity. + MDRawContextAMD64 context; + + // context_validity is actually ContextValidity, but int is used because + // the OR operator doesn't work well with enumerated types. This indicates + // which fields in context are valid. + int context_validity; +}; + struct StackFrameSPARC : public StackFrame { // to be confirmed enum ContextValidity { -- cgit v1.2.1