1 #include <linux/kernel.h>
5 #define MAJOR_OP 0xfc000000
6 #define LDA_OP 0x20000000
7 #define STQ_OP 0xb4000000
8 #define BR_OP 0xc0000000
10 #define STK_ALLOC_1 0x23de8000
11 #define STK_ALLOC_1M 0xffff8000
12 #define STK_ALLOC_2 0x43c0153e
13 #define STK_ALLOC_2M 0xffe01fff
15 #define MEM_REG 0x03e00000
16 #define MEM_BASE 0x001f0000
17 #define MEM_OFF 0x0000ffff
18 #define MEM_OFF_SIGN 0x00008000
19 #define BASE_SP 0x001e0000
21 #define STK_ALLOC_MATCH(INSTR) \
22 (((INSTR) & STK_ALLOC_1M) == STK_ALLOC_1 \
23 || ((INSTR) & STK_ALLOC_2M) == STK_ALLOC_2)
24 #define STK_PUSH_MATCH(INSTR) \
25 (((INSTR) & (MAJOR_OP | MEM_BASE | MEM_OFF_SIGN)) == (STQ_OP | BASE_SP))
26 #define MEM_OP_OFFSET(INSTR) \
27 (((long)((INSTR) & MEM_OFF) << 48) >> 48)
28 #define MEM_OP_REG(INSTR) \
29 (((INSTR) & MEM_REG) >> 22)
32 #define BB_END(INSTR) \
33 (((instr)(INSTR) >= BR_OP) | ((instr)(INSTR) < LDA_OP) | \
34 ((((instr)(INSTR) ^ 0x60000000) < 0x20000000) & \
35 (((instr)(INSTR) & 0x0c000000) != 0)))
37 #define IS_KERNEL_TEXT(PC) ((unsigned long)(PC) > START_ADDR)
40 "v0 ",
"t0 ",
"t1 ",
"t2 ",
"t3 ",
"t4 ",
"t5 ",
"t6 ",
"t7 ",
41 "s0 ",
"s1 ",
"s2 ",
"s3 ",
"s4 ",
"s5 ",
"s6 ",
"a0 ",
"a1 ",
42 "a2 ",
"a3 ",
"a4 ",
"a5 ",
"t8 ",
"t9 ",
"t10",
"t11",
"ra ",
43 "pv ",
"at ",
"gp ",
"sp ",
"0"
48 display_stored_regs(
instr * pro_pc,
unsigned char *
sp)
54 printk(
"Prologue [<%p>], Frame %p:\n", pro_pc, sp);
57 reg = (*pro_pc &
MEM_REG) >> 21;
58 value = *(
unsigned long *)(sp + (*pro_pc &
MEM_OFF));
60 ret_pc = (
instr *)value;
77 stack_increment(
instr * prologue_pc)
84 return -(((
long)(*prologue_pc) << 48) >> 48);
86 return (*prologue_pc >> 13) & 0xff;
94 register unsigned char * sp
__asm__ (
"$30");
96 printk(
"\tstack trace:\n");
98 ret_pc = display_stored_regs(prologue, sp);
99 sp += stack_increment(prologue);
100 prologue = seek_prologue(ret_pc);