fix(libs): fix libc building on win

This commit is contained in:
boykopovar 2026-08-22 16:16:11 +03:00
parent 5a1d7525f9
commit a89b9228f1
2 changed files with 58 additions and 5 deletions

View File

@ -1,6 +1,8 @@
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <new>
extern "C" {
@ -36,20 +38,56 @@ int fflush_nid_postfix(FILE* stream) {
return std::fflush(stream);
}
constexpr std::uintptr_t AlignedBlockTag = 1;
void* malloc_nid_postfix(size_t size) {
return std::malloc(size);
const size_t headerSize = sizeof(std::uintptr_t);
void* rawPtr = std::malloc(size + headerSize);
if (rawPtr == nullptr) {
throw std::bad_alloc();
}
*reinterpret_cast<std::uintptr_t*>(rawPtr) = 0;
return static_cast<char*>(rawPtr) + headerSize;
}
void free_nid_postfix(void* ptr) {
std::free(ptr);
if (ptr == nullptr) {
return;
}
const std::uintptr_t headerValue = reinterpret_cast<std::uintptr_t*>(ptr)[-1];
if (headerValue == AlignedBlockTag) {
std::free(reinterpret_cast<void**>(ptr)[-2]);
} else {
std::free(reinterpret_cast<char*>(ptr) - sizeof(std::uintptr_t));
}
}
void* realloc_nid_postfix(void* ptr, size_t newSize) {
return std::realloc(ptr, newSize);
if (ptr == nullptr) {
return malloc_nid_postfix(newSize);
}
const size_t headerSize = sizeof(std::uintptr_t);
void* rawPtr = static_cast<char*>(ptr) - headerSize;
void* newRawPtr = std::realloc(rawPtr, newSize + headerSize);
if (newRawPtr == nullptr) {
throw std::bad_alloc();
}
return static_cast<char*>(newRawPtr) + headerSize;
}
void* memalign_nid_postfix(size_t alignment, size_t size) {
return std::aligned_alloc(alignment, size);
const size_t headerSize = sizeof(void*) * 2;
const size_t worstCaseSize = size + alignment + headerSize;
void* rawPtr = std::malloc(worstCaseSize);
if (rawPtr == nullptr) {
throw std::bad_alloc();
}
const std::uintptr_t rawAddress = reinterpret_cast<std::uintptr_t>(rawPtr) + headerSize;
const std::uintptr_t alignedAddress = (rawAddress + alignment - 1) & ~(alignment - 1);
void* alignedPtr = reinterpret_cast<void*>(alignedAddress);
reinterpret_cast<void**>(alignedPtr)[-1] = reinterpret_cast<void*>(AlignedBlockTag);
reinterpret_cast<void**>(alignedPtr)[-2] = rawPtr;
return alignedPtr;
}
void qsort_nid_postfix(void* base, size_t count, size_t size, int (*compare)(const void*, const void*)) {

View File

@ -1,5 +1,6 @@
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include "SceTypes.hpp"
@ -37,7 +38,21 @@ int atexit_nid_postfix(atexit_func_t func) {
}
int setenv_nid_postfix(const char* name, const char* value, int overwrite) {
return ::setenv(name, value, overwrite);
if (overwrite == 0 && std::getenv(name) != nullptr) {
return 0;
}
const size_t nameLength = std::strlen(name);
const size_t valueLength = std::strlen(value);
char* entry = static_cast<char*>(std::malloc(nameLength + valueLength + 2));
if (entry == nullptr) {
errno = ENOMEM;
return -1;
}
std::memcpy(entry, name, nameLength);
entry[nameLength] = '=';
std::memcpy(entry + nameLength + 1, value, valueLength);
entry[nameLength + 1 + valueLength] = '\0';
return ::putenv(entry);
}
}