1 /* SPDX-License-Identifier: (BSD-2-Clause AND MIT-CMU) */ 2 /*- 3 * Copyright (c) 2023 Andes Technology Corporation 4 * Copyright (c) 2015-2019, Linaro Limited 5 * Copyright (c) 2000, 2001 Ben Harris 6 * Copyright (c) 1996 Scott K. Stevens 7 * 8 * Mach Operating System 9 * Copyright (c) 1991,1990 Carnegie Mellon University 10 * All Rights Reserved. 11 * 12 * Permission to use, copy, modify and distribute this software and its 13 * documentation is hereby granted, provided that both the copyright 14 * notice and this permission notice appear in all copies of the 15 * software, derivative works or modified versions, and any portions 16 * thereof, and that both notices appear in supporting documentation. 17 * 18 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 19 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 20 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 21 * 22 * Carnegie Mellon requests users of this software to return to 23 * 24 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 25 * School of Computer Science 26 * Carnegie Mellon University 27 * Pittsburgh PA 15213-3890 28 * 29 * any improvements or extensions that they make and grant Carnegie the 30 * rights to redistribute these changes. 31 * 32 * $FreeBSD$ 33 */ 34 35 #ifndef UNW_UNWIND_H 36 #define UNW_UNWIND_H 37 38 #include <compiler.h> 39 #include <types_ext.h> 40 41 /* The state of the unwind process (32-bit mode) */ 42 struct unwind_state_arm32 { 43 uint32_t registers[16]; 44 uint32_t start_pc; 45 vaddr_t insn; 46 unsigned int entries; 47 unsigned int byte; 48 uint16_t update_mask; 49 }; 50 51 #ifdef CFG_UNWIND 52 /* 53 * Unwind a 32-bit stack. 54 * @stack, @stack_size: the bottom of the stack and its size, respectively. 55 * Returns false when there is nothing more to unwind. 56 */ 57 bool unwind_stack_arm32(struct unwind_state_arm32 *state, 58 vaddr_t stack, size_t stack_size); 59 60 void print_stack_arm32(struct unwind_state_arm32 *state, 61 vaddr_t stack, size_t stack_size); 62 #else 63 static inline bool unwind_stack_arm32(struct unwind_state_arm32 *state __unused, 64 vaddr_t stack __unused, 65 size_t stack_size __unused) 66 { 67 return false; 68 } 69 70 static inline void print_stack_arm32(struct unwind_state_arm32 *state __unused, 71 vaddr_t stack __unused, 72 size_t stack_size __unused) 73 { 74 } 75 #endif 76 77 /* 78 * External helper function. Must be implemented by the caller of the 32-bit 79 * stack unwinding functions. 80 */ 81 bool find_exidx(vaddr_t addr, vaddr_t *idx_start, vaddr_t *idx_end); 82 83 /* The state of the unwind process (64-bit mode) */ 84 struct unwind_state_arm64 { 85 uint64_t fp; 86 uint64_t sp; 87 uint64_t pc; 88 }; 89 90 #if defined(ARM64) && defined(CFG_UNWIND) 91 /* 92 * Unwind a 64-bit stack. 93 * @stack, @stack_size: the bottom of the stack and its size, respectively. 94 * Returns false when there is nothing more to unwind. 95 */ 96 bool unwind_stack_arm64(struct unwind_state_arm64 *state, 97 vaddr_t stack, size_t stack_size); 98 99 void print_stack_arm64(struct unwind_state_arm64 *state, 100 vaddr_t stack, size_t stack_size); 101 #else 102 static inline bool unwind_stack_arm64(struct unwind_state_arm64 *state __unused, 103 vaddr_t stack __unused, 104 size_t stack_size __unused) 105 { 106 return false; 107 } 108 109 static inline void print_stack_arm64(struct unwind_state_arm64 *state __unused, 110 vaddr_t stack __unused, 111 size_t stack_size __unused) 112 { 113 } 114 #endif 115 116 /* The state of the unwind process */ 117 struct unwind_state_riscv { 118 unsigned long fp; 119 unsigned long pc; 120 }; 121 122 #if (defined(RV32) || defined(RV64)) && defined(CFG_UNWIND) 123 /* 124 * Unwind stack. 125 * @stack, @stack_size: the bottom of the stack and its size, respectively. 126 * Returns false when there is nothing more to unwind. 127 */ 128 bool unwind_stack_riscv(struct unwind_state_riscv *state, 129 vaddr_t stack, size_t stack_size); 130 131 void print_stack_riscv(struct unwind_state_riscv *state, 132 vaddr_t stack, size_t stack_size); 133 #else 134 static inline bool unwind_stack_riscv(struct unwind_state_riscv *state __unused, 135 vaddr_t stack __unused, 136 size_t stack_size __unused) 137 { 138 return false; 139 } 140 141 static inline void print_stack_riscv(struct unwind_state_riscv *state __unused, 142 vaddr_t stack __unused, 143 size_t stack_size __unused) 144 { 145 } 146 #endif 147 148 /* 149 * External helper function optionally implemented by the caller of the 64-bit 150 * stack unwinding functions. 151 */ 152 void ftrace_map_lr(uint64_t *lr); 153 154 /* Strip out PAuth tags from LR content if applicable */ 155 void pauth_strip_pac(uint64_t *lr); 156 157 #endif /*UNW_UNWIND_H*/ 158