1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * arch/arm64/kernel/return_address.c 4 * 5 * Copyright (C) 2013 Linaro Limited 6 * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> 7 */ 8 9 #include <linux/export.h> 10 #include <linux/ftrace.h> 11 #include <linux/kprobes.h> 12 13 #include <asm/stack_pointer.h> 14 #include <asm/stacktrace.h> 15 16 struct return_address_data { 17 unsigned int level; 18 void *addr; 19 }; 20 save_return_addr(void * d,unsigned long pc)21static bool save_return_addr(void *d, unsigned long pc) 22 { 23 struct return_address_data *data = d; 24 25 if (!data->level) { 26 data->addr = (void *)pc; 27 return false; 28 } else { 29 --data->level; 30 return true; 31 } 32 } 33 NOKPROBE_SYMBOL(save_return_addr); 34 return_address(unsigned int level)35void *return_address(unsigned int level) 36 { 37 struct return_address_data data; 38 struct stackframe frame; 39 40 data.level = level + 2; 41 data.addr = NULL; 42 43 start_backtrace(&frame, 44 (unsigned long)__builtin_frame_address(0), 45 (unsigned long)return_address); 46 walk_stackframe(current, &frame, save_return_addr, &data); 47 48 if (!data.level) 49 return data.addr; 50 else 51 return NULL; 52 } 53 EXPORT_SYMBOL_GPL(return_address); 54 NOKPROBE_SYMBOL(return_address); 55