From 0cd6b6c7212727b04174525fc1710f6178cf94c4 Mon Sep 17 00:00:00 2001 From: Michal Sytko Date: Fri, 9 Oct 2026 13:43:10 +0200 Subject: [PATCH] feat(libc): implement getprogname --- .../prx/libSceLibcInternal/CMakeLists.txt | 10 +++++++ core/libs/prx/libSceLibcInternal/Export.cpp | 5 ++++ core/libs/tests/GuestProgramName.cpp | 30 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 core/libs/tests/GuestProgramName.cpp diff --git a/core/libs/prx/libSceLibcInternal/CMakeLists.txt b/core/libs/prx/libSceLibcInternal/CMakeLists.txt index 2c0060756b6..61df7b27589 100644 --- a/core/libs/prx/libSceLibcInternal/CMakeLists.txt +++ b/core/libs/prx/libSceLibcInternal/CMakeLists.txt @@ -4,6 +4,16 @@ target_link_libraries(libSceLibcInternal PRIVATE ${CMAKE_DL_LIBS}) configure_windows_unwind(libSceLibcInternal) if(BUILD_TESTING) + add_test_executable(guest_program_name_tests ${LIBS_INCLUDE_DIR}/tests/GuestProgramName.cpp) + target_include_directories(guest_program_name_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_program_name_tests PRIVATE libSceLibcInternal libkernel libc) + configure_windows_unwind(guest_program_name_tests) + add_test(NAME guest_program_name COMMAND guest_program_name_tests) + set_tests_properties(guest_program_name PROPERTIES TIMEOUT 10) + if(WIN32) + set_tests_properties(guest_program_name PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() add_test_executable(guest_thread_atexit_tests ${LIBS_INCLUDE_DIR}/tests/GuestThreadAtexit.cpp) target_include_directories(guest_thread_atexit_tests PRIVATE ${LIBS_INCLUDE_DIR}) target_link_libraries(guest_thread_atexit_tests PRIVATE libSceLibcInternal libkernel libc) diff --git a/core/libs/prx/libSceLibcInternal/Export.cpp b/core/libs/prx/libSceLibcInternal/Export.cpp index f9425b744f8..43acde471d7 100644 --- a/core/libs/prx/libSceLibcInternal/Export.cpp +++ b/core/libs/prx/libSceLibcInternal/Export.cpp @@ -15,6 +15,7 @@ extern "C" void APS5_VABI sceKernelSetThreadDtors(thread_dtors_func_t dtors); extern "C" int APS5_VABI sceKernelGetModuleInfoFromAddr(std::uint64_t address, int flags, ModuleInfoEx* info); +extern "C" const char* __progname_nid_postfix; namespace { @@ -104,6 +105,10 @@ extern "C" { int Need_sceLibcInternal_nid_postfix = 1; +const char* APS5_VABI getprogname_nid_postfix() { + return __progname_nid_postfix; +} + void APS5_VABI __cxa_finalize_nid_postfix(void* dsoHandle) { CxaFinalize_nid_no_patch(dsoHandle); } diff --git a/core/libs/tests/GuestProgramName.cpp b/core/libs/tests/GuestProgramName.cpp new file mode 100644 index 00000000000..0c402027e84 --- /dev/null +++ b/core/libs/tests/GuestProgramName.cpp @@ -0,0 +1,30 @@ +#include "SceTypes.hpp" +#include +#include + +extern "C" { +const char* APS5_VABI getprogname_nid_postfix(); +extern const char* __progname_nid_postfix; +int* APS5_VABI __error_nid_postfix(); +} + +static void Require(bool value) { if (!value) std::abort(); } + +int main() { + const auto* original = __progname_nid_postfix; + const auto savedError = *__error_nid_postfix(); + *__error_nid_postfix() = 45; + Require(getprogname_nid_postfix() == original); + Require(std::strcmp(getprogname_nid_postfix(), "eboot.bin") == 0); + char name[] = "guest-program"; + __progname_nid_postfix = name; + Require(getprogname_nid_postfix() == name); + name[0] = 'G'; + Require(std::strcmp(getprogname_nid_postfix(), "Guest-program") == 0); + __progname_nid_postfix = ""; + Require(getprogname_nid_postfix() == __progname_nid_postfix); + Require(*getprogname_nid_postfix() == '\0'); + Require(*__error_nid_postfix() == 45); + __progname_nid_postfix = original; + *__error_nid_postfix() = savedError; +}