From 687d9739802097703a09f63d20ece741932b431b Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Wed, 26 Aug 2015 03:34:31 -0300 Subject: Core: Improve APT Shared Font hack Should fix invalid read loops in some games --- src/core/hle/kernel/shared_memory.cpp | 27 +++++++++++++++++++++++++-- src/core/hle/kernel/shared_memory.h | 2 ++ src/core/hle/service/apt/apt.cpp | 4 ++-- 3 files changed, 29 insertions(+), 4 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 4137683b5..1f477664b 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -20,6 +20,7 @@ SharedPtr SharedMemory::Create(u32 size, MemoryPermission permissi shared_memory->name = std::move(name); shared_memory->base_address = 0x0; + shared_memory->fixed_address = 0x0; shared_memory->size = size; shared_memory->permissions = permissions; shared_memory->other_permissions = other_permissions; @@ -30,9 +31,31 @@ SharedPtr SharedMemory::Create(u32 size, MemoryPermission permissi ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, MemoryPermission other_permissions) { + if (base_address != 0) { + LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s: already mapped at 0x%08X!", + GetObjectId(), address, name.c_str(), base_address); + // TODO: Verify error code with hardware + return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, + ErrorSummary::InvalidArgument, ErrorLevel::Permanent); + } + + if (fixed_address != 0) { + if (address != 0 && address != fixed_address) { + LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s: fixed_addres is 0x%08X!", + GetObjectId(), address, name.c_str(), fixed_address); + // TODO: Verify error code with hardware + return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, + ErrorSummary::InvalidArgument, ErrorLevel::Permanent); + } + + // HACK(yuriks): This is only here to support the APT shared font mapping right now. + // Later, this should actually map the memory block onto the address space. + return RESULT_SUCCESS; + } + if (address < Memory::SHARED_MEMORY_VADDR || address + size >= Memory::SHARED_MEMORY_VADDR_END) { - LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X outside of shared mem bounds!", - GetObjectId(), address); + LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s outside of shared mem bounds!", + GetObjectId(), address, name.c_str()); // TODO: Verify error code with hardware return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 7a2922776..35b550d12 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -61,6 +61,8 @@ public: /// Address of shared memory block in the process. VAddr base_address; + /// Fixed address to allow mapping to. Used for blocks created from the linear heap. + VAddr fixed_address; /// Size of the memory block. Page-aligned. u32 size; /// Permission restrictions applied to the process which created the block. diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 6a2fdea2b..ba66569b4 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -78,8 +78,8 @@ void GetSharedFont(Service::Interface* self) { if (shared_font != nullptr) { // TODO(yuriks): This is a hack to keep this working right now even with our completely // broken shared memory system. - shared_font_mem->base_address = SHARED_FONT_VADDR; - Kernel::g_current_process->vm_manager.MapMemoryBlock(shared_font_mem->base_address, + shared_font_mem->fixed_address = SHARED_FONT_VADDR; + Kernel::g_current_process->vm_manager.MapMemoryBlock(shared_font_mem->fixed_address, shared_font, 0, shared_font_mem->size, Kernel::MemoryState::Shared); cmd_buff[0] = IPC::MakeHeader(0x44, 2, 2); -- cgit v1.2.3 From 12390eb155c055884f183cc547473a1dd92ff667 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Wed, 26 Aug 2015 06:38:26 -0300 Subject: Kernel: Fix assertion failure when ControlMemory is called with size=0 --- src/core/hle/kernel/process.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/core') diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 124047a53..6279a4bf8 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -174,6 +174,10 @@ ResultCode Process::HeapFree(VAddr target, u32 size) { return ERR_INVALID_ADDRESS; } + if (size == 0) { + return RESULT_SUCCESS; + } + ResultCode result = vm_manager.UnmapRange(target, size); if (result.IsError()) return result; @@ -226,6 +230,10 @@ ResultCode Process::LinearFree(VAddr target, u32 size) { return ERR_INVALID_ADDRESS; } + if (size == 0) { + return RESULT_SUCCESS; + } + VAddr heap_end = GetLinearHeapBase() + (u32)linheap_memory->size(); if (target + size > heap_end) { return ERR_INVALID_ADDRESS_STATE; -- cgit v1.2.3