summaryrefslogtreecommitdiff
path: root/src/Runtime/__init_cpp_exceptions.cpp
blob: 937cc790be0b6fa6c4d14a5790bf7f4bb195e4c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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;