KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
stack.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 arch/dreamcast/include/arch/stack.h
4 (c)2002 Megan Potter
5 (c)2025 Eric Fradella
6
7*/
8
9/** \file arch/stack.h
10 \brief Stack functions
11 \ingroup debugging_stacktrace
12
13 This file contains arch-specific stack implementations, including defining
14 stack sizes and alignments, as well as functions for stack tracing and
15 debugging. On Dreamcast, the stack tracing functions use heuristic stack
16 pointer scanning rather than frame pointer chains, because GCC for SH4
17 does not reliably maintain r14-based frame pointers, even with
18 -fno-omit-frame-pointer.
19
20 \author Megan Potter
21 \author Eric Fradella
22*/
23
24#ifndef __ARCH_STACK_H
25#define __ARCH_STACK_H
26
27#include <kos/cdefs.h>
28__BEGIN_DECLS
29
30#include <stdint.h>
31#include <kos/thread.h>
32
33/** \defgroup debugging_stacktrace Stack Traces
34 \brief API for managing stack backtracing
35 \ingroup debugging
36
37 @{
38*/
39
40#ifndef THD_STACK_ALIGNMENT
41/** \brief Required alignment for stack. */
42#define THD_STACK_ALIGNMENT 8
43#endif
44
45#ifndef THD_STACK_SIZE
46/** \brief Default thread stack size. */
47#define THD_STACK_SIZE 32768
48#endif
49
50#ifndef THD_KERNEL_STACK_SIZE
51/** \brief Main/kernel thread's stack size. */
52#define THD_KERNEL_STACK_SIZE (64 * 1024)
53#endif
54
55/** \brief DC specific "function" to get the return address from the current
56 function.
57
58 \return The return address of the current function.
59*/
60static __always_inline uintptr_t arch_get_ret_addr(void) {
61 uintptr_t pr;
62
63 __asm__ __volatile__("sts pr,%0\n" : "=r"(pr));
64
65 return pr;
66}
67
68/* Please note that all of the following frame pointer macros are ONLY
69 valid if you have compiled your code WITHOUT -fomit-frame-pointer. These
70 are mainly useful for getting a stack trace from an error. */
71
72/** \brief DC specific "function" to get the frame pointer from the current
73 function.
74
75 \return The frame pointer from the current function.
76 \note This only works if you don't disable frame pointers.
77*/
78static __always_inline uintptr_t arch_get_fptr(void) {
79 register uintptr_t fp __asm__("r14");
80
81 return fp;
82}
83
84/** \brief Pass in a frame pointer value to get the return address for the
85 given frame.
86
87 \param fptr The frame pointer to look at.
88 \return The return address of the pointer.
89*/
90static inline uintptr_t arch_fptr_ret_addr(uintptr_t fptr) {
91 return *(uintptr_t *)fptr;
92}
93
94/** \brief Pass in a frame pointer value to get the previous frame pointer for
95 the given frame.
96
97 \param fptr The frame pointer to look at.
98 \return The previous frame pointer.
99*/
100static inline uintptr_t arch_fptr_next(uintptr_t fptr) {
101 return arch_fptr_ret_addr(fptr + 4);
102}
103
104/** \brief Find the next return address by scanning the stack.
105
106 Scans upward from the given stack pointer for saved PR values
107 validated as return addresses from call instructions.
108
109 \param sp Stack pointer to start scanning from.
110 \param ret_addr_out On success, receives the found return address.
111 \param next_sp_out On success, receives the stack position to
112 continue scanning from.
113 \return `true` if a return address was found.
114*/
115bool arch_stk_unwind_step(uintptr_t sp, uintptr_t *ret_addr_out,
116 uintptr_t *next_sp_out);
117
118/** \brief Set up new stack before running.
119
120 This function does nothing as it is unnecessary on Dreamcast.
121
122 \param nt A pointer to the new thread for which a stack
123 is to be set up.
124*/
126
127/** \brief Do a stack trace from the current function.
128
129 This function does a stack trace from the current function, printing the
130 results to stdout. This is used, for instance, when an assertion fails in
131 assert().
132
133 \param n The number of frames to leave off. Each frame is a
134 jump to subroutine or branch to subroutine. assert()
135 leaves off 2 frames, for reference.
136
137 \see arch_stk_trace_at
138*/
139void arch_stk_trace(int n);
140
141/** \brief Do a stack trace from the given stack pointer.
142
143 This function does a stack trace from the specified stack pointer,
144 printing the results to stdout. This could be used for doing something like
145 stack tracing a main thread from inside an IRQ handler.
146
147 \param sp The stack pointer to start scanning from.
148 \param n The number of frames to leave off.
149*/
150void arch_stk_trace_at(uintptr_t sp, size_t n);
151
152/** @} */
153
154__END_DECLS
155
156#endif /* __ARCH_EXEC_H */
Various common macros used throughout the codebase.
static __always_inline uintptr_t arch_get_fptr(void)
DC specific "function" to get the frame pointer from the current function.
Definition stack.h:78
void arch_stk_trace_at(uintptr_t sp, size_t n)
Do a stack trace from the given stack pointer.
static uintptr_t arch_fptr_ret_addr(uintptr_t fptr)
Pass in a frame pointer value to get the return address for the given frame.
Definition stack.h:90
bool arch_stk_unwind_step(uintptr_t sp, uintptr_t *ret_addr_out, uintptr_t *next_sp_out)
Find the next return address by scanning the stack.
static __always_inline uintptr_t arch_get_ret_addr(void)
DC specific "function" to get the return address from the current function.
Definition stack.h:60
void arch_stk_trace(int n)
Do a stack trace from the current function.
static uintptr_t arch_fptr_next(uintptr_t fptr)
Pass in a frame pointer value to get the previous frame pointer for the given frame.
Definition stack.h:100
void arch_stk_setup(kthread_t *nt)
Set up new stack before running.
Structure describing one running thread.
Definition thread.h:168
Threading support.