feat(sysmodule): implement sceSysmoduleLoadModuleInternal and sceSysmoduleUnloadModuleInternal
Two exports were missing. System modules are linked statically, so load and unload are reference counts over the known module table, exactly like the existing sceSysmoduleLoadModuleInternalWithArg and sceSysmoduleUnloadModule: - sceSysmoduleLoadModuleInternal(uint32_t) -> increments the module's load count, returns 0 - sceSysmoduleUnloadModuleInternal(uint32_t) -> decrements it, or 0x80A90003 when the module was not loaded Unknown or zero ids throw, like the sibling internal loader. Adds a CMakeLists.txt so the library can carry its guest test. Signatures follow the public OpenOrbis SDK headers. New test core/libs/tests/GuestSysmodule.cpp loads a module twice, unloads it twice and checks the not-loaded error on a third unload; it fails without the change (the symbols are undefined) and passes with it.
This commit is contained in:
parent
d7f0c49fdc
commit
75c2ea8548
|
|
@ -0,0 +1,20 @@
|
|||
add_library(libSceSysmodule SHARED EXCLUDE_FROM_ALL Export.cpp)
|
||||
target_include_directories(libSceSysmodule PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
configure_windows_unwind(libSceSysmodule)
|
||||
|
||||
if(MINGW)
|
||||
foreach(runtimeLinkFlag IN ITEMS -static-libgcc -static-libstdc++ -static)
|
||||
string(REPLACE "${runtimeLinkFlag}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test_executable(guest_sysmodule_tests ${LIBS_INCLUDE_DIR}/tests/GuestSysmodule.cpp)
|
||||
target_include_directories(guest_sysmodule_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_sysmodule_tests PRIVATE libSceSysmodule)
|
||||
add_test(NAME guest_sysmodule COMMAND guest_sysmodule_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_sysmodule PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceSysmodule>")
|
||||
endif()
|
||||
endif()
|
||||
|
|
@ -166,4 +166,32 @@ int APS5_VABI sceSysmoduleUnloadModule(std::uint16_t id) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceSysmoduleLoadModuleInternal(std::uint32_t id) {
|
||||
if ((id & 0x7fffffffu) == 0) {
|
||||
throw std::runtime_error("sceSysmoduleLoadModuleInternal: invalid id 0");
|
||||
}
|
||||
if (!findModuleName(id)) {
|
||||
throw std::runtime_error(std::string("sceSysmoduleLoadModuleInternal: unknown id ") + std::to_string(id));
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(gMutex);
|
||||
gLoadCount[id]++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceSysmoduleUnloadModuleInternal(std::uint32_t id) {
|
||||
if ((id & 0x7fffffffu) == 0) {
|
||||
throw std::runtime_error("sceSysmoduleUnloadModuleInternal: invalid id 0");
|
||||
}
|
||||
if (!findModuleName(id)) {
|
||||
throw std::runtime_error(std::string("sceSysmoduleUnloadModuleInternal: unknown id ") + std::to_string(id));
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(gMutex);
|
||||
auto it = gLoadCount.find(id);
|
||||
if (it == gLoadCount.end() || it->second < 1) {
|
||||
return 0x80A90003;
|
||||
}
|
||||
it->second--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
extern "C" {
|
||||
int APS5_VABI sceSysmoduleLoadModuleInternal(std::uint32_t id);
|
||||
int APS5_VABI sceSysmoduleUnloadModuleInternal(std::uint32_t id);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void Require(bool value) { if (!value) std::abort(); }
|
||||
|
||||
constexpr std::uint32_t kFiberModuleId = 0x00000006;
|
||||
constexpr int kModuleNotLoaded = static_cast<int>(0x80A90003);
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
Require(sceSysmoduleLoadModuleInternal(kFiberModuleId) == 0);
|
||||
Require(sceSysmoduleLoadModuleInternal(kFiberModuleId) == 0);
|
||||
Require(sceSysmoduleUnloadModuleInternal(kFiberModuleId) == 0);
|
||||
Require(sceSysmoduleUnloadModuleInternal(kFiberModuleId) == 0);
|
||||
Require(sceSysmoduleUnloadModuleInternal(kFiberModuleId) == kModuleNotLoaded);
|
||||
}
|
||||
Loading…
Reference in New Issue