From c1d01709bed276b174a90a679100ecbc8576c2bc Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Mon, 29 Jul 2024 19:08:06 +0300 Subject: [PATCH] kernel: Implement sceKernelSetVirtualRangeName (#338) * Fix in searchFree should fix #337 * clang format fix * sceKernelSetVirtualRangeName implementation * improved vaddr conversion * updated VirtualQuery to include name too * unmap also removed name thanks @red_prig * fixed copy... --- src/core/libraries/kernel/libkernel.cpp | 1 + src/core/libraries/kernel/memory_management.cpp | 15 +++++++++++++++ src/core/libraries/kernel/memory_management.h | 2 ++ src/core/memory.cpp | 11 ++++++++++- src/core/memory.h | 2 ++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index a7f619f1..5f2e5a50 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -407,6 +407,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("2SKEx6bSq-4", "libkernel", 1, "libkernel", 1, 1, sceKernelBatchMap); LIB_FUNCTION("kBJzF8x4SyE", "libkernel", 1, "libkernel", 1, 1, sceKernelBatchMap2); + LIB_FUNCTION("DGMG3JshrZU", "libkernel", 1, "libkernel", 1, 1, sceKernelSetVirtualRangeName); // equeue LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateEqueue); diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index 988b69d0..d396e1d7 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -274,4 +274,19 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn return result; } +s32 PS4_SYSV_ABI sceKernelSetVirtualRangeName(const void* addr, size_t len, const char* name) { + static constexpr size_t MaxNameSize = 32; + if (std::strlen(name) > MaxNameSize) { + LOG_ERROR(Kernel_Vmm, "name exceeds 32 bytes!"); + return ORBIS_KERNEL_ERROR_ENAMETOOLONG; + } + + if (name == nullptr) { + LOG_ERROR(Kernel_Vmm, "name is invalid!"); + return ORBIS_KERNEL_ERROR_EFAULT; + } + auto* memory = Core::Memory::Instance(); + memory->NameVirtualRange(std::bit_cast(addr), len, name); + return ORBIS_OK; +} } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/memory_management.h b/src/core/libraries/kernel/memory_management.h index cc89dfa7..25a4a9f0 100644 --- a/src/core/libraries/kernel/memory_management.h +++ b/src/core/libraries/kernel/memory_management.h @@ -108,4 +108,6 @@ s32 PS4_SYSV_ABI sceKernelBatchMap(OrbisKernelBatchMapEntry* entries, int numEnt s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEntries, int* numEntriesOut, int flags); +s32 PS4_SYSV_ABI sceKernelSetVirtualRangeName(const void* addr, size_t len, const char* name); + } // namespace Libraries::Kernel diff --git a/src/core/memory.cpp b/src/core/memory.cpp index f2607bff..27e05f41 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -188,7 +188,7 @@ int MemoryManager::MapFile(void** out_addr, VAddr virtual_addr, size_t size, Mem // Find first free area to map the file. if (False(flags & MemoryMapFlags::Fixed)) { - mapped_addr = SearchFree(mapped_addr, size_aligned); + mapped_addr = SearchFree(mapped_addr, size_aligned, 1); } if (True(flags & MemoryMapFlags::Fixed)) { @@ -235,6 +235,7 @@ void MemoryManager::UnmapMemory(VAddr virtual_addr, size_t size) { vma.prot = MemoryProt::NoAccess; vma.phys_base = 0; vma.disallow_merge = false; + vma.name = ""; MergeAdjacent(vma_map, new_it); // Unmap the memory region. @@ -280,6 +281,7 @@ int MemoryManager::VirtualQuery(VAddr addr, int flags, info->is_flexible.Assign(vma.type == VMAType::Flexible); info->is_direct.Assign(vma.type == VMAType::Direct); info->is_commited.Assign(vma.type != VMAType::Free); + vma.name.copy(info->name.data(), std::min(info->name.size(), vma.name.size())); if (vma.type == VMAType::Direct) { const auto dmem_it = FindDmemArea(vma.phys_base); ASSERT(dmem_it != dmem_map.end()); @@ -338,6 +340,13 @@ std::pair MemoryManager::GetVulkanBuffer(VAddr addr) { return std::make_pair(*it->second.buffer, addr - it->first); } +void MemoryManager::NameVirtualRange(VAddr virtual_addr, size_t size, std::string_view name) { + auto it = FindVMA(virtual_addr); + + ASSERT_MSG(it->second.Contains(virtual_addr, size), + "Range provided is not fully containted in vma"); + it->second.name = name; +} VAddr MemoryManager::SearchFree(VAddr virtual_addr, size_t size, u32 alignment) { auto it = FindVMA(virtual_addr); // If the VMA is free and contains the requested mapping we are done. diff --git a/src/core/memory.h b/src/core/memory.h index ff4af5cd..2b3d07a7 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -177,6 +177,8 @@ public: int GetDirectMemoryType(PAddr addr, int* directMemoryTypeOut, void** directMemoryStartOut, void** directMemoryEndOut); + void NameVirtualRange(VAddr virtual_addr, size_t size, std::string_view name); + private: VMAHandle FindVMA(VAddr target) { return std::prev(vma_map.upper_bound(target));