From dcaedc89a00778c513f82786eee5e9b28f660a49 Mon Sep 17 00:00:00 2001 From: raphaelthegreat <47210458+raphaelthegreat@users.noreply.github.com> Date: Wed, 5 Jun 2024 20:22:00 +0300 Subject: [PATCH] kernel: Fix a few memory functions --- src/core/address_space.cpp | 6 +++--- src/core/address_space.h | 2 +- src/core/libraries/kernel/libkernel.cpp | 2 ++ src/core/libraries/kernel/memory_management.cpp | 10 ++++++++-- src/core/libraries/kernel/memory_management.h | 2 ++ src/core/loader/symbols_resolver.cpp | 13 ++++--------- src/core/memory.cpp | 4 ++-- src/core/memory.h | 4 ++-- src/core/module.cpp | 1 - src/core/tls.cpp | 1 + 10 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index f10527b9e..ceafa7ba6 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -102,14 +102,14 @@ struct AddressSpace::Impl { // Perform the map. void* ptr = nullptr; - if (phys_addr) { + if (phys_addr != -1) { ptr = MapViewOfFile3(backing_handle, process, reinterpret_cast(virtual_addr), phys_addr, size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0); } else { ptr = VirtualAlloc2(process, reinterpret_cast(virtual_addr), size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0); } - ASSERT(ptr); + ASSERT_MSG(ptr, "{}", Common::GetLastErrorMsg()); return ptr; } @@ -121,7 +121,7 @@ struct AddressSpace::Impl { // (virtual_addr == 0 ? reinterpret_cast(SYSTEM_MANAGED_MIN) // : reinterpret_cast(virtual_addr)); req.HighestEndingAddress = reinterpret_cast(SYSTEM_MANAGED_MAX); - req.Alignment = alignment; + req.Alignment = alignment < 64_KB ? 0 : alignment; param.Type = MemExtendedParameterAddressRequirements; param.Pointer = &req; ULONG alloc_type = MEM_COMMIT | MEM_RESERVE | (alignment > 2_MB ? MEM_LARGE_PAGES : 0); diff --git a/src/core/address_space.h b/src/core/address_space.h index 963e9afae..322ab9c7f 100644 --- a/src/core/address_space.h +++ b/src/core/address_space.h @@ -42,7 +42,7 @@ public: * If zero is provided the mapping is considered as private. * @return A pointer to the mapped memory. */ - void* Map(VAddr virtual_addr, size_t size, u64 alignment = 0, PAddr phys_addr = 0); + void* Map(VAddr virtual_addr, size_t size, u64 alignment = 0, PAddr phys_addr = -1); /// Unmaps specified virtual memory area. void Unmap(VAddr virtual_addr, size_t size); diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index 3fc70d6bf..96f7c429d 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -204,6 +204,8 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard); // memory LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateDirectMemory); + LIB_FUNCTION("B+vc2AO2Zrc", "libkernel", 1, "libkernel", 1, 1, + sceKernelAllocateMainDirectMemory); LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize); LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory); LIB_FUNCTION("WFcfL2lzido", "libkernel", 1, "libkernel", 1, 1, sceKernelQueryMemoryProtection); diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index 88525241d..6b7780ee0 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -23,12 +23,12 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!"); return SCE_KERNEL_ERROR_EINVAL; } - const bool is_in_range = (searchStart < len && searchEnd > len); + const bool is_in_range = searchEnd - searchStart >= len; if (len <= 0 || !Common::Is16KBAligned(len) || !is_in_range) { LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!"); return SCE_KERNEL_ERROR_EINVAL; } - if ((alignment != 0 || Common::Is16KBAligned(alignment)) && !std::has_single_bit(alignment)) { + if (alignment != 0 && !Common::Is16KBAligned(alignment)) { LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!"); return SCE_KERNEL_ERROR_EINVAL; } @@ -49,6 +49,12 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u return SCE_OK; } +s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType, + s64* physAddrOut) { + return sceKernelAllocateDirectMemory(0, SCE_KERNEL_MAIN_DMEM_SIZE, len, alignment, memoryType, + physAddrOut); +} + int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, s64 directMemoryStart, u64 alignment) { LOG_INFO( diff --git a/src/core/libraries/kernel/memory_management.h b/src/core/libraries/kernel/memory_management.h index 9433c1aaa..23d25a227 100644 --- a/src/core/libraries/kernel/memory_management.h +++ b/src/core/libraries/kernel/memory_management.h @@ -41,6 +41,8 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u u64 alignment, int memoryType, s64* physAddrOut); int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, s64 directMemoryStart, u64 alignment); +s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType, + s64* physAddrOut); s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addrInOut, std::size_t len, int prot, int flags, const char* name); s32 PS4_SYSV_ABI sceKernelMapFlexibleMemory(void** addr_in_out, std::size_t len, int prot, diff --git a/src/core/loader/symbols_resolver.cpp b/src/core/loader/symbols_resolver.cpp index e294f7423..9a8c95845 100644 --- a/src/core/loader/symbols_resolver.cpp +++ b/src/core/loader/symbols_resolver.cpp @@ -38,17 +38,12 @@ void SymbolsResolver::DebugDump(const std::filesystem::path& file_name) { Common::FS::FileType::TextFile}; for (const auto& symbol : m_symbols) { const auto ids = Common::SplitString(symbol.name, '#'); - std::string nidName = ""; - auto aeronid = AeroLib::FindByNid(ids.at(0).c_str()); - if (aeronid != nullptr) { - nidName = aeronid->name; - } else { - nidName = "UNK"; - } + const auto aeronid = AeroLib::FindByNid(ids.at(0).c_str()); + const auto nid_name = aeronid ? aeronid->name : "UNK"; f.WriteString( fmt::format("0x{:<20x} {:<16} {:<60} {:<30} {:<2} {:<30} {:<2} {:<2} {:<10}\n", - symbol.virtual_address, ids.at(0), nidName, ids.at(1), ids.at(2), ids.at(3), - ids.at(4), ids.at(5), ids.at(6))); + symbol.virtual_address, ids.at(0), nid_name, ids.at(1), ids.at(2), + ids.at(3), ids.at(4), ids.at(5), ids.at(6))); } } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 0e99fab4d..8ecd311b9 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -26,7 +26,7 @@ MemoryManager::~MemoryManager() = default; PAddr MemoryManager::Allocate(PAddr search_start, PAddr search_end, size_t size, u64 alignment, int memory_type) { - PAddr free_addr = 0; + PAddr free_addr = search_start; // Iterate through allocated blocked and find the next free position for (const auto& block : allocations) { @@ -99,7 +99,7 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M } // Perform the mapping. - *out_addr = impl.Map(mapped_addr, size); + *out_addr = impl.Map(mapped_addr, size, alignment, phys_addr); return ORBIS_OK; } diff --git a/src/core/memory.h b/src/core/memory.h index ab9006a45..7a623db70 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -107,7 +107,7 @@ public: int MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot, MemoryMapFlags flags, VMAType type, std::string_view name = "", - PAddr phys_addr = 0, u64 alignment = 0); + PAddr phys_addr = -1, u64 alignment = 0); void UnmapMemory(VAddr virtual_addr, size_t size); @@ -121,7 +121,7 @@ private: VMAHandle FindVMA(VAddr target) { // Return first the VMA with base >= target. const auto it = vma_map.lower_bound(target); - if (it->first == target) { + if (it != vma_map.end() && it->first == target) { return it; } return std::prev(it); diff --git a/src/core/module.cpp b/src/core/module.cpp index 01da8bf60..cb266a2f3 100644 --- a/src/core/module.cpp +++ b/src/core/module.cpp @@ -349,7 +349,6 @@ void Module::LoadSymbols() { const auto aeronid = AeroLib::FindByNid(ids.at(0).c_str()); const auto nid_name = aeronid ? aeronid->name : "UNK"; - LOG_INFO(Core_Linker, "NidName {}", nid_name); Loader::SymbolResolver sym_r{}; sym_r.name = ids.at(0); diff --git a/src/core/tls.cpp b/src/core/tls.cpp index 57bce1d9b..de0ba9bfd 100644 --- a/src/core/tls.cpp +++ b/src/core/tls.cpp @@ -83,6 +83,7 @@ void PatchTLS(u64 segment_addr, u64 segment_size, Xbyak::CodeGenerator& c) { std::memcpy(&offset, code + tls_pattern.pattern_size, sizeof(u64)); LOG_INFO(Core_Linker, "PATTERN64 FOUND at {}, reg: {} offset: {:#x}", fmt::ptr(code), tls_pattern.target_reg, offset); + continue; } ASSERT(offset == 0);