kernel/process: Make CodeSet a regular non-inherited object
These only exist to ferry data into a Process instance and end up going out of scope quite early. Because of this, we can just make it a plain struct for holding things and just std::move it into the relevant function. There's no need to make this inherit from the kernel's Object type.
This commit is contained in:
		| @@ -25,7 +25,6 @@ bool Object::IsWaitable() const { | ||||
|     case HandleType::Process: | ||||
|     case HandleType::AddressArbiter: | ||||
|     case HandleType::ResourceLimit: | ||||
|     case HandleType::CodeSet: | ||||
|     case HandleType::ClientPort: | ||||
|     case HandleType::ClientSession: | ||||
|         return false; | ||||
|   | ||||
| @@ -26,7 +26,6 @@ enum class HandleType : u32 { | ||||
|     AddressArbiter, | ||||
|     Timer, | ||||
|     ResourceLimit, | ||||
|     CodeSet, | ||||
|     ClientPort, | ||||
|     ServerPort, | ||||
|     ClientSession, | ||||
|   | ||||
| @@ -20,13 +20,7 @@ | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| SharedPtr<CodeSet> CodeSet::Create(KernelCore& kernel, std::string name) { | ||||
|     SharedPtr<CodeSet> codeset(new CodeSet(kernel)); | ||||
|     codeset->name = std::move(name); | ||||
|     return codeset; | ||||
| } | ||||
|  | ||||
| CodeSet::CodeSet(KernelCore& kernel) : Object{kernel} {} | ||||
| CodeSet::CodeSet() = default; | ||||
| CodeSet::~CodeSet() = default; | ||||
|  | ||||
| SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) { | ||||
| @@ -224,20 +218,20 @@ void Process::FreeTLSSlot(VAddr tls_address) { | ||||
|     tls_slots[tls_page].reset(tls_slot); | ||||
| } | ||||
|  | ||||
| void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { | ||||
| void Process::LoadModule(CodeSet module_, VAddr base_addr) { | ||||
|     const 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(); | ||||
|         const auto vma = vm_manager | ||||
|                              .MapMemoryBlock(segment.addr + base_addr, module_.memory, | ||||
|                                              segment.offset, segment.size, memory_state) | ||||
|                              .Unwrap(); | ||||
|         vm_manager.Reprotect(vma, permissions); | ||||
|     }; | ||||
|  | ||||
|     // Map CodeSet segments | ||||
|     MapSegment(module_->CodeSegment(), VMAPermission::ReadExecute, MemoryState::CodeStatic); | ||||
|     MapSegment(module_->RODataSegment(), VMAPermission::Read, MemoryState::CodeMutable); | ||||
|     MapSegment(module_->DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeMutable); | ||||
|     MapSegment(module_.CodeSegment(), VMAPermission::ReadExecute, MemoryState::CodeStatic); | ||||
|     MapSegment(module_.RODataSegment(), VMAPermission::Read, MemoryState::CodeMutable); | ||||
|     MapSegment(module_.DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeMutable); | ||||
| } | ||||
|  | ||||
| ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { | ||||
|   | ||||
| @@ -61,26 +61,15 @@ enum class ProcessStatus { Created, Running, Exited }; | ||||
|  | ||||
| class ResourceLimit; | ||||
|  | ||||
| struct CodeSet final : public Object { | ||||
| struct CodeSet final { | ||||
|     struct Segment { | ||||
|         std::size_t offset = 0; | ||||
|         VAddr addr = 0; | ||||
|         u32 size = 0; | ||||
|     }; | ||||
|  | ||||
|     static SharedPtr<CodeSet> Create(KernelCore& kernel, std::string name); | ||||
|  | ||||
|     std::string GetTypeName() const override { | ||||
|         return "CodeSet"; | ||||
|     } | ||||
|     std::string GetName() const override { | ||||
|         return name; | ||||
|     } | ||||
|  | ||||
|     static const HandleType HANDLE_TYPE = HandleType::CodeSet; | ||||
|     HandleType GetHandleType() const override { | ||||
|         return HANDLE_TYPE; | ||||
|     } | ||||
|     explicit CodeSet(); | ||||
|     ~CodeSet(); | ||||
|  | ||||
|     Segment& CodeSegment() { | ||||
|         return segments[0]; | ||||
| @@ -109,14 +98,7 @@ struct CodeSet final : public Object { | ||||
|     std::shared_ptr<std::vector<u8>> memory; | ||||
|  | ||||
|     std::array<Segment, 3> segments; | ||||
|     VAddr entrypoint; | ||||
|  | ||||
|     /// Name of the process | ||||
|     std::string name; | ||||
|  | ||||
| private: | ||||
|     explicit CodeSet(KernelCore& kernel); | ||||
|     ~CodeSet() override; | ||||
|     VAddr entrypoint = 0; | ||||
| }; | ||||
|  | ||||
| class Process final : public Object { | ||||
| @@ -219,7 +201,7 @@ public: | ||||
|      */ | ||||
|     void PrepareForTermination(); | ||||
|  | ||||
|     void LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr); | ||||
|     void LoadModule(CodeSet module_, VAddr base_addr); | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|     // Memory Management | ||||
|   | ||||
| @@ -9,16 +9,11 @@ | ||||
| #include "common/common_types.h" | ||||
| #include "common/file_util.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/vm_manager.h" | ||||
| #include "core/loader/elf.h" | ||||
| #include "core/memory.h" | ||||
|  | ||||
| using Kernel::CodeSet; | ||||
| using Kernel::SharedPtr; | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // ELF Header Constants | ||||
|  | ||||
| @@ -211,7 +206,7 @@ public: | ||||
|     u32 GetFlags() const { | ||||
|         return (u32)(header->e_flags); | ||||
|     } | ||||
|     SharedPtr<CodeSet> LoadInto(VAddr vaddr); | ||||
|     Kernel::CodeSet LoadInto(VAddr vaddr); | ||||
|  | ||||
|     int GetNumSegments() const { | ||||
|         return (int)(header->e_phnum); | ||||
| @@ -274,7 +269,7 @@ const char* ElfReader::GetSectionName(int section) const { | ||||
|     return nullptr; | ||||
| } | ||||
|  | ||||
| SharedPtr<CodeSet> ElfReader::LoadInto(VAddr vaddr) { | ||||
| Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { | ||||
|     LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx); | ||||
|  | ||||
|     // Should we relocate? | ||||
| @@ -302,8 +297,7 @@ SharedPtr<CodeSet> ElfReader::LoadInto(VAddr vaddr) { | ||||
|     std::vector<u8> program_image(total_image_size); | ||||
|     std::size_t current_image_position = 0; | ||||
|  | ||||
|     auto& kernel = Core::System::GetInstance().Kernel(); | ||||
|     SharedPtr<CodeSet> codeset = CodeSet::Create(kernel, ""); | ||||
|     Kernel::CodeSet codeset; | ||||
|  | ||||
|     for (unsigned int i = 0; i < header->e_phnum; ++i) { | ||||
|         const Elf32_Phdr* p = &segments[i]; | ||||
| @@ -311,14 +305,14 @@ SharedPtr<CodeSet> ElfReader::LoadInto(VAddr vaddr) { | ||||
|                   p->p_vaddr, p->p_filesz, p->p_memsz); | ||||
|  | ||||
|         if (p->p_type == PT_LOAD) { | ||||
|             CodeSet::Segment* codeset_segment; | ||||
|             Kernel::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->CodeSegment(); | ||||
|                 codeset_segment = &codeset.CodeSegment(); | ||||
|             } else if (permission_flags == (PF_R)) { | ||||
|                 codeset_segment = &codeset->RODataSegment(); | ||||
|                 codeset_segment = &codeset.RODataSegment(); | ||||
|             } else if (permission_flags == (PF_R | PF_W)) { | ||||
|                 codeset_segment = &codeset->DataSegment(); | ||||
|                 codeset_segment = &codeset.DataSegment(); | ||||
|             } else { | ||||
|                 LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, | ||||
|                           p->p_flags); | ||||
| @@ -345,8 +339,8 @@ SharedPtr<CodeSet> ElfReader::LoadInto(VAddr vaddr) { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     codeset->entrypoint = base_addr + header->e_entry; | ||||
|     codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | ||||
|     codeset.entrypoint = base_addr + header->e_entry; | ||||
|     codeset.memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | ||||
|  | ||||
|     LOG_DEBUG(Loader, "Done loading."); | ||||
|  | ||||
| @@ -397,11 +391,11 @@ ResultStatus AppLoader_ELF::Load(Kernel::Process& process) { | ||||
|  | ||||
|     const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); | ||||
|     ElfReader elf_reader(&buffer[0]); | ||||
|     SharedPtr<CodeSet> codeset = elf_reader.LoadInto(base_address); | ||||
|     codeset->name = file->GetName(); | ||||
|     Kernel::CodeSet codeset = elf_reader.LoadInto(base_address); | ||||
|     const VAddr entry_point = codeset.entrypoint; | ||||
|  | ||||
|     process.LoadModule(codeset, codeset->entrypoint); | ||||
|     process.Run(codeset->entrypoint, 48, Memory::DEFAULT_STACK_SIZE); | ||||
|     process.LoadModule(std::move(codeset), entry_point); | ||||
|     process.Run(entry_point, 48, Memory::DEFAULT_STACK_SIZE); | ||||
|  | ||||
|     is_loaded = true; | ||||
|     return ResultStatus::Success; | ||||
|   | ||||
| @@ -14,7 +14,6 @@ | ||||
| #include "core/file_sys/control_metadata.h" | ||||
| #include "core/file_sys/vfs_offset.h" | ||||
| #include "core/gdbstub/gdbstub.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/vm_manager.h" | ||||
| #include "core/loader/nro.h" | ||||
| @@ -139,22 +138,21 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) { | ||||
|     } | ||||
|  | ||||
|     // Build program image | ||||
|     auto& kernel = Core::System::GetInstance().Kernel(); | ||||
|     Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(kernel, ""); | ||||
|     std::vector<u8> program_image = file->ReadBytes(PageAlignSize(nro_header.file_size)); | ||||
|     if (program_image.size() != PageAlignSize(nro_header.file_size)) { | ||||
|         return {}; | ||||
|     } | ||||
|  | ||||
|     Kernel::CodeSet codeset; | ||||
|     for (std::size_t i = 0; i < nro_header.segments.size(); ++i) { | ||||
|         codeset->segments[i].addr = nro_header.segments[i].offset; | ||||
|         codeset->segments[i].offset = nro_header.segments[i].offset; | ||||
|         codeset->segments[i].size = PageAlignSize(nro_header.segments[i].size); | ||||
|         codeset.segments[i].addr = nro_header.segments[i].offset; | ||||
|         codeset.segments[i].offset = nro_header.segments[i].offset; | ||||
|         codeset.segments[i].size = PageAlignSize(nro_header.segments[i].size); | ||||
|     } | ||||
|  | ||||
|     if (!Settings::values.program_args.empty()) { | ||||
|         const auto arg_data = Settings::values.program_args; | ||||
|         codeset->DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE; | ||||
|         codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE; | ||||
|         NSOArgumentHeader args_header{ | ||||
|             NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}}; | ||||
|         const auto end_offset = program_image.size(); | ||||
| @@ -176,16 +174,15 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) { | ||||
|         // Resize program image to include .bss section and page align each section | ||||
|         bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); | ||||
|     } | ||||
|     codeset->DataSegment().size += bss_size; | ||||
|     codeset.DataSegment().size += bss_size; | ||||
|     program_image.resize(static_cast<u32>(program_image.size()) + bss_size); | ||||
|  | ||||
|     // Load codeset for current process | ||||
|     codeset->name = file->GetName(); | ||||
|     codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | ||||
|     Core::CurrentProcess()->LoadModule(codeset, load_base); | ||||
|     codeset.memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | ||||
|     Core::CurrentProcess()->LoadModule(std::move(codeset), load_base); | ||||
|  | ||||
|     // Register module with GDBStub | ||||
|     GDBStub::RegisterModule(codeset->name, load_base, load_base); | ||||
|     GDBStub::RegisterModule(file->GetName(), load_base, load_base); | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|   | ||||
| @@ -12,7 +12,6 @@ | ||||
| #include "core/core.h" | ||||
| #include "core/file_sys/patch_manager.h" | ||||
| #include "core/gdbstub/gdbstub.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/vm_manager.h" | ||||
| #include "core/loader/nso.h" | ||||
| @@ -111,8 +110,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, | ||||
|         return {}; | ||||
|  | ||||
|     // Build program image | ||||
|     auto& kernel = Core::System::GetInstance().Kernel(); | ||||
|     Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(kernel, ""); | ||||
|     Kernel::CodeSet codeset; | ||||
|     std::vector<u8> program_image; | ||||
|     for (std::size_t i = 0; i < nso_header.segments.size(); ++i) { | ||||
|         std::vector<u8> data = | ||||
| @@ -122,14 +120,14 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, | ||||
|         } | ||||
|         program_image.resize(nso_header.segments[i].location); | ||||
|         program_image.insert(program_image.end(), data.begin(), data.end()); | ||||
|         codeset->segments[i].addr = nso_header.segments[i].location; | ||||
|         codeset->segments[i].offset = nso_header.segments[i].location; | ||||
|         codeset->segments[i].size = PageAlignSize(static_cast<u32>(data.size())); | ||||
|         codeset.segments[i].addr = nso_header.segments[i].location; | ||||
|         codeset.segments[i].offset = nso_header.segments[i].location; | ||||
|         codeset.segments[i].size = PageAlignSize(static_cast<u32>(data.size())); | ||||
|     } | ||||
|  | ||||
|     if (should_pass_arguments && !Settings::values.program_args.empty()) { | ||||
|         const auto arg_data = Settings::values.program_args; | ||||
|         codeset->DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE; | ||||
|         codeset.DataSegment().size += NSO_ARGUMENT_DATA_ALLOCATION_SIZE; | ||||
|         NSOArgumentHeader args_header{ | ||||
|             NSO_ARGUMENT_DATA_ALLOCATION_SIZE, static_cast<u32_le>(arg_data.size()), {}}; | ||||
|         const auto end_offset = program_image.size(); | ||||
| @@ -154,7 +152,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, | ||||
|         // Resize program image to include .bss section and page align each section | ||||
|         bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); | ||||
|     } | ||||
|     codeset->DataSegment().size += bss_size; | ||||
|     codeset.DataSegment().size += bss_size; | ||||
|     const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)}; | ||||
|     program_image.resize(image_size); | ||||
|  | ||||
| @@ -170,12 +168,11 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base, | ||||
|     } | ||||
|  | ||||
|     // Load codeset for current process | ||||
|     codeset->name = file->GetName(); | ||||
|     codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | ||||
|     Core::CurrentProcess()->LoadModule(codeset, load_base); | ||||
|     codeset.memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | ||||
|     Core::CurrentProcess()->LoadModule(std::move(codeset), load_base); | ||||
|  | ||||
|     // Register module with GDBStub | ||||
|     GDBStub::RegisterModule(codeset->name, load_base, load_base); | ||||
|     GDBStub::RegisterModule(file->GetName(), load_base, load_base); | ||||
|  | ||||
|     return load_base + image_size; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lioncash
					Lioncash