1/* Provide basic stack dumping functions 2 * 3 * Copyright 2004-2009 Analog Devices Inc. 4 * 5 * Licensed under the GPL-2 or later 6 */ 7 8#include <linux/kernel.h> 9#include <linux/thread_info.h> 10#include <linux/mm.h> 11#include <linux/uaccess.h> 12#include <linux/module.h> 13#include <asm/trace.h> 14 15/* 16 * Checks to see if the address pointed to is either a 17 * 16-bit CALL instruction, or a 32-bit CALL instruction 18 */ 19static bool is_bfin_call(unsigned short *addr) 20{ 21 unsigned int opcode; 22 23 if (!get_instruction(&opcode, addr)) 24 return false; 25 26 if ((opcode >= 0x0060 && opcode <= 0x0067) || 27 (opcode >= 0x0070 && opcode <= 0x0077) || 28 (opcode >= 0xE3000000 && opcode <= 0xE3FFFFFF)) 29 return true; 30 31 return false; 32 33} 34 35void show_stack(struct task_struct *task, unsigned long *stack) 36{ 37#ifdef CONFIG_PRINTK 38 unsigned int *addr, *endstack, *fp = 0, *frame; 39 unsigned short *ins_addr; 40 char buf[150]; 41 unsigned int i, j, ret_addr, frame_no = 0; 42 43 /* 44 * If we have been passed a specific stack, use that one otherwise 45 * if we have been passed a task structure, use that, otherwise 46 * use the stack of where the variable "stack" exists 47 */ 48 49 if (stack == NULL) { 50 if (task) { 51 /* We know this is a kernel stack, so this is the start/end */ 52 stack = (unsigned long *)task->thread.ksp; 53 endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); 54 } else { 55 /* print out the existing stack info */ 56 stack = (unsigned long *)&stack; 57 endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 58 } 59 } else 60 endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 61 62 printk(KERN_NOTICE "Stack info:\n"); 63 decode_address(buf, (unsigned int)stack); 64 printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); 65 66 if (!access_ok(VERIFY_READ, stack, (unsigned int)endstack - (unsigned int)stack)) { 67 printk(KERN_NOTICE "Invalid stack pointer\n"); 68 return; 69 } 70 71 /* First thing is to look for a frame pointer */ 72 for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { 73 if (*addr & 0x1) 74 continue; 75 ins_addr = (unsigned short *)*addr; 76 ins_addr--; 77 if (is_bfin_call(ins_addr)) 78 fp = addr - 1; 79 80 if (fp) { 81 /* Let's check to see if it is a frame pointer */ 82 while (fp >= (addr - 1) && fp < endstack 83 && fp && ((unsigned int) fp & 0x3) == 0) 84 fp = (unsigned int *)*fp; 85 if (fp == 0 || fp == endstack) { 86 fp = addr - 1; 87 break; 88 } 89 fp = 0; 90 } 91 } 92 if (fp) { 93 frame = fp; 94 printk(KERN_NOTICE " FP: (0x%p)\n", fp); 95 } else 96 frame = 0; 97 98 /* 99 * Now that we think we know where things are, we 100 * walk the stack again, this time printing things out 101 * incase there is no frame pointer, we still look for 102 * valid return addresses 103 */ 104 105 /* First time print out data, next time, print out symbols */ 106 for (j = 0; j <= 1; j++) { 107 if (j) 108 printk(KERN_NOTICE "Return addresses in stack:\n"); 109 else 110 printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); 111 112 fp = frame; 113 frame_no = 0; 114 115 for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; 116 addr < endstack; addr++, i++) { 117 118 ret_addr = 0; 119 if (!j && i % 8 == 0) 120 printk(KERN_NOTICE "%p:", addr); 121 122 /* if it is an odd address, or zero, just skip it */ 123 if (*addr & 0x1 || !*addr) 124 goto print; 125 126 ins_addr = (unsigned short *)*addr; 127 128 /* Go back one instruction, and see if it is a CALL */ 129 ins_addr--; 130 ret_addr = is_bfin_call(ins_addr); 131 print: 132 if (!j && stack == (unsigned long *)addr) 133 printk("[%08x]", *addr); 134 else if (ret_addr) 135 if (j) { 136 decode_address(buf, (unsigned int)*addr); 137 if (frame == addr) { 138 printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); 139 continue; 140 } 141 printk(KERN_NOTICE " address : %s\n", buf); 142 } else 143 printk("<%08x>", *addr); 144 else if (fp == addr) { 145 if (j) 146 frame = addr+1; 147 else 148 printk("(%08x)", *addr); 149 150 fp = (unsigned int *)*addr; 151 frame_no++; 152 153 } else if (!j) 154 printk(" %08x ", *addr); 155 } 156 if (!j) 157 printk("\n"); 158 } 159#endif 160} 161EXPORT_SYMBOL(show_stack); 162 163void dump_stack(void) 164{ 165 unsigned long stack; 166#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 167 int tflags; 168#endif 169 trace_buffer_save(tflags); 170 dump_bfin_trace_buffer(); 171 dump_stack_print_info(KERN_DEFAULT); 172 show_stack(current, &stack); 173 trace_buffer_restore(tflags); 174} 175EXPORT_SYMBOL(dump_stack); 176