~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sh/kernel/dumpstack.c

Version: ~ [ linux-5.9-rc6 ] ~ [ linux-5.8.10 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.66 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.146 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.198 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.236 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.236 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  Copyright (C) 1991, 1992  Linus Torvalds
  3  *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
  4  *  Copyright (C) 2009  Matt Fleming
  5  *  Copyright (C) 2002 - 2012  Paul Mundt
  6  *
  7  * This file is subject to the terms and conditions of the GNU General Public
  8  * License.  See the file "COPYING" in the main directory of this archive
  9  * for more details.
 10  */
 11 #include <linux/kallsyms.h>
 12 #include <linux/ftrace.h>
 13 #include <linux/debug_locks.h>
 14 #include <linux/sched/debug.h>
 15 #include <linux/sched/task_stack.h>
 16 #include <linux/kdebug.h>
 17 #include <linux/export.h>
 18 #include <linux/uaccess.h>
 19 #include <asm/unwinder.h>
 20 #include <asm/stacktrace.h>
 21 
 22 void dump_mem(const char *str, unsigned long bottom, unsigned long top)
 23 {
 24         unsigned long p;
 25         int i;
 26 
 27         printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
 28 
 29         for (p = bottom & ~31; p < top; ) {
 30                 printk("%04lx: ", p & 0xffff);
 31 
 32                 for (i = 0; i < 8; i++, p += 4) {
 33                         unsigned int val;
 34 
 35                         if (p < bottom || p >= top)
 36                                 printk("         ");
 37                         else {
 38                                 if (__get_user(val, (unsigned int __user *)p)) {
 39                                         printk("\n");
 40                                         return;
 41                                 }
 42                                 printk("%08x ", val);
 43                         }
 44                 }
 45                 printk("\n");
 46         }
 47 }
 48 
 49 void printk_address(unsigned long address, int reliable)
 50 {
 51         printk(" [<%p>] %s%pS\n", (void *) address,
 52                         reliable ? "" : "? ", (void *) address);
 53 }
 54 
 55 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 56 static void
 57 print_ftrace_graph_addr(unsigned long addr, void *data,
 58                         const struct stacktrace_ops *ops,
 59                         struct thread_info *tinfo, int *graph)
 60 {
 61         struct task_struct *task = tinfo->task;
 62         unsigned long ret_addr;
 63         int index = task->curr_ret_stack;
 64 
 65         if (addr != (unsigned long)return_to_handler)
 66                 return;
 67 
 68         if (!task->ret_stack || index < *graph)
 69                 return;
 70 
 71         index -= *graph;
 72         ret_addr = task->ret_stack[index].ret;
 73 
 74         ops->address(data, ret_addr, 1);
 75 
 76         (*graph)++;
 77 }
 78 #else
 79 static inline void
 80 print_ftrace_graph_addr(unsigned long addr, void *data,
 81                         const struct stacktrace_ops *ops,
 82                         struct thread_info *tinfo, int *graph)
 83 { }
 84 #endif
 85 
 86 void
 87 stack_reader_dump(struct task_struct *task, struct pt_regs *regs,
 88                   unsigned long *sp, const struct stacktrace_ops *ops,
 89                   void *data)
 90 {
 91         struct thread_info *context;
 92         int graph = 0;
 93 
 94         context = (struct thread_info *)
 95                 ((unsigned long)sp & (~(THREAD_SIZE - 1)));
 96 
 97         while (!kstack_end(sp)) {
 98                 unsigned long addr = *sp++;
 99 
100                 if (__kernel_text_address(addr)) {
101                         ops->address(data, addr, 1);
102 
103                         print_ftrace_graph_addr(addr, data, ops,
104                                                 context, &graph);
105                 }
106         }
107 }
108 
109 static int print_trace_stack(void *data, char *name)
110 {
111         printk("%s <%s> ", (char *)data, name);
112         return 0;
113 }
114 
115 /*
116  * Print one address/symbol entries per line.
117  */
118 static void print_trace_address(void *data, unsigned long addr, int reliable)
119 {
120         printk("%s", (char *)data);
121         printk_address(addr, reliable);
122 }
123 
124 static const struct stacktrace_ops print_trace_ops = {
125         .stack = print_trace_stack,
126         .address = print_trace_address,
127 };
128 
129 void show_trace(struct task_struct *tsk, unsigned long *sp,
130                 struct pt_regs *regs)
131 {
132         if (regs && user_mode(regs))
133                 return;
134 
135         printk("\nCall trace:\n");
136 
137         unwind_stack(tsk, regs, sp, &print_trace_ops, "");
138 
139         printk("\n");
140 
141         if (!tsk)
142                 tsk = current;
143 
144         debug_show_held_locks(tsk);
145 }
146 
147 void show_stack(struct task_struct *tsk, unsigned long *sp)
148 {
149         unsigned long stack;
150 
151         if (!tsk)
152                 tsk = current;
153         if (tsk == current)
154                 sp = (unsigned long *)current_stack_pointer;
155         else
156                 sp = (unsigned long *)tsk->thread.sp;
157 
158         stack = (unsigned long)sp;
159         dump_mem("Stack: ", stack, THREAD_SIZE +
160                  (unsigned long)task_stack_page(tsk));
161         show_trace(tsk, sp, NULL);
162 }
163 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp