summaryrefslogtreecommitdiff
path: root/src/Runtime/__init_cpp_exceptions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Runtime/__init_cpp_exceptions.cpp')
-rw-r--r--src/Runtime/__init_cpp_exceptions.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/Runtime/__init_cpp_exceptions.cpp b/src/Runtime/__init_cpp_exceptions.cpp
new file mode 100644
index 0000000..937cc79
--- /dev/null
+++ b/src/Runtime/__init_cpp_exceptions.cpp
@@ -0,0 +1,52 @@
+// This file was taken from the Metroid Prime decompilation project.
+// https://github.com/PrimeDecomp/prime/blob/main/src/Runtime/__init_cpp_exceptions.cpp
+#include "NMWException.h"
+#include "__ppc_eabi_linker.h"
+
+static int fragmentID = -2;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void __init_cpp_exceptions(void);
+extern void __fini_cpp_exceptions(void);
+extern void suspend(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* clang-format off */
+static asm char* GetR2() {
+ nofralloc;
+ mr r3, r2
+ blr
+}
+/* clang-format on */
+
+extern void __init_cpp_exceptions(void) {
+ char* R2;
+ if (fragmentID == -2) {
+
+ R2 = GetR2();
+
+ /* HACK: TODO: _eti_init_info should be _eti_init_info, we can't use the appropriate name yet due to the
+ * linker not being able to generate it*/
+ fragmentID = __register_fragment(_eti_init_info, R2);
+ }
+}
+
+extern void __fini_cpp_exceptions(void) {
+ if (fragmentID != -2) {
+ __unregister_fragment(fragmentID);
+ fragmentID = -2;
+ }
+}
+
+__declspec(section
+ ".ctors") static void* const __init_cpp_exceptions_reference = __init_cpp_exceptions;
+__declspec(section
+ ".dtors") static void* const __destroy_global_chain_reference = __destroy_global_chain;
+__declspec(section
+ ".dtors") static void* const __fini_cpp_exceptions_reference = __fini_cpp_exceptions;