From 37e78de2065e5e16ac63c52dbde3fe81b006c2f1 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 Aug 2018 14:33:59 -0400 Subject: [PATCH 1/3] kernel/process: Use accessors instead of class members for referencing segment array Using member variables for referencing the segments array increases the size of the class in memory for little benefit. The same behavior can be achieved through the use of accessors that just return the relevant segment. --- src/core/hle/kernel/process.cpp | 6 ++--- src/core/hle/kernel/process.h | 46 +++++++++++++++++++++++++-------- src/core/loader/elf.cpp | 6 ++--- 3 files changed, 41 insertions(+), 17 deletions(-) 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..5b2291bad 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -55,6 +55,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 +75,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; + + Segment segments[3]; + 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/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); From c786df3e4b626fbd59ff75d9c5e7d8826a3165ec Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 Aug 2018 14:42:28 -0400 Subject: [PATCH 2/3] kernel/process: Use std::array where applicable --- src/core/hle/kernel/process.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 5b2291bad..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 @@ -101,7 +102,7 @@ struct CodeSet final : public Object { std::shared_ptr> memory; - Segment segments[3]; + std::array segments; VAddr entrypoint; /// Name of the process From 2abe11ee1ef98ecda34c25be413cebecd03a8853 Mon Sep 17 00:00:00 2001 From: fearlessTobi Date: Thu, 23 Aug 2018 18:23:21 +0200 Subject: [PATCH 3/3] Fix compile errors --- src/core/loader/3dsx.cpp | 20 ++++++++++---------- src/core/loader/ncch.cpp | 22 ++++++++++++---------- 2 files changed, 22 insertions(+), 20 deletions(-) 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/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));