1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Stacktrace support for Hexagon 4 * 5 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 6 */ 7 8 #include <linux/sched.h> 9 #include <linux/sched/task_stack.h> 10 #include <linux/stacktrace.h> 11 #include <linux/thread_info.h> 12 #include <linux/module.h> 13 14 struct stackframe { 15 unsigned long fp; 16 unsigned long rets; 17 }; 18 19 /* 20 * Save stack-backtrace addresses into a stack_trace buffer. 21 */ 22 void save_stack_trace(struct stack_trace *trace) 23 { 24 unsigned long low, high; 25 unsigned long fp; 26 struct stackframe *frame; 27 int skip = trace->skip; 28 29 low = (unsigned long)task_stack_page(current); 30 high = low + THREAD_SIZE; 31 fp = (unsigned long)__builtin_frame_address(0); 32 33 while (fp >= low && fp <= (high - sizeof(*frame))) { 34 frame = (struct stackframe *)fp; 35 36 if (skip) { 37 skip--; 38 } else { 39 trace->entries[trace->nr_entries++] = frame->rets; 40 if (trace->nr_entries >= trace->max_entries) 41 break; 42 } 43 44 /* 45 * The next frame must be at a higher address than the 46 * current frame. 47 */ 48 low = fp + sizeof(*frame); 49 fp = frame->fp; 50 } 51 } 52 EXPORT_SYMBOL_GPL(save_stack_trace); 53