diff --git a/include/wums/meta.h b/include/wums/meta.h index f87332b..e60e099 100644 --- a/include/wums/meta.h +++ b/include/wums/meta.h @@ -50,13 +50,9 @@ extern "C" { WUMS_USE_WUT_STDCPP(); \ WUMS___INIT_WRAPPER(); \ WUMS___FINI_WRAPPER(); \ - __EXTERN_C_MACRO void abort(); \ - void abort() { \ - OSFatal(__module_name ": abort() called. Uncaught exception?"); \ - while (1) \ - ; \ - } \ WUMS_META(buildtimestamp, __DATE__ " " __TIME__); \ + extern const char wums_meta_module_name[] WUMS_SECTION("meta"); \ + const char wums_meta_module_name[] = __module_name; \ extern const char wums_meta_info_dump[] WUMS_SECTION("meta"); \ const char wums_meta_info_dump[] = "(module: " __module_name ";" \ "wums " WUMS_VERSION ";" \ diff --git a/libraries/libwums/crt.cpp b/libraries/libwums/crt.cpp index 5c030ab..2d44ec9 100644 --- a/libraries/libwums/crt.cpp +++ b/libraries/libwums/crt.cpp @@ -1,5 +1,7 @@ #include "wums_reent.h" #include "wums_thread_specific.h" +#include +#include extern "C" void OSFatal(const char *); @@ -52,3 +54,59 @@ extern "C" void *__attribute__((weak)) wut_get_thread_specific(__wut_thread_spec void *wut_get_thread_specific(__wut_thread_specific_id id) { return wums_get_thread_specific(id); } + +extern "C" const char wums_meta_module_name[]; +extern "C" void __attribute__((weak)) abort(void); +extern "C" void __attribute__((weak)) __assert_func(const char *file, int line, const char *func, const char *failedexpr); +extern "C" void __attribute__((weak)) __assert(const char *file, int line, const char *failedexpr); + +void __attribute__((weak)) +abort(void) { + char buffer[512] = {}; + strcat(buffer, "Wii U Module System (module: \""); + strcat(buffer, wums_meta_module_name); + strcat(buffer, "\"):\n Abort called. Uncaught exception?"); + OSFatal(buffer); + /* 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] = {}; + + snprintf(tmp, sizeof(tmp), "Wii U Module System (module: \"%s\"):\n\n" + "assertion \"%s\" failed:\n\n" + "file \"%s\", line %d%s%s", + wums_meta_module_name, 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 < (int) 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++; + } + + OSFatal(buffer); + /* NOTREACHED */ +} + +void __attribute__((weak)) +__assert(const char *file, + int line, + const char *failedexpr) { + __assert_func(file, line, NULL, failedexpr); + /* NOTREACHED */ +} \ No newline at end of file diff --git a/libraries/libwums/wums_reent.cpp b/libraries/libwums/wums_reent.cpp index 7441e9f..8b3d5ed 100644 --- a/libraries/libwums/wums_reent.cpp +++ b/libraries/libwums/wums_reent.cpp @@ -9,14 +9,14 @@ typedef uint32_t OSThread; extern const char wums_meta_info_dump[]; -extern void OSFatal(const char *); -extern void OSReport(const char *, ...); +extern "C" void OSFatal(const char *); +extern "C" void OSReport(const char *, ...); -extern OSThread *OSGetCurrentThread(); +extern "C" OSThread *OSGetCurrentThread(); typedef void (*OSThreadCleanupCallbackFn)(OSThread *thread, void *stack); -OSThreadCleanupCallbackFn +extern "C" OSThreadCleanupCallbackFn OSSetThreadCleanupCallback(OSThread *thread, OSThreadCleanupCallbackFn callback);