diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index de8bd0f96..b69acd424 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -133,9 +133,9 @@ void Process::Run(s32 main_thread_priority, u32 stack_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); + MapSegment(codeset->CodeSegment(), VMAPermission::ReadExecute, MemoryState::Code); + MapSegment(codeset->RODataSegment(), VMAPermission::Read, MemoryState::Code); + MapSegment(codeset->DataSegment(), VMAPermission::ReadWrite, MemoryState::Private); // Allocate and map stack vm_manager diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index a21b8e704..360d16cf8 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include @@ -55,6 +56,12 @@ class ResourceLimit; struct MemoryRegionInfo; struct CodeSet final : public Object { + struct Segment { + size_t offset = 0; + VAddr addr = 0; + u32 size = 0; + }; + static SharedPtr Create(std::string name, u64 program_id); std::string GetTypeName() const override { @@ -69,22 +76,40 @@ struct CodeSet final : public Object { return HANDLE_TYPE; } + Segment& CodeSegment() { + return segments[0]; + } + + const Segment& CodeSegment() const { + return segments[0]; + } + + Segment& RODataSegment() { + return segments[1]; + } + + const Segment& RODataSegment() const { + return segments[1]; + } + + Segment& DataSegment() { + return segments[2]; + } + + const Segment& DataSegment() const { + return segments[2]; + } + + std::shared_ptr> memory; + + std::array segments; + VAddr entrypoint; + /// Name of the process std::string name; /// Title ID corresponding to the process u64 program_id; - std::shared_ptr> memory; - - struct Segment { - size_t offset = 0; - VAddr addr = 0; - u32 size = 0; - }; - - Segment code, rodata, data; - VAddr entrypoint; - private: CodeSet(); ~CodeSet() override; diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index ecdfb7eaf..b206a94e7 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -219,19 +219,19 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, // Create the CodeSet SharedPtr code_set = CodeSet::Create("", 0); - code_set->code.offset = loadinfo.seg_ptrs[0] - program_image.data(); - code_set->code.addr = loadinfo.seg_addrs[0]; - code_set->code.size = loadinfo.seg_sizes[0]; + code_set->CodeSegment().offset = loadinfo.seg_ptrs[0] - program_image.data(); + code_set->CodeSegment().addr = loadinfo.seg_addrs[0]; + code_set->CodeSegment().size = loadinfo.seg_sizes[0]; - code_set->rodata.offset = loadinfo.seg_ptrs[1] - program_image.data(); - code_set->rodata.addr = loadinfo.seg_addrs[1]; - code_set->rodata.size = loadinfo.seg_sizes[1]; + code_set->RODataSegment().offset = loadinfo.seg_ptrs[1] - program_image.data(); + code_set->RODataSegment().addr = loadinfo.seg_addrs[1]; + code_set->RODataSegment().size = loadinfo.seg_sizes[1]; - code_set->data.offset = loadinfo.seg_ptrs[2] - program_image.data(); - code_set->data.addr = loadinfo.seg_addrs[2]; - code_set->data.size = loadinfo.seg_sizes[2]; + code_set->DataSegment().offset = loadinfo.seg_ptrs[2] - program_image.data(); + code_set->DataSegment().addr = loadinfo.seg_addrs[2]; + code_set->DataSegment().size = loadinfo.seg_sizes[2]; - code_set->entrypoint = code_set->code.addr; + code_set->entrypoint = code_set->CodeSegment().addr; code_set->memory = std::make_shared>(std::move(program_image)); LOG_DEBUG(Loader, "code size: {:#X}", loadinfo.seg_sizes[0]); diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 5c45e5bb4..8bc888acc 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -310,11 +310,11 @@ SharedPtr ElfReader::LoadInto(u32 vaddr) { CodeSet::Segment* codeset_segment; u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); if (permission_flags == (PF_R | PF_X)) { - codeset_segment = &codeset->code; + codeset_segment = &codeset->CodeSegment(); } else if (permission_flags == (PF_R)) { - codeset_segment = &codeset->rodata; + codeset_segment = &codeset->RODataSegment(); } else if (permission_flags == (PF_R | PF_W)) { - codeset_segment = &codeset->data; + codeset_segment = &codeset->DataSegment(); } else { LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, p->p_flags); diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index afe93321e..fdb147a64 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -76,14 +76,15 @@ ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr& proces SharedPtr codeset = CodeSet::Create(process_name, program_id); - codeset->code.offset = 0; - codeset->code.addr = overlay_ncch->exheader_header.codeset_info.text.address; - codeset->code.size = + codeset->CodeSegment().offset = 0; + codeset->CodeSegment().addr = overlay_ncch->exheader_header.codeset_info.text.address; + codeset->CodeSegment().size = overlay_ncch->exheader_header.codeset_info.text.num_max_pages * Memory::PAGE_SIZE; - codeset->rodata.offset = codeset->code.offset + codeset->code.size; - codeset->rodata.addr = overlay_ncch->exheader_header.codeset_info.ro.address; - codeset->rodata.size = + codeset->RODataSegment().offset = + codeset->CodeSegment().offset + codeset->CodeSegment().size; + codeset->RODataSegment().addr = overlay_ncch->exheader_header.codeset_info.ro.address; + codeset->RODataSegment().size = overlay_ncch->exheader_header.codeset_info.ro.num_max_pages * Memory::PAGE_SIZE; // TODO(yuriks): Not sure if the bss size is added to the page-aligned .data size or just @@ -91,13 +92,14 @@ ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr& proces u32 bss_page_size = (overlay_ncch->exheader_header.codeset_info.bss_size + 0xFFF) & ~0xFFF; code.resize(code.size() + bss_page_size, 0); - codeset->data.offset = codeset->rodata.offset + codeset->rodata.size; - codeset->data.addr = overlay_ncch->exheader_header.codeset_info.data.address; - codeset->data.size = + codeset->DataSegment().offset = + codeset->RODataSegment().offset + codeset->RODataSegment().size; + codeset->DataSegment().addr = overlay_ncch->exheader_header.codeset_info.data.address; + codeset->DataSegment().size = overlay_ncch->exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE + bss_page_size; - codeset->entrypoint = codeset->code.addr; + codeset->entrypoint = codeset->CodeSegment().addr; codeset->memory = std::make_shared>(std::move(code)); process = Kernel::Process::Create(std::move(codeset));