Add support for generating RPL files.

RPL files are shared libraries (like a .dll file), as opposed to the RPX
files which are executables (like a .exe file).

Use rpl_main as defined in dynload.h like one would DllMain on Windows.
This commit is contained in:
James Benton 2018-05-30 21:56:18 +01:00
parent 6f877a2a3c
commit f281be50ab
5 changed files with 66 additions and 12 deletions

View File

@ -27,7 +27,13 @@ typedef enum OSDynLoad_Error
OS_DYNLOAD_TLS_ALLOCATOR_LOCKED = 0xBAD10031, OS_DYNLOAD_TLS_ALLOCATOR_LOCKED = 0xBAD10031,
} OSDynLoad_Error; } 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 OSDynLoad_Error (*OSDynLoadAllocFn)(int32_t size, int32_t align, void **outAddr);
typedef void (*OSDynLoadFreeFn)(void *addr); typedef void (*OSDynLoadFreeFn)(void *addr);
@ -41,7 +47,7 @@ typedef void (*OSDynLoadFreeFn)(void *addr);
*/ */
OSDynLoad_Error OSDynLoad_Error
OSDynLoad_Acquire(char const *name, OSDynLoad_Acquire(char const *name,
OSDynLoadModule *outModule); OSDynLoad_Module *outModule);
/** /**
@ -50,7 +56,7 @@ OSDynLoad_Acquire(char const *name,
* Similar to GetProcAddress on Windows. * Similar to GetProcAddress on Windows.
*/ */
OSDynLoad_Error OSDynLoad_Error
OSDynLoad_FindExport(OSDynLoadModule module, OSDynLoad_FindExport(OSDynLoad_Module module,
BOOL isData, BOOL isData,
char const *name, char const *name,
void **outAddr); void **outAddr);
@ -63,7 +69,7 @@ OSDynLoad_FindExport(OSDynLoadModule module,
* Similar to FreeLibrary on Windows. * Similar to FreeLibrary on Windows.
*/ */
void void
OSDynLoad_Release(OSDynLoadModule module); OSDynLoad_Release(OSDynLoad_Module module);
/** /**
@ -97,6 +103,15 @@ OSDynLoad_Error
OSDynLoad_GetTLSAllocator(OSDynLoadAllocFn *outAllocFn, OSDynLoad_GetTLSAllocator(OSDynLoadAllocFn *outAllocFn,
OSDynLoadFreeFn *outFreeFn); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,12 +1,16 @@
cmake_minimum_required(VERSION 3.2) cmake_minimum_required(VERSION 3.2)
project(wutnewlib C) project(wutcrt C ASM)
set_property(SOURCE crt0.s PROPERTY LANGUAGE C)
add_library(wutcrt add_library(wutcrt
crt0.s crt0_rpx.s
wut_crt.c) 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") ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")

View File

@ -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

View File

@ -42,12 +42,16 @@ function(wut_create_rpl target source)
set(RPL_MULTI_ARGS "") set(RPL_MULTI_ARGS "")
cmake_parse_arguments(RPL "${RPL_OPTIONS}" "${RPL_SINGLE_ARGS}" "${RPL_MULTI_ARGS}" "${ARGN}") 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) set(ELF2RPL_FLAGS ${ELF2RPL_FLAGS} --rpl)
target_link_libraries(${source}
wutcrtrpl)
endif() endif()
target_link_libraries(${source} target_link_libraries(${source}
wutcrt
coreinit) coreinit)
add_custom_target(${target} ALL add_custom_target(${target} ALL