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