From: kosmirror <kos...@us...> - 2025-06-22 23:58:19
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 3de8ac8f710ab4456c5abe5230c6615074fadb4f (commit) via fc1a6a049a86e5a8f5e163f14022961ca03199b7 (commit) via a1a315e9b828e2eda03beb236e771a6254e49482 (commit) via ac0c6ff2e5db4a971de79f671f109e60415d5ab4 (commit) from 50322ad313f8c46db7e1aa1391a153ae14f9f003 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3de8ac8f710ab4456c5abe5230c6615074fadb4f Author: QuzarDC <qu...@co...> Date: Sat Jun 7 15:23:36 2025 -0400 Apply noinline if we expect a function call for stack tracing. In the examples, ensure that the functions we are stack tracing are not inlined as it would defeat the purpose of the example. Inside the stack tracing functions and assert, there are assumptions made that we are going back by fixed numbers of frame pointers, so avoid inlining as that would the intended tracing. commit fc1a6a049a86e5a8f5e163f14022961ca03199b7 Author: QuzarDC <qu...@co...> Date: Sat Jun 7 13:54:47 2025 -0400 arch: Mark register access inlines as `always_inline` The behavior of these would break if the function call is not inlined, so ensure that they are always inlined. commit a1a315e9b828e2eda03beb236e771a6254e49482 Author: QuzarDC <qu...@co...> Date: Sat Jun 7 13:43:55 2025 -0400 irq: Don't deref fp twice. In #600 there was a change to store `arch_fptr_ret_addr` as it was being tested as valid before being printed. Unfortunately this was done in a way that overwrote the current fp being worked on. So when it came time to pass it to `arch_fptr_next` another layer of deference was happening. commit ac0c6ff2e5db4a971de79f671f109e60415d5ab4 Author: QuzarDC <qu...@co...> Date: Sat Jun 7 13:06:27 2025 -0400 stack: Don't deref fp twice. In #600 there was a change to store `arch_fptr_ret_addr` as it was being tested as valid before being printed. Unfortunately this was done in a way that overwrote the current fp being worked on. So when it came time to pass it to `arch_fptr_next` another layer of deference was happening. ----------------------------------------------------------------------- Summary of changes: examples/dreamcast/basic/asserthnd/asserthnd.c | 8 ++++++-- examples/dreamcast/basic/stacktrace/stacktrace.c | 6 +++++- kernel/arch/dreamcast/include/arch/arch.h | 4 ++-- kernel/arch/dreamcast/kernel/irq.c | 9 +++++---- kernel/arch/dreamcast/kernel/stack.c | 15 ++++++++------- kernel/libc/koslib/assert.c | 2 +- 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/examples/dreamcast/basic/asserthnd/asserthnd.c b/examples/dreamcast/basic/asserthnd/asserthnd.c index a0a06a60..abe486dd 100644 --- a/examples/dreamcast/basic/asserthnd/asserthnd.c +++ b/examples/dreamcast/basic/asserthnd/asserthnd.c @@ -35,14 +35,18 @@ assuming you compiled your program with -g: */ -void func2(void) { +/* These are marked as __noinline to ensure the compiler + doesn't try to get smart and inline them which would + defeat the purpose of the example. +*/ +__noinline void func2(void) { int a = 5; assert_msg(a != 5, "This is a test message!"); assert(a != 5); } -void func1(void) { +__noinline void func1(void) { func2(); } diff --git a/examples/dreamcast/basic/stacktrace/stacktrace.c b/examples/dreamcast/basic/stacktrace/stacktrace.c index 74eaa1f7..67051a9b 100644 --- a/examples/dreamcast/basic/stacktrace/stacktrace.c +++ b/examples/dreamcast/basic/stacktrace/stacktrace.c @@ -6,7 +6,11 @@ #include <kos.h> -void func(void) { +/* This is marked as __noinline to ensure the compiler + doesn't try to get smart and inline it which would + defeat the purpose of the example. +*/ +__noinline void func(void) { arch_stk_trace(0); } diff --git a/kernel/arch/dreamcast/include/arch/arch.h b/kernel/arch/dreamcast/include/arch/arch.h index b26d9ea3..f79915de 100644 --- a/kernel/arch/dreamcast/include/arch/arch.h +++ b/kernel/arch/dreamcast/include/arch/arch.h @@ -367,7 +367,7 @@ static inline void arch_sleep(void) { \return The return address of the current function. */ -static inline uintptr_t arch_get_ret_addr(void) { +static __always_inline uintptr_t arch_get_ret_addr(void) { uintptr_t pr; __asm__ __volatile__("sts pr,%0\n" : "=r"(pr)); @@ -386,7 +386,7 @@ static inline uintptr_t arch_get_ret_addr(void) { \return The frame pointer from the current function. \note This only works if you don't disable frame pointers. */ -static inline uintptr_t arch_get_fptr(void) { +static __always_inline uintptr_t arch_get_fptr(void) { register uintptr_t fp __asm__("r14"); return fp; diff --git a/kernel/arch/dreamcast/kernel/irq.c b/kernel/arch/dreamcast/kernel/irq.c index 6201e93b..a7b4c127 100644 --- a/kernel/arch/dreamcast/kernel/irq.c +++ b/kernel/arch/dreamcast/kernel/irq.c @@ -153,8 +153,9 @@ static char *irq_exception_string(irq_t evt) { /* Print a kernel panic reg dump */ extern irq_context_t *irq_srt_addr; -static void irq_dump_regs(int code, irq_t evt) { +void irq_dump_regs(int code, irq_t evt) { uint32_t fp; + uint32_t ret_addr; uint32_t *regs = irq_srt_addr->r; bool valid_pc; bool valid_pr; @@ -191,13 +192,13 @@ static void irq_dump_regs(int code, irq_t evt) { break; /* Get the return address from the function pointer */ - fp = arch_fptr_ret_addr(fp); + ret_addr = arch_fptr_ret_addr(fp); /* Validate the return address */ - if(!arch_valid_text_address(fp)) + if(!arch_valid_text_address(ret_addr)) break; - dbglog(DBG_DEAD, " %08lx", fp); + dbglog(DBG_DEAD, " %08lx", ret_addr); fp = arch_fptr_next(fp); } } diff --git a/kernel/arch/dreamcast/kernel/stack.c b/kernel/arch/dreamcast/kernel/stack.c index 1883a1da..31dffb16 100644 --- a/kernel/arch/dreamcast/kernel/stack.c +++ b/kernel/arch/dreamcast/kernel/stack.c @@ -25,13 +25,14 @@ extern uintptr_t arch_stack_32m __attribute__((weak,alias("arch_stack_32m_dft")) /* Do a stack trace from the current function; leave off the first n frames (i.e., in assert()). */ -void arch_stk_trace(int n) { +__noinline void arch_stk_trace(int n) { arch_stk_trace_at(arch_get_fptr(), n + 1); } /* Do a stack trace from the given frame pointer (useful for things like tracing from an ISR); leave off the first n frames. */ void arch_stk_trace_at(uint32_t fp, size_t n) { + uint32_t ret_addr; if(!__is_defined(FRAME_POINTERS)) { dbgio_printf("Stack Trace: frame pointers not enabled!\n"); return; @@ -42,20 +43,20 @@ void arch_stk_trace_at(uint32_t fp, size_t n) { while(fp != 0xffffffff) { /* Validate the function pointer (fp) */ if((fp & 3) || (fp < 0x8c000000) || (fp > _arch_mem_top)) { - dbgio_printf(" (invalid frame pointer)\n"); + dbgio_printf(" %08lx (invalid frame pointer)\n", fp); break; } - + if(n == 0) { /* Get the return address from the function pointer */ - fp = arch_fptr_ret_addr(fp); + ret_addr = arch_fptr_ret_addr(fp); /* Validate the return address */ - if(!arch_valid_address(fp)) { - dbgio_printf(" %08lx (invalid return address)\n", fp); + if(!arch_valid_address(ret_addr)) { + dbgio_printf(" %08lx (invalid return address)\n", ret_addr); break; } else - dbgio_printf(" %08lx\n", fp); + dbgio_printf(" %08lx\n", ret_addr); } else n--; diff --git a/kernel/libc/koslib/assert.c b/kernel/libc/koslib/assert.c index fdf8c2a6..ca610448 100644 --- a/kernel/libc/koslib/assert.c +++ b/kernel/libc/koslib/assert.c @@ -16,7 +16,7 @@ #include <arch/stack.h> /* The default assert handler */ -static void __noreturn assert_handler_default(const char *file, int line, +__noinline static void __noreturn assert_handler_default(const char *file, int line, const char *expr, const char *msg, const char *func) { dbglog(DBG_CRITICAL, "\n*** ASSERTION FAILURE ***\n"); hooks/post-receive -- A pseudo Operating System for the Dreamcast. |