xref: /linux-6.15/arch/um/kernel/sysrq.c (revision 9d1ee8ce)
1 /*
2  * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3  * Copyright (C) 2013 Richard Weinberger <[email protected]>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9 
10 #include <linux/kallsyms.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/sched.h>
14 #include <asm/sysrq.h>
15 
16 struct stack_frame {
17 	struct stack_frame *next_frame;
18 	unsigned long return_address;
19 };
20 
21 static void print_stack_trace(unsigned long *sp, unsigned long bp)
22 {
23 	int reliable;
24 	unsigned long addr;
25 	struct stack_frame *frame = (struct stack_frame *)bp;
26 
27 	printk(KERN_INFO "Call Trace:\n");
28 	while (((long) sp & (THREAD_SIZE-1)) != 0) {
29 		addr = *sp;
30 		if (__kernel_text_address(addr)) {
31 			reliable = 0;
32 			if ((unsigned long) sp == bp + sizeof(long)) {
33 				frame = frame ? frame->next_frame : NULL;
34 				bp = (unsigned long)frame;
35 				reliable = 1;
36 			}
37 
38 			printk(KERN_INFO " [<%08lx>]", addr);
39 			printk(KERN_CONT " %s", reliable ? "" : "? ");
40 			print_symbol(KERN_CONT "%s", addr);
41 			printk(KERN_CONT "\n");
42 		}
43 		sp++;
44 	}
45 	printk(KERN_INFO "\n");
46 }
47 
48 /*Stolen from arch/i386/kernel/traps.c */
49 static const int kstack_depth_to_print = 24;
50 
51 static unsigned long get_frame_pointer(struct task_struct *task)
52 {
53 	if (!task || task == current)
54 		return current_bp();
55 	else
56 		return KSTK_EBP(task);
57 }
58 
59 void show_stack(struct task_struct *task, unsigned long *stack)
60 {
61 	unsigned long *sp = stack, bp = 0;
62 	int i;
63 
64 #ifdef CONFIG_FRAME_POINTER
65 	bp = get_frame_pointer(task);
66 #endif
67 
68 	if (!stack) {
69 		if (!task || task == current)
70 			sp = current_sp();
71 		else
72 			sp = (unsigned long *)KSTK_ESP(task);
73 	}
74 
75 	printk(KERN_INFO "Stack:\n");
76 	stack = sp;
77 	for (i = 0; i < kstack_depth_to_print; i++) {
78 		if (kstack_end(stack))
79 			break;
80 		if (i && ((i % STACKSLOTS_PER_LINE) == 0))
81 			printk(KERN_CONT "\n");
82 		printk(KERN_CONT " %08lx", *stack++);
83 	}
84 	printk(KERN_CONT "\n");
85 
86 	print_stack_trace(sp, bp);
87 }
88