From 91943cb93ec399498536e82fb1761515d00e16b3 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Mon, 10 Oct 2022 01:46:54 -0700 Subject: [PATCH] Match and link more of Runtime --- configure.py | 6 +-- src/Runtime/CPlusLibPPC.cpp | 25 +++++++++ src/Runtime/MWCPlusLib.h | 15 ++++++ src/Runtime/NMWException.cpp | 0 src/Runtime/__init_cpp_exceptions.cpp | 50 ++++++++++++++++++ src/Runtime/__ppc_eabi_linker.h | 74 +++++++++++++++++++++++++++ src/Runtime/global_destructor_chain.c | 27 ++++++++++ 7 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 src/Runtime/CPlusLibPPC.cpp create mode 100644 src/Runtime/MWCPlusLib.h create mode 100644 src/Runtime/NMWException.cpp create mode 100644 src/Runtime/__init_cpp_exceptions.cpp create mode 100644 src/Runtime/__ppc_eabi_linker.h create mode 100644 src/Runtime/global_destructor_chain.c diff --git a/configure.py b/configure.py index 76728dc5..bf2ddc96 100755 --- a/configure.py +++ b/configure.py @@ -843,12 +843,12 @@ LIBS = [ "objects": [ ["Runtime/__mem", True], "Runtime/__va_arg", - "Runtime/global_destructor_chain", - "Runtime/CPlusLibPPC", + ["Runtime/global_destructor_chain", True], + ["Runtime/CPlusLibPPC", True], "Runtime/NMWException", "Runtime/ptmf", "Runtime/runtime", - "Runtime/__init_cpp_exceptions", + ["Runtime/__init_cpp_exceptions", True], "Runtime/Gecko_ExceptionPPC", ["Runtime/abort_exit", True], "Runtime/alloc", diff --git a/src/Runtime/CPlusLibPPC.cpp b/src/Runtime/CPlusLibPPC.cpp new file mode 100644 index 00000000..4a0b5b93 --- /dev/null +++ b/src/Runtime/CPlusLibPPC.cpp @@ -0,0 +1,25 @@ +#include "MWCPlusLib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void* __copy(char* to, char* from, size_t size) { + char* p; + + if (to && size) { + p = to; + do { + *p = *from; + ++p; + ++from; + --size; + } while (size > 0); + } + + return to; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/Runtime/MWCPlusLib.h b/src/Runtime/MWCPlusLib.h new file mode 100644 index 00000000..f2680166 --- /dev/null +++ b/src/Runtime/MWCPlusLib.h @@ -0,0 +1,15 @@ +#ifndef _MWCPLUSLIB +#define _MWCPLUSLIB + +#include + +#ifdef __cplusplus +extern "C" { +#endif +void* __copy(char* to, char* from, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif // _MWCPLUSLIB diff --git a/src/Runtime/NMWException.cpp b/src/Runtime/NMWException.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/Runtime/__init_cpp_exceptions.cpp b/src/Runtime/__init_cpp_exceptions.cpp new file mode 100644 index 00000000..413a85d6 --- /dev/null +++ b/src/Runtime/__init_cpp_exceptions.cpp @@ -0,0 +1,50 @@ +#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; diff --git a/src/Runtime/__ppc_eabi_linker.h b/src/Runtime/__ppc_eabi_linker.h new file mode 100644 index 00000000..382b80db --- /dev/null +++ b/src/Runtime/__ppc_eabi_linker.h @@ -0,0 +1,74 @@ +#ifndef __PPC_EABI_LINKER +#define __PPC_EABI_LINKER + +__declspec(section ".init") extern char _stack_addr[]; +__declspec(section ".init") extern char _stack_end[]; +__declspec(section ".init") extern char _heap_addr[]; +__declspec(section ".init") extern char _heap_end[]; +__declspec(section ".init") extern const char _fextabindex_rom[]; +__declspec(section ".init") extern char _fextabindex[]; +__declspec(section ".init") extern char _eextabindex[]; + +__declspec(section ".init") extern char _SDA_BASE_[]; + +__declspec(section ".init") extern char _SDA2_BASE_[]; + +typedef struct __rom_copy_info { + char* rom; + char* addr; + unsigned int size; +} __rom_copy_info; + +__declspec(section ".init") extern __rom_copy_info _rom_copy_info[]; + +typedef struct __bss_init_info { + char* addr; + unsigned int size; +} __bss_init_info; + +__declspec(section ".init") extern __bss_init_info _bss_init_info[]; + +typedef struct __eti_init_info { + void* eti_start; + void* eti_end; + void* code_start; + unsigned long code_size; +} __eti_init_info; + +/* TODO: Fix this once we can link with generated symbols */ +__declspec(section ".init") extern __eti_init_info _eti_init_info_[]; +__declspec(section ".init") extern const char _f_init_rom[]; +__declspec(section ".init") extern char _f_init[]; +__declspec(section ".init") extern char _e_init[]; +__declspec(section ".init") extern const char _f_text_rom[]; +__declspec(section ".init") extern char _f_text[]; +__declspec(section ".init") extern char _e_text[]; +__declspec(section ".init") extern const char _f_rodata_rom[]; +__declspec(section ".init") extern char _f_rodata[]; +__declspec(section ".init") extern char _e_rodata[]; +__declspec(section ".init") extern const char _fextab_rom[]; +__declspec(section ".init") extern char _fextab[]; +__declspec(section ".init") extern char _eextab[]; +__declspec(section ".init") extern const char _f_data_rom[]; +__declspec(section ".init") extern char _f_data[]; +__declspec(section ".init") extern char _e_data[]; +__declspec(section ".init") extern char _f_bss[]; +__declspec(section ".init") extern char _e_bss[]; +__declspec(section ".init") extern const char _f_sdata_rom[]; +__declspec(section ".init") extern char _f_sdata[]; +__declspec(section ".init") extern char _e_sdata[]; +__declspec(section ".init") extern char _f_sbss[]; +__declspec(section ".init") extern char _e_sbss[]; +__declspec(section ".init") extern const char _f_sdata2_rom[]; +__declspec(section ".init") extern char _f_sdata2[]; +__declspec(section ".init") extern char _e_sdata2[]; +__declspec(section ".init") extern char _f_sbss2[]; +__declspec(section ".init") extern char _e_sbss2[]; +__declspec(section ".init") extern const char _f_PPC_EMB_sdata0_rom[]; +__declspec(section ".init") extern char _f_PPC_EMB_sdata0[]; +__declspec(section ".init") extern char _e_PPC_EMB_sdata0[]; +__declspec(section ".init") extern char _f_PPC_EMB_sbss0[]; +__declspec(section ".init") extern char _e_PPC_EMB_sbss0[]; + + +#endif // __PPC_EABI_LINKER diff --git a/src/Runtime/global_destructor_chain.c b/src/Runtime/global_destructor_chain.c new file mode 100644 index 00000000..da281f37 --- /dev/null +++ b/src/Runtime/global_destructor_chain.c @@ -0,0 +1,27 @@ +#include "NMWException.h" + + +typedef void (*CompleteDestructor)(void *,int); + +DestructorChain* __global_destructor_chain; + +extern void* __register_global_object(void* object, void* destructor, void* regmem) { + ((DestructorChain*)regmem)->next = __global_destructor_chain; + ((DestructorChain*)regmem)->destructor = destructor; + ((DestructorChain*)regmem)->object = object; + __global_destructor_chain = (DestructorChain*)regmem; + + return object; +} + +void __destroy_global_chain(void) { + DestructorChain* iter; + + while ((iter=__global_destructor_chain) != 0) { + __global_destructor_chain = iter->next; + ((CompleteDestructor)iter->destructor)(iter->object, -1); + } +} + +__declspec(section + ".dtors") static void* const __destroy_global_chain_reference = __destroy_global_chain;