mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 23:49:01 -05:00 
			
		
		
		
	kernel/process: Hook up the process capability parser to the process itself
While we're at it, we can also toss out the leftover capability parsing from Citra.
This commit is contained in:
		| @@ -28,13 +28,11 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) { | ||||
|     SharedPtr<Process> process(new Process(kernel)); | ||||
|  | ||||
|     process->name = std::move(name); | ||||
|     process->flags.raw = 0; | ||||
|     process->flags.memory_region.Assign(MemoryRegion::APPLICATION); | ||||
|     process->resource_limit = kernel.GetSystemResourceLimit(); | ||||
|     process->status = ProcessStatus::Created; | ||||
|     process->program_id = 0; | ||||
|     process->process_id = kernel.CreateNewProcessID(); | ||||
|     process->svc_access_mask.set(); | ||||
|     process->capabilities.InitializeForMetadatalessProcess(); | ||||
|  | ||||
|     std::mt19937 rng(Settings::values.rng_seed.value_or(0)); | ||||
|     std::uniform_int_distribution<u64> distribution; | ||||
| @@ -64,83 +62,15 @@ ResultCode Process::ClearSignalState() { | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { | ||||
| ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { | ||||
|     program_id = metadata.GetTitleID(); | ||||
|     ideal_processor = metadata.GetMainThreadCore(); | ||||
|     is_64bit_process = metadata.Is64BitProgram(); | ||||
|  | ||||
|     vm_manager.Reset(metadata.GetAddressSpaceType()); | ||||
| } | ||||
|  | ||||
| void Process::ParseKernelCaps(const u32* kernel_caps, std::size_t len) { | ||||
|     for (std::size_t i = 0; i < len; ++i) { | ||||
|         u32 descriptor = kernel_caps[i]; | ||||
|         u32 type = descriptor >> 20; | ||||
|  | ||||
|         if (descriptor == 0xFFFFFFFF) { | ||||
|             // Unused descriptor entry | ||||
|             continue; | ||||
|         } else if ((type & 0xF00) == 0xE00) { // 0x0FFF | ||||
|             // Allowed interrupts list | ||||
|             LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored"); | ||||
|         } else if ((type & 0xF80) == 0xF00) { // 0x07FF | ||||
|             // Allowed syscalls mask | ||||
|             unsigned int index = ((descriptor >> 24) & 7) * 24; | ||||
|             u32 bits = descriptor & 0xFFFFFF; | ||||
|  | ||||
|             while (bits && index < svc_access_mask.size()) { | ||||
|                 svc_access_mask.set(index, bits & 1); | ||||
|                 ++index; | ||||
|                 bits >>= 1; | ||||
|             } | ||||
|         } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF | ||||
|             // Handle table size | ||||
|             handle_table_size = descriptor & 0x3FF; | ||||
|         } else if ((type & 0xFF8) == 0xFF0) { // 0x007F | ||||
|             // Misc. flags | ||||
|             flags.raw = descriptor & 0xFFFF; | ||||
|         } else if ((type & 0xFFE) == 0xFF8) { // 0x001F | ||||
|             // Mapped memory range | ||||
|             if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) { | ||||
|                 LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); | ||||
|                 continue; | ||||
|             } | ||||
|             u32 end_desc = kernel_caps[i + 1]; | ||||
|             ++i; // Skip over the second descriptor on the next iteration | ||||
|  | ||||
|             AddressMapping mapping; | ||||
|             mapping.address = descriptor << 12; | ||||
|             VAddr end_address = end_desc << 12; | ||||
|  | ||||
|             if (mapping.address < end_address) { | ||||
|                 mapping.size = end_address - mapping.address; | ||||
|             } else { | ||||
|                 mapping.size = 0; | ||||
|             } | ||||
|  | ||||
|             mapping.read_only = (descriptor & (1 << 20)) != 0; | ||||
|             mapping.unk_flag = (end_desc & (1 << 20)) != 0; | ||||
|  | ||||
|             address_mappings.push_back(mapping); | ||||
|         } else if ((type & 0xFFF) == 0xFFE) { // 0x000F | ||||
|             // Mapped memory page | ||||
|             AddressMapping mapping; | ||||
|             mapping.address = descriptor << 12; | ||||
|             mapping.size = Memory::PAGE_SIZE; | ||||
|             mapping.read_only = false; | ||||
|             mapping.unk_flag = false; | ||||
|  | ||||
|             address_mappings.push_back(mapping); | ||||
|         } else if ((type & 0xFE0) == 0xFC0) { // 0x01FF | ||||
|             // Kernel version | ||||
|             kernel_version = descriptor & 0xFFFF; | ||||
|  | ||||
|             int minor = kernel_version & 0xFF; | ||||
|             int major = (kernel_version >> 8) & 0xFF; | ||||
|             LOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor); | ||||
|         } else { | ||||
|             LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x{:08X}", descriptor); | ||||
|         } | ||||
|     } | ||||
|     const auto& caps = metadata.GetKernelCapabilities(); | ||||
|     return capabilities.InitializeForUserProcess(caps.data(), caps.size(), vm_manager); | ||||
| } | ||||
|  | ||||
| void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | ||||
|   | ||||
| @@ -11,9 +11,9 @@ | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <boost/container/static_vector.hpp> | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| #include "core/hle/kernel/process_capability.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/hle/kernel/vm_manager.h" | ||||
| #include "core/hle/kernel/wait_object.h" | ||||
| @@ -42,24 +42,6 @@ enum class MemoryRegion : u16 { | ||||
|     BASE = 3, | ||||
| }; | ||||
|  | ||||
| union ProcessFlags { | ||||
|     u16 raw; | ||||
|  | ||||
|     BitField<0, 1, u16> | ||||
|         allow_debug; ///< Allows other processes to attach to and debug this process. | ||||
|     BitField<1, 1, u16> force_debug; ///< Allows this process to attach to processes even if they | ||||
|                                      /// don't have allow_debug set. | ||||
|     BitField<2, 1, u16> allow_nonalphanum; | ||||
|     BitField<3, 1, u16> shared_page_writable; ///< Shared page is mapped with write permissions. | ||||
|     BitField<4, 1, u16> privileged_priority;  ///< Can use priority levels higher than 24. | ||||
|     BitField<5, 1, u16> allow_main_args; | ||||
|     BitField<6, 1, u16> shared_device_mem; | ||||
|     BitField<7, 1, u16> runnable_on_sleep; | ||||
|     BitField<8, 4, MemoryRegion> | ||||
|         memory_region;                ///< Default region for memory allocations for this process | ||||
|     BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Indicates the status of a Process instance. | ||||
|  * | ||||
| @@ -180,13 +162,13 @@ public: | ||||
|     } | ||||
|  | ||||
|     /// Gets the bitmask of allowed CPUs that this process' threads can run on. | ||||
|     u32 GetAllowedProcessorMask() const { | ||||
|         return allowed_processor_mask; | ||||
|     u64 GetAllowedProcessorMask() const { | ||||
|         return capabilities.GetCoreMask(); | ||||
|     } | ||||
|  | ||||
|     /// Gets the bitmask of allowed thread priorities. | ||||
|     u32 GetAllowedThreadPriorityMask() const { | ||||
|         return allowed_thread_priority_mask; | ||||
|     u64 GetAllowedThreadPriorityMask() const { | ||||
|         return capabilities.GetPriorityMask(); | ||||
|     } | ||||
|  | ||||
|     u32 IsVirtualMemoryEnabled() const { | ||||
| @@ -227,15 +209,12 @@ public: | ||||
|      * Loads process-specifics configuration info with metadata provided | ||||
|      * by an executable. | ||||
|      * | ||||
|      * @param metadata The provided metadata to load process specific info. | ||||
|      * @param metadata The provided metadata to load process specific info from. | ||||
|      * | ||||
|      * @returns RESULT_SUCCESS if all relevant metadata was able to be | ||||
|      *          loaded and parsed. Otherwise, an error code is returned. | ||||
|      */ | ||||
|     void LoadFromMetadata(const FileSys::ProgramMetadata& metadata); | ||||
|  | ||||
|     /** | ||||
|      * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them | ||||
|      * to this process. | ||||
|      */ | ||||
|     void ParseKernelCaps(const u32* kernel_caps, std::size_t len); | ||||
|     ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata); | ||||
|  | ||||
|     /** | ||||
|      * Applies address space changes and launches the process main thread. | ||||
| @@ -296,22 +275,8 @@ private: | ||||
|     /// Resource limit descriptor for this process | ||||
|     SharedPtr<ResourceLimit> resource_limit; | ||||
|  | ||||
|     /// The process may only call SVCs which have the corresponding bit set. | ||||
|     std::bitset<0x80> svc_access_mask; | ||||
|     /// Maximum size of the handle table for the process. | ||||
|     u32 handle_table_size = 0x200; | ||||
|     /// Special memory ranges mapped into this processes address space. This is used to give | ||||
|     /// processes access to specific I/O regions and device memory. | ||||
|     boost::container::static_vector<AddressMapping, 8> address_mappings; | ||||
|     ProcessFlags flags; | ||||
|     /// Kernel compatibility version for this process | ||||
|     u16 kernel_version = 0; | ||||
|     /// The default CPU for this process, threads are scheduled on this cpu by default. | ||||
|     u8 ideal_processor = 0; | ||||
|     /// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse | ||||
|     /// this value from the process header. | ||||
|     u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK; | ||||
|     u32 allowed_thread_priority_mask = 0xFFFFFFFF; | ||||
|     u32 is_virtual_address_memory_enabled = 0; | ||||
|  | ||||
|     /// The Thread Local Storage area is allocated as processes create threads, | ||||
| @@ -321,6 +286,9 @@ private: | ||||
|     /// This vector will grow as more pages are allocated for new threads. | ||||
|     std::vector<std::bitset<8>> tls_slots; | ||||
|  | ||||
|     /// Contains the parsed process capability descriptors. | ||||
|     ProcessCapabilities capabilities; | ||||
|  | ||||
|     /// Whether or not this process is AArch64, or AArch32. | ||||
|     /// By default, we currently assume this is true, unless otherwise | ||||
|     /// specified by metadata provided to the process during loading. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lioncash
					Lioncash