mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-01 12:45:56 +00:00
feat(libc): implement _Vacopy
Copy the 24-byte System V argument list, writing the overflow pointer before the register offsets as the console's libc.prx does. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
0b1d678fe5
commit
abc07a1192
2 files changed
+40
No files matched your search
@@ -95,6 +95,15 @@ void APS5_VABI cxa_finalize_nid_postfix(void* dsoHandle) {
|
||||
CxaFinalize_nid_no_patch(dsoHandle);
|
||||
}
|
||||
|
||||
void APS5_VABI _Vacopy_nid_postfix(unsigned char* destination, const unsigned char* source) {
|
||||
std::uint64_t overflowArea;
|
||||
std::memcpy(&overflowArea, source + 16, sizeof(overflowArea));
|
||||
std::memcpy(destination + 16, &overflowArea, sizeof(overflowArea));
|
||||
unsigned char offsets[16];
|
||||
std::memcpy(offsets, source, sizeof(offsets));
|
||||
std::memcpy(destination, offsets, sizeof(offsets));
|
||||
}
|
||||
|
||||
unsigned int APS5_VABI _Atomic_fetch_add_4_nid_postfix(volatile unsigned int* target, unsigned int value, int memoryOrder) {
|
||||
(void)memoryOrder;
|
||||
return GccAtomicFetchAdd(target, value);
|
||||
|
||||
@@ -16,6 +16,7 @@ int APS5_VABI vfwprintf_nid_postfix(FileStream*, const char16_t*, void*);
|
||||
int APS5_VABI fwprintf_nid_postfix(FileStream*, const char16_t*, ...);
|
||||
int APS5_VABI vswscanf_nid_postfix(const char16_t*, const char16_t*, void*);
|
||||
int APS5_VABI vswscanf_s_nid_postfix(const char16_t*, const char16_t*, void*);
|
||||
void APS5_VABI _Vacopy_nid_postfix(void*, const void*);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -67,6 +68,36 @@ static int APS5_VABI ScanWideSized(const char16_t* input, const char16_t* format
|
||||
return result;
|
||||
}
|
||||
|
||||
static long APS5_VABI SumThroughCopy(int count, ...) {
|
||||
APS5_VA_BEGIN(count);
|
||||
unsigned char before[24];
|
||||
std::memcpy(before, &args, sizeof(before));
|
||||
#ifdef _WIN32
|
||||
__builtin_sysv_va_list copy;
|
||||
#else
|
||||
std::va_list copy;
|
||||
#endif
|
||||
_Vacopy_nid_postfix(©, &args);
|
||||
Require(std::memcmp(©, &args, sizeof(before)) == 0, "_Vacopy copies all 24 bytes");
|
||||
long sum = 0;
|
||||
for (int index = 0; index < count; ++index) sum += __builtin_va_arg(copy, long) * (index + 1);
|
||||
Require(std::memcmp(&args, before, sizeof(before)) == 0, "_Vacopy leaves the source untouched");
|
||||
for (int index = 0; index < count; ++index) sum -= __builtin_va_arg(args, long);
|
||||
APS5_VA_END();
|
||||
return sum;
|
||||
}
|
||||
|
||||
static void CheckVacopy() {
|
||||
long expected = 0;
|
||||
for (long index = 1; index <= 9; ++index) expected += index * 100 * index - index * 100;
|
||||
Require(SumThroughCopy(9, 100L, 200L, 300L, 400L, 500L, 600L, 700L, 800L, 900L) == expected, "_Vacopy copy reads every argument");
|
||||
unsigned char overlap[32];
|
||||
for (int index = 0; index < 32; ++index) overlap[index] = static_cast<unsigned char>(index);
|
||||
_Vacopy_nid_postfix(overlap + 8, overlap);
|
||||
const unsigned char shifted[32] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
|
||||
Require(std::memcmp(overlap, shifted, sizeof(overlap)) == 0, "_Vacopy copies the overflow area before the offsets");
|
||||
}
|
||||
|
||||
static std::string Contents(FileStream& stream) {
|
||||
std::fflush(stream.GetHandle());
|
||||
std::rewind(stream.GetHandle());
|
||||
|
||||
Reference in new issue
Block a user