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
unwind_stack_arm32(struct unwind_state_arm32 * state __unused,vaddr_t stack __unused,size_t stack_size __unused)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
print_stack_arm32(struct unwind_state_arm32 * state __unused,vaddr_t stack __unused,size_t stack_size __unused)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
unwind_stack_arm64(struct unwind_state_arm64 * state __unused,vaddr_t stack __unused,size_t stack_size __unused)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
print_stack_arm64(struct unwind_state_arm64 * state __unused,vaddr_t stack __unused,size_t stack_size __unused)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
unwind_stack_riscv(struct unwind_state_riscv * state __unused,vaddr_t stack __unused,size_t stack_size __unused)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
print_stack_riscv(struct unwind_state_riscv * state __unused,vaddr_t stack __unused,size_t stack_size __unused)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