diff --git a/core/libs/prx/libc/CMakeLists.txt b/core/libs/prx/libc/CMakeLists.txt index 7e732496a..f77c34248 100644 --- a/core/libs/prx/libc/CMakeLists.txt +++ b/core/libs/prx/libc/CMakeLists.txt @@ -233,6 +233,15 @@ if(BUILD_TESTING) set_tests_properties(guest_hostname PROPERTIES ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$") endif() + add_test_executable(guest_memrchr_tests ${LIBS_INCLUDE_DIR}/tests/GuestMemrchr.cpp) + target_include_directories(guest_memrchr_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_memrchr_tests PRIVATE libc) + configure_windows_unwind(guest_memrchr_tests) + add_test(NAME guest_memrchr COMMAND guest_memrchr_tests) + if(WIN32) + set_tests_properties(guest_memrchr PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() add_test_executable(guest_lifecycle_tests ${LIBS_INCLUDE_DIR}/tests/GuestLifecycle.cpp) target_include_directories(guest_lifecycle_tests PRIVATE ${LIBS_INCLUDE_DIR}) target_link_libraries(guest_lifecycle_tests PRIVATE libc) diff --git a/core/libs/prx/libc/src/Strings.cpp b/core/libs/prx/libc/src/Strings.cpp index 4399cbe08..a0ddafb24 100644 --- a/core/libs/prx/libc/src/Strings.cpp +++ b/core/libs/prx/libc/src/Strings.cpp @@ -73,6 +73,16 @@ const void* APS5_VABI memchr_nid_postfix(const void* s, int c, size_t n) { return std::memchr(s, c, n); } +void* APS5_VABI memrchr_nid_postfix(const void* s, int c, size_t n) { + const auto* bytes = static_cast(s); + const auto value = static_cast(c); + while (n != 0) { + --n; + if (bytes[n] == value) return const_cast(bytes + n); + } + return nullptr; +} + int APS5_VABI strcmp_nid_postfix(const char* s1, const char* s2) { return std::strcmp(s1, s2); } diff --git a/core/libs/tests/GuestMemrchr.cpp b/core/libs/tests/GuestMemrchr.cpp new file mode 100644 index 000000000..8715e30bf --- /dev/null +++ b/core/libs/tests/GuestMemrchr.cpp @@ -0,0 +1,17 @@ +#include "prx/libc/include/general/VabiMacros.hpp" +#include + +extern "C" { +void* APS5_VABI memrchr_nid_postfix(const void*, int, std::size_t); +} + +int main() { + const unsigned char bytes[] = {0xff, 0x01, 0xff, 0x00}; + const auto* found = static_cast(memrchr_nid_postfix(bytes, 0xff, sizeof(bytes))); + if (found != bytes + 2) std::abort(); + found = static_cast(memrchr_nid_postfix(bytes, 0x1ff, sizeof(bytes))); + if (found != bytes + 2) std::abort(); + found = static_cast(memrchr_nid_postfix(bytes, 0xff, 2)); + if (found != bytes) std::abort(); + if (memrchr_nid_postfix(bytes, 0x02, sizeof(bytes)) != nullptr) std::abort(); +}