From fa1c7c7ee18af73f73a1160e48e57abbddcf8b23 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 24 Sep 2017 11:12:16 -0400 Subject: [PATCH] process: Support loading multiple codesets. --- src/core/hle/kernel/process.cpp | 39 +++++++++++++++++---------------- src/core/hle/kernel/process.h | 8 ++++++- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 522ad2333..2b6634069 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -33,7 +33,7 @@ u32 Process::next_process_id; SharedPtr Process::Create(SharedPtr code_set) { SharedPtr process(new Process); - process->codeset = std::move(code_set); + process->codeset = code_set; process->flags.raw = 0; process->flags.memory_region.Assign(MemoryRegion::APPLICATION); @@ -113,24 +113,6 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { } void Process::Run(s32 main_thread_priority, u32 stack_size) { - memory_region = GetMemoryRegion(flags.memory_region); - - auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, - MemoryState memory_state) { - auto vma = vm_manager - .MapMemoryBlock(segment.addr, codeset->memory, segment.offset, segment.size, - memory_state) - .Unwrap(); - vm_manager.Reprotect(vma, permissions); - misc_memory_used += segment.size; - memory_region->used += segment.size; - }; - - // Map CodeSet segments - MapSegment(codeset->code, VMAPermission::ReadExecute, MemoryState::Code); - MapSegment(codeset->rodata, VMAPermission::Read, MemoryState::Code); - MapSegment(codeset->data, VMAPermission::ReadWrite, MemoryState::Private); - // Allocate and map stack vm_manager .MapMemoryBlock(Memory::HEAP_VADDR_END - stack_size, @@ -148,6 +130,25 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) { vm_manager.LogLayout(Log::Level::Debug); Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority); + +void Process::LoadModule(SharedPtr module_, VAddr base_addr) { + memory_region = GetMemoryRegion(flags.memory_region); + + auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, + MemoryState memory_state) { + auto vma = vm_manager + .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, segment.size, + memory_state) + .Unwrap(); + vm_manager.Reprotect(vma, permissions); + misc_memory_used += segment.size; + memory_region->used += segment.size; + }; + + // Map CodeSet segments + MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::Code); + MapSegment(module_->rodata, VMAPermission::Read, MemoryState::Code); + MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::Private); } VAddr Process::GetLinearHeapAreaAddress() const { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index b52211d2a..7350c6c41 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -79,7 +79,11 @@ struct CodeSet final : public Object { u32 size = 0; }; - Segment code, rodata, data; + Segment segments[3]; + Segment& code = segments[0]; + Segment& rodata = segments[1]; + Segment& data = segments[2]; + VAddr entrypoint; private: @@ -136,6 +140,8 @@ public: */ void Run(s32 main_thread_priority, u32 stack_size); + void LoadModule(SharedPtr module_, VAddr base_addr); + /////////////////////////////////////////////////////////////////////////////////////////////// // Memory Management