From 3577dd027ddbaa2517eacad700ed0768a1f4b518 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 16 Jun 2014 22:57:09 -0400 Subject: Loader: Added support for booting NCCH executables. NCCH: Fixed typo in printing NCCH filename. --- src/core/loader/ncch.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/core/loader/ncch.h (limited to 'src/core/loader/ncch.h') diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h new file mode 100644 index 000000000..778e8b456 --- /dev/null +++ b/src/core/loader/ncch.h @@ -0,0 +1,21 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "common/common.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace Loader { + +/** + * Loads an NCCH file (e.g. from a CCI or CXI) + * @param filename String filename of NCCH file + * @param error_string Pointer to string to put error message if an error has occurred + * @return True on success, otherwise false + */ +bool Load_NCCH(std::string& filename, std::string* error_string); + +} // namespace Loader -- cgit v1.2.3 From 7889cafc76ac99b8509fa3cd1558a09f8a7e5f91 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 18 Jun 2014 18:58:09 -0400 Subject: Loader: Implemented AppLoader interface for abstracting application loading. - Various cleanups/refactorings to Loader, ELF, and NCCH modules. - Added AppLoader interface to ELF and NCCH. - Updated Qt/GLFW frontends to check AppLoader ResultStatus. NCCH: Removed extra qualification typos. Loader: Removed unnecessary #include's. NCCH: Improved readability of memcmp statements. NCCH: Added missing space. Elf: Removed unnecessary usage of unique_ptr. Loader: Removed unnecessary usage of unique_ptr. --- src/core/loader/ncch.h | 181 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 174 insertions(+), 7 deletions(-) (limited to 'src/core/loader/ncch.h') diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 778e8b456..3aae5417c 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -5,17 +5,184 @@ #pragma once #include "common/common.h" +#include "common/file_util.h" + +#include "core/loader/loader.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// NCCH header (Note: "NCCH" appears to be a publically unknown acronym) + +struct NCCH_Header { + u8 signature[0x100]; + char magic[4]; + u32 content_size; + u8 partition_id[8]; + u16 maker_code; + u16 version; + u8 reserved_0[4]; + u8 program_id[8]; + u8 temp_flag; + u8 reserved_1[0x2f]; + u8 product_code[0x10]; + u8 extended_header_hash[0x20]; + u32 extended_header_size; + u8 reserved_2[4]; + u8 flags[8]; + u32 plain_region_offset; + u32 plain_region_size; + u8 reserved_3[8]; + u32 exefs_offset; + u32 exefs_size; + u32 exefs_hash_region_size; + u8 reserved_4[4]; + u32 romfs_offset; + u32 romfs_size; + u32 romfs_hash_region_size; + u8 reserved_5[4]; + u8 exefs_super_block_hash[0x20]; + u8 romfs_super_block_hash[0x20]; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// ExeFS (executable file system) headers + +typedef struct { + char name[8]; + u32 offset; + u32 size; +} ExeFs_SectionHeader; + +typedef struct { + ExeFs_SectionHeader section[8]; + u8 reserved[0x80]; + u8 hashes[8][0x20]; +} ExeFs_Header; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// ExHeader (executable file system header) headers + +struct ExHeader_SystemInfoFlags{ + u8 reserved[5]; + u8 flag; + u8 remaster_version[2]; +}; + +struct ExHeader_CodeSegmentInfo{ + u32 address; + u32 num_max_pages; + u32 code_size; +}; + +struct ExHeader_CodeSetInfo { + u8 name[8]; + ExHeader_SystemInfoFlags flags; + ExHeader_CodeSegmentInfo text; + u8 stacksize[4]; + ExHeader_CodeSegmentInfo ro; + u8 reserved[4]; + ExHeader_CodeSegmentInfo data; + u8 bsssize[4]; +}; + +struct ExHeader_DependencyList{ + u8 program_id[0x30][8]; +}; + +struct ExHeader_SystemInfo{ + u32 save_data_size; + u8 reserved[4]; + u8 jump_id[8]; + u8 reserved_2[0x30]; +}; + +struct ExHeader_StorageInfo{ + u8 ext_save_data_id[8]; + u8 system_save_data_id[8]; + u8 reserved[8]; + u8 access_info[7]; + u8 other_attributes; +}; + +struct ExHeader_ARM11_SystemLocalCaps{ + u8 program_id[8]; + u8 flags[8]; + u8 resource_limit_descriptor[0x10][2]; + ExHeader_StorageInfo storage_info; + u8 service_access_control[0x20][8]; + u8 reserved[0x1f]; + u8 resource_limit_category; +}; + +struct ExHeader_ARM11_KernelCaps{ + u8 descriptors[28][4]; + u8 reserved[0x10]; +}; + +struct ExHeader_ARM9_AccessControl{ + u8 descriptors[15]; + u8 descversion; +}; + +struct ExHeader_Header{ + ExHeader_CodeSetInfo codeset_info; + ExHeader_DependencyList dependency_list; + ExHeader_SystemInfo system_info; + ExHeader_ARM11_SystemLocalCaps arm11_system_local_caps; + ExHeader_ARM11_KernelCaps arm11_kernel_caps; + ExHeader_ARM9_AccessControl arm9_access_control; + struct { + u8 signature[0x100]; + u8 ncch_public_key_modulus[0x100]; + ExHeader_ARM11_SystemLocalCaps arm11_system_local_caps; + ExHeader_ARM11_KernelCaps arm11_kernel_caps; + ExHeader_ARM9_AccessControl arm9_access_control; + } access_desc; +}; //////////////////////////////////////////////////////////////////////////////////////////////////// +// Loader namespace namespace Loader { -/** - * Loads an NCCH file (e.g. from a CCI or CXI) - * @param filename String filename of NCCH file - * @param error_string Pointer to string to put error message if an error has occurred - * @return True on success, otherwise false - */ -bool Load_NCCH(std::string& filename, std::string* error_string); +/// Loads an NCCH file (e.g. from a CCI, or the first NCCH in a CXI) +class AppLoader_NCCH : public AppLoader { +public: + AppLoader_NCCH(std::string& filename); + ~AppLoader_NCCH(); + + /** + * Load the application + * @return ResultStatus result of function + */ + const ResultStatus Load(); + +private: + + /** + * Reads an application section of an NCCH file into AppLoader (e.g. .code, .logo, etc.) + * @param file Handle to file to read from + * @param name Name of section to read out of NCCH file + * @param buffer Buffer to read section into. + */ + const ResultStatus LoadSection(File::IOFile& file, const char* name, + std::vector& buffer); + + /** + * Loads .code section into memory for booting + * @return ResultStatus result of function + */ + const ResultStatus LoadExec() const; + + std::string filename; + bool is_loaded; + bool is_compressed; + u32 entry_point; + + u32 ncch_offset; // Offset to NCCH header, can be 0 or after NCSD header + u32 exefs_offset; + + ExeFs_Header exefs_header; + ExHeader_Header exheader_header; +}; } // namespace Loader -- cgit v1.2.3 From 3da2bc6830e05d943c4d131a3167c2df25bff344 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 18 Jun 2014 23:53:22 -0400 Subject: NCCH: Fixes reduce unnecessary logging and load logo/banner/etc. sections correctly. Loader: Added ErrorNotUsed ReturnStatus type to specify when something is not used. --- src/core/loader/ncch.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/core/loader/ncch.h') diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 3aae5417c..525a5aef5 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -159,12 +159,13 @@ public: private: /** - * Reads an application section of an NCCH file into AppLoader (e.g. .code, .logo, etc.) + * Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.) * @param file Handle to file to read from * @param name Name of section to read out of NCCH file * @param buffer Buffer to read section into. + * @return ResultStatus result of function */ - const ResultStatus LoadSection(File::IOFile& file, const char* name, + const ResultStatus LoadSectionExeFS(File::IOFile& file, const char* name, std::vector& buffer); /** -- cgit v1.2.3 From a8c46485203d3ab00ef478bbf9daa7450df14dfd Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 19 Jun 2014 00:11:45 -0400 Subject: NCCH: Added RomFS loading. --- src/core/loader/ncch.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/core/loader/ncch.h') diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 525a5aef5..939b144a6 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -168,6 +168,13 @@ private: const ResultStatus LoadSectionExeFS(File::IOFile& file, const char* name, std::vector& buffer); + /** + * Reads RomFS of an NCCH file into AppLoader + * @param file Handle to file to read from + * @return ResultStatus result of function + */ + const ResultStatus LoadRomFS(File::IOFile& file); + /** * Loads .code section into memory for booting * @return ResultStatus result of function @@ -182,6 +189,7 @@ private: u32 ncch_offset; // Offset to NCCH header, can be 0 or after NCSD header u32 exefs_offset; + NCCH_Header ncch_header; ExeFs_Header exefs_header; ExHeader_Header exheader_header; }; -- cgit v1.2.3 From 62b444cd17c17e6f8009d87609b620bcb51b43bd Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 19 Jun 2014 17:46:05 -0400 Subject: Loader: Refactored use of const. --- src/core/loader/ncch.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/core/loader/ncch.h') diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 939b144a6..126eb4c80 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -147,14 +147,14 @@ namespace Loader { /// Loads an NCCH file (e.g. from a CCI, or the first NCCH in a CXI) class AppLoader_NCCH : public AppLoader { public: - AppLoader_NCCH(std::string& filename); + AppLoader_NCCH(const std::string& filename); ~AppLoader_NCCH(); /** * Load the application * @return ResultStatus result of function */ - const ResultStatus Load(); + ResultStatus Load(); private: @@ -165,21 +165,20 @@ private: * @param buffer Buffer to read section into. * @return ResultStatus result of function */ - const ResultStatus LoadSectionExeFS(File::IOFile& file, const char* name, - std::vector& buffer); + ResultStatus LoadSectionExeFS(File::IOFile& file, const char* name, std::vector& buffer); /** * Reads RomFS of an NCCH file into AppLoader * @param file Handle to file to read from * @return ResultStatus result of function */ - const ResultStatus LoadRomFS(File::IOFile& file); + ResultStatus LoadRomFS(File::IOFile& file); /** * Loads .code section into memory for booting * @return ResultStatus result of function */ - const ResultStatus LoadExec() const; + ResultStatus LoadExec() const; std::string filename; bool is_loaded; -- cgit v1.2.3 From a7f1c544909ee1034356666e04bea3a4b4609a95 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 22 Jun 2014 15:40:21 -0400 Subject: Loader: Refactored loading functions to only read data from binary if called. NCCH: Updated LoadExec to use Memory::WriteBlock function to load binary code. --- src/core/loader/ncch.h | 57 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 13 deletions(-) (limited to 'src/core/loader/ncch.h') diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 126eb4c80..bf65425a4 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -156,35 +156,66 @@ public: */ ResultStatus Load(); -private: + /** + * Get the code (typically .code section) of the application + * @param error ResultStatus result of function + * @return Reference to code buffer + */ + const std::vector& ReadCode(ResultStatus& error); /** - * Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.) - * @param file Handle to file to read from - * @param name Name of section to read out of NCCH file - * @param buffer Buffer to read section into. - * @return ResultStatus result of function + * Get the icon (typically icon section) of the application + * @param error ResultStatus result of function + * @return Reference to icon buffer */ - ResultStatus LoadSectionExeFS(File::IOFile& file, const char* name, std::vector& buffer); + const std::vector& ReadIcon(ResultStatus& error); /** - * Reads RomFS of an NCCH file into AppLoader - * @param file Handle to file to read from - * @return ResultStatus result of function + * Get the banner (typically banner section) of the application + * @param error ResultStatus result of function + * @return Reference to banner buffer + */ + const std::vector& ReadBanner(ResultStatus& error); + + /** + * Get the logo (typically logo section) of the application + * @param error ResultStatus result of function + * @return Reference to logo buffer */ - ResultStatus LoadRomFS(File::IOFile& file); + const std::vector& ReadLogo(ResultStatus& error); + + /** + * Get the RomFs archive of the application + * @param error ResultStatus result of function + * @return Reference to RomFs archive buffer + */ + const std::vector& ReadRomFS(ResultStatus& error); + +private: + + /** + * Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.) + * @param name Name of section to read out of NCCH file + * @param buffer Vector to read data into + * @param error ResultStatus result of function + * @return Reference to buffer of data that was read + */ + const std::vector& LoadSectionExeFS(const char* name, std::vector& buffer, + ResultStatus& error); /** * Loads .code section into memory for booting * @return ResultStatus result of function */ - ResultStatus LoadExec() const; + ResultStatus LoadExec(); + File::IOFile file; std::string filename; + bool is_loaded; bool is_compressed; - u32 entry_point; + u32 entry_point; u32 ncch_offset; // Offset to NCCH header, can be 0 or after NCSD header u32 exefs_offset; -- cgit v1.2.3