Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions core/libs/prx/libc/src/ApplicationHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,20 @@ void* ApplicationHeapAlign_nid_no_patch(std::size_t alignment, std::size_t bytes
return pointer;
}

extern "C" void* APS5_VABI scriptingGetMem_nid_postfix(std::size_t alignment, std::size_t bytes) {
alignment = std::max<std::size_t>(alignment, 16);
if ((alignment & (alignment - 1)) != 0) return nullptr;
try {
return ApplicationHeapAlign_nid_no_patch(alignment, bytes);
} catch (const std::bad_alloc&) {
return nullptr;
}
}

extern "C" void APS5_VABI scriptingFreeMem_nid_postfix(void* pointer) {
ApplicationHeapFree_nid_no_patch(pointer);
}

void* ApplicationHeapRealign_nid_no_patch(void* pointer, std::size_t bytes, std::size_t alignment) {
if (bytes == 0) {
ApplicationHeapFree_nid_no_patch(pointer);
Expand Down
13 changes: 13 additions & 0 deletions core/libs/tests/ApplicationHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ char* APS5_VABI strndup_nid_postfix(const char*, std::size_t);
char* APS5_VABI getcwd_nid_postfix(char*, std::size_t);
int* APS5_VABI __error_nid_postfix();
int APS5_VABI atexit_nid_postfix(void (APS5_VABI*)());
void* APS5_VABI scriptingGetMem_nid_postfix(std::size_t, std::size_t);
void APS5_VABI scriptingFreeMem_nid_postfix(void*);
}

namespace {
Expand Down Expand Up @@ -385,4 +387,15 @@ int main(int argc, char** argv) {
*__error_nid_postfix() = 0;
require(getcwd_nid_postfix(nullptr, 0) == nullptr && *__error_nid_postfix() == 12);
fail = false;
const auto beforeScripting = frees;
scriptingFreeMem_nid_postfix(nullptr);
require(frees == beforeScripting);
require(scriptingGetMem_nid_postfix(0, 31) == storage.data() && lastAlignment == 16 && lastSize == 31);
require(scriptingGetMem_nid_postfix(64, 37) == storage.data() && lastAlignment == 64 && lastSize == 37);
scriptingFreeMem_nid_postfix(storage.data());
require(frees == beforeScripting + 1);
require(scriptingGetMem_nid_postfix(24, 80) == nullptr && lastSize == 37);
fail = true;
require(scriptingGetMem_nid_postfix(16, 64) == nullptr);
fail = false;
}
2 changes: 2 additions & 0 deletions docs/dev/debt/libc.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
### Unknown function info

- [fdopen](../../../core/libs/prx/libc/src/FileAndHeap.cpp) (libc) validates descriptor access modes as FreeBSD 11.4 [fdopen.c](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/stdio/fdopen.c) does: a requested mode incompatible with a descriptor not opened for both reading and writing returns null with `EINVAL`, leaving the descriptor open. Windows reads the handle's granted access through the same host helper as `fcntl(F_GETFL)`; a closed descriptor returns null with `EBADF`. Console behavior is unverified.
- [scriptingGetMem, scriptingFreeMem](../../../core/libs/prx/libc/src/ApplicationHeap.cpp) (libc) - runtime allocator hooks for Unity titles. The allocation signature `(alignment, size)`, minimum alignment 16 and null result for a non-power-of-two alignment follow [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/df5b9b92be7dfd463b47756b707d6d356a9f0550/src/libs/libKernel.cpp); the free hook's one-pointer signature follows [Raeen's recorded contract](https://github.com/Whoisraeen/Raeen/blob/2db56923204b89719916b95e29c2f3c4e1d9f90b/docs/unity-dlsym-blocker.md). Both use the registered application allocator. No console measurement; null allocation returns null and other allocator errors throw.

- [_Mtx_trylock](../../../core/libs/prx/libc/src/Threads.cpp) (libc, NID `k6pGNMwJB08`) - returns busy for a non-recursive mutex already owned by the caller, assumed to match `_Mtx_lock`'s ownership handling; exact console behavior is unverified.
- [nearbyintf](../../../core/libs/prx/libc/src/Math.cpp) (libc, NID `c+4r-T-tEIc`) uses the host rounding mode, not the console's; console rounding mode state remains unverified.
- [_Thrd_sleep](../../../core/libs/prx/libc/src/Threads.cpp) (libc, NID `jfRI3snge3o`) follows the Dinkumware threads library shipped with [Visual C++ 2013](https://github.com/adityaramesh/concurrency_runtime/tree/master/VS2013_SP2/crt/src/thr) (`xtime.c`) and C11 Annex K, without console verification. It reads a 16-byte xtime (64-bit seconds and nanoseconds) on the guest `CLOCK_REALTIME`, normalizes the nanoseconds and sleeps through `nanosleep`, retrying on `EINTR`, so it is a cancellation point; a null xtime or one whose normalization overflows throws. The console's `_Thrd_sleep` (disassembled from a title's `libc.prx`) also takes an optional `xtime*` of remaining time and returns `int`; here the sleep is never cut short, so it returns 0 and leaves the remaining time untouched.
Expand Down
Loading