2 * Copyright (C) 2014 Google, Inc.
3 * Author: Colin Cross <ccross@android.com>
4 * Copyright (C) 2010-2015 NVIDIA Corporation. All rights reserved.
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/ptrace.h>
18 #include <asm/stacktrace.h>
20 #include "fiq_debugger_priv.h"
22 static char *mode_name(const struct pt_regs *regs)
24 if (compat_user_mode(regs)) {
27 switch (processor_mode(regs)) {
28 case PSR_MODE_EL0t: return "EL0t";
29 case PSR_MODE_EL1t: return "EL1t";
30 case PSR_MODE_EL1h: return "EL1h";
31 case PSR_MODE_EL2t: return "EL2t";
32 case PSR_MODE_EL2h: return "EL2h";
33 default: return "???";
38 void fiq_debugger_dump_pc(struct fiq_debugger_output *output,
39 const struct pt_regs *regs)
41 output->printf(output, " pc %016lx cpsr %08lx mode %s\n",
42 regs->pc, regs->pstate, mode_name(regs));
45 void fiq_debugger_dump_regs_aarch32(struct fiq_debugger_output *output,
46 const struct pt_regs *regs)
48 output->printf(output, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
49 regs->compat_usr(0), regs->compat_usr(1),
50 regs->compat_usr(2), regs->compat_usr(3));
51 output->printf(output, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
52 regs->compat_usr(4), regs->compat_usr(5),
53 regs->compat_usr(6), regs->compat_usr(7));
54 output->printf(output, " r8 %08x r9 %08x r10 %08x r11 %08x\n",
55 regs->compat_usr(8), regs->compat_usr(9),
56 regs->compat_usr(10), regs->compat_usr(11));
57 output->printf(output, " ip %08x sp %08x lr %08x pc %08x\n",
58 regs->compat_usr(12), regs->compat_sp,
59 regs->compat_lr, regs->pc);
60 output->printf(output, " cpsr %08x (%s)\n",
61 regs->pstate, mode_name(regs));
64 void fiq_debugger_dump_regs_aarch64(struct fiq_debugger_output *output,
65 const struct pt_regs *regs)
68 output->printf(output, " x0 %016lx x1 %016lx\n",
69 regs->regs[0], regs->regs[1]);
70 output->printf(output, " x2 %016lx x3 %016lx\n",
71 regs->regs[2], regs->regs[3]);
72 output->printf(output, " x4 %016lx x5 %016lx\n",
73 regs->regs[4], regs->regs[5]);
74 output->printf(output, " x6 %016lx x7 %016lx\n",
75 regs->regs[6], regs->regs[7]);
76 output->printf(output, " x8 %016lx x9 %016lx\n",
77 regs->regs[8], regs->regs[9]);
78 output->printf(output, " x10 %016lx x11 %016lx\n",
79 regs->regs[10], regs->regs[11]);
80 output->printf(output, " x12 %016lx x13 %016lx\n",
81 regs->regs[12], regs->regs[13]);
82 output->printf(output, " x14 %016lx x15 %016lx\n",
83 regs->regs[14], regs->regs[15]);
84 output->printf(output, " x16 %016lx x17 %016lx\n",
85 regs->regs[16], regs->regs[17]);
86 output->printf(output, " x18 %016lx x19 %016lx\n",
87 regs->regs[18], regs->regs[19]);
88 output->printf(output, " x20 %016lx x21 %016lx\n",
89 regs->regs[20], regs->regs[21]);
90 output->printf(output, " x22 %016lx x23 %016lx\n",
91 regs->regs[22], regs->regs[23]);
92 output->printf(output, " x24 %016lx x25 %016lx\n",
93 regs->regs[24], regs->regs[25]);
94 output->printf(output, " x26 %016lx x27 %016lx\n",
95 regs->regs[26], regs->regs[27]);
96 output->printf(output, " x28 %016lx x29 %016lx\n",
97 regs->regs[28], regs->regs[29]);
98 output->printf(output, " x30 %016lx sp %016lx\n",
99 regs->regs[30], regs->sp);
100 output->printf(output, " pc %016lx cpsr %08x (%s)\n",
101 regs->pc, regs->pstate, mode_name(regs));
104 void fiq_debugger_dump_regs(struct fiq_debugger_output *output,
105 const struct pt_regs *regs)
107 if (compat_user_mode(regs))
108 fiq_debugger_dump_regs_aarch32(output, regs);
110 fiq_debugger_dump_regs_aarch64(output, regs);
113 #define READ_SPECIAL_REG(x) ({ \
115 asm volatile ("mrs %0, " # x : "=r"(val)); \
119 void fiq_debugger_dump_allregs(struct fiq_debugger_output *output,
120 const struct pt_regs *regs)
122 u32 pstate = READ_SPECIAL_REG(CurrentEl);
123 bool in_el2 = (pstate & PSR_MODE_MASK) >= PSR_MODE_EL2t;
125 fiq_debugger_dump_regs(output, regs);
127 output->printf(output, " sp_el0 %016lx\n",
128 READ_SPECIAL_REG(sp_el0));
131 output->printf(output, " sp_el1 %016lx\n",
132 READ_SPECIAL_REG(sp_el1));
134 output->printf(output, " elr_el1 %016lx\n",
135 READ_SPECIAL_REG(elr_el1));
137 output->printf(output, " spsr_el1 %08lx\n",
138 READ_SPECIAL_REG(spsr_el1));
141 output->printf(output, " spsr_irq %08lx\n",
142 READ_SPECIAL_REG(spsr_irq));
143 output->printf(output, " spsr_abt %08lx\n",
144 READ_SPECIAL_REG(spsr_abt));
145 output->printf(output, " spsr_und %08lx\n",
146 READ_SPECIAL_REG(spsr_und));
147 output->printf(output, " spsr_fiq %08lx\n",
148 READ_SPECIAL_REG(spsr_fiq));
149 output->printf(output, " spsr_el2 %08lx\n",
150 READ_SPECIAL_REG(elr_el2));
151 output->printf(output, " spsr_el2 %08lx\n",
152 READ_SPECIAL_REG(spsr_el2));
156 struct stacktrace_state {
157 struct fiq_debugger_output *output;
161 static int report_trace(struct stackframe *frame, void *d)
163 struct stacktrace_state *sts = d;
166 sts->output->printf(sts->output, "%pF:\n", frame->pc);
167 sts->output->printf(sts->output,
168 " pc %016lx sp %016lx fp %016lx\n",
169 frame->pc, frame->sp, frame->fp);
173 sts->output->printf(sts->output, " ...\n");
175 return sts->depth == 0;
178 void fiq_debugger_dump_stacktrace(struct fiq_debugger_output *output,
179 const struct pt_regs *regs, unsigned int depth, void *ssp)
181 struct thread_info *real_thread_info = THREAD_INFO(ssp);
182 struct stacktrace_state sts;
186 *current_thread_info() = *real_thread_info;
189 output->printf(output, "current NULL\n");
191 output->printf(output, "pid: %d comm: %s\n",
192 current->pid, current->comm);
193 fiq_debugger_dump_regs(output, regs);
195 if (!user_mode(regs)) {
196 struct stackframe frame;
197 frame.fp = regs->regs[29];
200 output->printf(output, "\n");
201 walk_stackframe(&frame, report_trace, &sts);