mirror of
https://github.com/PabloMK7/citra
synced 2024-11-15 05:08:23 +00:00
Match changes to svcMapProcessMemoryEx from latest Luma3DS (#264)
This commit is contained in:
parent
f3fb038587
commit
608383ec84
4 changed files with 45 additions and 11 deletions
|
@ -179,6 +179,8 @@ Loader::ResultStatus FileSys::Plugin3GXLoader::Map(
|
||||||
4 * 1024 * 1024 // 4 MiB
|
4 * 1024 * 1024 // 4 MiB
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const bool is_mem_private = header.infos.flags.use_private_memory != 0;
|
||||||
|
|
||||||
// Map memory block. This behaviour mimics how plugins are loaded on 3DS as much as possible.
|
// Map memory block. This behaviour mimics how plugins are loaded on 3DS as much as possible.
|
||||||
// Calculate the sizes of the different memory regions
|
// Calculate the sizes of the different memory regions
|
||||||
const u32 block_size = mem_region_sizes[header.infos.flags.memory_region_size.Value()];
|
const u32 block_size = mem_region_sizes[header.infos.flags.memory_region_size.Value()];
|
||||||
|
@ -199,7 +201,8 @@ Loader::ResultStatus FileSys::Plugin3GXLoader::Map(
|
||||||
std::fill(backing_memory_fb.GetPtr(), backing_memory_fb.GetPtr() + _3GX_fb_size, 0);
|
std::fill(backing_memory_fb.GetPtr(), backing_memory_fb.GetPtr() + _3GX_fb_size, 0);
|
||||||
|
|
||||||
auto vma_heap_fb = process.vm_manager.MapBackingMemory(
|
auto vma_heap_fb = process.vm_manager.MapBackingMemory(
|
||||||
_3GX_heap_load_addr, backing_memory_fb, _3GX_fb_size, Kernel::MemoryState::Continuous);
|
_3GX_heap_load_addr, backing_memory_fb, _3GX_fb_size,
|
||||||
|
is_mem_private ? Kernel::MemoryState::Private : Kernel::MemoryState::Shared);
|
||||||
ASSERT(vma_heap_fb.Succeeded());
|
ASSERT(vma_heap_fb.Succeeded());
|
||||||
process.vm_manager.Reprotect(vma_heap_fb.Unwrap(), Kernel::VMAPermission::ReadWrite);
|
process.vm_manager.Reprotect(vma_heap_fb.Unwrap(), Kernel::VMAPermission::ReadWrite);
|
||||||
|
|
||||||
|
@ -217,7 +220,8 @@ Loader::ResultStatus FileSys::Plugin3GXLoader::Map(
|
||||||
|
|
||||||
// Then we map part of the memory, which contains the executable
|
// Then we map part of the memory, which contains the executable
|
||||||
auto vma = process.vm_manager.MapBackingMemory(_3GX_exe_load_addr, backing_memory, exe_size,
|
auto vma = process.vm_manager.MapBackingMemory(_3GX_exe_load_addr, backing_memory, exe_size,
|
||||||
Kernel::MemoryState::Continuous);
|
is_mem_private ? Kernel::MemoryState::Private
|
||||||
|
: Kernel::MemoryState::Shared);
|
||||||
ASSERT(vma.Succeeded());
|
ASSERT(vma.Succeeded());
|
||||||
process.vm_manager.Reprotect(vma.Unwrap(), Kernel::VMAPermission::ReadWriteExecute);
|
process.vm_manager.Reprotect(vma.Unwrap(), Kernel::VMAPermission::ReadWriteExecute);
|
||||||
|
|
||||||
|
@ -256,7 +260,8 @@ Loader::ResultStatus FileSys::Plugin3GXLoader::Map(
|
||||||
// Map the rest of the memory at the heap location
|
// Map the rest of the memory at the heap location
|
||||||
auto vma_heap = process.vm_manager.MapBackingMemory(
|
auto vma_heap = process.vm_manager.MapBackingMemory(
|
||||||
_3GX_heap_load_addr + _3GX_fb_size, backing_memory_heap,
|
_3GX_heap_load_addr + _3GX_fb_size, backing_memory_heap,
|
||||||
block_size - exe_size - _3GX_fb_size, Kernel::MemoryState::Continuous);
|
block_size - exe_size - _3GX_fb_size,
|
||||||
|
is_mem_private ? Kernel::MemoryState::Private : Kernel::MemoryState::Shared);
|
||||||
ASSERT(vma_heap.Succeeded());
|
ASSERT(vma_heap.Succeeded());
|
||||||
process.vm_manager.Reprotect(vma_heap.Unwrap(), Kernel::VMAPermission::ReadWriteExecute);
|
process.vm_manager.Reprotect(vma_heap.Unwrap(), Kernel::VMAPermission::ReadWriteExecute);
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,9 @@ private:
|
||||||
BitField<1, 1, u32_le> embedded_swap_func;
|
BitField<1, 1, u32_le> embedded_swap_func;
|
||||||
BitField<2, 2, u32_le> memory_region_size;
|
BitField<2, 2, u32_le> memory_region_size;
|
||||||
BitField<4, 2, u32_le> compatibility;
|
BitField<4, 2, u32_le> compatibility;
|
||||||
|
BitField<6, 1, u32_le> events_self_managed;
|
||||||
|
BitField<7, 1, u32_le> swap_not_needed;
|
||||||
|
BitField<8, 1, u32_le> use_private_memory;
|
||||||
} flags;
|
} flags;
|
||||||
u32_le exe_load_checksum;
|
u32_le exe_load_checksum;
|
||||||
u32_le builtin_load_exe_args[4];
|
u32_le builtin_load_exe_args[4];
|
||||||
|
|
|
@ -369,6 +369,16 @@ enum class ControlProcessOP {
|
||||||
PROCESSOP_DISABLE_CREATE_THREAD_RESTRICTIONS,
|
PROCESSOP_DISABLE_CREATE_THREAD_RESTRICTIONS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepted by the custom svcMapProcessMemoryEx.
|
||||||
|
*/
|
||||||
|
enum class MapMemoryExFlag {
|
||||||
|
/**
|
||||||
|
* Maps the memory region as PRIVATE instead of SHARED
|
||||||
|
*/
|
||||||
|
MAPEXFLAGS_PRIVATE = (1 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
class SVC : public SVCWrapper<SVC> {
|
class SVC : public SVCWrapper<SVC> {
|
||||||
public:
|
public:
|
||||||
SVC(Core::System& system);
|
SVC(Core::System& system);
|
||||||
|
@ -460,7 +470,8 @@ private:
|
||||||
Result InvalidateEntireInstructionCache();
|
Result InvalidateEntireInstructionCache();
|
||||||
u32 ConvertVaToPa(u32 addr);
|
u32 ConvertVaToPa(u32 addr);
|
||||||
Result MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address, Handle src_process_handle,
|
Result MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address, Handle src_process_handle,
|
||||||
u32 src_address, u32 size);
|
u32 src_address, u32 size, MapMemoryExFlag flags,
|
||||||
|
Handle dst_process_handle_backup);
|
||||||
Result UnmapProcessMemoryEx(Handle process, u32 dst_address, u32 size);
|
Result UnmapProcessMemoryEx(Handle process, u32 dst_address, u32 size);
|
||||||
Result ControlProcess(Handle process_handle, u32 process_OP, u32 varg2, u32 varg3);
|
Result ControlProcess(Handle process_handle, u32 process_OP, u32 varg2, u32 varg3);
|
||||||
|
|
||||||
|
@ -2012,7 +2023,22 @@ u32 SVC::ConvertVaToPa(u32 addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SVC::MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address,
|
Result SVC::MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address,
|
||||||
Handle src_process_handle, u32 src_address, u32 size) {
|
Handle src_process_handle, u32 src_address, u32 size,
|
||||||
|
MapMemoryExFlag flags, Handle dst_process_handle_backup) {
|
||||||
|
|
||||||
|
// Determine if this is the second version of the svc by checking the value at R0.
|
||||||
|
constexpr u32 SVC_VERSION2_MAGIC = 0xFFFFFFF2;
|
||||||
|
if (static_cast<u32>(dst_process_handle) == SVC_VERSION2_MAGIC) {
|
||||||
|
// Version 2, actual handle is provided in 6th argument
|
||||||
|
dst_process_handle = dst_process_handle_backup;
|
||||||
|
} else {
|
||||||
|
// Version 1, the flags argument is not used
|
||||||
|
flags = static_cast<MapMemoryExFlag>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool map_as_private =
|
||||||
|
(static_cast<u32>(flags) & static_cast<u32>(MapMemoryExFlag::MAPEXFLAGS_PRIVATE)) != 0;
|
||||||
|
|
||||||
std::shared_ptr<Process> dst_process =
|
std::shared_ptr<Process> dst_process =
|
||||||
kernel.GetCurrentProcess()->handle_table.Get<Process>(dst_process_handle);
|
kernel.GetCurrentProcess()->handle_table.Get<Process>(dst_process_handle);
|
||||||
std::shared_ptr<Process> src_process =
|
std::shared_ptr<Process> src_process =
|
||||||
|
@ -2024,11 +2050,12 @@ Result SVC::MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address,
|
||||||
size = (size & ~0xFFF) + Memory::CITRA_PAGE_SIZE;
|
size = (size & ~0xFFF) + Memory::CITRA_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(PabloMK7) Fix-up this svc.
|
||||||
|
|
||||||
// Only linear memory supported
|
// Only linear memory supported
|
||||||
auto vma = src_process->vm_manager.FindVMA(src_address);
|
auto vma = src_process->vm_manager.FindVMA(src_address);
|
||||||
R_UNLESS(vma != src_process->vm_manager.vma_map.end() &&
|
R_UNLESS(vma != src_process->vm_manager.vma_map.end() &&
|
||||||
vma->second.type == VMAType::BackingMemory &&
|
vma->second.type == VMAType::BackingMemory,
|
||||||
vma->second.meminfo_state == MemoryState::Continuous,
|
|
||||||
ResultInvalidAddress);
|
ResultInvalidAddress);
|
||||||
|
|
||||||
const u32 offset = src_address - vma->second.base;
|
const u32 offset = src_address - vma->second.base;
|
||||||
|
@ -2038,7 +2065,7 @@ Result SVC::MapProcessMemoryEx(Handle dst_process_handle, u32 dst_address,
|
||||||
dst_address,
|
dst_address,
|
||||||
memory.GetFCRAMRef(vma->second.backing_memory.GetPtr() + offset -
|
memory.GetFCRAMRef(vma->second.backing_memory.GetPtr() + offset -
|
||||||
kernel.memory.GetFCRAMPointer(0)),
|
kernel.memory.GetFCRAMPointer(0)),
|
||||||
size, Kernel::MemoryState::Continuous);
|
size, map_as_private ? MemoryState::Private : MemoryState::Shared);
|
||||||
|
|
||||||
if (!vma_res.Succeeded()) {
|
if (!vma_res.Succeeded()) {
|
||||||
return ResultInvalidAddressState;
|
return ResultInvalidAddressState;
|
||||||
|
@ -2060,8 +2087,7 @@ Result SVC::UnmapProcessMemoryEx(Handle process, u32 dst_address, u32 size) {
|
||||||
// Only linear memory supported
|
// Only linear memory supported
|
||||||
auto vma = dst_process->vm_manager.FindVMA(dst_address);
|
auto vma = dst_process->vm_manager.FindVMA(dst_address);
|
||||||
R_UNLESS(vma != dst_process->vm_manager.vma_map.end() &&
|
R_UNLESS(vma != dst_process->vm_manager.vma_map.end() &&
|
||||||
vma->second.type == VMAType::BackingMemory &&
|
vma->second.type == VMAType::BackingMemory,
|
||||||
vma->second.meminfo_state == MemoryState::Continuous,
|
|
||||||
ResultInvalidAddress);
|
ResultInvalidAddress);
|
||||||
|
|
||||||
dst_process->vm_manager.UnmapRange(dst_address, size);
|
dst_process->vm_manager.UnmapRange(dst_address, size);
|
||||||
|
|
|
@ -38,7 +38,7 @@ SERVICE_CONSTRUCT_IMPL(Service::PLGLDR::PLG_LDR)
|
||||||
|
|
||||||
namespace Service::PLGLDR {
|
namespace Service::PLGLDR {
|
||||||
|
|
||||||
static const Kernel::CoreVersion plgldr_version = Kernel::CoreVersion(1, 0, 0);
|
static const Kernel::CoreVersion plgldr_version = Kernel::CoreVersion(1, 0, 2);
|
||||||
|
|
||||||
PLG_LDR::PLG_LDR(Core::System& system_) : ServiceFramework{"plg:ldr", 1}, system(system_) {
|
PLG_LDR::PLG_LDR(Core::System& system_) : ServiceFramework{"plg:ldr", 1}, system(system_) {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
|
|
Loading…
Reference in a new issue