1*9712c20fSFrederick Mayle // Copyright 2010 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle // * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle // * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle // * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle
29*9712c20fSFrederick Mayle // dump_context.cc: A (mini/micro)dump context.
30*9712c20fSFrederick Mayle //
31*9712c20fSFrederick Mayle // See dump_context.h for documentation.
32*9712c20fSFrederick Mayle
33*9712c20fSFrederick Mayle #ifdef HAVE_CONFIG_H
34*9712c20fSFrederick Mayle #include <config.h> // Must come first
35*9712c20fSFrederick Mayle #endif
36*9712c20fSFrederick Mayle
37*9712c20fSFrederick Mayle #include "google_breakpad/processor/dump_context.h"
38*9712c20fSFrederick Mayle
39*9712c20fSFrederick Mayle #include <assert.h>
40*9712c20fSFrederick Mayle
41*9712c20fSFrederick Mayle #ifdef _WIN32
42*9712c20fSFrederick Mayle #include <io.h>
43*9712c20fSFrederick Mayle #else // _WIN32
44*9712c20fSFrederick Mayle #include <unistd.h>
45*9712c20fSFrederick Mayle #endif // _WIN32
46*9712c20fSFrederick Mayle
47*9712c20fSFrederick Mayle #include "common/stdio_wrapper.h"
48*9712c20fSFrederick Mayle #include "processor/logging.h"
49*9712c20fSFrederick Mayle
50*9712c20fSFrederick Mayle namespace google_breakpad {
51*9712c20fSFrederick Mayle
DumpContext()52*9712c20fSFrederick Mayle DumpContext::DumpContext() : context_(),
53*9712c20fSFrederick Mayle context_flags_(0) { }
54*9712c20fSFrederick Mayle
~DumpContext()55*9712c20fSFrederick Mayle DumpContext::~DumpContext() {
56*9712c20fSFrederick Mayle FreeContext();
57*9712c20fSFrederick Mayle }
58*9712c20fSFrederick Mayle
GetContextCPU() const59*9712c20fSFrederick Mayle uint32_t DumpContext::GetContextCPU() const {
60*9712c20fSFrederick Mayle if (!valid_) {
61*9712c20fSFrederick Mayle // Don't log a message, GetContextCPU can be legitimately called with
62*9712c20fSFrederick Mayle // valid_ false by FreeContext, which is called by Read.
63*9712c20fSFrederick Mayle return 0;
64*9712c20fSFrederick Mayle }
65*9712c20fSFrederick Mayle
66*9712c20fSFrederick Mayle return context_flags_ & MD_CONTEXT_CPU_MASK;
67*9712c20fSFrederick Mayle }
68*9712c20fSFrederick Mayle
GetContextFlags() const69*9712c20fSFrederick Mayle uint32_t DumpContext::GetContextFlags() const {
70*9712c20fSFrederick Mayle return context_flags_;
71*9712c20fSFrederick Mayle }
72*9712c20fSFrederick Mayle
GetContextX86() const73*9712c20fSFrederick Mayle const MDRawContextX86* DumpContext::GetContextX86() const {
74*9712c20fSFrederick Mayle if (GetContextCPU() != MD_CONTEXT_X86) {
75*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get x86 context";
76*9712c20fSFrederick Mayle return NULL;
77*9712c20fSFrederick Mayle }
78*9712c20fSFrederick Mayle
79*9712c20fSFrederick Mayle return context_.x86;
80*9712c20fSFrederick Mayle }
81*9712c20fSFrederick Mayle
GetContextPPC() const82*9712c20fSFrederick Mayle const MDRawContextPPC* DumpContext::GetContextPPC() const {
83*9712c20fSFrederick Mayle if (GetContextCPU() != MD_CONTEXT_PPC) {
84*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get ppc context";
85*9712c20fSFrederick Mayle return NULL;
86*9712c20fSFrederick Mayle }
87*9712c20fSFrederick Mayle
88*9712c20fSFrederick Mayle return context_.ppc;
89*9712c20fSFrederick Mayle }
90*9712c20fSFrederick Mayle
GetContextPPC64() const91*9712c20fSFrederick Mayle const MDRawContextPPC64* DumpContext::GetContextPPC64() const {
92*9712c20fSFrederick Mayle if (GetContextCPU() != MD_CONTEXT_PPC64) {
93*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get ppc64 context";
94*9712c20fSFrederick Mayle return NULL;
95*9712c20fSFrederick Mayle }
96*9712c20fSFrederick Mayle
97*9712c20fSFrederick Mayle return context_.ppc64;
98*9712c20fSFrederick Mayle }
99*9712c20fSFrederick Mayle
GetContextAMD64() const100*9712c20fSFrederick Mayle const MDRawContextAMD64* DumpContext::GetContextAMD64() const {
101*9712c20fSFrederick Mayle if (GetContextCPU() != MD_CONTEXT_AMD64) {
102*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get amd64 context";
103*9712c20fSFrederick Mayle return NULL;
104*9712c20fSFrederick Mayle }
105*9712c20fSFrederick Mayle
106*9712c20fSFrederick Mayle return context_.amd64;
107*9712c20fSFrederick Mayle }
108*9712c20fSFrederick Mayle
GetContextSPARC() const109*9712c20fSFrederick Mayle const MDRawContextSPARC* DumpContext::GetContextSPARC() const {
110*9712c20fSFrederick Mayle if (GetContextCPU() != MD_CONTEXT_SPARC) {
111*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get sparc context";
112*9712c20fSFrederick Mayle return NULL;
113*9712c20fSFrederick Mayle }
114*9712c20fSFrederick Mayle
115*9712c20fSFrederick Mayle return context_.ctx_sparc;
116*9712c20fSFrederick Mayle }
117*9712c20fSFrederick Mayle
GetContextARM() const118*9712c20fSFrederick Mayle const MDRawContextARM* DumpContext::GetContextARM() const {
119*9712c20fSFrederick Mayle if (GetContextCPU() != MD_CONTEXT_ARM) {
120*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get arm context";
121*9712c20fSFrederick Mayle return NULL;
122*9712c20fSFrederick Mayle }
123*9712c20fSFrederick Mayle
124*9712c20fSFrederick Mayle return context_.arm;
125*9712c20fSFrederick Mayle }
126*9712c20fSFrederick Mayle
GetContextARM64() const127*9712c20fSFrederick Mayle const MDRawContextARM64* DumpContext::GetContextARM64() const {
128*9712c20fSFrederick Mayle if (GetContextCPU() != MD_CONTEXT_ARM64) {
129*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get arm64 context";
130*9712c20fSFrederick Mayle return NULL;
131*9712c20fSFrederick Mayle }
132*9712c20fSFrederick Mayle
133*9712c20fSFrederick Mayle return context_.arm64;
134*9712c20fSFrederick Mayle }
135*9712c20fSFrederick Mayle
GetContextMIPS() const136*9712c20fSFrederick Mayle const MDRawContextMIPS* DumpContext::GetContextMIPS() const {
137*9712c20fSFrederick Mayle if ((GetContextCPU() != MD_CONTEXT_MIPS) &&
138*9712c20fSFrederick Mayle (GetContextCPU() != MD_CONTEXT_MIPS64)) {
139*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get MIPS context";
140*9712c20fSFrederick Mayle return NULL;
141*9712c20fSFrederick Mayle }
142*9712c20fSFrederick Mayle
143*9712c20fSFrederick Mayle return context_.ctx_mips;
144*9712c20fSFrederick Mayle }
145*9712c20fSFrederick Mayle
GetContextRISCV() const146*9712c20fSFrederick Mayle const MDRawContextRISCV* DumpContext::GetContextRISCV() const {
147*9712c20fSFrederick Mayle if (GetContextCPU() != MD_CONTEXT_RISCV) {
148*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get RISCV context";
149*9712c20fSFrederick Mayle return NULL;
150*9712c20fSFrederick Mayle }
151*9712c20fSFrederick Mayle
152*9712c20fSFrederick Mayle return context_.riscv;
153*9712c20fSFrederick Mayle }
154*9712c20fSFrederick Mayle
GetContextRISCV64() const155*9712c20fSFrederick Mayle const MDRawContextRISCV64* DumpContext::GetContextRISCV64() const {
156*9712c20fSFrederick Mayle if (GetContextCPU() != MD_CONTEXT_RISCV64) {
157*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot get RISCV64 context";
158*9712c20fSFrederick Mayle return NULL;
159*9712c20fSFrederick Mayle }
160*9712c20fSFrederick Mayle
161*9712c20fSFrederick Mayle return context_.riscv64;
162*9712c20fSFrederick Mayle }
163*9712c20fSFrederick Mayle
GetInstructionPointer(uint64_t * ip) const164*9712c20fSFrederick Mayle bool DumpContext::GetInstructionPointer(uint64_t* ip) const {
165*9712c20fSFrederick Mayle BPLOG_IF(ERROR, !ip) << "DumpContext::GetInstructionPointer requires |ip|";
166*9712c20fSFrederick Mayle assert(ip);
167*9712c20fSFrederick Mayle *ip = 0;
168*9712c20fSFrederick Mayle
169*9712c20fSFrederick Mayle if (!valid_) {
170*9712c20fSFrederick Mayle BPLOG(ERROR) << "Invalid DumpContext for GetInstructionPointer";
171*9712c20fSFrederick Mayle return false;
172*9712c20fSFrederick Mayle }
173*9712c20fSFrederick Mayle
174*9712c20fSFrederick Mayle switch (GetContextCPU()) {
175*9712c20fSFrederick Mayle case MD_CONTEXT_AMD64:
176*9712c20fSFrederick Mayle *ip = GetContextAMD64()->rip;
177*9712c20fSFrederick Mayle break;
178*9712c20fSFrederick Mayle case MD_CONTEXT_ARM:
179*9712c20fSFrederick Mayle *ip = GetContextARM()->iregs[MD_CONTEXT_ARM_REG_PC];
180*9712c20fSFrederick Mayle break;
181*9712c20fSFrederick Mayle case MD_CONTEXT_ARM64:
182*9712c20fSFrederick Mayle *ip = GetContextARM64()->iregs[MD_CONTEXT_ARM64_REG_PC];
183*9712c20fSFrederick Mayle break;
184*9712c20fSFrederick Mayle case MD_CONTEXT_PPC:
185*9712c20fSFrederick Mayle *ip = GetContextPPC()->srr0;
186*9712c20fSFrederick Mayle break;
187*9712c20fSFrederick Mayle case MD_CONTEXT_PPC64:
188*9712c20fSFrederick Mayle *ip = GetContextPPC64()->srr0;
189*9712c20fSFrederick Mayle break;
190*9712c20fSFrederick Mayle case MD_CONTEXT_SPARC:
191*9712c20fSFrederick Mayle *ip = GetContextSPARC()->pc;
192*9712c20fSFrederick Mayle break;
193*9712c20fSFrederick Mayle case MD_CONTEXT_X86:
194*9712c20fSFrederick Mayle *ip = GetContextX86()->eip;
195*9712c20fSFrederick Mayle break;
196*9712c20fSFrederick Mayle case MD_CONTEXT_MIPS:
197*9712c20fSFrederick Mayle case MD_CONTEXT_MIPS64:
198*9712c20fSFrederick Mayle *ip = GetContextMIPS()->epc;
199*9712c20fSFrederick Mayle break;
200*9712c20fSFrederick Mayle case MD_CONTEXT_RISCV:
201*9712c20fSFrederick Mayle *ip = GetContextRISCV()->pc;
202*9712c20fSFrederick Mayle break;
203*9712c20fSFrederick Mayle case MD_CONTEXT_RISCV64:
204*9712c20fSFrederick Mayle *ip = GetContextRISCV64()->pc;
205*9712c20fSFrederick Mayle break;
206*9712c20fSFrederick Mayle default:
207*9712c20fSFrederick Mayle // This should never happen.
208*9712c20fSFrederick Mayle BPLOG(ERROR) << "Unknown CPU architecture in GetInstructionPointer";
209*9712c20fSFrederick Mayle return false;
210*9712c20fSFrederick Mayle }
211*9712c20fSFrederick Mayle return true;
212*9712c20fSFrederick Mayle }
213*9712c20fSFrederick Mayle
GetStackPointer(uint64_t * sp) const214*9712c20fSFrederick Mayle bool DumpContext::GetStackPointer(uint64_t* sp) const {
215*9712c20fSFrederick Mayle BPLOG_IF(ERROR, !sp) << "DumpContext::GetStackPointer requires |sp|";
216*9712c20fSFrederick Mayle assert(sp);
217*9712c20fSFrederick Mayle *sp = 0;
218*9712c20fSFrederick Mayle
219*9712c20fSFrederick Mayle if (!valid_) {
220*9712c20fSFrederick Mayle BPLOG(ERROR) << "Invalid DumpContext for GetStackPointer";
221*9712c20fSFrederick Mayle return false;
222*9712c20fSFrederick Mayle }
223*9712c20fSFrederick Mayle
224*9712c20fSFrederick Mayle switch (GetContextCPU()) {
225*9712c20fSFrederick Mayle case MD_CONTEXT_AMD64:
226*9712c20fSFrederick Mayle *sp = GetContextAMD64()->rsp;
227*9712c20fSFrederick Mayle break;
228*9712c20fSFrederick Mayle case MD_CONTEXT_ARM:
229*9712c20fSFrederick Mayle *sp = GetContextARM()->iregs[MD_CONTEXT_ARM_REG_SP];
230*9712c20fSFrederick Mayle break;
231*9712c20fSFrederick Mayle case MD_CONTEXT_ARM64:
232*9712c20fSFrederick Mayle *sp = GetContextARM64()->iregs[MD_CONTEXT_ARM64_REG_SP];
233*9712c20fSFrederick Mayle break;
234*9712c20fSFrederick Mayle case MD_CONTEXT_PPC:
235*9712c20fSFrederick Mayle *sp = GetContextPPC()->gpr[MD_CONTEXT_PPC_REG_SP];
236*9712c20fSFrederick Mayle break;
237*9712c20fSFrederick Mayle case MD_CONTEXT_PPC64:
238*9712c20fSFrederick Mayle *sp = GetContextPPC64()->gpr[MD_CONTEXT_PPC64_REG_SP];
239*9712c20fSFrederick Mayle break;
240*9712c20fSFrederick Mayle case MD_CONTEXT_SPARC:
241*9712c20fSFrederick Mayle *sp = GetContextSPARC()->g_r[MD_CONTEXT_SPARC_REG_SP];
242*9712c20fSFrederick Mayle break;
243*9712c20fSFrederick Mayle case MD_CONTEXT_X86:
244*9712c20fSFrederick Mayle *sp = GetContextX86()->esp;
245*9712c20fSFrederick Mayle break;
246*9712c20fSFrederick Mayle case MD_CONTEXT_MIPS:
247*9712c20fSFrederick Mayle case MD_CONTEXT_MIPS64:
248*9712c20fSFrederick Mayle *sp = GetContextMIPS()->iregs[MD_CONTEXT_MIPS_REG_SP];
249*9712c20fSFrederick Mayle break;
250*9712c20fSFrederick Mayle case MD_CONTEXT_RISCV:
251*9712c20fSFrederick Mayle *sp = GetContextRISCV()->sp;
252*9712c20fSFrederick Mayle break;
253*9712c20fSFrederick Mayle case MD_CONTEXT_RISCV64:
254*9712c20fSFrederick Mayle *sp = GetContextRISCV64()->sp;
255*9712c20fSFrederick Mayle break;
256*9712c20fSFrederick Mayle default:
257*9712c20fSFrederick Mayle // This should never happen.
258*9712c20fSFrederick Mayle BPLOG(ERROR) << "Unknown CPU architecture in GetStackPointer";
259*9712c20fSFrederick Mayle return false;
260*9712c20fSFrederick Mayle }
261*9712c20fSFrederick Mayle return true;
262*9712c20fSFrederick Mayle }
263*9712c20fSFrederick Mayle
SetContextFlags(uint32_t context_flags)264*9712c20fSFrederick Mayle void DumpContext::SetContextFlags(uint32_t context_flags) {
265*9712c20fSFrederick Mayle context_flags_ = context_flags;
266*9712c20fSFrederick Mayle }
267*9712c20fSFrederick Mayle
SetContextX86(MDRawContextX86 * x86)268*9712c20fSFrederick Mayle void DumpContext::SetContextX86(MDRawContextX86* x86) {
269*9712c20fSFrederick Mayle context_.x86 = x86;
270*9712c20fSFrederick Mayle }
271*9712c20fSFrederick Mayle
SetContextPPC(MDRawContextPPC * ppc)272*9712c20fSFrederick Mayle void DumpContext::SetContextPPC(MDRawContextPPC* ppc) {
273*9712c20fSFrederick Mayle context_.ppc = ppc;
274*9712c20fSFrederick Mayle }
275*9712c20fSFrederick Mayle
SetContextPPC64(MDRawContextPPC64 * ppc64)276*9712c20fSFrederick Mayle void DumpContext::SetContextPPC64(MDRawContextPPC64* ppc64) {
277*9712c20fSFrederick Mayle context_.ppc64 = ppc64;
278*9712c20fSFrederick Mayle }
279*9712c20fSFrederick Mayle
SetContextAMD64(MDRawContextAMD64 * amd64)280*9712c20fSFrederick Mayle void DumpContext::SetContextAMD64(MDRawContextAMD64* amd64) {
281*9712c20fSFrederick Mayle context_.amd64 = amd64;
282*9712c20fSFrederick Mayle }
283*9712c20fSFrederick Mayle
SetContextSPARC(MDRawContextSPARC * ctx_sparc)284*9712c20fSFrederick Mayle void DumpContext::SetContextSPARC(MDRawContextSPARC* ctx_sparc) {
285*9712c20fSFrederick Mayle context_.ctx_sparc = ctx_sparc;
286*9712c20fSFrederick Mayle }
287*9712c20fSFrederick Mayle
SetContextARM(MDRawContextARM * arm)288*9712c20fSFrederick Mayle void DumpContext::SetContextARM(MDRawContextARM* arm) {
289*9712c20fSFrederick Mayle context_.arm = arm;
290*9712c20fSFrederick Mayle }
291*9712c20fSFrederick Mayle
SetContextARM64(MDRawContextARM64 * arm64)292*9712c20fSFrederick Mayle void DumpContext::SetContextARM64(MDRawContextARM64* arm64) {
293*9712c20fSFrederick Mayle context_.arm64 = arm64;
294*9712c20fSFrederick Mayle }
295*9712c20fSFrederick Mayle
SetContextMIPS(MDRawContextMIPS * ctx_mips)296*9712c20fSFrederick Mayle void DumpContext::SetContextMIPS(MDRawContextMIPS* ctx_mips) {
297*9712c20fSFrederick Mayle context_.ctx_mips = ctx_mips;
298*9712c20fSFrederick Mayle }
299*9712c20fSFrederick Mayle
SetContextRISCV(MDRawContextRISCV * riscv)300*9712c20fSFrederick Mayle void DumpContext::SetContextRISCV(MDRawContextRISCV* riscv) {
301*9712c20fSFrederick Mayle context_.riscv = riscv;
302*9712c20fSFrederick Mayle }
303*9712c20fSFrederick Mayle
SetContextRISCV64(MDRawContextRISCV64 * riscv64)304*9712c20fSFrederick Mayle void DumpContext::SetContextRISCV64(MDRawContextRISCV64* riscv64) {
305*9712c20fSFrederick Mayle context_.riscv64 = riscv64;
306*9712c20fSFrederick Mayle }
307*9712c20fSFrederick Mayle
FreeContext()308*9712c20fSFrederick Mayle void DumpContext::FreeContext() {
309*9712c20fSFrederick Mayle switch (GetContextCPU()) {
310*9712c20fSFrederick Mayle case MD_CONTEXT_X86:
311*9712c20fSFrederick Mayle delete context_.x86;
312*9712c20fSFrederick Mayle break;
313*9712c20fSFrederick Mayle
314*9712c20fSFrederick Mayle case MD_CONTEXT_PPC:
315*9712c20fSFrederick Mayle delete context_.ppc;
316*9712c20fSFrederick Mayle break;
317*9712c20fSFrederick Mayle
318*9712c20fSFrederick Mayle case MD_CONTEXT_PPC64:
319*9712c20fSFrederick Mayle delete context_.ppc64;
320*9712c20fSFrederick Mayle break;
321*9712c20fSFrederick Mayle
322*9712c20fSFrederick Mayle case MD_CONTEXT_AMD64:
323*9712c20fSFrederick Mayle delete context_.amd64;
324*9712c20fSFrederick Mayle break;
325*9712c20fSFrederick Mayle
326*9712c20fSFrederick Mayle case MD_CONTEXT_SPARC:
327*9712c20fSFrederick Mayle delete context_.ctx_sparc;
328*9712c20fSFrederick Mayle break;
329*9712c20fSFrederick Mayle
330*9712c20fSFrederick Mayle case MD_CONTEXT_ARM:
331*9712c20fSFrederick Mayle delete context_.arm;
332*9712c20fSFrederick Mayle break;
333*9712c20fSFrederick Mayle
334*9712c20fSFrederick Mayle case MD_CONTEXT_ARM64:
335*9712c20fSFrederick Mayle delete context_.arm64;
336*9712c20fSFrederick Mayle break;
337*9712c20fSFrederick Mayle
338*9712c20fSFrederick Mayle case MD_CONTEXT_MIPS:
339*9712c20fSFrederick Mayle case MD_CONTEXT_MIPS64:
340*9712c20fSFrederick Mayle delete context_.ctx_mips;
341*9712c20fSFrederick Mayle break;
342*9712c20fSFrederick Mayle
343*9712c20fSFrederick Mayle case MD_CONTEXT_RISCV:
344*9712c20fSFrederick Mayle delete context_.riscv;
345*9712c20fSFrederick Mayle break;
346*9712c20fSFrederick Mayle
347*9712c20fSFrederick Mayle case MD_CONTEXT_RISCV64:
348*9712c20fSFrederick Mayle delete context_.riscv64;
349*9712c20fSFrederick Mayle break;
350*9712c20fSFrederick Mayle
351*9712c20fSFrederick Mayle default:
352*9712c20fSFrederick Mayle // There is no context record (valid_ is false) or there's a
353*9712c20fSFrederick Mayle // context record for an unknown CPU (shouldn't happen, only known
354*9712c20fSFrederick Mayle // records are stored by Read).
355*9712c20fSFrederick Mayle break;
356*9712c20fSFrederick Mayle }
357*9712c20fSFrederick Mayle
358*9712c20fSFrederick Mayle context_flags_ = 0;
359*9712c20fSFrederick Mayle context_.base = NULL;
360*9712c20fSFrederick Mayle }
361*9712c20fSFrederick Mayle
Print()362*9712c20fSFrederick Mayle void DumpContext::Print() {
363*9712c20fSFrederick Mayle if (!valid_) {
364*9712c20fSFrederick Mayle BPLOG(ERROR) << "DumpContext cannot print invalid data";
365*9712c20fSFrederick Mayle return;
366*9712c20fSFrederick Mayle }
367*9712c20fSFrederick Mayle
368*9712c20fSFrederick Mayle switch (GetContextCPU()) {
369*9712c20fSFrederick Mayle case MD_CONTEXT_X86: {
370*9712c20fSFrederick Mayle const MDRawContextX86* context_x86 = GetContextX86();
371*9712c20fSFrederick Mayle printf("MDRawContextX86\n");
372*9712c20fSFrederick Mayle printf(" context_flags = 0x%x\n",
373*9712c20fSFrederick Mayle context_x86->context_flags);
374*9712c20fSFrederick Mayle printf(" dr0 = 0x%x\n", context_x86->dr0);
375*9712c20fSFrederick Mayle printf(" dr1 = 0x%x\n", context_x86->dr1);
376*9712c20fSFrederick Mayle printf(" dr2 = 0x%x\n", context_x86->dr2);
377*9712c20fSFrederick Mayle printf(" dr3 = 0x%x\n", context_x86->dr3);
378*9712c20fSFrederick Mayle printf(" dr6 = 0x%x\n", context_x86->dr6);
379*9712c20fSFrederick Mayle printf(" dr7 = 0x%x\n", context_x86->dr7);
380*9712c20fSFrederick Mayle printf(" float_save.control_word = 0x%x\n",
381*9712c20fSFrederick Mayle context_x86->float_save.control_word);
382*9712c20fSFrederick Mayle printf(" float_save.status_word = 0x%x\n",
383*9712c20fSFrederick Mayle context_x86->float_save.status_word);
384*9712c20fSFrederick Mayle printf(" float_save.tag_word = 0x%x\n",
385*9712c20fSFrederick Mayle context_x86->float_save.tag_word);
386*9712c20fSFrederick Mayle printf(" float_save.error_offset = 0x%x\n",
387*9712c20fSFrederick Mayle context_x86->float_save.error_offset);
388*9712c20fSFrederick Mayle printf(" float_save.error_selector = 0x%x\n",
389*9712c20fSFrederick Mayle context_x86->float_save.error_selector);
390*9712c20fSFrederick Mayle printf(" float_save.data_offset = 0x%x\n",
391*9712c20fSFrederick Mayle context_x86->float_save.data_offset);
392*9712c20fSFrederick Mayle printf(" float_save.data_selector = 0x%x\n",
393*9712c20fSFrederick Mayle context_x86->float_save.data_selector);
394*9712c20fSFrederick Mayle printf(" float_save.register_area[%2d] = 0x",
395*9712c20fSFrederick Mayle MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE);
396*9712c20fSFrederick Mayle for (unsigned int register_index = 0;
397*9712c20fSFrederick Mayle register_index < MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE;
398*9712c20fSFrederick Mayle ++register_index) {
399*9712c20fSFrederick Mayle printf("%02x", context_x86->float_save.register_area[register_index]);
400*9712c20fSFrederick Mayle }
401*9712c20fSFrederick Mayle printf("\n");
402*9712c20fSFrederick Mayle printf(" float_save.cr0_npx_state = 0x%x\n",
403*9712c20fSFrederick Mayle context_x86->float_save.cr0_npx_state);
404*9712c20fSFrederick Mayle printf(" gs = 0x%x\n", context_x86->gs);
405*9712c20fSFrederick Mayle printf(" fs = 0x%x\n", context_x86->fs);
406*9712c20fSFrederick Mayle printf(" es = 0x%x\n", context_x86->es);
407*9712c20fSFrederick Mayle printf(" ds = 0x%x\n", context_x86->ds);
408*9712c20fSFrederick Mayle printf(" edi = 0x%x\n", context_x86->edi);
409*9712c20fSFrederick Mayle printf(" esi = 0x%x\n", context_x86->esi);
410*9712c20fSFrederick Mayle printf(" ebx = 0x%x\n", context_x86->ebx);
411*9712c20fSFrederick Mayle printf(" edx = 0x%x\n", context_x86->edx);
412*9712c20fSFrederick Mayle printf(" ecx = 0x%x\n", context_x86->ecx);
413*9712c20fSFrederick Mayle printf(" eax = 0x%x\n", context_x86->eax);
414*9712c20fSFrederick Mayle printf(" ebp = 0x%x\n", context_x86->ebp);
415*9712c20fSFrederick Mayle printf(" eip = 0x%x\n", context_x86->eip);
416*9712c20fSFrederick Mayle printf(" cs = 0x%x\n", context_x86->cs);
417*9712c20fSFrederick Mayle printf(" eflags = 0x%x\n", context_x86->eflags);
418*9712c20fSFrederick Mayle printf(" esp = 0x%x\n", context_x86->esp);
419*9712c20fSFrederick Mayle printf(" ss = 0x%x\n", context_x86->ss);
420*9712c20fSFrederick Mayle printf(" extended_registers[%3d] = 0x",
421*9712c20fSFrederick Mayle MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE);
422*9712c20fSFrederick Mayle for (unsigned int register_index = 0;
423*9712c20fSFrederick Mayle register_index < MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE;
424*9712c20fSFrederick Mayle ++register_index) {
425*9712c20fSFrederick Mayle printf("%02x", context_x86->extended_registers[register_index]);
426*9712c20fSFrederick Mayle }
427*9712c20fSFrederick Mayle printf("\n\n");
428*9712c20fSFrederick Mayle
429*9712c20fSFrederick Mayle break;
430*9712c20fSFrederick Mayle }
431*9712c20fSFrederick Mayle
432*9712c20fSFrederick Mayle case MD_CONTEXT_PPC: {
433*9712c20fSFrederick Mayle const MDRawContextPPC* context_ppc = GetContextPPC();
434*9712c20fSFrederick Mayle printf("MDRawContextPPC\n");
435*9712c20fSFrederick Mayle printf(" context_flags = 0x%x\n",
436*9712c20fSFrederick Mayle context_ppc->context_flags);
437*9712c20fSFrederick Mayle printf(" srr0 = 0x%x\n", context_ppc->srr0);
438*9712c20fSFrederick Mayle printf(" srr1 = 0x%x\n", context_ppc->srr1);
439*9712c20fSFrederick Mayle for (unsigned int gpr_index = 0;
440*9712c20fSFrederick Mayle gpr_index < MD_CONTEXT_PPC_GPR_COUNT;
441*9712c20fSFrederick Mayle ++gpr_index) {
442*9712c20fSFrederick Mayle printf(" gpr[%2d] = 0x%x\n",
443*9712c20fSFrederick Mayle gpr_index, context_ppc->gpr[gpr_index]);
444*9712c20fSFrederick Mayle }
445*9712c20fSFrederick Mayle printf(" cr = 0x%x\n", context_ppc->cr);
446*9712c20fSFrederick Mayle printf(" xer = 0x%x\n", context_ppc->xer);
447*9712c20fSFrederick Mayle printf(" lr = 0x%x\n", context_ppc->lr);
448*9712c20fSFrederick Mayle printf(" ctr = 0x%x\n", context_ppc->ctr);
449*9712c20fSFrederick Mayle printf(" mq = 0x%x\n", context_ppc->mq);
450*9712c20fSFrederick Mayle printf(" vrsave = 0x%x\n", context_ppc->vrsave);
451*9712c20fSFrederick Mayle for (unsigned int fpr_index = 0;
452*9712c20fSFrederick Mayle fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT;
453*9712c20fSFrederick Mayle ++fpr_index) {
454*9712c20fSFrederick Mayle printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n",
455*9712c20fSFrederick Mayle fpr_index, context_ppc->float_save.fpregs[fpr_index]);
456*9712c20fSFrederick Mayle }
457*9712c20fSFrederick Mayle printf(" float_save.fpscr = 0x%x\n",
458*9712c20fSFrederick Mayle context_ppc->float_save.fpscr);
459*9712c20fSFrederick Mayle // TODO(mmentovai): print the 128-bit quantities in
460*9712c20fSFrederick Mayle // context_ppc->vector_save. This isn't done yet because printf
461*9712c20fSFrederick Mayle // doesn't support 128-bit quantities, and printing them using
462*9712c20fSFrederick Mayle // PRIx64 as two 64-bit quantities requires knowledge of the CPU's
463*9712c20fSFrederick Mayle // byte ordering.
464*9712c20fSFrederick Mayle printf(" vector_save.save_vrvalid = 0x%x\n",
465*9712c20fSFrederick Mayle context_ppc->vector_save.save_vrvalid);
466*9712c20fSFrederick Mayle printf("\n");
467*9712c20fSFrederick Mayle
468*9712c20fSFrederick Mayle break;
469*9712c20fSFrederick Mayle }
470*9712c20fSFrederick Mayle
471*9712c20fSFrederick Mayle case MD_CONTEXT_PPC64: {
472*9712c20fSFrederick Mayle const MDRawContextPPC64* context_ppc64 = GetContextPPC64();
473*9712c20fSFrederick Mayle printf("MDRawContextPPC64\n");
474*9712c20fSFrederick Mayle printf(" context_flags = 0x%" PRIx64 "\n",
475*9712c20fSFrederick Mayle context_ppc64->context_flags);
476*9712c20fSFrederick Mayle printf(" srr0 = 0x%" PRIx64 "\n",
477*9712c20fSFrederick Mayle context_ppc64->srr0);
478*9712c20fSFrederick Mayle printf(" srr1 = 0x%" PRIx64 "\n",
479*9712c20fSFrederick Mayle context_ppc64->srr1);
480*9712c20fSFrederick Mayle for (unsigned int gpr_index = 0;
481*9712c20fSFrederick Mayle gpr_index < MD_CONTEXT_PPC64_GPR_COUNT;
482*9712c20fSFrederick Mayle ++gpr_index) {
483*9712c20fSFrederick Mayle printf(" gpr[%2d] = 0x%" PRIx64 "\n",
484*9712c20fSFrederick Mayle gpr_index, context_ppc64->gpr[gpr_index]);
485*9712c20fSFrederick Mayle }
486*9712c20fSFrederick Mayle printf(" cr = 0x%" PRIx64 "\n", context_ppc64->cr);
487*9712c20fSFrederick Mayle printf(" xer = 0x%" PRIx64 "\n",
488*9712c20fSFrederick Mayle context_ppc64->xer);
489*9712c20fSFrederick Mayle printf(" lr = 0x%" PRIx64 "\n", context_ppc64->lr);
490*9712c20fSFrederick Mayle printf(" ctr = 0x%" PRIx64 "\n",
491*9712c20fSFrederick Mayle context_ppc64->ctr);
492*9712c20fSFrederick Mayle printf(" vrsave = 0x%" PRIx64 "\n",
493*9712c20fSFrederick Mayle context_ppc64->vrsave);
494*9712c20fSFrederick Mayle for (unsigned int fpr_index = 0;
495*9712c20fSFrederick Mayle fpr_index < MD_FLOATINGSAVEAREA_PPC_FPR_COUNT;
496*9712c20fSFrederick Mayle ++fpr_index) {
497*9712c20fSFrederick Mayle printf(" float_save.fpregs[%2d] = 0x%" PRIx64 "\n",
498*9712c20fSFrederick Mayle fpr_index, context_ppc64->float_save.fpregs[fpr_index]);
499*9712c20fSFrederick Mayle }
500*9712c20fSFrederick Mayle printf(" float_save.fpscr = 0x%x\n",
501*9712c20fSFrederick Mayle context_ppc64->float_save.fpscr);
502*9712c20fSFrederick Mayle // TODO(mmentovai): print the 128-bit quantities in
503*9712c20fSFrederick Mayle // context_ppc64->vector_save. This isn't done yet because printf
504*9712c20fSFrederick Mayle // doesn't support 128-bit quantities, and printing them using
505*9712c20fSFrederick Mayle // PRIx64 as two 64-bit quantities requires knowledge of the CPU's
506*9712c20fSFrederick Mayle // byte ordering.
507*9712c20fSFrederick Mayle printf(" vector_save.save_vrvalid = 0x%x\n",
508*9712c20fSFrederick Mayle context_ppc64->vector_save.save_vrvalid);
509*9712c20fSFrederick Mayle printf("\n");
510*9712c20fSFrederick Mayle
511*9712c20fSFrederick Mayle break;
512*9712c20fSFrederick Mayle }
513*9712c20fSFrederick Mayle
514*9712c20fSFrederick Mayle case MD_CONTEXT_AMD64: {
515*9712c20fSFrederick Mayle const MDRawContextAMD64* context_amd64 = GetContextAMD64();
516*9712c20fSFrederick Mayle printf("MDRawContextAMD64\n");
517*9712c20fSFrederick Mayle printf(" p1_home = 0x%" PRIx64 "\n",
518*9712c20fSFrederick Mayle context_amd64->p1_home);
519*9712c20fSFrederick Mayle printf(" p2_home = 0x%" PRIx64 "\n",
520*9712c20fSFrederick Mayle context_amd64->p2_home);
521*9712c20fSFrederick Mayle printf(" p3_home = 0x%" PRIx64 "\n",
522*9712c20fSFrederick Mayle context_amd64->p3_home);
523*9712c20fSFrederick Mayle printf(" p4_home = 0x%" PRIx64 "\n",
524*9712c20fSFrederick Mayle context_amd64->p4_home);
525*9712c20fSFrederick Mayle printf(" p5_home = 0x%" PRIx64 "\n",
526*9712c20fSFrederick Mayle context_amd64->p5_home);
527*9712c20fSFrederick Mayle printf(" p6_home = 0x%" PRIx64 "\n",
528*9712c20fSFrederick Mayle context_amd64->p6_home);
529*9712c20fSFrederick Mayle printf(" context_flags = 0x%x\n",
530*9712c20fSFrederick Mayle context_amd64->context_flags);
531*9712c20fSFrederick Mayle printf(" mx_csr = 0x%x\n",
532*9712c20fSFrederick Mayle context_amd64->mx_csr);
533*9712c20fSFrederick Mayle printf(" cs = 0x%x\n", context_amd64->cs);
534*9712c20fSFrederick Mayle printf(" ds = 0x%x\n", context_amd64->ds);
535*9712c20fSFrederick Mayle printf(" es = 0x%x\n", context_amd64->es);
536*9712c20fSFrederick Mayle printf(" fs = 0x%x\n", context_amd64->fs);
537*9712c20fSFrederick Mayle printf(" gs = 0x%x\n", context_amd64->gs);
538*9712c20fSFrederick Mayle printf(" ss = 0x%x\n", context_amd64->ss);
539*9712c20fSFrederick Mayle printf(" eflags = 0x%x\n", context_amd64->eflags);
540*9712c20fSFrederick Mayle printf(" dr0 = 0x%" PRIx64 "\n", context_amd64->dr0);
541*9712c20fSFrederick Mayle printf(" dr1 = 0x%" PRIx64 "\n", context_amd64->dr1);
542*9712c20fSFrederick Mayle printf(" dr2 = 0x%" PRIx64 "\n", context_amd64->dr2);
543*9712c20fSFrederick Mayle printf(" dr3 = 0x%" PRIx64 "\n", context_amd64->dr3);
544*9712c20fSFrederick Mayle printf(" dr6 = 0x%" PRIx64 "\n", context_amd64->dr6);
545*9712c20fSFrederick Mayle printf(" dr7 = 0x%" PRIx64 "\n", context_amd64->dr7);
546*9712c20fSFrederick Mayle printf(" rax = 0x%" PRIx64 "\n", context_amd64->rax);
547*9712c20fSFrederick Mayle printf(" rcx = 0x%" PRIx64 "\n", context_amd64->rcx);
548*9712c20fSFrederick Mayle printf(" rdx = 0x%" PRIx64 "\n", context_amd64->rdx);
549*9712c20fSFrederick Mayle printf(" rbx = 0x%" PRIx64 "\n", context_amd64->rbx);
550*9712c20fSFrederick Mayle printf(" rsp = 0x%" PRIx64 "\n", context_amd64->rsp);
551*9712c20fSFrederick Mayle printf(" rbp = 0x%" PRIx64 "\n", context_amd64->rbp);
552*9712c20fSFrederick Mayle printf(" rsi = 0x%" PRIx64 "\n", context_amd64->rsi);
553*9712c20fSFrederick Mayle printf(" rdi = 0x%" PRIx64 "\n", context_amd64->rdi);
554*9712c20fSFrederick Mayle printf(" r8 = 0x%" PRIx64 "\n", context_amd64->r8);
555*9712c20fSFrederick Mayle printf(" r9 = 0x%" PRIx64 "\n", context_amd64->r9);
556*9712c20fSFrederick Mayle printf(" r10 = 0x%" PRIx64 "\n", context_amd64->r10);
557*9712c20fSFrederick Mayle printf(" r11 = 0x%" PRIx64 "\n", context_amd64->r11);
558*9712c20fSFrederick Mayle printf(" r12 = 0x%" PRIx64 "\n", context_amd64->r12);
559*9712c20fSFrederick Mayle printf(" r13 = 0x%" PRIx64 "\n", context_amd64->r13);
560*9712c20fSFrederick Mayle printf(" r14 = 0x%" PRIx64 "\n", context_amd64->r14);
561*9712c20fSFrederick Mayle printf(" r15 = 0x%" PRIx64 "\n", context_amd64->r15);
562*9712c20fSFrederick Mayle printf(" rip = 0x%" PRIx64 "\n", context_amd64->rip);
563*9712c20fSFrederick Mayle // TODO: print xmm, vector, debug registers
564*9712c20fSFrederick Mayle printf("\n");
565*9712c20fSFrederick Mayle break;
566*9712c20fSFrederick Mayle }
567*9712c20fSFrederick Mayle
568*9712c20fSFrederick Mayle case MD_CONTEXT_SPARC: {
569*9712c20fSFrederick Mayle const MDRawContextSPARC* context_sparc = GetContextSPARC();
570*9712c20fSFrederick Mayle printf("MDRawContextSPARC\n");
571*9712c20fSFrederick Mayle printf(" context_flags = 0x%x\n",
572*9712c20fSFrederick Mayle context_sparc->context_flags);
573*9712c20fSFrederick Mayle for (unsigned int g_r_index = 0;
574*9712c20fSFrederick Mayle g_r_index < MD_CONTEXT_SPARC_GPR_COUNT;
575*9712c20fSFrederick Mayle ++g_r_index) {
576*9712c20fSFrederick Mayle printf(" g_r[%2d] = 0x%" PRIx64 "\n",
577*9712c20fSFrederick Mayle g_r_index, context_sparc->g_r[g_r_index]);
578*9712c20fSFrederick Mayle }
579*9712c20fSFrederick Mayle printf(" ccr = 0x%" PRIx64 "\n", context_sparc->ccr);
580*9712c20fSFrederick Mayle printf(" pc = 0x%" PRIx64 "\n", context_sparc->pc);
581*9712c20fSFrederick Mayle printf(" npc = 0x%" PRIx64 "\n", context_sparc->npc);
582*9712c20fSFrederick Mayle printf(" y = 0x%" PRIx64 "\n", context_sparc->y);
583*9712c20fSFrederick Mayle printf(" asi = 0x%" PRIx64 "\n", context_sparc->asi);
584*9712c20fSFrederick Mayle printf(" fprs = 0x%" PRIx64 "\n", context_sparc->fprs);
585*9712c20fSFrederick Mayle
586*9712c20fSFrederick Mayle for (unsigned int fpr_index = 0;
587*9712c20fSFrederick Mayle fpr_index < MD_FLOATINGSAVEAREA_SPARC_FPR_COUNT;
588*9712c20fSFrederick Mayle ++fpr_index) {
589*9712c20fSFrederick Mayle printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n",
590*9712c20fSFrederick Mayle fpr_index, context_sparc->float_save.regs[fpr_index]);
591*9712c20fSFrederick Mayle }
592*9712c20fSFrederick Mayle printf(" float_save.filler = 0x%" PRIx64 "\n",
593*9712c20fSFrederick Mayle context_sparc->float_save.filler);
594*9712c20fSFrederick Mayle printf(" float_save.fsr = 0x%" PRIx64 "\n",
595*9712c20fSFrederick Mayle context_sparc->float_save.fsr);
596*9712c20fSFrederick Mayle break;
597*9712c20fSFrederick Mayle }
598*9712c20fSFrederick Mayle
599*9712c20fSFrederick Mayle case MD_CONTEXT_ARM: {
600*9712c20fSFrederick Mayle const MDRawContextARM* context_arm = GetContextARM();
601*9712c20fSFrederick Mayle const char * const names[] = {
602*9712c20fSFrederick Mayle "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
603*9712c20fSFrederick Mayle "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
604*9712c20fSFrederick Mayle };
605*9712c20fSFrederick Mayle printf("MDRawContextARM\n");
606*9712c20fSFrederick Mayle printf(" context_flags = 0x%x\n",
607*9712c20fSFrederick Mayle context_arm->context_flags);
608*9712c20fSFrederick Mayle for (unsigned int ireg_index = 0;
609*9712c20fSFrederick Mayle ireg_index < MD_CONTEXT_ARM_GPR_COUNT;
610*9712c20fSFrederick Mayle ++ireg_index) {
611*9712c20fSFrederick Mayle printf(" %-3s = 0x%x\n",
612*9712c20fSFrederick Mayle names[ireg_index], context_arm->iregs[ireg_index]);
613*9712c20fSFrederick Mayle }
614*9712c20fSFrederick Mayle printf(" cpsr = 0x%x\n", context_arm->cpsr);
615*9712c20fSFrederick Mayle printf(" float_save.fpscr = 0x%" PRIx64 "\n",
616*9712c20fSFrederick Mayle context_arm->float_save.fpscr);
617*9712c20fSFrederick Mayle for (unsigned int fpr_index = 0;
618*9712c20fSFrederick Mayle fpr_index < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT;
619*9712c20fSFrederick Mayle ++fpr_index) {
620*9712c20fSFrederick Mayle printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n",
621*9712c20fSFrederick Mayle fpr_index, context_arm->float_save.regs[fpr_index]);
622*9712c20fSFrederick Mayle }
623*9712c20fSFrederick Mayle for (unsigned int fpe_index = 0;
624*9712c20fSFrederick Mayle fpe_index < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT;
625*9712c20fSFrederick Mayle ++fpe_index) {
626*9712c20fSFrederick Mayle printf(" float_save.extra[%2d] = 0x%" PRIx32 "\n",
627*9712c20fSFrederick Mayle fpe_index, context_arm->float_save.extra[fpe_index]);
628*9712c20fSFrederick Mayle }
629*9712c20fSFrederick Mayle
630*9712c20fSFrederick Mayle break;
631*9712c20fSFrederick Mayle }
632*9712c20fSFrederick Mayle
633*9712c20fSFrederick Mayle case MD_CONTEXT_ARM64: {
634*9712c20fSFrederick Mayle const MDRawContextARM64* context_arm64 = GetContextARM64();
635*9712c20fSFrederick Mayle printf("MDRawContextARM64\n");
636*9712c20fSFrederick Mayle printf(" context_flags = 0x%x\n",
637*9712c20fSFrederick Mayle context_arm64->context_flags);
638*9712c20fSFrederick Mayle for (unsigned int ireg_index = 0;
639*9712c20fSFrederick Mayle ireg_index < MD_CONTEXT_ARM64_GPR_COUNT;
640*9712c20fSFrederick Mayle ++ireg_index) {
641*9712c20fSFrederick Mayle printf(" iregs[%2d] = 0x%" PRIx64 "\n",
642*9712c20fSFrederick Mayle ireg_index, context_arm64->iregs[ireg_index]);
643*9712c20fSFrederick Mayle }
644*9712c20fSFrederick Mayle printf(" cpsr = 0x%x\n", context_arm64->cpsr);
645*9712c20fSFrederick Mayle printf(" float_save.fpsr = 0x%x\n", context_arm64->float_save.fpsr);
646*9712c20fSFrederick Mayle printf(" float_save.fpcr = 0x%x\n", context_arm64->float_save.fpcr);
647*9712c20fSFrederick Mayle
648*9712c20fSFrederick Mayle for (unsigned int freg_index = 0;
649*9712c20fSFrederick Mayle freg_index < MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT;
650*9712c20fSFrederick Mayle ++freg_index) {
651*9712c20fSFrederick Mayle uint128_struct fp_value = context_arm64->float_save.regs[freg_index];
652*9712c20fSFrederick Mayle printf(" float_save.regs[%2d] = 0x%" PRIx64 "%" PRIx64 "\n",
653*9712c20fSFrederick Mayle freg_index, fp_value.high, fp_value.low);
654*9712c20fSFrederick Mayle }
655*9712c20fSFrederick Mayle
656*9712c20fSFrederick Mayle break;
657*9712c20fSFrederick Mayle }
658*9712c20fSFrederick Mayle
659*9712c20fSFrederick Mayle case MD_CONTEXT_MIPS:
660*9712c20fSFrederick Mayle case MD_CONTEXT_MIPS64: {
661*9712c20fSFrederick Mayle const MDRawContextMIPS* context_mips = GetContextMIPS();
662*9712c20fSFrederick Mayle printf("MDRawContextMIPS\n");
663*9712c20fSFrederick Mayle printf(" context_flags = 0x%x\n",
664*9712c20fSFrederick Mayle context_mips->context_flags);
665*9712c20fSFrederick Mayle for (int ireg_index = 0;
666*9712c20fSFrederick Mayle ireg_index < MD_CONTEXT_MIPS_GPR_COUNT;
667*9712c20fSFrederick Mayle ++ireg_index) {
668*9712c20fSFrederick Mayle printf(" iregs[%2d] = 0x%" PRIx64 "\n",
669*9712c20fSFrederick Mayle ireg_index, context_mips->iregs[ireg_index]);
670*9712c20fSFrederick Mayle }
671*9712c20fSFrederick Mayle printf(" mdhi = 0x%" PRIx64 "\n",
672*9712c20fSFrederick Mayle context_mips->mdhi);
673*9712c20fSFrederick Mayle printf(" mdlo = 0x%" PRIx64 "\n",
674*9712c20fSFrederick Mayle context_mips->mdhi);
675*9712c20fSFrederick Mayle for (int dsp_index = 0;
676*9712c20fSFrederick Mayle dsp_index < MD_CONTEXT_MIPS_DSP_COUNT;
677*9712c20fSFrederick Mayle ++dsp_index) {
678*9712c20fSFrederick Mayle printf(" hi[%1d] = 0x%" PRIx32 "\n",
679*9712c20fSFrederick Mayle dsp_index, context_mips->hi[dsp_index]);
680*9712c20fSFrederick Mayle printf(" lo[%1d] = 0x%" PRIx32 "\n",
681*9712c20fSFrederick Mayle dsp_index, context_mips->lo[dsp_index]);
682*9712c20fSFrederick Mayle }
683*9712c20fSFrederick Mayle printf(" dsp_control = 0x%" PRIx32 "\n",
684*9712c20fSFrederick Mayle context_mips->dsp_control);
685*9712c20fSFrederick Mayle printf(" epc = 0x%" PRIx64 "\n",
686*9712c20fSFrederick Mayle context_mips->epc);
687*9712c20fSFrederick Mayle printf(" badvaddr = 0x%" PRIx64 "\n",
688*9712c20fSFrederick Mayle context_mips->badvaddr);
689*9712c20fSFrederick Mayle printf(" status = 0x%" PRIx32 "\n",
690*9712c20fSFrederick Mayle context_mips->status);
691*9712c20fSFrederick Mayle printf(" cause = 0x%" PRIx32 "\n",
692*9712c20fSFrederick Mayle context_mips->cause);
693*9712c20fSFrederick Mayle
694*9712c20fSFrederick Mayle for (int fpr_index = 0;
695*9712c20fSFrederick Mayle fpr_index < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT;
696*9712c20fSFrederick Mayle ++fpr_index) {
697*9712c20fSFrederick Mayle printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n",
698*9712c20fSFrederick Mayle fpr_index, context_mips->float_save.regs[fpr_index]);
699*9712c20fSFrederick Mayle }
700*9712c20fSFrederick Mayle printf(" float_save.fpcsr = 0x%" PRIx32 "\n",
701*9712c20fSFrederick Mayle context_mips->float_save.fpcsr);
702*9712c20fSFrederick Mayle printf(" float_save.fir = 0x%" PRIx32 "\n",
703*9712c20fSFrederick Mayle context_mips->float_save.fir);
704*9712c20fSFrederick Mayle break;
705*9712c20fSFrederick Mayle }
706*9712c20fSFrederick Mayle
707*9712c20fSFrederick Mayle case MD_CONTEXT_RISCV: {
708*9712c20fSFrederick Mayle const MDRawContextRISCV* context_riscv = GetContextRISCV();
709*9712c20fSFrederick Mayle printf("MDRawContextRISCV\n");
710*9712c20fSFrederick Mayle printf(" context_flags = 0x%x\n",
711*9712c20fSFrederick Mayle context_riscv->context_flags);
712*9712c20fSFrederick Mayle
713*9712c20fSFrederick Mayle printf(" pc = 0x%" PRIx32 "\n",
714*9712c20fSFrederick Mayle context_riscv->pc);
715*9712c20fSFrederick Mayle printf(" ra = 0x%" PRIx32 "\n",
716*9712c20fSFrederick Mayle context_riscv->ra);
717*9712c20fSFrederick Mayle printf(" sp = 0x%" PRIx32 "\n",
718*9712c20fSFrederick Mayle context_riscv->sp);
719*9712c20fSFrederick Mayle printf(" gp = 0x%" PRIx32 "\n",
720*9712c20fSFrederick Mayle context_riscv->gp);
721*9712c20fSFrederick Mayle printf(" tp = 0x%" PRIx32 "\n",
722*9712c20fSFrederick Mayle context_riscv->tp);
723*9712c20fSFrederick Mayle printf(" t0 = 0x%" PRIx32 "\n",
724*9712c20fSFrederick Mayle context_riscv->t0);
725*9712c20fSFrederick Mayle printf(" t1 = 0x%" PRIx32 "\n",
726*9712c20fSFrederick Mayle context_riscv->t1);
727*9712c20fSFrederick Mayle printf(" t2 = 0x%" PRIx32 "\n",
728*9712c20fSFrederick Mayle context_riscv->t2);
729*9712c20fSFrederick Mayle printf(" s0 = 0x%" PRIx32 "\n",
730*9712c20fSFrederick Mayle context_riscv->s0);
731*9712c20fSFrederick Mayle printf(" s1 = 0x%" PRIx32 "\n",
732*9712c20fSFrederick Mayle context_riscv->s1);
733*9712c20fSFrederick Mayle printf(" a0 = 0x%" PRIx32 "\n",
734*9712c20fSFrederick Mayle context_riscv->a0);
735*9712c20fSFrederick Mayle printf(" a1 = 0x%" PRIx32 "\n",
736*9712c20fSFrederick Mayle context_riscv->a1);
737*9712c20fSFrederick Mayle printf(" a2 = 0x%" PRIx32 "\n",
738*9712c20fSFrederick Mayle context_riscv->a2);
739*9712c20fSFrederick Mayle printf(" a3 = 0x%" PRIx32 "\n",
740*9712c20fSFrederick Mayle context_riscv->a3);
741*9712c20fSFrederick Mayle printf(" a4 = 0x%" PRIx32 "\n",
742*9712c20fSFrederick Mayle context_riscv->a4);
743*9712c20fSFrederick Mayle printf(" a5 = 0x%" PRIx32 "\n",
744*9712c20fSFrederick Mayle context_riscv->a5);
745*9712c20fSFrederick Mayle printf(" a6 = 0x%" PRIx32 "\n",
746*9712c20fSFrederick Mayle context_riscv->a6);
747*9712c20fSFrederick Mayle printf(" a7 = 0x%" PRIx32 "\n",
748*9712c20fSFrederick Mayle context_riscv->a7);
749*9712c20fSFrederick Mayle printf(" s2 = 0x%" PRIx32 "\n",
750*9712c20fSFrederick Mayle context_riscv->s2);
751*9712c20fSFrederick Mayle printf(" s3 = 0x%" PRIx32 "\n",
752*9712c20fSFrederick Mayle context_riscv->s3);
753*9712c20fSFrederick Mayle printf(" s4 = 0x%" PRIx32 "\n",
754*9712c20fSFrederick Mayle context_riscv->s4);
755*9712c20fSFrederick Mayle printf(" s5 = 0x%" PRIx32 "\n",
756*9712c20fSFrederick Mayle context_riscv->s5);
757*9712c20fSFrederick Mayle printf(" s6 = 0x%" PRIx32 "\n",
758*9712c20fSFrederick Mayle context_riscv->s6);
759*9712c20fSFrederick Mayle printf(" s7 = 0x%" PRIx32 "\n",
760*9712c20fSFrederick Mayle context_riscv->s7);
761*9712c20fSFrederick Mayle printf(" s8 = 0x%" PRIx32 "\n",
762*9712c20fSFrederick Mayle context_riscv->s8);
763*9712c20fSFrederick Mayle printf(" s9 = 0x%" PRIx32 "\n",
764*9712c20fSFrederick Mayle context_riscv->s9);
765*9712c20fSFrederick Mayle printf(" s10 = 0x%" PRIx32 "\n",
766*9712c20fSFrederick Mayle context_riscv->s10);
767*9712c20fSFrederick Mayle printf(" s11 = 0x%" PRIx32 "\n",
768*9712c20fSFrederick Mayle context_riscv->s11);
769*9712c20fSFrederick Mayle printf(" t3 = 0x%" PRIx32 "\n",
770*9712c20fSFrederick Mayle context_riscv->t3);
771*9712c20fSFrederick Mayle printf(" t4 = 0x%" PRIx32 "\n",
772*9712c20fSFrederick Mayle context_riscv->t4);
773*9712c20fSFrederick Mayle printf(" t5 = 0x%" PRIx32 "\n",
774*9712c20fSFrederick Mayle context_riscv->t5);
775*9712c20fSFrederick Mayle printf(" t6 = 0x%" PRIx32 "\n",
776*9712c20fSFrederick Mayle context_riscv->t6);
777*9712c20fSFrederick Mayle
778*9712c20fSFrederick Mayle #if defined(__riscv)
779*9712c20fSFrederick Mayle for (unsigned int freg_index = 0; freg_index < MD_CONTEXT_RISCV_FPR_COUNT;
780*9712c20fSFrederick Mayle ++freg_index) {
781*9712c20fSFrederick Mayle // Breakpad only supports RISCV32 with 32 bit floating point.
782*9712c20fSFrederick Mayle uint32_t fp_value = context_riscv->fpregs[freg_index];
783*9712c20fSFrederick Mayle printf(" fpregs[%2d] = 0x%" PRIx32 "\n", freg_index,
784*9712c20fSFrederick Mayle fp_value);
785*9712c20fSFrederick Mayle }
786*9712c20fSFrederick Mayle printf(" fcsr = 0x%" PRIx32 "\n", context_riscv->fcsr);
787*9712c20fSFrederick Mayle #endif
788*9712c20fSFrederick Mayle break;
789*9712c20fSFrederick Mayle }
790*9712c20fSFrederick Mayle
791*9712c20fSFrederick Mayle case MD_CONTEXT_RISCV64: {
792*9712c20fSFrederick Mayle const MDRawContextRISCV64* context_riscv64 = GetContextRISCV64();
793*9712c20fSFrederick Mayle printf("MDRawContextRISCV64\n");
794*9712c20fSFrederick Mayle printf(" context_flags = 0x%x\n",
795*9712c20fSFrederick Mayle context_riscv64->context_flags);
796*9712c20fSFrederick Mayle
797*9712c20fSFrederick Mayle printf(" pc = 0x%" PRIx64 "\n",
798*9712c20fSFrederick Mayle context_riscv64->pc);
799*9712c20fSFrederick Mayle printf(" ra = 0x%" PRIx64 "\n",
800*9712c20fSFrederick Mayle context_riscv64->ra);
801*9712c20fSFrederick Mayle printf(" sp = 0x%" PRIx64 "\n",
802*9712c20fSFrederick Mayle context_riscv64->sp);
803*9712c20fSFrederick Mayle printf(" gp = 0x%" PRIx64 "\n",
804*9712c20fSFrederick Mayle context_riscv64->gp);
805*9712c20fSFrederick Mayle printf(" tp = 0x%" PRIx64 "\n",
806*9712c20fSFrederick Mayle context_riscv64->tp);
807*9712c20fSFrederick Mayle printf(" t0 = 0x%" PRIx64 "\n",
808*9712c20fSFrederick Mayle context_riscv64->t0);
809*9712c20fSFrederick Mayle printf(" t1 = 0x%" PRIx64 "\n",
810*9712c20fSFrederick Mayle context_riscv64->t1);
811*9712c20fSFrederick Mayle printf(" t2 = 0x%" PRIx64 "\n",
812*9712c20fSFrederick Mayle context_riscv64->t2);
813*9712c20fSFrederick Mayle printf(" s0 = 0x%" PRIx64 "\n",
814*9712c20fSFrederick Mayle context_riscv64->s0);
815*9712c20fSFrederick Mayle printf(" s1 = 0x%" PRIx64 "\n",
816*9712c20fSFrederick Mayle context_riscv64->s1);
817*9712c20fSFrederick Mayle printf(" a0 = 0x%" PRIx64 "\n",
818*9712c20fSFrederick Mayle context_riscv64->a0);
819*9712c20fSFrederick Mayle printf(" a1 = 0x%" PRIx64 "\n",
820*9712c20fSFrederick Mayle context_riscv64->a1);
821*9712c20fSFrederick Mayle printf(" a2 = 0x%" PRIx64 "\n",
822*9712c20fSFrederick Mayle context_riscv64->a2);
823*9712c20fSFrederick Mayle printf(" a3 = 0x%" PRIx64 "\n",
824*9712c20fSFrederick Mayle context_riscv64->a3);
825*9712c20fSFrederick Mayle printf(" a4 = 0x%" PRIx64 "\n",
826*9712c20fSFrederick Mayle context_riscv64->a4);
827*9712c20fSFrederick Mayle printf(" a5 = 0x%" PRIx64 "\n",
828*9712c20fSFrederick Mayle context_riscv64->a5);
829*9712c20fSFrederick Mayle printf(" a6 = 0x%" PRIx64 "\n",
830*9712c20fSFrederick Mayle context_riscv64->a6);
831*9712c20fSFrederick Mayle printf(" a7 = 0x%" PRIx64 "\n",
832*9712c20fSFrederick Mayle context_riscv64->a7);
833*9712c20fSFrederick Mayle printf(" s2 = 0x%" PRIx64 "\n",
834*9712c20fSFrederick Mayle context_riscv64->s2);
835*9712c20fSFrederick Mayle printf(" s3 = 0x%" PRIx64 "\n",
836*9712c20fSFrederick Mayle context_riscv64->s3);
837*9712c20fSFrederick Mayle printf(" s4 = 0x%" PRIx64 "\n",
838*9712c20fSFrederick Mayle context_riscv64->s4);
839*9712c20fSFrederick Mayle printf(" s5 = 0x%" PRIx64 "\n",
840*9712c20fSFrederick Mayle context_riscv64->s5);
841*9712c20fSFrederick Mayle printf(" s6 = 0x%" PRIx64 "\n",
842*9712c20fSFrederick Mayle context_riscv64->s6);
843*9712c20fSFrederick Mayle printf(" s7 = 0x%" PRIx64 "\n",
844*9712c20fSFrederick Mayle context_riscv64->s7);
845*9712c20fSFrederick Mayle printf(" s8 = 0x%" PRIx64 "\n",
846*9712c20fSFrederick Mayle context_riscv64->s8);
847*9712c20fSFrederick Mayle printf(" s9 = 0x%" PRIx64 "\n",
848*9712c20fSFrederick Mayle context_riscv64->s9);
849*9712c20fSFrederick Mayle printf(" s10 = 0x%" PRIx64 "\n",
850*9712c20fSFrederick Mayle context_riscv64->s10);
851*9712c20fSFrederick Mayle printf(" s11 = 0x%" PRIx64 "\n",
852*9712c20fSFrederick Mayle context_riscv64->s11);
853*9712c20fSFrederick Mayle printf(" t3 = 0x%" PRIx64 "\n",
854*9712c20fSFrederick Mayle context_riscv64->t3);
855*9712c20fSFrederick Mayle printf(" t4 = 0x%" PRIx64 "\n",
856*9712c20fSFrederick Mayle context_riscv64->t4);
857*9712c20fSFrederick Mayle printf(" t5 = 0x%" PRIx64 "\n",
858*9712c20fSFrederick Mayle context_riscv64->t5);
859*9712c20fSFrederick Mayle printf(" t6 = 0x%" PRIx64 "\n",
860*9712c20fSFrederick Mayle context_riscv64->t6);
861*9712c20fSFrederick Mayle
862*9712c20fSFrederick Mayle #if defined(__riscv)
863*9712c20fSFrederick Mayle for (unsigned int freg_index = 0; freg_index < MD_CONTEXT_RISCV_FPR_COUNT;
864*9712c20fSFrederick Mayle ++freg_index) {
865*9712c20fSFrederick Mayle // Breakpad only supports RISCV64 with 64 bit floating point.
866*9712c20fSFrederick Mayle uint64_t fp_value = context_riscv64->fpregs[freg_index];
867*9712c20fSFrederick Mayle printf(" fpregs[%2d] = 0x%" PRIx64 "\n", freg_index,
868*9712c20fSFrederick Mayle fp_value);
869*9712c20fSFrederick Mayle }
870*9712c20fSFrederick Mayle printf(" fcsr = 0x%" PRIx32 "\n", context_riscv64->fcsr);
871*9712c20fSFrederick Mayle #endif
872*9712c20fSFrederick Mayle break;
873*9712c20fSFrederick Mayle }
874*9712c20fSFrederick Mayle
875*9712c20fSFrederick Mayle default: {
876*9712c20fSFrederick Mayle break;
877*9712c20fSFrederick Mayle }
878*9712c20fSFrederick Mayle }
879*9712c20fSFrederick Mayle }
880*9712c20fSFrederick Mayle
881*9712c20fSFrederick Mayle } // namespace google_breakpad
882