1 /* 2 * arch/sh/kernel/return_address.c 3 * 4 * Copyright (C) 2009 Matt Fleming 5 * Copyright (C) 2009 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/kernel.h> 12 #include <linux/module.h> 13 #include <asm/dwarf.h> 14 15 #ifdef CONFIG_DWARF_UNWINDER 16 return_address(unsigned int depth)17void *return_address(unsigned int depth) 18 { 19 struct dwarf_frame *frame; 20 unsigned long ra; 21 int i; 22 23 for (i = 0, frame = NULL, ra = 0; i <= depth; i++) { 24 struct dwarf_frame *tmp; 25 26 tmp = dwarf_unwind_stack(ra, frame); 27 if (!tmp) 28 return NULL; 29 30 if (frame) 31 dwarf_free_frame(frame); 32 33 frame = tmp; 34 35 if (!frame || !frame->return_addr) 36 break; 37 38 ra = frame->return_addr; 39 } 40 41 /* Failed to unwind the stack to the specified depth. */ 42 WARN_ON(i != depth + 1); 43 44 if (frame) 45 dwarf_free_frame(frame); 46 47 return (void *)ra; 48 } 49 50 #else 51 return_address(unsigned int depth)52void *return_address(unsigned int depth) 53 { 54 return NULL; 55 } 56 57 #endif 58 59 EXPORT_SYMBOL_GPL(return_address); 60