diff --git a/include/coreinit/dynload.h b/include/coreinit/dynload.h index b25c414..9f8e8d0 100644 --- a/include/coreinit/dynload.h +++ b/include/coreinit/dynload.h @@ -27,7 +27,13 @@ typedef enum OSDynLoad_Error OS_DYNLOAD_TLS_ALLOCATOR_LOCKED = 0xBAD10031, } OSDynLoad_Error; -typedef void *OSDynLoadModule; +typedef enum OSDynLoad_EntryReason +{ + OS_DYNLOAD_LOADED = 0, + OS_DYNLOAD_UNLOADED = 1, +} OSDynLoad_EntryReason; + +typedef void *OSDynLoad_Module; typedef OSDynLoad_Error (*OSDynLoadAllocFn)(int32_t size, int32_t align, void **outAddr); typedef void (*OSDynLoadFreeFn)(void *addr); @@ -41,7 +47,7 @@ typedef void (*OSDynLoadFreeFn)(void *addr); */ OSDynLoad_Error OSDynLoad_Acquire(char const *name, - OSDynLoadModule *outModule); + OSDynLoad_Module *outModule); /** @@ -50,7 +56,7 @@ OSDynLoad_Acquire(char const *name, * Similar to GetProcAddress on Windows. */ OSDynLoad_Error -OSDynLoad_FindExport(OSDynLoadModule module, +OSDynLoad_FindExport(OSDynLoad_Module module, BOOL isData, char const *name, void **outAddr); @@ -63,7 +69,7 @@ OSDynLoad_FindExport(OSDynLoadModule module, * Similar to FreeLibrary on Windows. */ void -OSDynLoad_Release(OSDynLoadModule module); +OSDynLoad_Release(OSDynLoad_Module module); /** @@ -97,6 +103,15 @@ OSDynLoad_Error OSDynLoad_GetTLSAllocator(OSDynLoadAllocFn *outAllocFn, OSDynLoadFreeFn *outFreeFn); +/** + * The prototype for an RPL entry point. + * + * Use this instead of main when creating .rpl files + */ +int +rpl_main(OSDynLoad_Module module, + OSDynLoad_EntryReason reason); + #ifdef __cplusplus } #endif diff --git a/libraries/wutcrt/CMakeLists.txt b/libraries/wutcrt/CMakeLists.txt index 468a3c9..b293b82 100644 --- a/libraries/wutcrt/CMakeLists.txt +++ b/libraries/wutcrt/CMakeLists.txt @@ -1,12 +1,16 @@ cmake_minimum_required(VERSION 3.2) -project(wutnewlib C) - -set_property(SOURCE crt0.s PROPERTY LANGUAGE C) +project(wutcrt C ASM) add_library(wutcrt - crt0.s + crt0_rpx.s wut_crt.c) -target_include_directories(wutcrt PRIVATE "${WUT_ROOT}/include") -install(TARGETS wutcrt +add_library(wutcrtrpl + crt0_rpl.s + wut_crt.c) + +target_include_directories(wutcrt PRIVATE "${WUT_ROOT}/include") +target_include_directories(wutcrtrpl PRIVATE "${WUT_ROOT}/include") + +install(TARGETS wutcrt wutcrtrpl ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") diff --git a/libraries/wutcrt/crt0_rpl.s b/libraries/wutcrt/crt0_rpl.s new file mode 100644 index 0000000..28e4b45 --- /dev/null +++ b/libraries/wutcrt/crt0_rpl.s @@ -0,0 +1,31 @@ +.extern main +.extern exit +.extern __init_wut +.extern __fini_wut + +.global _start +_start: + stwu 1, -0x8(1) + stw 3, 0(1) + stw 4, 4(1) + cmpwi 3, 2 + beq unload + +load: + # Load + bl __fini_wut + bl __eabi + lwz 3, 0(1) + lwz 4, 4(1) + bl rpl_main + addi 1, 1, 0x8 + blr + +unload: + # Handle unload + lwz 3, 0(1) + lwz 4, 4(1) + bl rpl_main + bl __fini_wut + addi 1, 1, 0x8 + b exit diff --git a/libraries/wutcrt/crt0.s b/libraries/wutcrt/crt0_rpx.s similarity index 100% rename from libraries/wutcrt/crt0.s rename to libraries/wutcrt/crt0_rpx.s diff --git a/share/wut.cmake b/share/wut.cmake index 54c5d1e..0ca96ca 100644 --- a/share/wut.cmake +++ b/share/wut.cmake @@ -42,12 +42,16 @@ function(wut_create_rpl target source) set(RPL_MULTI_ARGS "") cmake_parse_arguments(RPL "${RPL_OPTIONS}" "${RPL_SINGLE_ARGS}" "${RPL_MULTI_ARGS}" "${ARGN}") - if(NOT RPL_IS_RPX) + if(RPL_IS_RPX) + target_link_libraries(${source} + wutcrt) + else() set(ELF2RPL_FLAGS ${ELF2RPL_FLAGS} --rpl) + target_link_libraries(${source} + wutcrtrpl) endif() target_link_libraries(${source} - wutcrt coreinit) add_custom_target(${target} ALL