Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config/RSBE01_02/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ symbols: config/RSBE01_02/symbols.txt
mw_comment_version: 14 # GC 3.0a5.2 linker
quick_analysis: true # Faster reruns after full analysis

# The .ctors$10/.dtors$15 entries that reference these are data-only, so the
# linker drops them unless the symbols are kept alive explicitly.
force_active:
- __init_cpp_exceptions_reference
- __fini_cpp_exceptions_reference

extract:
- symbol: HomeBtnIcon
binary: HomeBtnIcon.bin
Expand Down
2 changes: 1 addition & 1 deletion configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def MatchingFor(*versions):
"host": False,
"objects": [
Object(NonMatching, "Runtime.PPCEABI.H/global_destructor_chain.c"),
Object(NonMatching, "Runtime.PPCEABI.H/__init_cpp_exceptions.cpp"),
Object(Matching, "Runtime.PPCEABI.H/__init_cpp_exceptions.cpp"),
],
},
# The DOL
Expand Down
53 changes: 53 additions & 0 deletions src/Runtime.PPCEABI.H/__init_cpp_exceptions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
extern "C" {

typedef struct ExtabIndexInfo {
unsigned long size;
struct ExtabIndexInfo* extab;
unsigned long extabend;
} ExtabIndexInfo;

extern const ExtabIndexInfo _eti_init_info[];

int __register_fragment(const ExtabIndexInfo* info, char* toc);
void __unregister_fragment(int fragmentID);
void __destroy_global_chain(void);

// The unit owns 8 bytes of .sdata but only the first word is ever read, and a
// lone int leaves the section 4 bytes short of the split. Pairing the id with
// its trailing word reproduces the section exactly.
static struct {
int id;
int pad;
} fragment = { -2, 0 };

void __init_cpp_exceptions(void)
{
// __register_fragment takes the TOC in r2, which has no C spelling.
register char* toc;
if (fragment.id == -2) {
asm { mr toc, r2 }
fragment.id = __register_fragment(_eti_init_info, toc);
}
}

void __fini_cpp_exceptions(void)
{
if (fragment.id != -2) {
__unregister_fragment(fragment.id);
fragment.id = -2;
}
}

#pragma section ".ctors$10"
__declspec(section ".ctors$10")
extern void* const __init_cpp_exceptions_reference = (void*) __init_cpp_exceptions;

#pragma section ".dtors$10"
__declspec(section ".dtors$10") __declspec(weak)
extern void* const __destroy_global_chain_reference = (void*) __destroy_global_chain;

#pragma section ".dtors$15"
__declspec(section ".dtors$15")
extern void* const __fini_cpp_exceptions_reference = (void*) __fini_cpp_exceptions;

}