From 4caff51710a793c6c2c1069ddd6e92185aa731fe Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 31 Mar 2020 15:10:44 -0400 Subject: core: memory: Move to Core::Memory namespace. - helpful to disambiguate Kernel::Memory namespace. --- src/core/hle/service/audio/audout_u.cpp | 2 +- src/core/hle/service/lm/lm.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 4fb2cbc4b..106e89743 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -210,7 +210,7 @@ private: /// This is the event handle used to check if the audio buffer was released Kernel::EventPair buffer_event; - Memory::Memory& main_memory; + Core::Memory::Memory& main_memory; }; AudOutU::AudOutU(Core::System& system_) : ServiceFramework("audout:u"), system{system_} { diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index 346c8f899..dec96b771 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -17,7 +17,7 @@ namespace Service::LM { class ILogger final : public ServiceFramework { public: - explicit ILogger(Manager& manager_, Memory::Memory& memory_) + explicit ILogger(Manager& manager_, Core::Memory::Memory& memory_) : ServiceFramework("ILogger"), manager{manager_}, memory{memory_} { static const FunctionInfo functions[] = { {0, &ILogger::Log, "Log"}, @@ -75,12 +75,12 @@ private: } Manager& manager; - Memory::Memory& memory; + Core::Memory::Memory& memory; }; class LM final : public ServiceFramework { public: - explicit LM(Manager& manager_, Memory::Memory& memory_) + explicit LM(Manager& manager_, Core::Memory::Memory& memory_) : ServiceFramework{"lm"}, manager{manager_}, memory{memory_} { // clang-format off static const FunctionInfo functions[] = { @@ -101,7 +101,7 @@ private: } Manager& manager; - Memory::Memory& memory; + Core::Memory::Memory& memory; }; void InstallInterfaces(Core::System& system) { -- cgit v1.2.3 From 8bbc38a7bd59e285c4098c1a70528455c4bb0f29 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 8 Apr 2020 21:08:28 -0400 Subject: service: irs: Update for new shared memory layout. --- src/core/hle/service/hid/irs.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index 5e79e2c1a..36ed6f7da 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp @@ -6,6 +6,7 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/hid/irs.h" @@ -38,9 +39,8 @@ IRS::IRS(Core::System& system) : ServiceFramework{"irs"}, system(system) { RegisterHandlers(functions); auto& kernel = system.Kernel(); - shared_mem = Kernel::SharedMemory::Create( - kernel, nullptr, 0x8000, Kernel::MemoryPermission::ReadWrite, - Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "IRS:SharedMemory"); + + shared_mem = SharedFrom(&kernel.GetIrsSharedMem()); } void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) { -- cgit v1.2.3 From 8eca0f9cd22fd49470dfcba1132d1cf0f897b6ca Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 8 Apr 2020 21:08:44 -0400 Subject: service: hid: Update for new shared memory layout. --- src/core/hle/service/hid/hid.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index d6ed5f304..d6031a987 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -14,6 +14,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/readable_event.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/writable_event.h" @@ -53,9 +54,7 @@ IAppletResource::IAppletResource(Core::System& system) RegisterHandlers(functions); auto& kernel = system.Kernel(); - shared_mem = Kernel::SharedMemory::Create( - kernel, nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite, - Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); + shared_mem = SharedFrom(&kernel.GetHidSharedMem()); MakeController(HidController::DebugPad); MakeController(HidController::Touchscreen); -- cgit v1.2.3 From 67b3df683b91ca7f207c0ead898ee09bd5c4ec58 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 8 Apr 2020 21:09:16 -0400 Subject: service: time: Update for new shared memory layout. --- src/core/hle/service/time/time_sharedmemory.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index fdaef233f..999ec1e51 100644 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp @@ -6,6 +6,7 @@ #include "core/core_timing.h" #include "core/core_timing_util.h" #include "core/hardware_properties.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/service/time/clock_types.h" #include "core/hle/service/time/steady_clock_core.h" #include "core/hle/service/time/time_sharedmemory.h" @@ -15,9 +16,7 @@ namespace Service::Time { static constexpr std::size_t SHARED_MEMORY_SIZE{0x1000}; SharedMemory::SharedMemory(Core::System& system) : system(system) { - shared_memory_holder = Kernel::SharedMemory::Create( - system.Kernel(), nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite, - Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "Time:SharedMemory"); + shared_memory_holder = SharedFrom(&system.Kernel().GetTimeSharedMem()); std::memset(shared_memory_holder->GetPointer(), 0, SHARED_MEMORY_SIZE); } -- cgit v1.2.3 From 77382ac2b2d29b69b2a1140ba43e6a178ff4187f Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 8 Apr 2020 21:10:02 -0400 Subject: service: pl_u: Update for new shared memory layout. --- src/core/hle/service/ns/pl_u.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 8da4e52c5..ab1746d28 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -19,6 +19,7 @@ #include "core/file_sys/romfs.h" #include "core/file_sys/system_archive/system_archive.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_memory.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/filesystem/filesystem.h" @@ -265,16 +266,13 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) { void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { // Map backing memory for the font data LOG_DEBUG(Service_NS, "called"); - system.CurrentProcess()->VMManager().MapMemoryBlock(SHARED_FONT_MEM_VADDR, impl->shared_font, 0, - SHARED_FONT_MEM_SIZE, - Kernel::MemoryState::Shared); // Create shared font memory object auto& kernel = system.Kernel(); - impl->shared_font_mem = Kernel::SharedMemory::Create( - kernel, system.CurrentProcess(), SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite, - Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE, - "PL_U:shared_font_mem"); + impl->shared_font_mem = SharedFrom(&kernel.GetFontSharedMem()); + + std::memcpy(impl->shared_font_mem->GetPointer(), impl->shared_font->data(), + impl->shared_font->size()); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); -- cgit v1.2.3 From 37b79ebe854003d2ba1d08a4523fd8cab418d485 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 9 Apr 2020 13:50:55 -0400 Subject: service: ldr: Updates for new VMM. - Includes removing some service impls. that are untested. --- src/core/hle/service/ldr/ldr.cpp | 365 +++++++++++++++++++++++---------------- 1 file changed, 215 insertions(+), 150 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 647943020..73a2bc770 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -8,14 +8,21 @@ #include "common/alignment.h" #include "common/hex_util.h" +#include "common/scope_exit.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/errors.h" +#include "core/hle/kernel/memory/page_table.h" +#include "core/hle/kernel/memory/system_control.h" #include "core/hle/kernel/process.h" #include "core/hle/service/ldr/ldr.h" #include "core/hle/service/service.h" #include "core/loader/nro.h" +#include "core/memory.h" namespace Service::LDR { +constexpr ResultCode ERROR_INSUFFICIENT_ADDRESS_SPACE{ErrorModule::RO, 2}; + constexpr ResultCode ERROR_INVALID_MEMORY_STATE{ErrorModule::Loader, 51}; constexpr ResultCode ERROR_INVALID_NRO{ErrorModule::Loader, 52}; constexpr ResultCode ERROR_INVALID_NRR{ErrorModule::Loader, 53}; @@ -29,7 +36,61 @@ constexpr ResultCode ERROR_INVALID_NRO_ADDRESS{ErrorModule::Loader, 84}; constexpr ResultCode ERROR_INVALID_NRR_ADDRESS{ErrorModule::Loader, 85}; constexpr ResultCode ERROR_NOT_INITIALIZED{ErrorModule::Loader, 87}; -constexpr u64 MAXIMUM_LOADED_RO = 0x40; +constexpr std::size_t MAXIMUM_LOADED_RO{0x40}; +constexpr std::size_t MAXIMUM_MAP_RETRIES{0x200}; + +struct NRRHeader { + u32_le magic; + INSERT_PADDING_BYTES(12); + u64_le title_id_mask; + u64_le title_id_pattern; + INSERT_PADDING_BYTES(16); + std::array modulus; + std::array signature_1; + std::array signature_2; + u64_le title_id; + u32_le size; + INSERT_PADDING_BYTES(4); + u32_le hash_offset; + u32_le hash_count; + INSERT_PADDING_BYTES(8); +}; +static_assert(sizeof(NRRHeader) == 0x350, "NRRHeader has incorrect size."); + +struct NROHeader { + INSERT_PADDING_WORDS(1); + u32_le mod_offset; + INSERT_PADDING_WORDS(2); + u32_le magic; + u32_le version; + u32_le nro_size; + u32_le flags; + u32_le text_offset; + u32_le text_size; + u32_le ro_offset; + u32_le ro_size; + u32_le rw_offset; + u32_le rw_size; + u32_le bss_size; + INSERT_PADDING_WORDS(1); + std::array build_id; + INSERT_PADDING_BYTES(0x20); +}; +static_assert(sizeof(NROHeader) == 0x80, "NROHeader has invalid size."); + +using SHA256Hash = std::array; + +struct NROInfo { + SHA256Hash hash{}; + VAddr nro_address{}; + std::size_t nro_size{}; + VAddr bss_address{}; + std::size_t bss_size{}; + std::size_t text_size{}; + std::size_t ro_size{}; + std::size_t data_size{}; + VAddr src_addr{}; +}; class DebugMonitor final : public ServiceFramework { public: @@ -84,7 +145,7 @@ public: {0, &RelocatableObject::LoadNro, "LoadNro"}, {1, &RelocatableObject::UnloadNro, "UnloadNro"}, {2, &RelocatableObject::LoadNrr, "LoadNrr"}, - {3, &RelocatableObject::UnloadNrr, "UnloadNrr"}, + {3, nullptr, "UnloadNrr"}, {4, &RelocatableObject::Initialize, "Initialize"}, {10, nullptr, "LoadNrrEx"}, }; @@ -190,46 +251,127 @@ public: rb.Push(RESULT_SUCCESS); } - void UnloadNrr(Kernel::HLERequestContext& ctx) { - if (!initialized) { - LOG_ERROR(Service_LDR, "LDR:RO not initialized before use!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_NOT_INITIALIZED); - return; + bool ValidateRegionForMap(Kernel::Memory::PageTable& page_table, VAddr start, + std::size_t size) const { + constexpr std::size_t padding_size{4 * Kernel::Memory::PageSize}; + const auto start_info{page_table.QueryInfo(start - 1)}; + + if (start_info.state != Kernel::Memory::MemoryState::Free) { + return {}; } - struct Parameters { - u64_le process_id; - u64_le nrr_address; - }; + if (start_info.GetAddress() > (start - padding_size)) { + return {}; + } - IPC::RequestParser rp{ctx}; - const auto [process_id, nrr_address] = rp.PopRaw(); + const auto end_info{page_table.QueryInfo(start + size)}; - LOG_DEBUG(Service_LDR, "called with process_id={:016X}, nrr_addr={:016X}", process_id, - nrr_address); + if (end_info.state != Kernel::Memory::MemoryState::Free) { + return {}; + } - if (!Common::Is4KBAligned(nrr_address)) { - LOG_ERROR(Service_LDR, "NRR Address has invalid alignment (actual {:016X})!", - nrr_address); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_ALIGNMENT); - return; + return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize()); + } + + VAddr GetRandomMapRegion(const Kernel::Memory::PageTable& page_table, std::size_t size) const { + VAddr addr{}; + const std::size_t end_pages{(page_table.GetAliasCodeRegionSize() - size) >> + Kernel::Memory::PageBits}; + do { + addr = page_table.GetAliasCodeRegionStart() + + (Kernel::Memory::SystemControl::GenerateRandomRange(0, end_pages) + << Kernel::Memory::PageBits); + } while (!page_table.IsInsideAddressSpace(addr, size) || + page_table.IsInsideHeapRegion(addr, size) || + page_table.IsInsideAliasRegion(addr, size)); + return addr; + } + + ResultVal MapProcessCodeMemory(Kernel::Process* process, VAddr baseAddress, + u64 size) const { + for (int retry{}; retry < MAXIMUM_MAP_RETRIES; retry++) { + auto& page_table{process->PageTable()}; + const VAddr addr{GetRandomMapRegion(page_table, size)}; + const ResultCode result{page_table.MapProcessCodeMemory(addr, baseAddress, size)}; + + if (result == Kernel::ERR_INVALID_ADDRESS_STATE) { + continue; + } + + if (result.IsError()) { + return result; + } + + if (ValidateRegionForMap(page_table, addr, size)) { + return MakeResult(addr); + } } - const auto iter = nrr.find(nrr_address); - if (iter == nrr.end()) { - LOG_ERROR(Service_LDR, - "Attempting to unload NRR which has not been loaded! (addr={:016X})", - nrr_address); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_NRR_ADDRESS); - return; + return ERROR_INSUFFICIENT_ADDRESS_SPACE; + } + + ResultVal MapNro(Kernel::Process* process, VAddr nro_addr, std::size_t nro_size, + VAddr bss_addr, std::size_t bss_size, std::size_t size) const { + + for (int retry{}; retry < MAXIMUM_MAP_RETRIES; retry++) { + auto& page_table{process->PageTable()}; + VAddr addr{}; + + CASCADE_RESULT(addr, MapProcessCodeMemory(process, nro_addr, nro_size)); + + if (bss_size) { + auto block_guard = detail::ScopeExit([&] { + page_table.UnmapProcessCodeMemory(addr + nro_size, bss_addr, bss_size); + page_table.UnmapProcessCodeMemory(addr, nro_addr, nro_size); + }); + + const ResultCode result{ + page_table.MapProcessCodeMemory(addr + nro_size, bss_addr, bss_size)}; + + if (result == Kernel::ERR_INVALID_ADDRESS_STATE) { + continue; + } + + if (result.IsError()) { + return result; + } + + block_guard.Cancel(); + } + + if (ValidateRegionForMap(page_table, addr, size)) { + return MakeResult(addr); + } } - nrr.erase(iter); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_SUCCESS); + return ERROR_INSUFFICIENT_ADDRESS_SPACE; + } + + ResultCode LoadNro(Kernel::Process* process, const NROHeader& nro_header, VAddr nro_addr, + VAddr start) const { + const VAddr text_start{start + nro_header.text_offset}; + const VAddr ro_start{start + nro_header.ro_offset}; + const VAddr data_start{start + nro_header.rw_offset}; + const VAddr bss_start{data_start + nro_header.rw_size}; + const VAddr bss_end_addr{ + Common::AlignUp(bss_start + nro_header.bss_size, Kernel::Memory::PageSize)}; + + auto CopyCode{[&](VAddr src_addr, VAddr dst_addr, u64 size) { + std::vector source_data(size); + system.Memory().ReadBlock(src_addr, source_data.data(), source_data.size()); + system.Memory().WriteBlock(dst_addr, source_data.data(), source_data.size()); + }}; + CopyCode(nro_addr + nro_header.text_offset, text_start, nro_header.text_size); + CopyCode(nro_addr + nro_header.ro_offset, ro_start, nro_header.ro_size); + CopyCode(nro_addr + nro_header.rw_offset, data_start, nro_header.rw_size); + + CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( + text_start, ro_start - text_start, Kernel::Memory::MemoryPermission::ReadAndExecute)); + CASCADE_CODE(process->PageTable().SetCodeMemoryPermission( + ro_start, data_start - ro_start, Kernel::Memory::MemoryPermission::Read)); + + return process->PageTable().SetCodeMemoryPermission( + data_start, bss_end_addr - data_start, Kernel::Memory::MemoryPermission::ReadAndWrite); } void LoadNro(Kernel::HLERequestContext& ctx) { @@ -317,9 +459,9 @@ public: return; } - NROHeader header; + // Load and validate the NRO header + NROHeader header{}; std::memcpy(&header, nro_data.data(), sizeof(NROHeader)); - if (!IsValidNRO(header, nro_size, bss_size)) { LOG_ERROR(Service_LDR, "NRO was invalid!"); IPC::ResponseBuilder rb{ctx, 2}; @@ -327,62 +469,49 @@ public: return; } - // Load NRO as new executable module - auto* process = system.CurrentProcess(); - auto& vm_manager = process->VMManager(); - auto map_address = vm_manager.FindFreeRegion(nro_size + bss_size); - - if (!map_address.Succeeded() || - *map_address + nro_size + bss_size > vm_manager.GetAddressSpaceEndAddress()) { - - LOG_ERROR(Service_LDR, - "General error while allocation memory or no available memory to allocate!"); + // Map memory for the NRO + const ResultVal map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, + bss_address, bss_size, nro_size + bss_size)}; + if (map_result.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_MEMORY_STATE); - return; + rb.Push(map_result.Code()); } - // Mark text and read-only region as ModuleCode - ASSERT(vm_manager - .MirrorMemory(*map_address, nro_address, header.text_size + header.ro_size, - Kernel::MemoryState::ModuleCode) - .IsSuccess()); - // Mark read/write region as ModuleCodeData, which is necessary if this region is used for - // TransferMemory (e.g. Final Fantasy VIII Remastered does this) - ASSERT(vm_manager - .MirrorMemory(*map_address + header.rw_offset, nro_address + header.rw_offset, - header.rw_size, Kernel::MemoryState::ModuleCodeData) - .IsSuccess()); - // Revoke permissions from the old memory region - ASSERT(vm_manager.ReprotectRange(nro_address, nro_size, Kernel::VMAPermission::None) - .IsSuccess()); - - if (bss_size > 0) { - // Mark BSS region as ModuleCodeData, which is necessary if this region is used for - // TransferMemory (e.g. Final Fantasy VIII Remastered does this) - ASSERT(vm_manager - .MirrorMemory(*map_address + nro_size, bss_address, bss_size, - Kernel::MemoryState::ModuleCodeData) - .IsSuccess()); - ASSERT(vm_manager.ReprotectRange(bss_address, bss_size, Kernel::VMAPermission::None) - .IsSuccess()); + // Load the NRO into the mapped memory + if (const ResultCode result{ + LoadNro(system.CurrentProcess(), header, nro_address, *map_result)}; + result.IsError()) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(map_result.Code()); } - vm_manager.ReprotectRange(*map_address, header.text_size, - Kernel::VMAPermission::ReadExecute); - vm_manager.ReprotectRange(*map_address + header.ro_offset, header.ro_size, - Kernel::VMAPermission::Read); - vm_manager.ReprotectRange(*map_address + header.rw_offset, header.rw_size, - Kernel::VMAPermission::ReadWrite); + // Track the loaded NRO + nro.insert_or_assign(*map_result, NROInfo{hash, *map_result, nro_size, bss_address, + bss_size, header.text_size, header.ro_size, + header.rw_size, nro_address}); + // Invalidate JIT caches for the newly mapped process code system.InvalidateCpuInstructionCaches(); - nro.insert_or_assign(*map_address, - NROInfo{hash, nro_address, nro_size, bss_address, bss_size}); - IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.Push(*map_address); + rb.Push(*map_result); + } + + ResultCode UnmapNro(const NROInfo& info) { + // Each region must be unmapped separately to validate memory state + auto& page_table{system.CurrentProcess()->PageTable()}; + CASCADE_CODE(page_table.UnmapProcessCodeMemory(info.nro_address + info.text_size + + info.ro_size + info.data_size, + info.bss_address, info.bss_size)); + CASCADE_CODE(page_table.UnmapProcessCodeMemory( + info.nro_address + info.text_size + info.ro_size, + info.src_addr + info.text_size + info.ro_size, info.data_size)); + CASCADE_CODE(page_table.UnmapProcessCodeMemory( + info.nro_address + info.text_size, info.src_addr + info.text_size, info.ro_size)); + CASCADE_CODE( + page_table.UnmapProcessCodeMemory(info.nro_address, info.src_addr, info.text_size)); + return RESULT_SUCCESS; } void UnloadNro(Kernel::HLERequestContext& ctx) { @@ -422,30 +551,15 @@ public: return; } - auto& vm_manager = system.CurrentProcess()->VMManager(); - const auto& nro_info = iter->second; - - // Unmap the mirrored memory - ASSERT( - vm_manager.UnmapRange(nro_address, nro_info.nro_size + nro_info.bss_size).IsSuccess()); - - // Reprotect the source memory - ASSERT(vm_manager - .ReprotectRange(nro_info.nro_address, nro_info.nro_size, - Kernel::VMAPermission::ReadWrite) - .IsSuccess()); - if (nro_info.bss_size > 0) { - ASSERT(vm_manager - .ReprotectRange(nro_info.bss_address, nro_info.bss_size, - Kernel::VMAPermission::ReadWrite) - .IsSuccess()); - } + const ResultCode result{UnmapNro(iter->second)}; system.InvalidateCpuInstructionCaches(); nro.erase(iter); + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_SUCCESS); + + rb.Push(result); } void Initialize(Kernel::HLERequestContext& ctx) { @@ -458,56 +572,7 @@ public: } private: - using SHA256Hash = std::array; - - struct NROHeader { - INSERT_PADDING_WORDS(1); - u32_le mod_offset; - INSERT_PADDING_WORDS(2); - u32_le magic; - u32_le version; - u32_le nro_size; - u32_le flags; - u32_le text_offset; - u32_le text_size; - u32_le ro_offset; - u32_le ro_size; - u32_le rw_offset; - u32_le rw_size; - u32_le bss_size; - INSERT_PADDING_WORDS(1); - std::array build_id; - INSERT_PADDING_BYTES(0x20); - }; - static_assert(sizeof(NROHeader) == 0x80, "NROHeader has invalid size."); - - struct NRRHeader { - u32_le magic; - INSERT_PADDING_BYTES(12); - u64_le title_id_mask; - u64_le title_id_pattern; - INSERT_PADDING_BYTES(16); - std::array modulus; - std::array signature_1; - std::array signature_2; - u64_le title_id; - u32_le size; - INSERT_PADDING_BYTES(4); - u32_le hash_offset; - u32_le hash_count; - INSERT_PADDING_BYTES(8); - }; - static_assert(sizeof(NRRHeader) == 0x350, "NRRHeader has incorrect size."); - - struct NROInfo { - SHA256Hash hash; - VAddr nro_address; - u64 nro_size; - VAddr bss_address; - u64 bss_size; - }; - - bool initialized = false; + bool initialized{}; std::map nro; std::map> nrr; -- cgit v1.2.3 From 8bbe74a8dc62cd3933fd08237e707b0059fe8a78 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 17 Apr 2020 00:59:08 -0400 Subject: core: hle: Address various feedback & code cleanup. - Should be no functional changes. --- src/core/device_memory.h | 16 +- src/core/hle/kernel/memory/address_space_info.cpp | 22 +- .../hle/kernel/memory/memory_block_manager.cpp | 6 +- src/core/hle/kernel/memory/memory_manager.cpp | 29 ++- src/core/hle/kernel/memory/page_heap.h | 48 ++-- src/core/hle/kernel/memory/page_table.cpp | 256 +++++++-------------- src/core/hle/kernel/memory/system_control.cpp | 6 +- src/core/hle/kernel/shared_memory.cpp | 4 +- src/core/hle/kernel/shared_memory.h | 2 +- src/core/hle/kernel/svc.cpp | 2 +- src/core/hle/service/ldr/ldr.cpp | 13 +- 11 files changed, 153 insertions(+), 251 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/device_memory.h b/src/core/device_memory.h index ff66e202d..9efa088d0 100644 --- a/src/core/device_memory.h +++ b/src/core/device_memory.h @@ -13,13 +13,15 @@ namespace Core { class System; namespace DramMemoryMap { -constexpr u64 Base = 0x80000000ULL; -constexpr u64 Size = 0x100000000ULL; -constexpr u64 End = Base + Size; -constexpr u64 KernelReserveBase = Base + 0x60000; -constexpr u64 SlabHeapBase = KernelReserveBase + 0x85000; -constexpr u64 SlapHeapSize = 0xa21000; -constexpr u64 SlabHeapEnd = SlabHeapBase + SlapHeapSize; +enum : u64 { + Base = 0x80000000ULL, + Size = 0x100000000ULL, + End = Base + Size, + KernelReserveBase = Base + 0x60000, + SlabHeapBase = KernelReserveBase + 0x85000, + SlapHeapSize = 0xa21000, + SlabHeapEnd = SlabHeapBase + SlapHeapSize, +}; }; // namespace DramMemoryMap class DeviceMemory : NonCopyable { diff --git a/src/core/hle/kernel/memory/address_space_info.cpp b/src/core/hle/kernel/memory/address_space_info.cpp index 6a267c951..27fae05e7 100644 --- a/src/core/hle/kernel/memory/address_space_info.cpp +++ b/src/core/hle/kernel/memory/address_space_info.cpp @@ -14,16 +14,18 @@ namespace Kernel::Memory { namespace { -constexpr std::size_t Size_1_MB{0x100000}; -constexpr std::size_t Size_2_MB{2 * Size_1_MB}; -constexpr std::size_t Size_128_MB{128 * Size_1_MB}; -constexpr std::size_t Size_1_GB{0x40000000}; -constexpr std::size_t Size_2_GB{2 * Size_1_GB}; -constexpr std::size_t Size_4_GB{4 * Size_1_GB}; -constexpr std::size_t Size_6_GB{6 * Size_1_GB}; -constexpr std::size_t Size_64_GB{64 * Size_1_GB}; -constexpr std::size_t Size_512_GB{512 * Size_1_GB}; -constexpr u64 Invalid{std::numeric_limits::max()}; +enum : u64 { + Size_1_MB = 0x100000, + Size_2_MB = 2 * Size_1_MB, + Size_128_MB = 128 * Size_1_MB, + Size_1_GB = 0x40000000, + Size_2_GB = 2 * Size_1_GB, + Size_4_GB = 4 * Size_1_GB, + Size_6_GB = 6 * Size_1_GB, + Size_64_GB = 64 * Size_1_GB, + Size_512_GB = 512 * Size_1_GB, + Invalid = std::numeric_limits::max(), +}; // clang-format off constexpr std::array AddressSpaceInfos{{ diff --git a/src/core/hle/kernel/memory/memory_block_manager.cpp b/src/core/hle/kernel/memory/memory_block_manager.cpp index da009566f..1ebc126c0 100644 --- a/src/core/hle/kernel/memory/memory_block_manager.cpp +++ b/src/core/hle/kernel/memory/memory_block_manager.cpp @@ -15,7 +15,7 @@ MemoryBlockManager::MemoryBlockManager(VAddr start_addr, VAddr end_addr) } MemoryBlockManager::iterator MemoryBlockManager::FindIterator(VAddr addr) { - iterator node{memory_block_tree.begin()}; + auto node{memory_block_tree.begin()}; while (node != end()) { const VAddr end_addr{node->GetNumPages() * PageSize + node->GetAddress()}; if (node->GetAddress() <= addr && end_addr - 1 >= addr) { @@ -35,8 +35,8 @@ VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_nu const VAddr region_end{region_start + region_num_pages * PageSize}; const VAddr region_last{region_end - 1}; - for (const_iterator it{FindIterator(region_start)}; it != memory_block_tree.cend(); it++) { - const MemoryInfo info{it->GetMemoryInfo()}; + for (auto it{FindIterator(region_start)}; it != memory_block_tree.cend(); it++) { + const auto info{it->GetMemoryInfo()}; if (region_last < info.GetAddress()) { break; } diff --git a/src/core/hle/kernel/memory/memory_manager.cpp b/src/core/hle/kernel/memory/memory_manager.cpp index 9c1bb981b..3cd4f9e85 100644 --- a/src/core/hle/kernel/memory/memory_manager.cpp +++ b/src/core/hle/kernel/memory/memory_manager.cpp @@ -15,15 +15,14 @@ namespace Kernel::Memory { std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) { - const std::size_t size{end_address - start_address}; + const auto size{end_address - start_address}; // Calculate metadata sizes - const std::size_t ref_count_size{(size / PageSize) * sizeof(u16)}; - const std::size_t optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * - sizeof(u64)}; - const std::size_t manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)}; - const std::size_t page_heap_size{PageHeap::CalculateMetadataOverheadSize(size)}; - const std::size_t total_metadata_size{manager_size + page_heap_size}; + const auto ref_count_size{(size / PageSize) * sizeof(u16)}; + const auto optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * sizeof(u64)}; + const auto manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)}; + const auto page_heap_size{PageHeap::CalculateMetadataOverheadSize(size)}; + const auto total_metadata_size{manager_size + page_heap_size}; ASSERT(manager_size <= total_metadata_size); ASSERT(Common::IsAligned(total_metadata_size, PageSize)); @@ -55,7 +54,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align } // Lock the pool that we're allocating from - const std::size_t pool_index{static_cast(pool)}; + const auto pool_index{static_cast(pool)}; std::lock_guard lock{pool_locks[pool_index]}; // Choose a heap based on our page size request @@ -72,7 +71,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align } // If we allocated more than we need, free some - const std::size_t allocated_pages{PageHeap::GetBlockNumPages(heap_index)}; + const auto allocated_pages{PageHeap::GetBlockNumPages(heap_index)}; if (allocated_pages > num_pages) { chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages); } @@ -90,7 +89,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa } // Lock the pool that we're allocating from - const std::size_t pool_index{static_cast(pool)}; + const auto pool_index{static_cast(pool)}; std::lock_guard lock{pool_locks[pool_index]}; // Choose a heap based on our page size request @@ -105,7 +104,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa // Ensure that we don't leave anything un-freed auto group_guard = detail::ScopeExit([&] { for (const auto& it : page_list.Nodes()) { - const std::size_t num_pages{std::min( + const auto num_pages{std::min( it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; chosen_manager.Free(it.GetAddress(), num_pages); } @@ -113,12 +112,12 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa // Keep allocating until we've allocated all our pages for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) { - const std::size_t pages_per_alloc{PageHeap::GetBlockNumPages(index)}; + const auto pages_per_alloc{PageHeap::GetBlockNumPages(index)}; while (num_pages >= pages_per_alloc) { // Allocate a block VAddr allocated_block{chosen_manager.AllocateBlock(index)}; - if (allocated_block == 0) { + if (!allocated_block) { break; } @@ -158,7 +157,7 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages, } // Lock the pool that we're freeing from - const std::size_t pool_index{static_cast(pool)}; + const auto pool_index{static_cast(pool)}; std::lock_guard lock{pool_locks[pool_index]}; // TODO (bunnei): Support multiple managers @@ -166,7 +165,7 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages, // Free all of the pages for (const auto& it : page_list.Nodes()) { - const std::size_t num_pages{std::min( + const auto num_pages{std::min( it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; chosen_manager.Free(it.GetAddress(), num_pages); } diff --git a/src/core/hle/kernel/memory/page_heap.h b/src/core/hle/kernel/memory/page_heap.h index 39ca45ab1..380c3f5a1 100644 --- a/src/core/hle/kernel/memory/page_heap.h +++ b/src/core/hle/kernel/memory/page_heap.h @@ -22,9 +22,10 @@ namespace Kernel::Memory { class PageHeap final : NonCopyable { public: static constexpr s32 GetAlignedBlockIndex(std::size_t num_pages, std::size_t align_pages) { - const std::size_t target_pages{std::max(num_pages, align_pages)}; + const auto target_pages{std::max(num_pages, align_pages)}; for (std::size_t i = 0; i < NumMemoryBlockPageShifts; i++) { - if (target_pages <= (std::size_t(1) << MemoryBlockPageShifts[i]) / PageSize) { + if (target_pages <= + (static_cast(1) << MemoryBlockPageShifts[i]) / PageSize) { return static_cast(i); } } @@ -33,7 +34,7 @@ public: static constexpr s32 GetBlockIndex(std::size_t num_pages) { for (s32 i{static_cast(NumMemoryBlockPageShifts) - 1}; i >= 0; i--) { - if (num_pages >= (std::size_t(1) << MemoryBlockPageShifts[i]) / PageSize) { + if (num_pages >= (static_cast(1) << MemoryBlockPageShifts[i]) / PageSize) { return i; } } @@ -41,7 +42,7 @@ public: } static constexpr std::size_t GetBlockSize(std::size_t index) { - return std::size_t(1) << MemoryBlockPageShifts[index]; + return static_cast(1) << MemoryBlockPageShifts[index]; } static constexpr std::size_t GetBlockNumPages(std::size_t index) { @@ -51,7 +52,8 @@ public: private: static constexpr std::size_t NumMemoryBlockPageShifts{7}; static constexpr std::array MemoryBlockPageShifts{ - 0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E}; + 0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E, + }; class Block final : NonCopyable { private: @@ -122,13 +124,13 @@ private: constexpr bool ClearRange(std::size_t offset, std::size_t count) { const s32 depth{GetHighestDepthIndex()}; - const std::size_t bit_ind{offset / 64}; + const auto bit_ind{offset / 64}; u64* bits{bit_storages[depth]}; if (count < 64) { - const std::size_t shift{offset % 64}; + const auto shift{offset % 64}; ASSERT(shift + count <= 64); // Check that all the bits are set - const u64 mask{((u64(1) << count) - 1) << shift}; + const u64 mask{((1ULL << count) - 1) << shift}; u64 v{bits[bit_ind]}; if ((v & mask) != mask) { return false; @@ -171,9 +173,9 @@ private: private: constexpr void SetBit(s32 depth, std::size_t offset) { while (depth >= 0) { - const std::size_t ind{offset / 64}; - const std::size_t which{offset % 64}; - const u64 mask{u64(1) << which}; + const auto ind{offset / 64}; + const auto which{offset % 64}; + const u64 mask{1ULL << which}; u64* bit{std::addressof(bit_storages[depth][ind])}; const u64 v{*bit}; @@ -189,9 +191,9 @@ private: constexpr void ClearBit(s32 depth, std::size_t offset) { while (depth >= 0) { - const std::size_t ind{offset / 64}; - const std::size_t which{offset % 64}; - const u64 mask{u64(1) << which}; + const auto ind{offset / 64}; + const auto which{offset % 64}; + const u64 mask{1ULL << which}; u64* bit{std::addressof(bit_storages[depth][ind])}; u64 v{*bit}; @@ -246,7 +248,7 @@ private: return next_block_shift; } constexpr std::size_t GetSize() const { - return std::size_t(1) << GetShift(); + return static_cast(1) << GetShift(); } constexpr std::size_t GetNumPages() const { return GetSize() / PageSize; @@ -266,13 +268,13 @@ private: // Align up the address VAddr end{addr + size}; - const std::size_t align{(next_block_shift != 0) ? (u64(1) << next_block_shift) - : (u64(1) << block_shift)}; + const auto align{(next_block_shift != 0) ? (1ULL << next_block_shift) + : (1ULL << block_shift)}; addr = Common::AlignDown((addr), align); end = Common::AlignUp((end), align); heap_address = addr; - end_offset = (end - addr) / (u64(1) << block_shift); + end_offset = (end - addr) / (1ULL << block_shift); return bitmap.Initialize(bit_storage, end_offset); } @@ -283,7 +285,7 @@ private: // If we have a next shift, try to clear the blocks below and return the address if (GetNextShift()) { - const std::size_t diff{u64(1) << (GetNextShift() - GetShift())}; + const auto diff{1ULL << (GetNextShift() - GetShift())}; offset = Common::AlignDown(offset, diff); if (bitmap.ClearRange(offset, diff)) { return heap_address + (offset << GetShift()); @@ -300,7 +302,7 @@ private: if (soffset < 0) { return 0; } - const std::size_t offset{static_cast(soffset)}; + const auto offset{static_cast(soffset)}; // Update our tracking and return it bitmap.ClearBit(offset); @@ -311,9 +313,9 @@ private: static constexpr std::size_t CalculateMetadataOverheadSize(std::size_t region_size, std::size_t cur_block_shift, std::size_t next_block_shift) { - const std::size_t cur_block_size{(u64(1) << cur_block_shift)}; - const std::size_t next_block_size{(u64(1) << next_block_shift)}; - const std::size_t align{(next_block_shift != 0) ? next_block_size : cur_block_size}; + const auto cur_block_size{(1ULL << cur_block_shift)}; + const auto next_block_size{(1ULL << next_block_shift)}; + const auto align{(next_block_shift != 0) ? next_block_size : cur_block_size}; return Bitmap::CalculateMetadataOverheadSize( (align * 2 + Common::AlignUp(region_size, align)) / cur_block_size); } diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index 941ecda21..091e52ca4 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp @@ -64,10 +64,10 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t bool enable_aslr, VAddr code_addr, std::size_t code_size, Memory::MemoryManager::Pool pool) { - const auto GetSpaceStart = [&](AddressSpaceInfo::Type type) { + const auto GetSpaceStart = [this](AddressSpaceInfo::Type type) { return AddressSpaceInfo::GetAddressSpaceStart(address_space_width, type); }; - const auto GetSpaceSize = [&](AddressSpaceInfo::Type type) { + const auto GetSpaceSize = [this](AddressSpaceInfo::Type type) { return AddressSpaceInfo::GetAddressSpaceSize(address_space_width, type); }; @@ -286,17 +286,9 @@ ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemorySt } PageLinkedList page_linked_list; - if (const ResultCode result{ - system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)}; - result.IsError()) { - return result; - } - - if (const ResultCode result{ - Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)}; - result.IsError()) { - return result; - } + CASCADE_CODE( + system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); + CASCADE_CODE(Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)); block_manager->Update(addr, num_pages, state, perm); @@ -310,13 +302,10 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:: MemoryState state{}; MemoryPermission perm{}; - if (const ResultCode result{CheckMemoryState( - &state, &perm, nullptr, src_addr, size, MemoryState::All, MemoryState::Normal, - MemoryPermission::Mask, MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, - MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, MemoryState::All, + MemoryState::Normal, MemoryPermission::Mask, + MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, + MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); if (IsRegionMapped(dst_addr, size)) { return ERR_INVALID_ADDRESS_STATE; @@ -329,16 +318,9 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:: auto block_guard = detail::ScopeExit( [&] { Operate(src_addr, num_pages, perm, OperationType::ChangePermissions); }); - if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::None, - OperationType::ChangePermissions)}; - result.IsError()) { - return result; - } - - if (const ResultCode result{MapPages(dst_addr, page_linked_list, MemoryPermission::None)}; - result.IsError()) { - return result; - } + CASCADE_CODE( + Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); + CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::None)); block_guard.Cancel(); } @@ -359,35 +341,20 @@ ResultCode PageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std const std::size_t num_pages{size / PageSize}; - if (const ResultCode result{CheckMemoryState( - nullptr, nullptr, nullptr, src_addr, size, MemoryState::All, MemoryState::Normal, - MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, - MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, src_addr, size, MemoryState::All, + MemoryState::Normal, MemoryPermission::None, + MemoryPermission::None, MemoryAttribute::Mask, + MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); MemoryState state{}; - if (const ResultCode result{CheckMemoryState( - &state, nullptr, nullptr, dst_addr, PageSize, MemoryState::FlagCanCodeAlias, - MemoryState::FlagCanCodeAlias, MemoryPermission::None, MemoryPermission::None, - MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; - result.IsError()) { - return result; - } - - if (const ResultCode result{CheckMemoryState(dst_addr, size, MemoryState::All, state, - MemoryPermission::None, MemoryPermission::None, - MemoryAttribute::Mask, MemoryAttribute::None)}; - result.IsError()) { - return result; - } - - if (const ResultCode result{ - Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState( + &state, nullptr, nullptr, dst_addr, PageSize, MemoryState::FlagCanCodeAlias, + MemoryState::FlagCanCodeAlias, MemoryPermission::None, MemoryPermission::None, + MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); + CASCADE_CODE(CheckMemoryState(dst_addr, size, MemoryState::All, state, MemoryPermission::None, + MemoryPermission::None, MemoryAttribute::Mask, + MemoryAttribute::None)); + CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); block_manager->Update(dst_addr, num_pages, MemoryState::Free); block_manager->Update(src_addr, num_pages, MemoryState::Normal, MemoryPermission::ReadAndWrite); @@ -459,11 +426,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size); }); - if (const ResultCode result{system.Kernel().MemoryManager().Allocate( - page_linked_list, remaining_pages, memory_pool)}; - result.IsError()) { - return result; - } + CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, + memory_pool)); block_guard.Cancel(); } @@ -508,9 +472,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) { return RESULT_SUCCESS; } - if (const ResultCode result{UnmapMemory(addr, size)}; result.IsError()) { - return result; - } + CASCADE_CODE(UnmapMemory(addr, size)); auto process{system.Kernel().CurrentProcess()}; process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size); @@ -559,13 +521,10 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { std::lock_guard lock{page_table_lock}; MemoryState src_state{}; - if (const ResultCode result{CheckMemoryState( - &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, - MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::ReadAndWrite, - MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState( + &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, + MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::ReadAndWrite, + MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); if (IsRegionMapped(dst_addr, size)) { return ERR_INVALID_ADDRESS_STATE; @@ -582,17 +541,9 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { OperationType::ChangePermissions); }); - if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::None, - OperationType::ChangePermissions)}; - result.IsError()) { - return result; - } - - if (const ResultCode result{ - MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite)}; - result.IsError()) { - return result; - } + CASCADE_CODE( + Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); + CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite)); block_guard.Cancel(); } @@ -608,22 +559,16 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { std::lock_guard lock{page_table_lock}; MemoryState src_state{}; - if (const ResultCode result{CheckMemoryState( - &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, - MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::None, - MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState( + &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, + MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::None, + MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); MemoryPermission dst_perm{}; - if (const ResultCode result{CheckMemoryState( - nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All, MemoryState::Stack, - MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, - MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All, + MemoryState::Stack, MemoryPermission::None, + MemoryPermission::None, MemoryAttribute::Mask, + MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); PageLinkedList src_pages; PageLinkedList dst_pages; @@ -639,17 +584,9 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { { auto block_guard = detail::ScopeExit([&] { MapPages(dst_addr, dst_pages, dst_perm); }); - if (const ResultCode result{ - Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)}; - result.IsError()) { - return result; - } - - if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, - OperationType::ChangePermissions)}; - result.IsError()) { - return result; - } + CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); + CASCADE_CODE(Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, + OperationType::ChangePermissions)); block_guard.Cancel(); } @@ -665,7 +602,7 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis VAddr cur_addr{addr}; for (const auto& node : page_linked_list.Nodes()) { - if (const ResultCode result{ + if (const auto result{ Operate(cur_addr, node.GetNumPages(), perm, OperationType::Map, node.GetAddress())}; result.IsError()) { const MemoryInfo info{block_manager->FindBlock(cur_addr).GetMemoryInfo()}; @@ -698,9 +635,7 @@ ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, Mem return ERR_INVALID_ADDRESS_STATE; } - if (const ResultCode result{MapPages(addr, page_linked_list, perm)}; result.IsError()) { - return result; - } + CASCADE_CODE(MapPages(addr, page_linked_list, perm)); block_manager->Update(addr, num_pages, state, perm); @@ -714,13 +649,10 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo MemoryState prev_state{}; MemoryPermission prev_perm{}; - if (const ResultCode result{CheckMemoryState( - &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode, - MemoryState::FlagCode, MemoryPermission::None, MemoryPermission::None, - MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState( + &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode, MemoryState::FlagCode, + MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, + MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); MemoryState state{prev_state}; @@ -745,9 +677,7 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo ? OperationType::ChangePermissionsAndRefresh : OperationType::ChangePermissions}; - if (const ResultCode result{Operate(addr, num_pages, perm, operation)}; result.IsError()) { - return result; - } + CASCADE_CODE(Operate(addr, num_pages, perm, operation)); block_manager->Update(addr, num_pages, state, perm); @@ -775,15 +705,12 @@ ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, Memory MemoryState state{}; MemoryAttribute attribute{}; - if (const ResultCode result{CheckMemoryState( - &state, nullptr, &attribute, addr, size, - MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, - MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, - MemoryPermission::Mask, MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, - MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState(&state, nullptr, &attribute, addr, size, + MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, + MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, + MemoryPermission::Mask, MemoryPermission::ReadAndWrite, + MemoryAttribute::Mask, MemoryAttribute::None, + MemoryAttribute::IpcAndDeviceMapped)); block_manager->Update(addr, size / PageSize, state, perm, attribute | MemoryAttribute::Locked); @@ -795,15 +722,12 @@ ResultCode PageTable::ResetTransferMemory(VAddr addr, std::size_t size) { MemoryState state{}; - if (const ResultCode result{ - CheckMemoryState(&state, nullptr, nullptr, addr, size, - MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, - MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, - MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, - MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState(&state, nullptr, nullptr, addr, size, + MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, + MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, + MemoryPermission::None, MemoryPermission::None, + MemoryAttribute::Mask, MemoryAttribute::Locked, + MemoryAttribute::IpcAndDeviceMapped)); block_manager->Update(addr, size / PageSize, state, MemoryPermission::ReadAndWrite); @@ -818,14 +742,11 @@ ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAtt MemoryPermission perm{}; MemoryAttribute attribute{}; - if (const ResultCode result{CheckMemoryState( - &state, &perm, &attribute, addr, size, MemoryState::FlagCanChangeAttribute, - MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None, - MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None, - MemoryAttribute::DeviceSharedAndUncached)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState(&state, &perm, &attribute, addr, size, + MemoryState::FlagCanChangeAttribute, + MemoryState::FlagCanChangeAttribute, MemoryPermission::None, + MemoryPermission::None, MemoryAttribute::LockedAndIpcLocked, + MemoryAttribute::None, MemoryAttribute::DeviceSharedAndUncached)); attribute = attribute & ~mask; attribute = attribute | (mask & value); @@ -866,21 +787,15 @@ ResultVal PageTable::SetHeapSize(std::size_t size) { PageLinkedList page_linked_list; const std::size_t num_pages{delta / PageSize}; - if (const ResultCode result{ - system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)}; - result.IsError()) { - return result; - } + CASCADE_CODE( + system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); if (IsRegionMapped(current_heap_addr, delta)) { return ERR_INVALID_ADDRESS_STATE; } - if (const ResultCode result{ - Operate(current_heap_addr, num_pages, page_linked_list, OperationType::MapGroup)}; - result.IsError()) { - return result; - } + CASCADE_CODE( + Operate(current_heap_addr, num_pages, page_linked_list, OperationType::MapGroup)); block_manager->Update(current_heap_addr, num_pages, MemoryState::Normal, MemoryPermission::ReadAndWrite); @@ -912,23 +827,12 @@ ResultVal PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s } if (is_map_only) { - if (const ResultCode result{ - Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)}; - result.IsError()) { - return result; - } + CASCADE_CODE(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)); } else { PageLinkedList page_group; - if (const ResultCode result{system.Kernel().MemoryManager().Allocate( - page_group, needed_num_pages, memory_pool)}; - result.IsError()) { - return result; - } - if (const ResultCode result{ - Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)}; - result.IsError()) { - return result; - } + CASCADE_CODE( + system.Kernel().MemoryManager().Allocate(page_group, needed_num_pages, memory_pool)); + CASCADE_CODE(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)); } block_manager->Update(addr, needed_num_pages, state, perm); @@ -1196,11 +1100,7 @@ ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission* } // Validate against the provided masks - if (const ResultCode result{ - CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)}; - result.IsError()) { - return result; - } + CASCADE_CODE(CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); // Break once we're done if (last_addr <= info.GetLastAddress()) { diff --git a/src/core/hle/kernel/memory/system_control.cpp b/src/core/hle/kernel/memory/system_control.cpp index e61522dc0..9cae3c6cb 100644 --- a/src/core/hle/kernel/memory/system_control.cpp +++ b/src/core/hle/kernel/memory/system_control.cpp @@ -11,9 +11,9 @@ namespace Kernel::Memory::SystemControl { u64 GenerateRandomU64ForInit() { - std::random_device device; - std::mt19937 gen(device()); - std::uniform_int_distribution distribution(1, std::numeric_limits::max()); + static std::random_device device; + static std::mt19937 gen(device()); + static std::uniform_int_distribution distribution(1, std::numeric_limits::max()); return distribution(gen); } diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index e28da6869..c67696757 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -40,14 +40,14 @@ ResultCode SharedMemory::Map(Process& target_process, VAddr address, std::size_t const u64 page_count{(size + Memory::PageSize - 1) / Memory::PageSize}; if (page_list.GetNumPages() != page_count) { - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Page count does not match"); } Memory::MemoryPermission expected = &target_process == owner_process ? owner_permission : user_permission; if (permission != expected) { - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Permission does not match"); } return target_process.PageTable().MapPages(address, page_list, Memory::MemoryState::Shared, diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 06fe693de..cd16d6412 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -28,7 +28,7 @@ public: KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, Memory::PageLinkedList&& page_list, Memory::MemoryPermission owner_permission, Memory::MemoryPermission user_permission, PAddr physical_address, std::size_t size, - std::string name = "Unknown"); + std::string name); std::string GetTypeName() const override { return "SharedMemory"; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 5914b5d39..4134acf65 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1196,7 +1196,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add } auto& memory{system.Memory()}; - const Svc::MemoryInfo memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; + const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; memory.Write64(memory_info_address + 0x00, memory_info.addr); memory.Write64(memory_info_address + 0x08, memory_info.size); diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 73a2bc770..0cde7a557 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -298,9 +298,7 @@ public: continue; } - if (result.IsError()) { - return result; - } + CASCADE_CODE(result); if (ValidateRegionForMap(page_table, addr, size)) { return MakeResult(addr); @@ -470,16 +468,15 @@ public: } // Map memory for the NRO - const ResultVal map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, - bss_address, bss_size, nro_size + bss_size)}; + const auto map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, bss_address, + bss_size, nro_size + bss_size)}; if (map_result.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(map_result.Code()); } // Load the NRO into the mapped memory - if (const ResultCode result{ - LoadNro(system.CurrentProcess(), header, nro_address, *map_result)}; + if (const auto result{LoadNro(system.CurrentProcess(), header, nro_address, *map_result)}; result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(map_result.Code()); @@ -551,7 +548,7 @@ public: return; } - const ResultCode result{UnmapNro(iter->second)}; + const auto result{UnmapNro(iter->second)}; system.InvalidateCpuInstructionCaches(); -- cgit v1.2.3