Merge pull request #4123 from FearlessTobi/port-914
Port #914 from yuzu: "kernel/process: Use accessors instead of class members for referencing segment array"
This commit is contained in:
commit
f2816aa430
|
@ -133,9 +133,9 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Map CodeSet segments
|
// Map CodeSet segments
|
||||||
MapSegment(codeset->code, VMAPermission::ReadExecute, MemoryState::Code);
|
MapSegment(codeset->CodeSegment(), VMAPermission::ReadExecute, MemoryState::Code);
|
||||||
MapSegment(codeset->rodata, VMAPermission::Read, MemoryState::Code);
|
MapSegment(codeset->RODataSegment(), VMAPermission::Read, MemoryState::Code);
|
||||||
MapSegment(codeset->data, VMAPermission::ReadWrite, MemoryState::Private);
|
MapSegment(codeset->DataSegment(), VMAPermission::ReadWrite, MemoryState::Private);
|
||||||
|
|
||||||
// Allocate and map stack
|
// Allocate and map stack
|
||||||
vm_manager
|
vm_manager
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -55,6 +56,12 @@ class ResourceLimit;
|
||||||
struct MemoryRegionInfo;
|
struct MemoryRegionInfo;
|
||||||
|
|
||||||
struct CodeSet final : public Object {
|
struct CodeSet final : public Object {
|
||||||
|
struct Segment {
|
||||||
|
size_t offset = 0;
|
||||||
|
VAddr addr = 0;
|
||||||
|
u32 size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
static SharedPtr<CodeSet> Create(std::string name, u64 program_id);
|
static SharedPtr<CodeSet> Create(std::string name, u64 program_id);
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
|
@ -69,22 +76,40 @@ struct CodeSet final : public Object {
|
||||||
return HANDLE_TYPE;
|
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<std::vector<u8>> memory;
|
||||||
|
|
||||||
|
std::array<Segment, 3> segments;
|
||||||
|
VAddr entrypoint;
|
||||||
|
|
||||||
/// Name of the process
|
/// Name of the process
|
||||||
std::string name;
|
std::string name;
|
||||||
/// Title ID corresponding to the process
|
/// Title ID corresponding to the process
|
||||||
u64 program_id;
|
u64 program_id;
|
||||||
|
|
||||||
std::shared_ptr<std::vector<u8>> memory;
|
|
||||||
|
|
||||||
struct Segment {
|
|
||||||
size_t offset = 0;
|
|
||||||
VAddr addr = 0;
|
|
||||||
u32 size = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
Segment code, rodata, data;
|
|
||||||
VAddr entrypoint;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CodeSet();
|
CodeSet();
|
||||||
~CodeSet() override;
|
~CodeSet() override;
|
||||||
|
|
|
@ -219,19 +219,19 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr,
|
||||||
// Create the CodeSet
|
// Create the CodeSet
|
||||||
SharedPtr<CodeSet> code_set = CodeSet::Create("", 0);
|
SharedPtr<CodeSet> code_set = CodeSet::Create("", 0);
|
||||||
|
|
||||||
code_set->code.offset = loadinfo.seg_ptrs[0] - program_image.data();
|
code_set->CodeSegment().offset = loadinfo.seg_ptrs[0] - program_image.data();
|
||||||
code_set->code.addr = loadinfo.seg_addrs[0];
|
code_set->CodeSegment().addr = loadinfo.seg_addrs[0];
|
||||||
code_set->code.size = loadinfo.seg_sizes[0];
|
code_set->CodeSegment().size = loadinfo.seg_sizes[0];
|
||||||
|
|
||||||
code_set->rodata.offset = loadinfo.seg_ptrs[1] - program_image.data();
|
code_set->RODataSegment().offset = loadinfo.seg_ptrs[1] - program_image.data();
|
||||||
code_set->rodata.addr = loadinfo.seg_addrs[1];
|
code_set->RODataSegment().addr = loadinfo.seg_addrs[1];
|
||||||
code_set->rodata.size = loadinfo.seg_sizes[1];
|
code_set->RODataSegment().size = loadinfo.seg_sizes[1];
|
||||||
|
|
||||||
code_set->data.offset = loadinfo.seg_ptrs[2] - program_image.data();
|
code_set->DataSegment().offset = loadinfo.seg_ptrs[2] - program_image.data();
|
||||||
code_set->data.addr = loadinfo.seg_addrs[2];
|
code_set->DataSegment().addr = loadinfo.seg_addrs[2];
|
||||||
code_set->data.size = loadinfo.seg_sizes[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::vector<u8>>(std::move(program_image));
|
code_set->memory = std::make_shared<std::vector<u8>>(std::move(program_image));
|
||||||
|
|
||||||
LOG_DEBUG(Loader, "code size: {:#X}", loadinfo.seg_sizes[0]);
|
LOG_DEBUG(Loader, "code size: {:#X}", loadinfo.seg_sizes[0]);
|
||||||
|
|
|
@ -310,11 +310,11 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
|
||||||
CodeSet::Segment* codeset_segment;
|
CodeSet::Segment* codeset_segment;
|
||||||
u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X);
|
u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X);
|
||||||
if (permission_flags == (PF_R | PF_X)) {
|
if (permission_flags == (PF_R | PF_X)) {
|
||||||
codeset_segment = &codeset->code;
|
codeset_segment = &codeset->CodeSegment();
|
||||||
} else if (permission_flags == (PF_R)) {
|
} else if (permission_flags == (PF_R)) {
|
||||||
codeset_segment = &codeset->rodata;
|
codeset_segment = &codeset->RODataSegment();
|
||||||
} else if (permission_flags == (PF_R | PF_W)) {
|
} else if (permission_flags == (PF_R | PF_W)) {
|
||||||
codeset_segment = &codeset->data;
|
codeset_segment = &codeset->DataSegment();
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i,
|
LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i,
|
||||||
p->p_flags);
|
p->p_flags);
|
||||||
|
|
|
@ -76,14 +76,15 @@ ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr<Kernel::Process>& proces
|
||||||
|
|
||||||
SharedPtr<CodeSet> codeset = CodeSet::Create(process_name, program_id);
|
SharedPtr<CodeSet> codeset = CodeSet::Create(process_name, program_id);
|
||||||
|
|
||||||
codeset->code.offset = 0;
|
codeset->CodeSegment().offset = 0;
|
||||||
codeset->code.addr = overlay_ncch->exheader_header.codeset_info.text.address;
|
codeset->CodeSegment().addr = overlay_ncch->exheader_header.codeset_info.text.address;
|
||||||
codeset->code.size =
|
codeset->CodeSegment().size =
|
||||||
overlay_ncch->exheader_header.codeset_info.text.num_max_pages * Memory::PAGE_SIZE;
|
overlay_ncch->exheader_header.codeset_info.text.num_max_pages * Memory::PAGE_SIZE;
|
||||||
|
|
||||||
codeset->rodata.offset = codeset->code.offset + codeset->code.size;
|
codeset->RODataSegment().offset =
|
||||||
codeset->rodata.addr = overlay_ncch->exheader_header.codeset_info.ro.address;
|
codeset->CodeSegment().offset + codeset->CodeSegment().size;
|
||||||
codeset->rodata.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;
|
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
|
// 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<Kernel::Process>& proces
|
||||||
u32 bss_page_size = (overlay_ncch->exheader_header.codeset_info.bss_size + 0xFFF) & ~0xFFF;
|
u32 bss_page_size = (overlay_ncch->exheader_header.codeset_info.bss_size + 0xFFF) & ~0xFFF;
|
||||||
code.resize(code.size() + bss_page_size, 0);
|
code.resize(code.size() + bss_page_size, 0);
|
||||||
|
|
||||||
codeset->data.offset = codeset->rodata.offset + codeset->rodata.size;
|
codeset->DataSegment().offset =
|
||||||
codeset->data.addr = overlay_ncch->exheader_header.codeset_info.data.address;
|
codeset->RODataSegment().offset + codeset->RODataSegment().size;
|
||||||
codeset->data.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 +
|
overlay_ncch->exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE +
|
||||||
bss_page_size;
|
bss_page_size;
|
||||||
|
|
||||||
codeset->entrypoint = codeset->code.addr;
|
codeset->entrypoint = codeset->CodeSegment().addr;
|
||||||
codeset->memory = std::make_shared<std::vector<u8>>(std::move(code));
|
codeset->memory = std::make_shared<std::vector<u8>>(std::move(code));
|
||||||
|
|
||||||
process = Kernel::Process::Create(std::move(codeset));
|
process = Kernel::Process::Create(std::move(codeset));
|
||||||
|
|
Reference in New Issue