diff --git a/asm/MetroidPrime/CWeaponMgr.s b/asm/MetroidPrime/CWeaponMgr.s index 676a218c..dde031f7 100644 --- a/asm/MetroidPrime/CWeaponMgr.s +++ b/asm/MetroidPrime/CWeaponMgr.s @@ -486,8 +486,8 @@ __ct__10CWeaponMgrFv: /* 800C22FC 000BF25C 38 21 00 10 */ addi r1, r1, 0x10 /* 800C2300 000BF260 4E 80 00 20 */ blr -.global sub_800c2304 -sub_800c2304: +.global __dl__FPv +__dl__FPv: /* 800C2304 000BF264 94 21 FF F0 */ stwu r1, -0x10(r1) /* 800C2308 000BF268 7C 08 02 A6 */ mflr r0 /* 800C230C 000BF26C 90 01 00 14 */ stw r0, 0x14(r1) @@ -703,4 +703,3 @@ lbl_803CE018: # ROM: 0x3CB018 .asciz "??(??)" .balign 4 - diff --git a/asm/Runtime/NMWException.s b/asm/Runtime/NMWException.s index b0fbea08..8c6a79a2 100644 --- a/asm/Runtime/NMWException.s +++ b/asm/Runtime/NMWException.s @@ -150,7 +150,7 @@ lbl_803898CC: /* 803898CC 0038682C 7F C0 07 35 */ extsh. r0, r30 /* 803898D0 00386830 40 81 00 0C */ ble lbl_803898DC /* 803898D4 00386834 7F A3 EB 78 */ mr r3, r29 -/* 803898D8 00386838 4B D3 8A 2D */ bl sub_800c2304 +/* 803898D8 00386838 4B D3 8A 2D */ bl __dl__FPv lbl_803898DC: /* 803898DC 0038683C 80 01 00 24 */ lwz r0, 0x24(r1) /* 803898E0 00386840 7F A3 EB 78 */ mr r3, r29 @@ -161,7 +161,7 @@ lbl_803898DC: /* 803898F4 00386854 38 21 00 20 */ addi r1, r1, 0x20 /* 803898F8 00386858 4E 80 00 20 */ blr -.section extab_, "wa" # 0x800035A0 - 0x800035E0 +.section extab, "wa" # 0x800035A0 - 0x800035E0 .global __destroy_arr_extab __destroy_arr_extab: # ROM: 0x3C8120 @@ -180,7 +180,7 @@ __partial_array_destructor_extab: .4byte 0x18080000 .4byte 0 -.section extabindex_, "wa" # 0x800035E0 - 0x80003640 +.section extabindex, "wa" # 0x800035E0 - 0x80003640 lbl_extabindex: # ROM: 0x3C8160 .4byte __destroy_arr @@ -193,11 +193,11 @@ lbl_extabindex: .4byte 0x000000B8 .4byte __partial_array_destructor_extab -.global _eti_init_info_ -_eti_init_info_: +.global _eti_init_info +_eti_init_info: # ROM: 0x3C8184 .4byte lbl_extabindex - .4byte _eti_init_info_ + .4byte _eti_init_info .4byte __destroy_arr .4byte 0x00000228 .4byte 0 diff --git a/asm/Runtime/__init_cpp_exceptions.s b/asm/Runtime/__init_cpp_exceptions.s index 2db1dcd9..47b23645 100644 --- a/asm/Runtime/__init_cpp_exceptions.s +++ b/asm/Runtime/__init_cpp_exceptions.s @@ -33,9 +33,9 @@ __init_cpp_exceptions: /* 8038A130 00387090 2C 00 FF FE */ cmpwi r0, -2 /* 8038A134 00387094 40 82 00 1C */ bne lbl_8038A150 /* 8038A138 00387098 4B FF FF AD */ bl GetR2__Fv -/* 8038A13C 0038709C 3C A0 80 00 */ lis r5, _eti_init_info_@ha +/* 8038A13C 0038709C 3C A0 80 00 */ lis r5, _eti_init_info@ha /* 8038A140 003870A0 7C 64 1B 78 */ mr r4, r3 -/* 8038A144 003870A4 38 65 36 04 */ addi r3, r5, _eti_init_info_@l +/* 8038A144 003870A4 38 65 36 04 */ addi r3, r5, _eti_init_info@l /* 8038A148 003870A8 48 00 00 4D */ bl __register_fragment /* 8038A14C 003870AC 90 6D 9F C8 */ stw r3, fragmentID@sda21(r13) lbl_8038A150: diff --git a/configure.py b/configure.py index 519cfd3e..8d89ad8c 100755 --- a/configure.py +++ b/configure.py @@ -845,7 +845,7 @@ LIBS = [ ["Runtime/__va_arg", True], ["Runtime/global_destructor_chain", True], ["Runtime/CPlusLibPPC", True], - "Runtime/NMWException", + ["Runtime/NMWException", True], ["Runtime/ptmf", True], "Runtime/runtime", ["Runtime/__init_cpp_exceptions", True], diff --git a/ldscript.lcf b/ldscript.lcf index 3115d4cb..f9f472de 100644 --- a/ldscript.lcf +++ b/ldscript.lcf @@ -8,9 +8,8 @@ SECTIONS GROUP: { .init ALIGN(0x20):{} - /* TODO: should be extab and extabindex */ - extab_ ALIGN(0x20):{} - extabindex_ ALIGN(0x20):{} + extab ALIGN(0x20):{} + extabindex ALIGN(0x20):{} .text ALIGN(0x20):{} .ctors ALIGN(0x20):{} .dtors ALIGN(0x20):{} diff --git a/obj_files.mk b/obj_files.mk index 5b13593e..28a19639 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -720,7 +720,7 @@ MSL_PPCEABI_BARE_H :=\ $(BUILD_DIR)/src/Runtime/__va_arg.o\ $(BUILD_DIR)/src/Runtime/global_destructor_chain.o\ $(BUILD_DIR)/src/Runtime/CPlusLibPPC.o\ - $(BUILD_DIR)/asm/Runtime/NMWException.o\ + $(BUILD_DIR)/src/Runtime/NMWException.o\ $(BUILD_DIR)/src/Runtime/ptmf.o\ $(BUILD_DIR)/asm/Runtime/runtime.o\ $(BUILD_DIR)/src/Runtime/__init_cpp_exceptions.o\ diff --git a/src/Runtime/Gecko_ExceptionPPC.cpp b/src/Runtime/Gecko_ExceptionPPC.cpp index 6e61f2f1..c2e99956 100644 --- a/src/Runtime/Gecko_ExceptionPPC.cpp +++ b/src/Runtime/Gecko_ExceptionPPC.cpp @@ -1,6 +1,10 @@ #include "__ppc_eabi_linker.h" #include "NMWException.h" +#if __MWERKS__ +#pragma exceptions on +#endif + typedef struct ProcessInfo { __eti_init_info* exception_info; char* TOC; diff --git a/src/Runtime/NMWException.cpp b/src/Runtime/NMWException.cpp index e69de29b..b54b8e8a 100644 --- a/src/Runtime/NMWException.cpp +++ b/src/Runtime/NMWException.cpp @@ -0,0 +1,49 @@ +#include "NMWException.h" +#pragma exceptions on + +class __partial_array_destructor { +private: + void* p; + size_t size; + size_t n; + void* dtor; + +public: + size_t i; + + __partial_array_destructor(void* array, size_t elementsize, size_t nelements, void* destructor) { + p = array; + size = elementsize; + n = nelements; + dtor = destructor; + i = n; + } + + ~__partial_array_destructor() { + char* ptr; + + if (i < n && dtor) { + for (ptr = (char*)p + size * i; i > 0; i--) { + ptr -= size; + DTORCALL_COMPLETE(dtor, ptr); + } + } + } +}; + +extern "C" void __construct_array(void* ptr, void* ctor, void* dtor, size_t size, size_t n) { + __partial_array_destructor pad(ptr, size, n, dtor); + char* p; + + for (pad.i = 0, p = (char*)ptr; pad.i < n; pad.i++, p += size) + CTORCALL_COMPLETE(ctor, p); +} + +extern "C" void __destroy_arr(void* block, void* dtor, size_t size, size_t n) { + char* p; + + for (p = (char*)block + size * n; n > 0; n--) { + p -= size; + DTORCALL_COMPLETE(dtor, p); + } +} diff --git a/src/Runtime/NMWException.h b/src/Runtime/NMWException.h index 3dae2e22..d3e6290f 100644 --- a/src/Runtime/NMWException.h +++ b/src/Runtime/NMWException.h @@ -1,10 +1,23 @@ #ifndef _NMWEXCEPTION #define _NMWEXCEPTION +#include + #ifdef __cplusplus extern "C" { #endif +#define CTORARG_TYPE int +#define CTORARG_PARTIAL (0) +#define CTORARG_COMPLETE (1) + +#define CTORCALL_COMPLETE(ctor, objptr) \ + (((void (*)(void*, CTORARG_TYPE))ctor)(objptr, CTORARG_COMPLETE)) + +#define DTORARG_TYPE int + +#define DTORCALL_COMPLETE(dtor, objptr) (((void (*)(void*, DTORARG_TYPE))dtor)(objptr, -1)) + typedef struct DestructorChain { struct DestructorChain* next; void* destructor; diff --git a/src/Runtime/__init_cpp_exceptions.cpp b/src/Runtime/__init_cpp_exceptions.cpp index 413a85d6..1a9a087b 100644 --- a/src/Runtime/__init_cpp_exceptions.cpp +++ b/src/Runtime/__init_cpp_exceptions.cpp @@ -29,9 +29,9 @@ extern void __init_cpp_exceptions(void) { R2 = GetR2(); - /* HACK: TODO: _eti_init_info_ should be _eti_init_info, we can't use the appropriate name yet due to the + /* 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); + fragmentID = __register_fragment(_eti_init_info, R2); } } diff --git a/src/Runtime/__ppc_eabi_linker.h b/src/Runtime/__ppc_eabi_linker.h index 382b80db..722acb18 100644 --- a/src/Runtime/__ppc_eabi_linker.h +++ b/src/Runtime/__ppc_eabi_linker.h @@ -36,7 +36,7 @@ typedef struct __eti_init_info { } __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 __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[]; diff --git a/src/Runtime/global_destructor_chain.c b/src/Runtime/global_destructor_chain.c index da281f37..7c24b76a 100644 --- a/src/Runtime/global_destructor_chain.c +++ b/src/Runtime/global_destructor_chain.c @@ -1,7 +1,6 @@ #include "NMWException.h" -typedef void (*CompleteDestructor)(void *,int); DestructorChain* __global_destructor_chain; @@ -19,7 +18,7 @@ void __destroy_global_chain(void) { while ((iter=__global_destructor_chain) != 0) { __global_destructor_chain = iter->next; - ((CompleteDestructor)iter->destructor)(iter->object, -1); + DTORCALL_COMPLETE(iter->destructor, iter->object); } }