* Handle empty mutex attribute - scePthreadMutexInit did not return default when the mutex attributes were empty, now it does * fix conditional unsafety * Update thread_management.cpp fix deref * accurate heap api - modified HeapAPI to a struct with preset function fields - utilized the full array parameter passed to _sceKernelRtldSetApplicationHeapAPI * fallback to std malloc * clang format * Declare all HeapAPI replacement functions - calloc, realloc, memalign, reallocalign, malloc_stats, malloc_stats_fast, malloc_usable_size - posix_memalign corrected parameters * resolve suggestions - `using` definition replacement for AppHeapAPI - linux uses heap_malloc, windows uses std::malloc --------- Co-authored-by: microsoftv <6063922+microsoftv@users.noreply.github.com>
This commit is contained in:
parent
18f1799280
commit
5eecd089ab
|
@ -212,9 +212,9 @@ s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* out_size) {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func) {
|
void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func[]) {
|
||||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
linker->SetHeapApiFunc(func);
|
linker->SetHeapAPI(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelGetDirectMemoryType(u64 addr, int* directMemoryTypeOut,
|
int PS4_SYSV_ABI sceKernelGetDirectMemoryType(u64 addr, int* directMemoryTypeOut,
|
||||||
|
|
|
@ -98,7 +98,7 @@ int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void**
|
||||||
int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info,
|
int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info,
|
||||||
size_t infoSize);
|
size_t infoSize);
|
||||||
s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* sizeOut);
|
s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* sizeOut);
|
||||||
void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func);
|
void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func[]);
|
||||||
int PS4_SYSV_ABI sceKernelGetDirectMemoryType(u64 addr, int* directMemoryTypeOut,
|
int PS4_SYSV_ABI sceKernelGetDirectMemoryType(u64 addr, int* directMemoryTypeOut,
|
||||||
void** directMemoryStartOut,
|
void** directMemoryStartOut,
|
||||||
void** directMemoryEndOut);
|
void** directMemoryEndOut);
|
||||||
|
|
|
@ -421,13 +421,21 @@ ScePthreadMutex* createMutex(ScePthreadMutex* addr) {
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr,
|
int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* mutex_attr,
|
||||||
const char* name) {
|
const char* name) {
|
||||||
|
const ScePthreadMutexattr* attr;
|
||||||
|
|
||||||
if (mutex == nullptr) {
|
if (mutex == nullptr) {
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
if (attr == nullptr) {
|
if (mutex_attr == nullptr) {
|
||||||
attr = g_pthread_cxt->getDefaultMutexattr();
|
attr = g_pthread_cxt->getDefaultMutexattr();
|
||||||
|
} else {
|
||||||
|
if (*mutex_attr == nullptr) {
|
||||||
|
attr = g_pthread_cxt->getDefaultMutexattr();
|
||||||
|
} else {
|
||||||
|
attr = mutex_attr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*mutex = new PthreadMutexInternal{};
|
*mutex = new PthreadMutexInternal{};
|
||||||
|
|
|
@ -305,7 +305,8 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) {
|
||||||
// Module was just loaded by above code. Allocate TLS block for it.
|
// Module was just loaded by above code. Allocate TLS block for it.
|
||||||
Module* module = m_modules[module_index - 1].get();
|
Module* module = m_modules[module_index - 1].get();
|
||||||
const u32 init_image_size = module->tls.init_image_size;
|
const u32 init_image_size = module->tls.init_image_size;
|
||||||
u8* dest = reinterpret_cast<u8*>(heap_api_func(module->tls.image_size));
|
// TODO: Determine if Windows will crash from this
|
||||||
|
u8* dest = reinterpret_cast<u8*>(heap_api->heap_malloc(module->tls.image_size));
|
||||||
const u8* src = reinterpret_cast<const u8*>(module->tls.image_virtual_addr);
|
const u8* src = reinterpret_cast<const u8*>(module->tls.image_virtual_addr);
|
||||||
std::memcpy(dest, src, init_image_size);
|
std::memcpy(dest, src, init_image_size);
|
||||||
std::memset(dest + init_image_size, 0, module->tls.image_size - init_image_size);
|
std::memset(dest + init_image_size, 0, module->tls.image_size - init_image_size);
|
||||||
|
@ -335,10 +336,23 @@ void Linker::InitTlsForThread(bool is_primary) {
|
||||||
&addr_out, tls_aligned, 3, 0, "SceKernelPrimaryTcbTls");
|
&addr_out, tls_aligned, 3, 0, "SceKernelPrimaryTcbTls");
|
||||||
ASSERT_MSG(ret == 0, "Unable to allocate TLS+TCB for the primary thread");
|
ASSERT_MSG(ret == 0, "Unable to allocate TLS+TCB for the primary thread");
|
||||||
} else {
|
} else {
|
||||||
if (heap_api_func) {
|
if (heap_api) {
|
||||||
addr_out = heap_api_func(total_tls_size);
|
#ifndef WIN32
|
||||||
|
addr_out = heap_api->heap_malloc(total_tls_size);
|
||||||
} else {
|
} else {
|
||||||
addr_out = std::malloc(total_tls_size);
|
addr_out = std::malloc(total_tls_size);
|
||||||
|
#else
|
||||||
|
// TODO: Windows tls malloc replacement, refer to rtld_tls_block_malloc
|
||||||
|
LOG_ERROR(Core_Linker, "TLS user malloc called, using std::malloc");
|
||||||
|
addr_out = std::malloc(total_tls_size);
|
||||||
|
if (!addr_out) {
|
||||||
|
auto pth_id = pthread_self();
|
||||||
|
auto handle = pthread_gethandle(pth_id);
|
||||||
|
ASSERT_MSG(addr_out,
|
||||||
|
"Cannot allocate TLS block defined for handle=%x, index=%d size=%d",
|
||||||
|
handle, pth_id, total_tls_size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,21 @@ struct EntryParams {
|
||||||
const char* argv[3];
|
const char* argv[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
using HeapApiFunc = PS4_SYSV_ABI void* (*)(size_t);
|
struct HeapAPI {
|
||||||
|
PS4_SYSV_ABI void* (*heap_malloc)(size_t);
|
||||||
|
PS4_SYSV_ABI void (*heap_free)(void*);
|
||||||
|
PS4_SYSV_ABI void* (*heap_calloc)(size_t, size_t);
|
||||||
|
PS4_SYSV_ABI void* (*heap_realloc)(void*, size_t);
|
||||||
|
PS4_SYSV_ABI void* (*heap_memalign)(size_t, size_t);
|
||||||
|
PS4_SYSV_ABI int (*heap_posix_memalign)(void**, size_t, size_t);
|
||||||
|
// NOTE: Fields below may be inaccurate
|
||||||
|
PS4_SYSV_ABI int (*heap_reallocalign)(void);
|
||||||
|
PS4_SYSV_ABI void (*heap_malloc_stats)(void);
|
||||||
|
PS4_SYSV_ABI int (*heap_malloc_stats_fast)(void);
|
||||||
|
PS4_SYSV_ABI size_t (*heap_malloc_usable_size)(void*);
|
||||||
|
};
|
||||||
|
|
||||||
|
using AppHeapAPI = HeapAPI*;
|
||||||
|
|
||||||
class Linker {
|
class Linker {
|
||||||
public:
|
public:
|
||||||
|
@ -75,8 +89,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetHeapApiFunc(void* func) {
|
void SetHeapAPI(void* func[]) {
|
||||||
heap_api_func = *reinterpret_cast<HeapApiFunc*>(func);
|
heap_api = reinterpret_cast<AppHeapAPI>(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvanceGenerationCounter() noexcept {
|
void AdvanceGenerationCounter() noexcept {
|
||||||
|
@ -104,7 +118,7 @@ private:
|
||||||
size_t static_tls_size{};
|
size_t static_tls_size{};
|
||||||
u32 max_tls_index{};
|
u32 max_tls_index{};
|
||||||
u32 num_static_modules{};
|
u32 num_static_modules{};
|
||||||
HeapApiFunc heap_api_func{};
|
AppHeapAPI heap_api{};
|
||||||
std::vector<std::unique_ptr<Module>> m_modules;
|
std::vector<std::unique_ptr<Module>> m_modules;
|
||||||
Loader::SymbolsResolver m_hle_symbols{};
|
Loader::SymbolsResolver m_hle_symbols{};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue