1 /*
2 * Copyright (c) 2020 Google Inc. All rights reserved
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #pragma once
25
26 #ifdef LIB_BACKTRACE_ENABLE
27 #include <kernel/thread.h>
28
29 /**
30 * stack_direction - direction of stack growth
31 *
32 * Stack direction is arch-specific. False if stack grows downwards (i.e.
33 * towards 0), true otherwise.
34 */
35 extern const bool stack_direction;
36
37 /**
38 * struct stack_frame - stack frame of a function call
39 * @frame_addr: address of the current frame on the stack
40 * @fp: pointer to previous frame on the stack
41 * @ret_addr: return address
42 *
43 * There is more stuff in the frame record. However, for the purpose of
44 * backtracing we only need frame pointer and return address.
45 */
46 struct stack_frame {
47 uintptr_t frame_addr;
48 uintptr_t fp;
49 uintptr_t ret_addr;
50 };
51
is_zero_frame(struct stack_frame * frame)52 static inline bool is_zero_frame(struct stack_frame* frame) {
53 return !frame->fp;
54 }
55
56 enum frame_state {
57 FRAME_OK,
58 FRAME_ZERO,
59 FRAME_CORRUPT,
60 FRAME_NON_MONOTONIC,
61 };
62
63 /**
64 * get_current_frame() - get current stack frame
65 * @frame: current frame will be copied into @frame
66 */
67 void get_current_frame(struct stack_frame* frame);
68
69 /**
70 * step_frame() - get next stack frame
71 * @frame: current frame, next frame will written in-place
72 * @user: true if we're traversing a user stack, false if kernel stack
73 *
74 * Return: frame_state, state of the next frame
75 */
76 int step_frame(struct stack_frame* frame, bool user);
77
78 /**
79 * dump_thread_backtrace() - dump backtrace of a given thread
80 * @thread: thread being backtraced
81 */
82 void dump_thread_backtrace(struct thread* thread);
83
84 /**
85 * dump_backtrace() - dump backtrace from current location
86 */
dump_backtrace(void)87 static inline void dump_backtrace(void) {
88 dump_thread_backtrace(get_current_thread());
89 }
90 #else
dump_backtrace(void)91 static void dump_backtrace(void) {}
92 #endif
93