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