diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/file_sys/program_metadata.cpp | 11 | ||||
| -rw-r--r-- | src/core/file_sys/program_metadata.h | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 80 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 58 | ||||
| -rw-r--r-- | src/core/loader/deconstructed_rom_directory.cpp | 5 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 2 |
7 files changed, 44 insertions, 122 deletions
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index 8903ed1d3..e90c8c2de 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp | |||
| @@ -40,6 +40,13 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { | |||
| 40 | if (sizeof(FileAccessHeader) != file->ReadObject(&aci_file_access, aci_header.fah_offset)) | 40 | if (sizeof(FileAccessHeader) != file->ReadObject(&aci_file_access, aci_header.fah_offset)) |
| 41 | return Loader::ResultStatus::ErrorBadFileAccessHeader; | 41 | return Loader::ResultStatus::ErrorBadFileAccessHeader; |
| 42 | 42 | ||
| 43 | aci_kernel_capabilities.resize(aci_header.kac_size / sizeof(u32)); | ||
| 44 | const u64 read_size = aci_header.kac_size; | ||
| 45 | const u64 read_offset = npdm_header.aci_offset + aci_header.kac_offset; | ||
| 46 | if (file->ReadBytes(aci_kernel_capabilities.data(), read_size, read_offset) != read_size) { | ||
| 47 | return Loader::ResultStatus::ErrorBadKernelCapabilityDescriptors; | ||
| 48 | } | ||
| 49 | |||
| 43 | return Loader::ResultStatus::Success; | 50 | return Loader::ResultStatus::Success; |
| 44 | } | 51 | } |
| 45 | 52 | ||
| @@ -71,6 +78,10 @@ u64 ProgramMetadata::GetFilesystemPermissions() const { | |||
| 71 | return aci_file_access.permissions; | 78 | return aci_file_access.permissions; |
| 72 | } | 79 | } |
| 73 | 80 | ||
| 81 | const ProgramMetadata::KernelCapabilityDescriptors& ProgramMetadata::GetKernelCapabilities() const { | ||
| 82 | return aci_kernel_capabilities; | ||
| 83 | } | ||
| 84 | |||
| 74 | void ProgramMetadata::Print() const { | 85 | void ProgramMetadata::Print() const { |
| 75 | LOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data()); | 86 | LOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data()); |
| 76 | LOG_DEBUG(Service_FS, "Main thread priority: 0x{:02X}", npdm_header.main_thread_priority); | 87 | LOG_DEBUG(Service_FS, "Main thread priority: 0x{:02X}", npdm_header.main_thread_priority); |
diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h index e4470d6f0..0033ba347 100644 --- a/src/core/file_sys/program_metadata.h +++ b/src/core/file_sys/program_metadata.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <vector> | ||
| 8 | #include "common/bit_field.h" | 9 | #include "common/bit_field.h" |
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| @@ -38,6 +39,8 @@ enum class ProgramFilePermission : u64 { | |||
| 38 | */ | 39 | */ |
| 39 | class ProgramMetadata { | 40 | class ProgramMetadata { |
| 40 | public: | 41 | public: |
| 42 | using KernelCapabilityDescriptors = std::vector<u32>; | ||
| 43 | |||
| 41 | ProgramMetadata(); | 44 | ProgramMetadata(); |
| 42 | ~ProgramMetadata(); | 45 | ~ProgramMetadata(); |
| 43 | 46 | ||
| @@ -50,6 +53,7 @@ public: | |||
| 50 | u32 GetMainThreadStackSize() const; | 53 | u32 GetMainThreadStackSize() const; |
| 51 | u64 GetTitleID() const; | 54 | u64 GetTitleID() const; |
| 52 | u64 GetFilesystemPermissions() const; | 55 | u64 GetFilesystemPermissions() const; |
| 56 | const KernelCapabilityDescriptors& GetKernelCapabilities() const; | ||
| 53 | 57 | ||
| 54 | void Print() const; | 58 | void Print() const; |
| 55 | 59 | ||
| @@ -154,6 +158,8 @@ private: | |||
| 154 | 158 | ||
| 155 | FileAccessControl acid_file_access; | 159 | FileAccessControl acid_file_access; |
| 156 | FileAccessHeader aci_file_access; | 160 | FileAccessHeader aci_file_access; |
| 161 | |||
| 162 | KernelCapabilityDescriptors aci_kernel_capabilities; | ||
| 157 | }; | 163 | }; |
| 158 | 164 | ||
| 159 | } // namespace FileSys | 165 | } // namespace FileSys |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 5356a4a3f..4f209a979 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -28,13 +28,11 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) { | |||
| 28 | SharedPtr<Process> process(new Process(kernel)); | 28 | SharedPtr<Process> process(new Process(kernel)); |
| 29 | 29 | ||
| 30 | process->name = std::move(name); | 30 | process->name = std::move(name); |
| 31 | process->flags.raw = 0; | ||
| 32 | process->flags.memory_region.Assign(MemoryRegion::APPLICATION); | ||
| 33 | process->resource_limit = kernel.GetSystemResourceLimit(); | 31 | process->resource_limit = kernel.GetSystemResourceLimit(); |
| 34 | process->status = ProcessStatus::Created; | 32 | process->status = ProcessStatus::Created; |
| 35 | process->program_id = 0; | 33 | process->program_id = 0; |
| 36 | process->process_id = kernel.CreateNewProcessID(); | 34 | process->process_id = kernel.CreateNewProcessID(); |
| 37 | process->svc_access_mask.set(); | 35 | process->capabilities.InitializeForMetadatalessProcess(); |
| 38 | 36 | ||
| 39 | std::mt19937 rng(Settings::values.rng_seed.value_or(0)); | 37 | std::mt19937 rng(Settings::values.rng_seed.value_or(0)); |
| 40 | std::uniform_int_distribution<u64> distribution; | 38 | std::uniform_int_distribution<u64> distribution; |
| @@ -64,83 +62,15 @@ ResultCode Process::ClearSignalState() { | |||
| 64 | return RESULT_SUCCESS; | 62 | return RESULT_SUCCESS; |
| 65 | } | 63 | } |
| 66 | 64 | ||
| 67 | void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { | 65 | ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { |
| 68 | program_id = metadata.GetTitleID(); | 66 | program_id = metadata.GetTitleID(); |
| 69 | ideal_processor = metadata.GetMainThreadCore(); | 67 | ideal_processor = metadata.GetMainThreadCore(); |
| 70 | is_64bit_process = metadata.Is64BitProgram(); | 68 | is_64bit_process = metadata.Is64BitProgram(); |
| 71 | vm_manager.Reset(metadata.GetAddressSpaceType()); | ||
| 72 | } | ||
| 73 | |||
| 74 | void Process::ParseKernelCaps(const u32* kernel_caps, std::size_t len) { | ||
| 75 | for (std::size_t i = 0; i < len; ++i) { | ||
| 76 | u32 descriptor = kernel_caps[i]; | ||
| 77 | u32 type = descriptor >> 20; | ||
| 78 | |||
| 79 | if (descriptor == 0xFFFFFFFF) { | ||
| 80 | // Unused descriptor entry | ||
| 81 | continue; | ||
| 82 | } else if ((type & 0xF00) == 0xE00) { // 0x0FFF | ||
| 83 | // Allowed interrupts list | ||
| 84 | LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored"); | ||
| 85 | } else if ((type & 0xF80) == 0xF00) { // 0x07FF | ||
| 86 | // Allowed syscalls mask | ||
| 87 | unsigned int index = ((descriptor >> 24) & 7) * 24; | ||
| 88 | u32 bits = descriptor & 0xFFFFFF; | ||
| 89 | |||
| 90 | while (bits && index < svc_access_mask.size()) { | ||
| 91 | svc_access_mask.set(index, bits & 1); | ||
| 92 | ++index; | ||
| 93 | bits >>= 1; | ||
| 94 | } | ||
| 95 | } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF | ||
| 96 | // Handle table size | ||
| 97 | handle_table_size = descriptor & 0x3FF; | ||
| 98 | } else if ((type & 0xFF8) == 0xFF0) { // 0x007F | ||
| 99 | // Misc. flags | ||
| 100 | flags.raw = descriptor & 0xFFFF; | ||
| 101 | } else if ((type & 0xFFE) == 0xFF8) { // 0x001F | ||
| 102 | // Mapped memory range | ||
| 103 | if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) { | ||
| 104 | LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); | ||
| 105 | continue; | ||
| 106 | } | ||
| 107 | u32 end_desc = kernel_caps[i + 1]; | ||
| 108 | ++i; // Skip over the second descriptor on the next iteration | ||
| 109 | 69 | ||
| 110 | AddressMapping mapping; | 70 | vm_manager.Reset(metadata.GetAddressSpaceType()); |
| 111 | mapping.address = descriptor << 12; | ||
| 112 | VAddr end_address = end_desc << 12; | ||
| 113 | |||
| 114 | if (mapping.address < end_address) { | ||
| 115 | mapping.size = end_address - mapping.address; | ||
| 116 | } else { | ||
| 117 | mapping.size = 0; | ||
| 118 | } | ||
| 119 | 71 | ||
| 120 | mapping.read_only = (descriptor & (1 << 20)) != 0; | 72 | const auto& caps = metadata.GetKernelCapabilities(); |
| 121 | mapping.unk_flag = (end_desc & (1 << 20)) != 0; | 73 | return capabilities.InitializeForUserProcess(caps.data(), caps.size(), vm_manager); |
| 122 | |||
| 123 | address_mappings.push_back(mapping); | ||
| 124 | } else if ((type & 0xFFF) == 0xFFE) { // 0x000F | ||
| 125 | // Mapped memory page | ||
| 126 | AddressMapping mapping; | ||
| 127 | mapping.address = descriptor << 12; | ||
| 128 | mapping.size = Memory::PAGE_SIZE; | ||
| 129 | mapping.read_only = false; | ||
| 130 | mapping.unk_flag = false; | ||
| 131 | |||
| 132 | address_mappings.push_back(mapping); | ||
| 133 | } else if ((type & 0xFE0) == 0xFC0) { // 0x01FF | ||
| 134 | // Kernel version | ||
| 135 | kernel_version = descriptor & 0xFFFF; | ||
| 136 | |||
| 137 | int minor = kernel_version & 0xFF; | ||
| 138 | int major = (kernel_version >> 8) & 0xFF; | ||
| 139 | LOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor); | ||
| 140 | } else { | ||
| 141 | LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x{:08X}", descriptor); | ||
| 142 | } | ||
| 143 | } | ||
| 144 | } | 74 | } |
| 145 | 75 | ||
| 146 | void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | 76 | void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 459eedfa6..f6fb72770 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -11,9 +11,9 @@ | |||
| 11 | #include <string> | 11 | #include <string> |
| 12 | #include <vector> | 12 | #include <vector> |
| 13 | #include <boost/container/static_vector.hpp> | 13 | #include <boost/container/static_vector.hpp> |
| 14 | #include "common/bit_field.h" | ||
| 15 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 16 | #include "core/hle/kernel/handle_table.h" | 15 | #include "core/hle/kernel/handle_table.h" |
| 16 | #include "core/hle/kernel/process_capability.h" | ||
| 17 | #include "core/hle/kernel/thread.h" | 17 | #include "core/hle/kernel/thread.h" |
| 18 | #include "core/hle/kernel/vm_manager.h" | 18 | #include "core/hle/kernel/vm_manager.h" |
| 19 | #include "core/hle/kernel/wait_object.h" | 19 | #include "core/hle/kernel/wait_object.h" |
| @@ -42,24 +42,6 @@ enum class MemoryRegion : u16 { | |||
| 42 | BASE = 3, | 42 | BASE = 3, |
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | union ProcessFlags { | ||
| 46 | u16 raw; | ||
| 47 | |||
| 48 | BitField<0, 1, u16> | ||
| 49 | allow_debug; ///< Allows other processes to attach to and debug this process. | ||
| 50 | BitField<1, 1, u16> force_debug; ///< Allows this process to attach to processes even if they | ||
| 51 | /// don't have allow_debug set. | ||
| 52 | BitField<2, 1, u16> allow_nonalphanum; | ||
| 53 | BitField<3, 1, u16> shared_page_writable; ///< Shared page is mapped with write permissions. | ||
| 54 | BitField<4, 1, u16> privileged_priority; ///< Can use priority levels higher than 24. | ||
| 55 | BitField<5, 1, u16> allow_main_args; | ||
| 56 | BitField<6, 1, u16> shared_device_mem; | ||
| 57 | BitField<7, 1, u16> runnable_on_sleep; | ||
| 58 | BitField<8, 4, MemoryRegion> | ||
| 59 | memory_region; ///< Default region for memory allocations for this process | ||
| 60 | BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). | ||
| 61 | }; | ||
| 62 | |||
| 63 | /** | 45 | /** |
| 64 | * Indicates the status of a Process instance. | 46 | * Indicates the status of a Process instance. |
| 65 | * | 47 | * |
| @@ -180,13 +162,13 @@ public: | |||
| 180 | } | 162 | } |
| 181 | 163 | ||
| 182 | /// Gets the bitmask of allowed CPUs that this process' threads can run on. | 164 | /// Gets the bitmask of allowed CPUs that this process' threads can run on. |
| 183 | u32 GetAllowedProcessorMask() const { | 165 | u64 GetAllowedProcessorMask() const { |
| 184 | return allowed_processor_mask; | 166 | return capabilities.GetCoreMask(); |
| 185 | } | 167 | } |
| 186 | 168 | ||
| 187 | /// Gets the bitmask of allowed thread priorities. | 169 | /// Gets the bitmask of allowed thread priorities. |
| 188 | u32 GetAllowedThreadPriorityMask() const { | 170 | u64 GetAllowedThreadPriorityMask() const { |
| 189 | return allowed_thread_priority_mask; | 171 | return capabilities.GetPriorityMask(); |
| 190 | } | 172 | } |
| 191 | 173 | ||
| 192 | u32 IsVirtualMemoryEnabled() const { | 174 | u32 IsVirtualMemoryEnabled() const { |
| @@ -227,15 +209,12 @@ public: | |||
| 227 | * Loads process-specifics configuration info with metadata provided | 209 | * Loads process-specifics configuration info with metadata provided |
| 228 | * by an executable. | 210 | * by an executable. |
| 229 | * | 211 | * |
| 230 | * @param metadata The provided metadata to load process specific info. | 212 | * @param metadata The provided metadata to load process specific info from. |
| 231 | */ | 213 | * |
| 232 | void LoadFromMetadata(const FileSys::ProgramMetadata& metadata); | 214 | * @returns RESULT_SUCCESS if all relevant metadata was able to be |
| 233 | 215 | * loaded and parsed. Otherwise, an error code is returned. | |
| 234 | /** | ||
| 235 | * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them | ||
| 236 | * to this process. | ||
| 237 | */ | 216 | */ |
| 238 | void ParseKernelCaps(const u32* kernel_caps, std::size_t len); | 217 | ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata); |
| 239 | 218 | ||
| 240 | /** | 219 | /** |
| 241 | * Applies address space changes and launches the process main thread. | 220 | * Applies address space changes and launches the process main thread. |
| @@ -296,22 +275,8 @@ private: | |||
| 296 | /// Resource limit descriptor for this process | 275 | /// Resource limit descriptor for this process |
| 297 | SharedPtr<ResourceLimit> resource_limit; | 276 | SharedPtr<ResourceLimit> resource_limit; |
| 298 | 277 | ||
| 299 | /// The process may only call SVCs which have the corresponding bit set. | ||
| 300 | std::bitset<0x80> svc_access_mask; | ||
| 301 | /// Maximum size of the handle table for the process. | ||
| 302 | u32 handle_table_size = 0x200; | ||
| 303 | /// Special memory ranges mapped into this processes address space. This is used to give | ||
| 304 | /// processes access to specific I/O regions and device memory. | ||
| 305 | boost::container::static_vector<AddressMapping, 8> address_mappings; | ||
| 306 | ProcessFlags flags; | ||
| 307 | /// Kernel compatibility version for this process | ||
| 308 | u16 kernel_version = 0; | ||
| 309 | /// The default CPU for this process, threads are scheduled on this cpu by default. | 278 | /// The default CPU for this process, threads are scheduled on this cpu by default. |
| 310 | u8 ideal_processor = 0; | 279 | u8 ideal_processor = 0; |
| 311 | /// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse | ||
| 312 | /// this value from the process header. | ||
| 313 | u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK; | ||
| 314 | u32 allowed_thread_priority_mask = 0xFFFFFFFF; | ||
| 315 | u32 is_virtual_address_memory_enabled = 0; | 280 | u32 is_virtual_address_memory_enabled = 0; |
| 316 | 281 | ||
| 317 | /// The Thread Local Storage area is allocated as processes create threads, | 282 | /// The Thread Local Storage area is allocated as processes create threads, |
| @@ -321,6 +286,9 @@ private: | |||
| 321 | /// This vector will grow as more pages are allocated for new threads. | 286 | /// This vector will grow as more pages are allocated for new threads. |
| 322 | std::vector<std::bitset<8>> tls_slots; | 287 | std::vector<std::bitset<8>> tls_slots; |
| 323 | 288 | ||
| 289 | /// Contains the parsed process capability descriptors. | ||
| 290 | ProcessCapabilities capabilities; | ||
| 291 | |||
| 324 | /// Whether or not this process is AArch64, or AArch32. | 292 | /// Whether or not this process is AArch64, or AArch32. |
| 325 | /// By default, we currently assume this is true, unless otherwise | 293 | /// By default, we currently assume this is true, unless otherwise |
| 326 | /// specified by metadata provided to the process during loading. | 294 | /// specified by metadata provided to the process during loading. |
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index ac04d72d7..07aa7a1cd 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -129,7 +129,10 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) | |||
| 129 | return ResultStatus::Error32BitISA; | 129 | return ResultStatus::Error32BitISA; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | process.LoadFromMetadata(metadata); | 132 | if (process.LoadFromMetadata(metadata).IsError()) { |
| 133 | return ResultStatus::ErrorUnableToParseKernelMetadata; | ||
| 134 | } | ||
| 135 | |||
| 133 | const FileSys::PatchManager pm(metadata.GetTitleID()); | 136 | const FileSys::PatchManager pm(metadata.GetTitleID()); |
| 134 | 137 | ||
| 135 | // Load NSO modules | 138 | // Load NSO modules |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 9cd0b0ccd..d8cc30959 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -93,7 +93,7 @@ std::string GetFileTypeString(FileType type) { | |||
| 93 | return "unknown"; | 93 | return "unknown"; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | constexpr std::array<const char*, 60> RESULT_MESSAGES{ | 96 | constexpr std::array<const char*, 62> RESULT_MESSAGES{ |
| 97 | "The operation completed successfully.", | 97 | "The operation completed successfully.", |
| 98 | "The loader requested to load is already loaded.", | 98 | "The loader requested to load is already loaded.", |
| 99 | "The operation is not implemented.", | 99 | "The operation is not implemented.", |
| @@ -103,6 +103,7 @@ constexpr std::array<const char*, 60> RESULT_MESSAGES{ | |||
| 103 | "The NPDM has a bad ACI header,", | 103 | "The NPDM has a bad ACI header,", |
| 104 | "The NPDM file has a bad file access control.", | 104 | "The NPDM file has a bad file access control.", |
| 105 | "The NPDM has a bad file access header.", | 105 | "The NPDM has a bad file access header.", |
| 106 | "The NPDM has bad kernel capability descriptors.", | ||
| 106 | "The PFS/HFS partition has a bad header.", | 107 | "The PFS/HFS partition has a bad header.", |
| 107 | "The PFS/HFS partition has incorrect size as determined by the header.", | 108 | "The PFS/HFS partition has incorrect size as determined by the header.", |
| 108 | "The NCA file has a bad header.", | 109 | "The NCA file has a bad header.", |
| @@ -125,6 +126,7 @@ constexpr std::array<const char*, 60> RESULT_MESSAGES{ | |||
| 125 | "The file could not be found or does not exist.", | 126 | "The file could not be found or does not exist.", |
| 126 | "The game is missing a program metadata file (main.npdm).", | 127 | "The game is missing a program metadata file (main.npdm).", |
| 127 | "The game uses the currently-unimplemented 32-bit architecture.", | 128 | "The game uses the currently-unimplemented 32-bit architecture.", |
| 129 | "Unable to completely parse the kernel metadata when loading the emulated process", | ||
| 128 | "The RomFS could not be found.", | 130 | "The RomFS could not be found.", |
| 129 | "The ELF file has incorrect size as determined by the header.", | 131 | "The ELF file has incorrect size as determined by the header.", |
| 130 | "There was a general error loading the NRO into emulated memory.", | 132 | "There was a general error loading the NRO into emulated memory.", |
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 0838e303b..a39cb812d 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -67,6 +67,7 @@ enum class ResultStatus : u16 { | |||
| 67 | ErrorBadACIHeader, | 67 | ErrorBadACIHeader, |
| 68 | ErrorBadFileAccessControl, | 68 | ErrorBadFileAccessControl, |
| 69 | ErrorBadFileAccessHeader, | 69 | ErrorBadFileAccessHeader, |
| 70 | ErrorBadKernelCapabilityDescriptors, | ||
| 70 | ErrorBadPFSHeader, | 71 | ErrorBadPFSHeader, |
| 71 | ErrorIncorrectPFSFileSize, | 72 | ErrorIncorrectPFSFileSize, |
| 72 | ErrorBadNCAHeader, | 73 | ErrorBadNCAHeader, |
| @@ -89,6 +90,7 @@ enum class ResultStatus : u16 { | |||
| 89 | ErrorNullFile, | 90 | ErrorNullFile, |
| 90 | ErrorMissingNPDM, | 91 | ErrorMissingNPDM, |
| 91 | Error32BitISA, | 92 | Error32BitISA, |
| 93 | ErrorUnableToParseKernelMetadata, | ||
| 92 | ErrorNoRomFS, | 94 | ErrorNoRomFS, |
| 93 | ErrorIncorrectELFFileSize, | 95 | ErrorIncorrectELFFileSize, |
| 94 | ErrorLoadingNRO, | 96 | ErrorLoadingNRO, |