diff options
Diffstat (limited to 'src/core/hle/service')
21 files changed, 276 insertions, 187 deletions
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/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 82a5dbf14..175cabf45 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -129,7 +129,7 @@ private: LOG_DEBUG(Service_Audio, "called. rendering_time_limit_percent={}", rendering_time_limit_percent); - ASSERT(rendering_time_limit_percent >= 0 && rendering_time_limit_percent <= 100); + ASSERT(rendering_time_limit_percent <= 100); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 102017d73..cadc03805 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -451,7 +451,8 @@ FileSys::SaveDataSize FileSystemController::ReadSaveDataSize(FileSys::SaveDataTy if (res != Loader::ResultStatus::Success) { FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()}; - auto [nacp_unique, discard] = pm.GetControlMetadata(); + const auto metadata = pm.GetControlMetadata(); + const auto& nacp_unique = metadata.first; if (nacp_unique != nullptr) { new_size = {nacp_unique->GetDefaultNormalSaveSize(), diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index e6811d5b5..61045c75c 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -575,6 +575,7 @@ private: 0, user_id->GetSize(), {}, + {}, }); continue; @@ -595,6 +596,7 @@ private: stoull_be(title_id->GetName()), title_id->GetSize(), {}, + {}, }); } } @@ -619,6 +621,7 @@ private: stoull_be(title_id->GetName()), title_id->GetSize(), {}, + {}, }); } } diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index c1e32b28c..2ccfffc19 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -107,6 +107,7 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { switch (controller_type) { case NPadControllerType::None: UNREACHABLE(); + break; case NPadControllerType::Handheld: controller.joy_styles.handheld.Assign(1); controller.device_type.handheld.Assign(1); @@ -363,6 +364,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* switch (controller_type) { case NPadControllerType::None: UNREACHABLE(); + break; case NPadControllerType::Handheld: handheld_entry.connection_status.raw = 0; handheld_entry.connection_status.IsWired.Assign(1); 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<Controller_DebugPad>(HidController::DebugPad); MakeController<Controller_Touchscreen>(HidController::Touchscreen); 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) { diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 647943020..0cde7a557 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<u8, 0x100> modulus; + std::array<u8, 0x100> signature_1; + std::array<u8, 0x100> 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<u8, 0x20> build_id; + INSERT_PADDING_BYTES(0x20); +}; +static_assert(sizeof(NROHeader) == 0x80, "NROHeader has invalid size."); + +using SHA256Hash = std::array<u8, 0x20>; + +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<DebugMonitor> { 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,125 @@ 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<Parameters>(); + 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<VAddr> 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; + } + + CASCADE_CODE(result); + + if (ValidateRegionForMap(page_table, addr, size)) { + return MakeResult<VAddr>(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<VAddr> 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<VAddr>(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<u8> 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 +457,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 +467,48 @@ 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 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(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 auto 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 +548,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 auto 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 +569,7 @@ public: } private: - using SHA256Hash = std::array<u8, 0x20>; - - 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<u8, 0x20> 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<u8, 0x100> modulus; - std::array<u8, 0x100> signature_1; - std::array<u8, 0x100> 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<VAddr, NROInfo> nro; std::map<VAddr, std::vector<SHA256Hash>> nrr; 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<ILogger> { 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<LM> { 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) { 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); diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp index f509653a3..ba8fd6152 100644 --- a/src/core/hle/service/time/interface.cpp +++ b/src/core/hle/service/time/interface.cpp @@ -29,7 +29,7 @@ Time::Time(std::shared_ptr<Module> module, Core::System& system, const char* nam {300, &Time::CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, {401, &Time::GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"}, - {500, nullptr, "CalculateStandardUserSystemClockDifferenceByUser"}, + {500, &Time::CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"}, {501, &Time::CalculateSpanBetween, "CalculateSpanBetween"}, }; // clang-format on diff --git a/src/core/hle/service/time/standard_network_system_clock_core.h b/src/core/hle/service/time/standard_network_system_clock_core.h index 3f505c37c..c993bdf79 100644 --- a/src/core/hle/service/time/standard_network_system_clock_core.h +++ b/src/core/hle/service/time/standard_network_system_clock_core.h @@ -23,7 +23,7 @@ public: standard_network_clock_sufficient_accuracy = value; } - bool IsStandardNetworkSystemClockAccuracySufficient(Core::System& system) { + bool IsStandardNetworkSystemClockAccuracySufficient(Core::System& system) const { SystemClockContext context{}; if (GetClockContext(system, context) != RESULT_SUCCESS) { return {}; diff --git a/src/core/hle/service/time/steady_clock_core.h b/src/core/hle/service/time/steady_clock_core.h index 84af3d105..d80a2385f 100644 --- a/src/core/hle/service/time/steady_clock_core.h +++ b/src/core/hle/service/time/steady_clock_core.h @@ -16,6 +16,7 @@ namespace Service::Time::Clock { class SteadyClockCore { public: SteadyClockCore() = default; + virtual ~SteadyClockCore() = default; const Common::UUID& GetClockSourceId() const { return clock_source_id; diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h index 6260de6c3..2b0fa7e75 100644 --- a/src/core/hle/service/time/system_clock_context_update_callback.h +++ b/src/core/hle/service/time/system_clock_context_update_callback.h @@ -20,7 +20,7 @@ namespace Service::Time::Clock { class SystemClockContextUpdateCallback { public: SystemClockContextUpdateCallback(); - ~SystemClockContextUpdateCallback(); + virtual ~SystemClockContextUpdateCallback(); bool NeedUpdate(const SystemClockContext& value) const; diff --git a/src/core/hle/service/time/system_clock_core.cpp b/src/core/hle/service/time/system_clock_core.cpp index 1a3ab8cfa..d31d4e2ca 100644 --- a/src/core/hle/service/time/system_clock_core.cpp +++ b/src/core/hle/service/time/system_clock_core.cpp @@ -9,7 +9,7 @@ namespace Service::Time::Clock { SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core) - : steady_clock_core{steady_clock_core}, is_initialized{} { + : steady_clock_core{steady_clock_core} { context.steady_time_point.clock_source_id = steady_clock_core.GetClockSourceId(); } diff --git a/src/core/hle/service/time/system_clock_core.h b/src/core/hle/service/time/system_clock_core.h index 54407a6c5..608dd3b2e 100644 --- a/src/core/hle/service/time/system_clock_core.h +++ b/src/core/hle/service/time/system_clock_core.h @@ -22,7 +22,7 @@ class SystemClockContextUpdateCallback; class SystemClockCore { public: explicit SystemClockCore(SteadyClockCore& steady_clock_core); - ~SystemClockCore(); + virtual ~SystemClockCore(); SteadyClockCore& GetSteadyClockCore() const { return steady_clock_core; diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index ce859f18d..e722886de 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -308,6 +308,29 @@ void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLEReques ctx.WriteBuffer(&clock_snapshot, sizeof(Clock::ClockSnapshot)); } +void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser( + Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_Time, "called"); + + IPC::RequestParser rp{ctx}; + const auto snapshot_a = rp.PopRaw<Clock::ClockSnapshot>(); + const auto snapshot_b = rp.PopRaw<Clock::ClockSnapshot>(); + + auto time_span_type{Clock::TimeSpanType::FromSeconds(snapshot_b.user_context.offset - + snapshot_a.user_context.offset)}; + + if ((snapshot_b.user_context.steady_time_point.clock_source_id != + snapshot_a.user_context.steady_time_point.clock_source_id) || + (snapshot_b.is_automatic_correction_enabled && + snapshot_a.is_automatic_correction_enabled)) { + time_span_type.nanoseconds = 0; + } + + IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(time_span_type.nanoseconds); +} + void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 351988468..41f3002e9 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h @@ -32,6 +32,7 @@ public: void CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx); void GetClockSnapshot(Kernel::HLERequestContext& ctx); void GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx); + void CalculateStandardUserSystemClockDifferenceByUser(Kernel::HLERequestContext& ctx); void CalculateSpanBetween(Kernel::HLERequestContext& ctx); void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); 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); } diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index 07b553a43..c8159bcd5 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp @@ -309,7 +309,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { offset = GetTZName(name, offset); std_len = offset; } - if (!std_len) { + if (std_len == 0) { return {}; } if (!GetOffset(name, offset, std_offset)) { @@ -320,7 +320,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { int dest_len{}; int dest_offset{}; const char* dest_name{name + offset}; - if (rule.chars.size() < char_count) { + if (rule.chars.size() < std::size_t(char_count)) { return {}; } @@ -343,7 +343,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { return {}; } char_count += dest_len + 1; - if (rule.chars.size() < char_count) { + if (rule.chars.size() < std::size_t(char_count)) { return {}; } if (name[offset] != '\0' && name[offset] != ',' && name[offset] != ';') { @@ -414,7 +414,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) { if (is_reversed || (start_time < end_time && (end_time - start_time < (year_seconds + (std_offset - dest_offset))))) { - if (rule.ats.size() - 2 < time_count) { + if (rule.ats.size() - 2 < std::size_t(time_count)) { break; } @@ -609,7 +609,7 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi } const u64 position{(read_offset - sizeof(TzifHeader))}; - const std::size_t bytes_read{vfs_file->GetSize() - sizeof(TzifHeader) - position}; + const s64 bytes_read = s64(vfs_file->GetSize() - sizeof(TzifHeader) - position); if (bytes_read < 0) { return {}; } @@ -621,11 +621,11 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi std::array<char, time_zone_name_max + 1> temp_name{}; vfs_file->ReadArray(temp_name.data(), bytes_read, read_offset); if (bytes_read > 2 && temp_name[0] == '\n' && temp_name[bytes_read - 1] == '\n' && - time_zone_rule.type_count + 2 <= time_zone_rule.ttis.size()) { + std::size_t(time_zone_rule.type_count) + 2 <= time_zone_rule.ttis.size()) { temp_name[bytes_read - 1] = '\0'; std::array<char, time_zone_name_max> name{}; - std::memcpy(name.data(), temp_name.data() + 1, bytes_read - 1); + std::memcpy(name.data(), temp_name.data() + 1, std::size_t(bytes_read - 1)); TimeZoneRule temp_rule; if (ParsePosixName(name.data(), temp_rule)) { diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index fdc62d05b..7f109f4eb 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -101,8 +101,8 @@ public: } std::u16string ReadInterfaceToken() { - u32 unknown = Read<u32_le>(); - u32 length = Read<u32_le>(); + [[maybe_unused]] const u32 unknown = Read<u32_le>(); + const u32 length = Read<u32_le>(); std::u16string token{}; |