From 1adf4740c77d67bdb51409f7d376183fe07b3985 Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 15 Jan 2024 18:36:59 +0100 Subject: [PATCH] wutnewlib: implement abort, assert and assert_func (#337) * wutnewlib: implement abort, assert and assert_func * wut_newlib: Trigger trap instruction on assert/abort * wut_newlib: Replace snprintf with cafe-os equivalent. --- libraries/wutnewlib/wut_newlib.c | 68 ++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/libraries/wutnewlib/wut_newlib.c b/libraries/wutnewlib/wut_newlib.c index e13bd601b..0e19d45fd 100644 --- a/libraries/wutnewlib/wut_newlib.c +++ b/libraries/wutnewlib/wut_newlib.c @@ -1,9 +1,77 @@ #include "wut_newlib.h" #include +#include +#include +#include +#include void(*__wut_exit)(int rc); extern void __fini_wut(void); +void __attribute__((weak)) +abort(void) { + const char *error_text = "Abort called.\n"; + if (OSIsDebuggerPresent()) { + __asm__ __volatile__("mr 3, %0\n" // load 'tmp' into r3 + "tw 0x1f, 31, 31" // DBGSTR_INSTRUCTION + : + : "r"(error_text) + : "r3"); + } + OSFatal(error_text); + /* NOTREACHED */ + while (1); +} + +void __attribute__((weak)) +__assert_func(const char *file, + int line, + const char *func, + const char *failedexpr) +{ + char tmp[512] = {}; + char buffer[512] = {}; + + __os_snprintf(tmp, sizeof(tmp), "assertion \"%s\" failed:\n file \"%s\", line %d%s%s", + failedexpr, file, line, + func ? ", function: " : "", func ? func : ""); + + // make sure to add a \n every 64 characters to fit on the DRC screen. + char *target_ptr = buffer; + int i = 0, j = 0, lineLength = 0; + while (tmp[i] != '\0' && j < sizeof(buffer) - 2) { + if (tmp[i] == '\n') { + lineLength = 0; + } else if (lineLength >= 64) { + target_ptr[j++] = '\n'; + lineLength = 0; + } + target_ptr[j++] = tmp[i++]; + lineLength++; + } + + if (OSIsDebuggerPresent()) { + __asm__ __volatile__("mr 3, %0\n" // load 'tmp' into r3 + "tw 0x1f, 31, 31" // DBGSTR_INSTRUCTION + : + : "r"(tmp) + : "r3"); + } + + OSFatal(buffer); + /* NOTREACHED */ + while (1); +} + +void __attribute__((weak)) +__assert(const char *file, + int line, + const char *failedexpr) +{ + __assert_func(file, line, NULL, failedexpr); + /* NOTREACHED */ +} + void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr) { return __wut_sbrk_r(ptr, incr); }