mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-02 19:08:03 -06:00
Initialize heap API and run malloc_init
Purely for testing
This commit is contained in:
parent
975b1d312a
commit
3949cf411f
@ -308,6 +308,38 @@ s32 PS4_SYSV_ABI sceKernelMapFlexibleMemory(void** addr_in_out, u64 len, s32 pro
|
||||
return sceKernelMapNamedFlexibleMemory(addr_in_out, len, prot, flags, "anon");
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelMapNamedSystemFlexibleMemory(void** addr_in_out, u64 len, s32 prot,
|
||||
s32 flags, const char* name) {
|
||||
LOG_INFO(Kernel_Vmm, "in_addr = {}, len = {:#x}, prot = {:#x}, flags = {:#x}, name = '{}'",
|
||||
fmt::ptr(*addr_in_out), len, prot, flags, name);
|
||||
if (len == 0 || !Common::Is16KBAligned(len)) {
|
||||
LOG_ERROR(Kernel_Vmm, "len is 0 or not 16kb multiple");
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
if (name == nullptr) {
|
||||
LOG_ERROR(Kernel_Vmm, "name is invalid!");
|
||||
return ORBIS_KERNEL_ERROR_EFAULT;
|
||||
}
|
||||
|
||||
if (std::strlen(name) >= ORBIS_KERNEL_MAXIMUM_NAME_LENGTH) {
|
||||
LOG_ERROR(Kernel_Vmm, "name exceeds 32 bytes!");
|
||||
return ORBIS_KERNEL_ERROR_ENAMETOOLONG;
|
||||
}
|
||||
|
||||
VAddr in_addr = reinterpret_cast<VAddr>(*addr_in_out);
|
||||
if (in_addr == 0) {
|
||||
in_addr = 0x880000000;
|
||||
}
|
||||
const auto mem_prot = static_cast<Core::MemoryProt>(prot);
|
||||
const auto map_flags = static_cast<Core::MemoryMapFlags>(flags);
|
||||
auto* memory = Core::Memory::Instance();
|
||||
const auto ret = memory->MapMemory(addr_in_out, in_addr, len, mem_prot, map_flags,
|
||||
Core::VMAType::Stack, name);
|
||||
LOG_INFO(Kernel_Vmm, "out_addr = {}", fmt::ptr(*addr_in_out));
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** end, u32* prot) {
|
||||
auto* memory = Core::Memory::Instance();
|
||||
return memory->QueryProtection(std::bit_cast<VAddr>(addr), start, end, prot);
|
||||
@ -823,6 +855,7 @@ void RegisterMemory(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("PGhQHd-dzv8", "libkernel", 1, "libkernel", sceKernelMmap);
|
||||
LIB_FUNCTION("cQke9UuBQOk", "libkernel", 1, "libkernel", sceKernelMunmap);
|
||||
LIB_FUNCTION("mL8NDH86iQI", "libkernel", 1, "libkernel", sceKernelMapNamedFlexibleMemory);
|
||||
LIB_FUNCTION("kc+LEEIYakc", "libkernel", 1, "libkernel", sceKernelMapNamedSystemFlexibleMemory);
|
||||
LIB_FUNCTION("aNz11fnnzi4", "libkernel", 1, "libkernel", sceKernelAvailableFlexibleMemorySize);
|
||||
LIB_FUNCTION("aNz11fnnzi4", "libkernel_avlfmem", 1, "libkernel",
|
||||
sceKernelAvailableFlexibleMemorySize);
|
||||
|
||||
@ -69,6 +69,67 @@ void Linker::Execute(const std::vector<std::string>& args) {
|
||||
Relocate(m.get());
|
||||
}
|
||||
|
||||
// Before we can run guest code, we need to properly initialize the heap API and
|
||||
// libSceLibcInternal. libSceLibcInternal's _malloc_init serves as an additional initialization
|
||||
// function called by libkernel.
|
||||
heap_api = new HeapAPI{};
|
||||
static PS4_SYSV_ABI void (*malloc_init)();
|
||||
|
||||
for (const auto& m : m_modules) {
|
||||
const auto& mod = m.get();
|
||||
if (mod->name.contains("libSceLibcInternal.sprx")) {
|
||||
// Found libSceLibcInternal, now search through function exports.
|
||||
// Looking for _malloc_init to init libSceLibcInternal properly
|
||||
// and for all the memory allocating functions, so we can initialize our heap API
|
||||
for (const auto& sym : mod->export_sym.GetSymbols()) {
|
||||
if (sym.nid_name.compare("_malloc_init") == 0) {
|
||||
malloc_init = reinterpret_cast<PS4_SYSV_ABI void (*)()>(sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("malloc") == 0) {
|
||||
heap_api->heap_malloc =
|
||||
reinterpret_cast<PS4_SYSV_ABI void* (*)(u64)>(sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("free") == 0) {
|
||||
heap_api->heap_free =
|
||||
reinterpret_cast<PS4_SYSV_ABI void (*)(void*)>(sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("calloc") == 0) {
|
||||
heap_api->heap_calloc =
|
||||
reinterpret_cast<PS4_SYSV_ABI void* (*)(u64, u64)>(sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("realloc") == 0) {
|
||||
heap_api->heap_realloc =
|
||||
reinterpret_cast<PS4_SYSV_ABI void* (*)(void*, u64)>(sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("memalign") == 0) {
|
||||
heap_api->heap_memalign =
|
||||
reinterpret_cast<PS4_SYSV_ABI void* (*)(u64, u64)>(sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("posix_memalign") == 0) {
|
||||
heap_api->heap_posix_memalign =
|
||||
reinterpret_cast<PS4_SYSV_ABI s32 (*)(void**, u64, u64)>(
|
||||
sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("reallocalign") == 0) {
|
||||
heap_api->heap_reallocalign =
|
||||
reinterpret_cast<PS4_SYSV_ABI s32 (*)()>(sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("malloc_stats") == 0) {
|
||||
heap_api->heap_malloc_stats =
|
||||
reinterpret_cast<PS4_SYSV_ABI void (*)()>(sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("malloc_stats_fast") == 0) {
|
||||
heap_api->heap_malloc_stats_fast =
|
||||
reinterpret_cast<PS4_SYSV_ABI s32 (*)()>(sym.virtual_address);
|
||||
}
|
||||
if (sym.nid_name.compare("malloc_usable_size") == 0) {
|
||||
heap_api->heap_malloc_usable_size =
|
||||
reinterpret_cast<PS4_SYSV_ABI u64 (*)(void*)>(sym.virtual_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Configure the direct and flexible memory regions.
|
||||
u64 fmem_size = ORBIS_FLEXIBLE_MEMORY_SIZE;
|
||||
bool use_extended_mem1 = true, use_extended_mem2 = true;
|
||||
@ -112,6 +173,9 @@ void Linker::Execute(const std::vector<std::string>& args) {
|
||||
|
||||
LoadSharedLibraries();
|
||||
|
||||
// Call _malloc_init
|
||||
malloc_init();
|
||||
|
||||
// Simulate libSceGnmDriver initialization, which maps a chunk of direct memory.
|
||||
// Some games fail without accurately emulating this behavior.
|
||||
s64 phys_addr{};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user