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...
This commit is contained in:
georgemoralis 2024-07-29 19:08:06 +03:00 committed by GitHub
parent 9b1092c995
commit c1d01709be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 30 additions and 1 deletions

View File

@ -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);

View File

@ -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<VAddr>(addr), len, name);
return ORBIS_OK;
}
} // namespace Libraries::Kernel

View File

@ -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

View File

@ -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<vk::Buffer, size_t> 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.

View File

@ -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));