xref: /linux/arch/x86/um/sysrq_32.c (revision 5c48b108ecbf6505d929e64d50dace13ac2bdf34)
1*5c48b108SAl Viro /*
2*5c48b108SAl Viro  * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
3*5c48b108SAl Viro  * Licensed under the GPL
4*5c48b108SAl Viro  */
5*5c48b108SAl Viro 
6*5c48b108SAl Viro #include "linux/kernel.h"
7*5c48b108SAl Viro #include "linux/smp.h"
8*5c48b108SAl Viro #include "linux/sched.h"
9*5c48b108SAl Viro #include "linux/kallsyms.h"
10*5c48b108SAl Viro #include "asm/ptrace.h"
11*5c48b108SAl Viro #include "sysrq.h"
12*5c48b108SAl Viro 
13*5c48b108SAl Viro /* This is declared by <linux/sched.h> */
14*5c48b108SAl Viro void show_regs(struct pt_regs *regs)
15*5c48b108SAl Viro {
16*5c48b108SAl Viro         printk("\n");
17*5c48b108SAl Viro         printk("EIP: %04lx:[<%08lx>] CPU: %d %s",
18*5c48b108SAl Viro 	       0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs),
19*5c48b108SAl Viro 	       smp_processor_id(), print_tainted());
20*5c48b108SAl Viro         if (PT_REGS_CS(regs) & 3)
21*5c48b108SAl Viro                 printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs),
22*5c48b108SAl Viro 		       PT_REGS_SP(regs));
23*5c48b108SAl Viro         printk(" EFLAGS: %08lx\n    %s\n", PT_REGS_EFLAGS(regs),
24*5c48b108SAl Viro 	       print_tainted());
25*5c48b108SAl Viro         printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
26*5c48b108SAl Viro                 PT_REGS_EAX(regs), PT_REGS_EBX(regs),
27*5c48b108SAl Viro 	       PT_REGS_ECX(regs),
28*5c48b108SAl Viro 	       PT_REGS_EDX(regs));
29*5c48b108SAl Viro         printk("ESI: %08lx EDI: %08lx EBP: %08lx",
30*5c48b108SAl Viro 	       PT_REGS_ESI(regs), PT_REGS_EDI(regs),
31*5c48b108SAl Viro 	       PT_REGS_EBP(regs));
32*5c48b108SAl Viro         printk(" DS: %04lx ES: %04lx\n",
33*5c48b108SAl Viro 	       0xffff & PT_REGS_DS(regs),
34*5c48b108SAl Viro 	       0xffff & PT_REGS_ES(regs));
35*5c48b108SAl Viro 
36*5c48b108SAl Viro         show_trace(NULL, (unsigned long *) &regs);
37*5c48b108SAl Viro }
38*5c48b108SAl Viro 
39*5c48b108SAl Viro /* Copied from i386. */
40*5c48b108SAl Viro static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
41*5c48b108SAl Viro {
42*5c48b108SAl Viro 	return	p > (void *)tinfo &&
43*5c48b108SAl Viro 		p < (void *)tinfo + THREAD_SIZE - 3;
44*5c48b108SAl Viro }
45*5c48b108SAl Viro 
46*5c48b108SAl Viro /* Adapted from i386 (we also print the address we read from). */
47*5c48b108SAl Viro static inline unsigned long print_context_stack(struct thread_info *tinfo,
48*5c48b108SAl Viro 				unsigned long *stack, unsigned long ebp)
49*5c48b108SAl Viro {
50*5c48b108SAl Viro 	unsigned long addr;
51*5c48b108SAl Viro 
52*5c48b108SAl Viro #ifdef CONFIG_FRAME_POINTER
53*5c48b108SAl Viro 	while (valid_stack_ptr(tinfo, (void *)ebp)) {
54*5c48b108SAl Viro 		addr = *(unsigned long *)(ebp + 4);
55*5c48b108SAl Viro 		printk("%08lx:  [<%08lx>]", ebp + 4, addr);
56*5c48b108SAl Viro 		print_symbol(" %s", addr);
57*5c48b108SAl Viro 		printk("\n");
58*5c48b108SAl Viro 		ebp = *(unsigned long *)ebp;
59*5c48b108SAl Viro 	}
60*5c48b108SAl Viro #else
61*5c48b108SAl Viro 	while (valid_stack_ptr(tinfo, stack)) {
62*5c48b108SAl Viro 		addr = *stack;
63*5c48b108SAl Viro 		if (__kernel_text_address(addr)) {
64*5c48b108SAl Viro 			printk("%08lx:  [<%08lx>]", (unsigned long) stack, addr);
65*5c48b108SAl Viro 			print_symbol(" %s", addr);
66*5c48b108SAl Viro 			printk("\n");
67*5c48b108SAl Viro 		}
68*5c48b108SAl Viro 		stack++;
69*5c48b108SAl Viro 	}
70*5c48b108SAl Viro #endif
71*5c48b108SAl Viro 	return ebp;
72*5c48b108SAl Viro }
73*5c48b108SAl Viro 
74*5c48b108SAl Viro void show_trace(struct task_struct* task, unsigned long * stack)
75*5c48b108SAl Viro {
76*5c48b108SAl Viro 	unsigned long ebp;
77*5c48b108SAl Viro 	struct thread_info *context;
78*5c48b108SAl Viro 
79*5c48b108SAl Viro 	/* Turn this into BUG_ON if possible. */
80*5c48b108SAl Viro 	if (!stack) {
81*5c48b108SAl Viro 		stack = (unsigned long*) &stack;
82*5c48b108SAl Viro 		printk("show_trace: got NULL stack, implicit assumption task == current");
83*5c48b108SAl Viro 		WARN_ON(1);
84*5c48b108SAl Viro 	}
85*5c48b108SAl Viro 
86*5c48b108SAl Viro 	if (!task)
87*5c48b108SAl Viro 		task = current;
88*5c48b108SAl Viro 
89*5c48b108SAl Viro 	if (task != current) {
90*5c48b108SAl Viro 		ebp = (unsigned long) KSTK_EBP(task);
91*5c48b108SAl Viro 	} else {
92*5c48b108SAl Viro 		asm ("movl %%ebp, %0" : "=r" (ebp) : );
93*5c48b108SAl Viro 	}
94*5c48b108SAl Viro 
95*5c48b108SAl Viro 	context = (struct thread_info *)
96*5c48b108SAl Viro 		((unsigned long)stack & (~(THREAD_SIZE - 1)));
97*5c48b108SAl Viro 	print_context_stack(context, stack, ebp);
98*5c48b108SAl Viro 
99*5c48b108SAl Viro 	printk("\n");
100*5c48b108SAl Viro }
101*5c48b108SAl Viro 
102