1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 // stack_frame_cpu.h: CPU-specific StackFrame extensions.
31 //
32 // These types extend the StackFrame structure to carry CPU-specific register
33 // state.  They are defined in this header instead of stack_frame.h to
34 // avoid the need to include minidump_format.h when only the generic
35 // StackFrame type is needed.
36 //
37 // Author: Mark Mentovai
38 
39 #ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__
40 #define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__
41 
42 #include "google_breakpad/common/minidump_format.h"
43 #include "google_breakpad/processor/stack_frame.h"
44 
45 namespace google_breakpad {
46 
47 struct StackFrameX86 : public StackFrame {
48   // ContextValidity has one entry for each relevant hardware pointer register
49   // (%eip and %esp) and one entry for each nonvolatile (callee-save) register.
50   enum ContextValidity {
51     CONTEXT_VALID_NONE = 0,
52     CONTEXT_VALID_EIP  = 1 << 0,
53     CONTEXT_VALID_ESP  = 1 << 1,
54     CONTEXT_VALID_EBP  = 1 << 2,
55     CONTEXT_VALID_EBX  = 1 << 3,
56     CONTEXT_VALID_ESI  = 1 << 4,
57     CONTEXT_VALID_EDI  = 1 << 5,
58     CONTEXT_VALID_ALL  = -1
59   };
60 
61   // Indicates how well we trust the instruction pointer we derived
62   // during stack walking. Since the stack walker can resort to
63   // stack scanning, we can wind up with dubious frames.
64   // In rough order of "trust metric".
65   enum FrameTrust {
66     FRAME_TRUST_NONE,     // Unknown
67     FRAME_TRUST_SCAN,     // Scanned the stack, found this
68     FRAME_TRUST_CFI_SCAN, // Scanned the stack using call frame info, found this
69     FRAME_TRUST_FP,       // Derived from frame pointer
70     FRAME_TRUST_CFI,      // Derived from call frame info
71     FRAME_TRUST_CONTEXT   // Given as instruction pointer in a context
72   };
73 
StackFrameX86StackFrameX8674  StackFrameX86()
75      : context(),
76        context_validity(CONTEXT_VALID_NONE),
77        trust(FRAME_TRUST_NONE) {}
78 
79   // Register state.  This is only fully valid for the topmost frame in a
80   // stack.  In other frames, the values of nonvolatile registers may be
81   // present, given sufficient debugging information.  Refer to
82   // context_validity.
83   MDRawContextX86 context;
84 
85   // context_validity is actually ContextValidity, but int is used because
86   // the OR operator doesn't work well with enumerated types.  This indicates
87   // which fields in context are valid.
88   int context_validity;
89 
90   // Amount of trust the stack walker has in the instruction pointer
91   // of this frame.
92   FrameTrust trust;
93 };
94 
95 struct StackFramePPC : public StackFrame {
96   // ContextValidity should eventually contain entries for the validity of
97   // other nonvolatile (callee-save) registers as in
98   // StackFrameX86::ContextValidity, but the ppc stackwalker doesn't currently
99   // locate registers other than the ones listed here.
100   enum ContextValidity {
101     CONTEXT_VALID_NONE = 0,
102     CONTEXT_VALID_SRR0 = 1 << 0,
103     CONTEXT_VALID_GPR1 = 1 << 1,
104     CONTEXT_VALID_ALL  = -1
105   };
106 
StackFramePPCStackFramePPC107   StackFramePPC() : context(), context_validity(CONTEXT_VALID_NONE) {}
108 
109   // Register state.  This is only fully valid for the topmost frame in a
110   // stack.  In other frames, the values of nonvolatile registers may be
111   // present, given sufficient debugging information.  Refer to
112   // context_validity.
113   MDRawContextPPC context;
114 
115   // context_validity is actually ContextValidity, but int is used because
116   // the OR operator doesn't work well with enumerated types.  This indicates
117   // which fields in context are valid.
118   int context_validity;
119 };
120 
121 struct StackFrameAMD64 : public StackFrame {
122   // ContextValidity has one entry for each relevant hardware pointer register
123   // (%rip and %rsp) and one entry for each nonvolatile (callee-save) register.
124   //FIXME: validate this list
125   enum ContextValidity {
126     CONTEXT_VALID_NONE = 0,
127     CONTEXT_VALID_RIP  = 1 << 0,
128     CONTEXT_VALID_RSP  = 1 << 1,
129     CONTEXT_VALID_RBP  = 1 << 2,
130     CONTEXT_VALID_ALL  = -1
131   };
132 
StackFrameAMD64StackFrameAMD64133   StackFrameAMD64() : context(), context_validity(CONTEXT_VALID_NONE) {}
134 
135   // Register state.  This is only fully valid for the topmost frame in a
136   // stack.  In other frames, the values of nonvolatile registers may be
137   // present, given sufficient debugging information.  Refer to
138   // context_validity.
139   MDRawContextAMD64 context;
140 
141   // context_validity is actually ContextValidity, but int is used because
142   // the OR operator doesn't work well with enumerated types.  This indicates
143   // which fields in context are valid.
144   int context_validity;
145 };
146 
147 struct StackFrameSPARC : public StackFrame {
148   // to be confirmed
149   enum ContextValidity {
150     CONTEXT_VALID_NONE = 0,
151     CONTEXT_VALID_PC   = 1 << 0,
152     CONTEXT_VALID_SP   = 1 << 1,
153     CONTEXT_VALID_FP   = 1 << 2,
154     CONTEXT_VALID_ALL  = -1
155   };
156 
StackFrameSPARCStackFrameSPARC157   StackFrameSPARC() : context(), context_validity(CONTEXT_VALID_NONE) {}
158 
159   // Register state.  This is only fully valid for the topmost frame in a
160   // stack.  In other frames, the values of nonvolatile registers may be
161   // present, given sufficient debugging information.  Refer to
162   // context_validity.
163   MDRawContextSPARC context;
164 
165   // context_validity is actually ContextValidity, but int is used because
166   // the OR operator doesn't work well with enumerated types.  This indicates
167   // which fields in context are valid.
168   int context_validity;
169 };
170 
171 }  // namespace google_breakpad
172 
173 #endif  // GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_CPU_H__
174