diff options
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> | 2016-09-18 02:38:01 +0200 |
---|---|---|
committer | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> | 2016-09-18 02:38:01 +0200 |
commit | dc8479928c5aee4c6ad6fe4f59006fb604cee701 (patch) | |
tree | 569a7f13128450bbab973236615587ff00bced5f /src/core/loader | |
parent | Travis: Import Dolphin’s clang-format hook. (diff) | |
download | yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.gz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.bz2 yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.lz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.xz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.zst yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.zip |
Diffstat (limited to 'src/core/loader')
-rw-r--r-- | src/core/loader/3dsx.cpp | 85 | ||||
-rw-r--r-- | src/core/loader/3dsx.h | 9 | ||||
-rw-r--r-- | src/core/loader/elf.cpp | 231 | ||||
-rw-r--r-- | src/core/loader/elf.h | 3 | ||||
-rw-r--r-- | src/core/loader/loader.cpp | 15 | ||||
-rw-r--r-- | src/core/loader/loader.h | 11 | ||||
-rw-r--r-- | src/core/loader/ncch.cpp | 62 | ||||
-rw-r--r-- | src/core/loader/ncch.h | 39 | ||||
-rw-r--r-- | src/core/loader/smdh.h | 2 |
9 files changed, 249 insertions, 208 deletions
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index a16411e14..c2e87f592 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -37,20 +37,14 @@ namespace Loader { * The BSS section must be cleared manually by the application. */ -enum THREEDSX_Error { - ERROR_NONE = 0, - ERROR_READ = 1, - ERROR_FILE = 2, - ERROR_ALLOC = 3 -}; +enum THREEDSX_Error { ERROR_NONE = 0, ERROR_READ = 1, ERROR_FILE = 2, ERROR_ALLOC = 3 }; static const u32 RELOCBUFSIZE = 512; static const unsigned int NUM_SEGMENTS = 3; // File header #pragma pack(1) -struct THREEDSX_Header -{ +struct THREEDSX_Header { u32 magic; u16 header_size, reloc_hdr_size; u32 format_ver; @@ -66,11 +60,11 @@ struct THREEDSX_Header }; // Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts. -struct THREEDSX_RelocHdr -{ +struct THREEDSX_RelocHdr { // # of absolute relocations (that is, fix address to post-relocation memory layout) u32 cross_segment_absolute; - // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be patched) + // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be + // patched) u32 cross_segment_relative; // more? @@ -80,21 +74,18 @@ struct THREEDSX_RelocHdr }; // Relocation entry: from the current pointer, skip X words and patch Y words -struct THREEDSX_Reloc -{ +struct THREEDSX_Reloc { u16 skip, patch; }; #pragma pack() -struct THREEloadinfo -{ +struct THREEloadinfo { u8* seg_ptrs[3]; // code, rodata & data u32 seg_addrs[3]; u32 seg_sizes[3]; }; -static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets) -{ +static u32 TranslateAddr(u32 addr, const THREEloadinfo* loadinfo, u32* offsets) { if (addr < offsets[0]) return loadinfo->seg_addrs[0] + addr; if (addr < offsets[1]) @@ -105,8 +96,8 @@ static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets) using Kernel::SharedPtr; using Kernel::CodeSet; -static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, SharedPtr<CodeSet>* out_codeset) -{ +static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, + SharedPtr<CodeSet>* out_codeset) { if (!file.IsOpen()) return ERROR_FILE; @@ -118,13 +109,14 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared return ERROR_READ; THREEloadinfo loadinfo; - //loadinfo segments must be a multiple of 0x1000 - loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) &~0xFFF; - loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) &~0xFFF; - loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) &~0xFFF; - u32 offsets[2] = { loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] }; + // loadinfo segments must be a multiple of 0x1000 + loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) & ~0xFFF; + loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) & ~0xFFF; + loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) & ~0xFFF; + u32 offsets[2] = {loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1]}; u32 n_reloc_tables = hdr.reloc_hdr_size / sizeof(u32); - std::vector<u8> program_image(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + loadinfo.seg_sizes[2]); + std::vector<u8> program_image(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + + loadinfo.seg_sizes[2]); loadinfo.seg_addrs[0] = base_addr; loadinfo.seg_addrs[1] = loadinfo.seg_addrs[0] + loadinfo.seg_sizes[0]; @@ -149,7 +141,8 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared return ERROR_READ; if (file.ReadBytes(loadinfo.seg_ptrs[1], hdr.rodata_seg_size) != hdr.rodata_seg_size) return ERROR_READ; - if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) != hdr.data_seg_size - hdr.bss_size) + if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) != + hdr.data_seg_size - hdr.bss_size) return ERROR_READ; // BSS clear @@ -157,11 +150,12 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared // Relocate the segments for (unsigned int current_segment = 0; current_segment < NUM_SEGMENTS; ++current_segment) { - for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; current_segment_reloc_table++) { + for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; + current_segment_reloc_table++) { u32 n_relocs = relocs[current_segment * n_reloc_tables + current_segment_reloc_table]; if (current_segment_reloc_table >= 2) { // We are not using this table - ignore it because we don't know what it dose - file.Seek(n_relocs*sizeof(THREEDSX_Reloc), SEEK_CUR); + file.Seek(n_relocs * sizeof(THREEDSX_Reloc), SEEK_CUR); continue; } THREEDSX_Reloc reloc_table[RELOCBUFSIZE]; @@ -173,17 +167,20 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared u32 remaining = std::min(RELOCBUFSIZE, n_relocs); n_relocs -= remaining; - if (file.ReadBytes(reloc_table, remaining * sizeof(THREEDSX_Reloc)) != remaining * sizeof(THREEDSX_Reloc)) + if (file.ReadBytes(reloc_table, remaining * sizeof(THREEDSX_Reloc)) != + remaining * sizeof(THREEDSX_Reloc)) return ERROR_READ; - for (unsigned current_inprogress = 0; current_inprogress < remaining && pos < end_pos; current_inprogress++) { + for (unsigned current_inprogress = 0; + current_inprogress < remaining && pos < end_pos; current_inprogress++) { const auto& table = reloc_table[current_inprogress]; LOG_TRACE(Loader, "(t=%d,skip=%u,patch=%u)", current_segment_reloc_table, static_cast<u32>(table.skip), static_cast<u32>(table.patch)); pos += table.skip; s32 num_patches = table.patch; while (0 < num_patches && pos < end_pos) { - u32 in_addr = static_cast<u32>(reinterpret_cast<u8*>(pos) - program_image.data()); + u32 in_addr = + static_cast<u32>(reinterpret_cast<u8*>(pos) - program_image.data()); u32 addr = TranslateAddr(*pos, &loadinfo, offsets); LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)", base_addr + in_addr, addr, current_segment_reloc_table, *pos); @@ -195,7 +192,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared *pos = static_cast<u32>(addr - in_addr); break; default: - break; //this should never happen + break; // this should never happen } pos++; num_patches--; @@ -209,23 +206,24 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared SharedPtr<CodeSet> code_set = CodeSet::Create("", 0); code_set->code.offset = loadinfo.seg_ptrs[0] - program_image.data(); - code_set->code.addr = loadinfo.seg_addrs[0]; - code_set->code.size = loadinfo.seg_sizes[0]; + code_set->code.addr = loadinfo.seg_addrs[0]; + code_set->code.size = loadinfo.seg_sizes[0]; code_set->rodata.offset = loadinfo.seg_ptrs[1] - program_image.data(); - code_set->rodata.addr = loadinfo.seg_addrs[1]; - code_set->rodata.size = loadinfo.seg_sizes[1]; + code_set->rodata.addr = loadinfo.seg_addrs[1]; + code_set->rodata.size = loadinfo.seg_sizes[1]; code_set->data.offset = loadinfo.seg_ptrs[2] - program_image.data(); - code_set->data.addr = loadinfo.seg_addrs[2]; - code_set->data.size = loadinfo.seg_sizes[2]; + code_set->data.addr = loadinfo.seg_addrs[2]; + code_set->data.size = loadinfo.seg_sizes[2]; code_set->entrypoint = code_set->code.addr; code_set->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); LOG_DEBUG(Loader, "code size: 0x%X", loadinfo.seg_sizes[0]); LOG_DEBUG(Loader, "rodata size: 0x%X", loadinfo.seg_sizes[1]); - LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], hdr.bss_size); + LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], + hdr.bss_size); *out_codeset = code_set; return ERROR_NONE; @@ -260,17 +258,20 @@ ResultStatus AppLoader_THREEDSX::Load() { Kernel::g_current_process->address_mappings = default_address_mappings; // Attach the default resource limit (APPLICATION) to the process - Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); + Kernel::g_current_process->resource_limit = + Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); - Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), Service::FS::ArchiveIdCode::RomFS); + Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), + Service::FS::ArchiveIdCode::RomFS); is_loaded = true; return ResultStatus::Success; } -ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { +ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, + u64& offset, u64& size) { if (!file.IsOpen()) return ResultStatus::Error; diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h index 90b20c61c..09a788a1c 100644 --- a/src/core/loader/3dsx.h +++ b/src/core/loader/3dsx.h @@ -17,8 +17,10 @@ namespace Loader { /// Loads an 3DSX file class AppLoader_THREEDSX final : public AppLoader { public: - AppLoader_THREEDSX(FileUtil::IOFile&& file, const std::string& filename, const std::string& filepath) - : AppLoader(std::move(file)), filename(std::move(filename)), filepath(filepath) {} + AppLoader_THREEDSX(FileUtil::IOFile&& file, const std::string& filename, + const std::string& filepath) + : AppLoader(std::move(file)), filename(std::move(filename)), filepath(filepath) { + } /** * Returns the type of the file @@ -55,7 +57,8 @@ public: * @param size Size of the RomFS in bytes * @return ResultStatus result of function */ - ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override; + ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, + u64& size) override; private: std::string filename; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 69df94324..53c10a456 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -3,8 +3,8 @@ // Refer to the license.txt file included. #include <cstring> -#include <string> #include <memory> +#include <string> #include "common/common_types.h" #include "common/file_util.h" @@ -24,112 +24,111 @@ using Kernel::CodeSet; // File type enum ElfType { - ET_NONE = 0, - ET_REL = 1, - ET_EXEC = 2, - ET_DYN = 3, - ET_CORE = 4, + ET_NONE = 0, + ET_REL = 1, + ET_EXEC = 2, + ET_DYN = 3, + ET_CORE = 4, ET_LOPROC = 0xFF00, ET_HIPROC = 0xFFFF, }; // Machine/Architecture enum ElfMachine { - EM_NONE = 0, - EM_M32 = 1, + EM_NONE = 0, + EM_M32 = 1, EM_SPARC = 2, - EM_386 = 3, - EM_68K = 4, - EM_88K = 5, - EM_860 = 7, - EM_MIPS = 8 + EM_386 = 3, + EM_68K = 4, + EM_88K = 5, + EM_860 = 7, + EM_MIPS = 8 }; // File version -#define EV_NONE 0 +#define EV_NONE 0 #define EV_CURRENT 1 // Identification index -#define EI_MAG0 0 -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 #define EI_VERSION 6 -#define EI_PAD 7 +#define EI_PAD 7 #define EI_NIDENT 16 // Sections constants // Section types -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 #define SHT_LOPROC 0x70000000 #define SHT_HIPROC 0x7FFFFFFF #define SHT_LOUSER 0x80000000 #define SHT_HIUSER 0xFFFFFFFF // Section flags -enum ElfSectionFlags -{ - SHF_WRITE = 0x1, - SHF_ALLOC = 0x2, +enum ElfSectionFlags { + SHF_WRITE = 0x1, + SHF_ALLOC = 0x2, SHF_EXECINSTR = 0x4, - SHF_MASKPROC = 0xF0000000, + SHF_MASKPROC = 0xF0000000, }; // Segment types -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7FFFFFFF +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7FFFFFFF // Segment flags -#define PF_X 0x1 -#define PF_W 0x2 -#define PF_R 0x4 +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 #define PF_MASKPROC 0xF0000000 -typedef unsigned int Elf32_Addr; +typedef unsigned int Elf32_Addr; typedef unsigned short Elf32_Half; -typedef unsigned int Elf32_Off; -typedef signed int Elf32_Sword; -typedef unsigned int Elf32_Word; +typedef unsigned int Elf32_Off; +typedef signed int Elf32_Sword; +typedef unsigned int Elf32_Word; //////////////////////////////////////////////////////////////////////////////////////////////////// // ELF file header struct Elf32_Ehdr { unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; }; // Section header @@ -138,7 +137,7 @@ struct Elf32_Shdr { Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; - Elf32_Off sh_offset; + Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; @@ -149,7 +148,7 @@ struct Elf32_Shdr { // Segment header struct Elf32_Phdr { Elf32_Word p_type; - Elf32_Off p_offset; + Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; @@ -160,12 +159,12 @@ struct Elf32_Phdr { // Symbol table entry struct Elf32_Sym { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; unsigned char st_info; unsigned char st_other; - Elf32_Half st_shndx; + Elf32_Half st_shndx; }; // Relocation entries @@ -181,35 +180,51 @@ typedef int SectionID; class ElfReader { private: - char *base; - u32 *base32; + char* base; + u32* base32; - Elf32_Ehdr *header; - Elf32_Phdr *segments; - Elf32_Shdr *sections; + Elf32_Ehdr* header; + Elf32_Phdr* segments; + Elf32_Shdr* sections; - u32 *sectionAddrs; + u32* sectionAddrs; bool relocate; u32 entryPoint; public: - ElfReader(void *ptr); + ElfReader(void* ptr); - u32 Read32(int off) const { return base32[off >> 2]; } + u32 Read32(int off) const { + return base32[off >> 2]; + } // Quick accessors - ElfType GetType() const { return (ElfType)(header->e_type); } - ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); } - u32 GetEntryPoint() const { return entryPoint; } - u32 GetFlags() const { return (u32)(header->e_flags); } + ElfType GetType() const { + return (ElfType)(header->e_type); + } + ElfMachine GetMachine() const { + return (ElfMachine)(header->e_machine); + } + u32 GetEntryPoint() const { + return entryPoint; + } + u32 GetFlags() const { + return (u32)(header->e_flags); + } SharedPtr<CodeSet> LoadInto(u32 vaddr); bool LoadSymbols(); - int GetNumSegments() const { return (int)(header->e_phnum); } - int GetNumSections() const { return (int)(header->e_shnum); } - const u8 *GetPtr(int offset) const { return (u8*)base + offset; } - const char *GetSectionName(int section) const; - const u8 *GetSectionDataPtr(int section) const { + int GetNumSegments() const { + return (int)(header->e_phnum); + } + int GetNumSections() const { + return (int)(header->e_shnum); + } + const u8* GetPtr(int offset) const { + return (u8*)base + offset; + } + const char* GetSectionName(int section) const; + const u8* GetSectionDataPtr(int section) const { if (section < 0 || section >= header->e_shnum) return nullptr; if (sections[section].sh_type != SHT_NOBITS) @@ -220,19 +235,23 @@ public: bool IsCodeSection(int section) const { return sections[section].sh_type == SHT_PROGBITS; } - const u8 *GetSegmentPtr(int segment) { + const u8* GetSegmentPtr(int segment) { return GetPtr(segments[segment].p_offset); } - u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; } - unsigned int GetSectionSize(SectionID section) const { return sections[section].sh_size; } - SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found + u32 GetSectionAddr(SectionID section) const { + return sectionAddrs[section]; + } + unsigned int GetSectionSize(SectionID section) const { + return sections[section].sh_size; + } + SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found bool DidRelocate() const { return relocate; } }; -ElfReader::ElfReader(void *ptr) { +ElfReader::ElfReader(void* ptr) { base = (char*)ptr; base32 = (u32*)ptr; header = (Elf32_Ehdr*)ptr; @@ -245,7 +264,7 @@ ElfReader::ElfReader(void *ptr) { LoadSymbols(); } -const char *ElfReader::GetSectionName(int section) const { +const char* ElfReader::GetSectionName(int section) const { if (sections[section].sh_type == SHT_NULL) return nullptr; @@ -303,12 +322,15 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { } else if (permission_flags == (PF_R | PF_W)) { codeset_segment = &codeset->data; } else { - LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i, p->p_flags); + LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i, + p->p_flags); continue; } if (codeset_segment->size != 0) { - LOG_ERROR(Loader, "ELF has more than one segment of the same type. Skipping extra segment (id %i)", i); + LOG_ERROR(Loader, "ELF has more than one segment of the same type. Skipping extra " + "segment (id %i)", + i); continue; } @@ -332,9 +354,9 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { return codeset; } -SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const { +SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const { for (int i = firstSection; i < header->e_shnum; i++) { - const char *secname = GetSectionName(i); + const char* secname = GetSectionName(i); if (secname != nullptr && strcmp(name, secname) == 0) return i; @@ -347,9 +369,9 @@ bool ElfReader::LoadSymbols() { SectionID sec = GetSectionByName(".symtab"); if (sec != -1) { int stringSection = sections[sec].sh_link; - const char *stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection)); + const char* stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection)); - //We have a symbol table! + // We have a symbol table! const Elf32_Sym* symtab = reinterpret_cast<const Elf32_Sym*>(GetSectionDataPtr(sec)); unsigned int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); for (unsigned sym = 0; sym < numSymbols; sym++) { @@ -359,7 +381,7 @@ bool ElfReader::LoadSymbols() { int type = symtab[sym].st_info & 0xF; - const char *name = stringBase + symtab[sym].st_name; + const char* name = stringBase + symtab[sym].st_name; Symbols::Add(symtab[sym].st_value, name, size, type); @@ -411,7 +433,8 @@ ResultStatus AppLoader_ELF::Load() { Kernel::g_current_process->address_mappings = default_address_mappings; // Attach the default resource limit (APPLICATION) to the process - Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); + Kernel::g_current_process->resource_limit = + Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index cb3724f9d..0b1456c64 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -18,7 +18,8 @@ namespace Loader { class AppLoader_ELF final : public AppLoader { public: AppLoader_ELF(FileUtil::IOFile&& file, std::string filename) - : AppLoader(std::move(file)), filename(std::move(filename)) { } + : AppLoader(std::move(file)), filename(std::move(filename)) { + } /** * Returns the type of the file diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 9719d30d5..b392bf544 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -18,17 +18,17 @@ namespace Loader { const std::initializer_list<Kernel::AddressMapping> default_address_mappings = { - { 0x1FF50000, 0x8000, true }, // part of DSP RAM - { 0x1FF70000, 0x8000, true }, // part of DSP RAM - { 0x1F000000, 0x600000, false }, // entire VRAM + {0x1FF50000, 0x8000, true}, // part of DSP RAM + {0x1FF70000, 0x8000, true}, // part of DSP RAM + {0x1F000000, 0x600000, false}, // entire VRAM }; FileType IdentifyFile(FileUtil::IOFile& file) { FileType type; -#define CHECK_TYPE(loader) \ - type = AppLoader_##loader::IdentifyType(file); \ - if (FileType::Error != type) \ +#define CHECK_TYPE(loader) \ + type = AppLoader_##loader::IdentifyType(file); \ + if (FileType::Error != type) \ return type; CHECK_TYPE(THREEDSX) @@ -100,7 +100,8 @@ const char* GetFileTypeString(FileType type) { * @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type */ static std::unique_ptr<AppLoader> GetFileLoader(FileUtil::IOFile&& file, FileType type, - const std::string& filename, const std::string& filepath) { + const std::string& filename, + const std::string& filepath) { switch (type) { // 3DSX file format. diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 77d87afe1..5f48d2ffe 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -30,7 +30,7 @@ enum class FileType { CXI, CIA, ELF, - THREEDSX, //3DSX + THREEDSX, // 3DSX }; /** @@ -81,8 +81,10 @@ constexpr u32 MakeMagic(char a, char b, char c, char d) { /// Interface for loading an application class AppLoader : NonCopyable { public: - AppLoader(FileUtil::IOFile&& file) : file(std::move(file)) { } - virtual ~AppLoader() { } + AppLoader(FileUtil::IOFile&& file) : file(std::move(file)) { + } + virtual ~AppLoader() { + } /** * Returns the type of this file @@ -140,7 +142,8 @@ public: * @param size The size of the romfs * @return ResultStatus result of function */ - virtual ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { + virtual ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, + u64& size) { return ResultStatus::ErrorNotImplemented; } diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index fca091ff9..5b996d671 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -22,8 +22,8 @@ namespace Loader { -static const int kMaxSections = 8; ///< Maximum number of sections (files) in an ExeFs -static const int kBlockSize = 0x200; ///< Size of ExeFS blocks (in bytes) +static const int kMaxSections = 8; ///< Maximum number of sections (files) in an ExeFs +static const int kBlockSize = 0x200; ///< Size of ExeFS blocks (in bytes) /** * Get the decompressed size of an LZSS compressed ExeFS file @@ -44,7 +44,8 @@ static u32 LZSS_GetDecompressedSize(const u8* buffer, u32 size) { * @param decompressed_size Size of decompressed buffer * @return True on success, otherwise false */ -static bool LZSS_Decompress(const u8* compressed, u32 compressed_size, u8* decompressed, u32 decompressed_size) { +static bool LZSS_Decompress(const u8* compressed, u32 compressed_size, u8* decompressed, + u32 decompressed_size) { const u8* footer = compressed + compressed_size - 8; u32 buffer_top_and_bottom = *reinterpret_cast<const u32*>(footer); u32 out = decompressed_size; @@ -55,7 +56,7 @@ static bool LZSS_Decompress(const u8* compressed, u32 compressed_size, u8* decom memcpy(decompressed, compressed, compressed_size); while (index > stop_index) { - u8 control = compressed[--index]; + u8 control = compressed[--index]; for (unsigned i = 0; i < 8; i++) { if (index <= stop_index) @@ -128,7 +129,7 @@ ResultStatus AppLoader_NCCH::LoadExec() { std::vector<u8> code; if (ResultStatus::Success == ReadCode(code)) { std::string process_name = Common::StringFromFixedZeroTerminatedBuffer( - (const char*)exheader_header.codeset_info.name, 8); + (const char*)exheader_header.codeset_info.name, 8); SharedPtr<CodeSet> codeset = CodeSet::Create(process_name, ncch_header.program_id); @@ -147,7 +148,8 @@ ResultStatus AppLoader_NCCH::LoadExec() { codeset->data.offset = codeset->rodata.offset + codeset->rodata.size; codeset->data.addr = exheader_header.codeset_info.data.address; - codeset->data.size = exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE + bss_page_size; + codeset->data.size = + exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE + bss_page_size; codeset->entrypoint = codeset->code.addr; codeset->memory = std::make_shared<std::vector<u8>>(std::move(code)); @@ -155,15 +157,18 @@ ResultStatus AppLoader_NCCH::LoadExec() { Kernel::g_current_process = Kernel::Process::Create(std::move(codeset)); // Attach a resource limit to the process based on the resource limit category - Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory( - static_cast<Kernel::ResourceLimitCategory>(exheader_header.arm11_system_local_caps.resource_limit_category)); + Kernel::g_current_process->resource_limit = + Kernel::ResourceLimit::GetForCategory(static_cast<Kernel::ResourceLimitCategory>( + exheader_header.arm11_system_local_caps.resource_limit_category)); // Set the default CPU core for this process - Kernel::g_current_process->ideal_processor = exheader_header.arm11_system_local_caps.ideal_processor; + Kernel::g_current_process->ideal_processor = + exheader_header.arm11_system_local_caps.ideal_processor; // Copy data while converting endianess std::array<u32, ARRAY_SIZE(exheader_header.arm11_kernel_caps.descriptors)> kernel_caps; - std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), begin(kernel_caps)); + std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), + begin(kernel_caps)); Kernel::g_current_process->ParseKernelCaps(kernel_caps.data(), kernel_caps.size()); s32 priority = exheader_header.arm11_system_local_caps.priority; @@ -192,7 +197,8 @@ ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector<u8>& LOG_DEBUG(Loader, "%d - offset: 0x%08X, size: 0x%08X, name: %s", section_number, section.offset, section.size, section.name); - s64 section_offset = (section.offset + exefs_offset + sizeof(ExeFs_Header) + ncch_offset); + s64 section_offset = + (section.offset + exefs_offset + sizeof(ExeFs_Header) + ncch_offset); file.Seek(section_offset, SEEK_SET); if (strcmp(section.name, ".code") == 0 && is_compressed) { @@ -254,25 +260,25 @@ ResultStatus AppLoader_NCCH::LoadExeFS() { if (file.ReadBytes(&exheader_header, sizeof(ExHeader_Header)) != sizeof(ExHeader_Header)) return ResultStatus::Error; - is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; - entry_point = exheader_header.codeset_info.text.address; - code_size = exheader_header.codeset_info.text.code_size; - stack_size = exheader_header.codeset_info.stack_size; - bss_size = exheader_header.codeset_info.bss_size; - core_version = exheader_header.arm11_system_local_caps.core_version; - priority = exheader_header.arm11_system_local_caps.priority; + is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; + entry_point = exheader_header.codeset_info.text.address; + code_size = exheader_header.codeset_info.text.code_size; + stack_size = exheader_header.codeset_info.stack_size; + bss_size = exheader_header.codeset_info.bss_size; + core_version = exheader_header.arm11_system_local_caps.core_version; + priority = exheader_header.arm11_system_local_caps.priority; resource_limit_category = exheader_header.arm11_system_local_caps.resource_limit_category; - LOG_INFO(Loader, "Name: %s" , exheader_header.codeset_info.name); - LOG_INFO(Loader, "Program ID: %016llX" , ncch_header.program_id); - LOG_DEBUG(Loader, "Code compressed: %s" , is_compressed ? "yes" : "no"); + LOG_INFO(Loader, "Name: %s", exheader_header.codeset_info.name); + LOG_INFO(Loader, "Program ID: %016llX", ncch_header.program_id); + LOG_DEBUG(Loader, "Code compressed: %s", is_compressed ? "yes" : "no"); LOG_DEBUG(Loader, "Entry point: 0x%08X", entry_point); LOG_DEBUG(Loader, "Code size: 0x%08X", code_size); LOG_DEBUG(Loader, "Stack size: 0x%08X", stack_size); LOG_DEBUG(Loader, "Bss size: 0x%08X", bss_size); - LOG_DEBUG(Loader, "Core version: %d" , core_version); - LOG_DEBUG(Loader, "Thread priority: 0x%X" , priority); - LOG_DEBUG(Loader, "Resource limit category: %d" , resource_limit_category); + LOG_DEBUG(Loader, "Core version: %d", core_version); + LOG_DEBUG(Loader, "Thread priority: 0x%X", priority); + LOG_DEBUG(Loader, "Resource limit category: %d", resource_limit_category); if (exheader_header.arm11_system_local_caps.program_id != ncch_header.program_id) { LOG_ERROR(Loader, "ExHeader Program ID mismatch: the ROM is probably encrypted."); @@ -309,7 +315,8 @@ ResultStatus AppLoader_NCCH::Load() { if (ResultStatus::Success != result) return result; - Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), Service::FS::ArchiveIdCode::RomFS); + Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), + Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } @@ -329,7 +336,8 @@ ResultStatus AppLoader_NCCH::ReadLogo(std::vector<u8>& buffer) { return LoadSectionExeFS("logo", buffer); } -ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { +ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, + u64& size) { if (!file.IsOpen()) return ResultStatus::Error; @@ -341,7 +349,7 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_ LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset); LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size); - if (file.GetSize () < romfs_offset + romfs_size) + if (file.GetSize() < romfs_offset + romfs_size) return ResultStatus::Error; // We reopen the file, to allow its position to be independent from file's diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 75609ee57..0cd70f70c 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -164,7 +164,8 @@ namespace Loader { class AppLoader_NCCH final : public AppLoader { public: AppLoader_NCCH(FileUtil::IOFile&& file, const std::string& filepath) - : AppLoader(std::move(file)), filepath(filepath) { } + : AppLoader(std::move(file)), filepath(filepath) { + } /** * Returns the type of the file @@ -222,10 +223,10 @@ public: * @param size Size of the RomFS in bytes * @return ResultStatus result of function */ - ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override; + ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, + u64& size) override; 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 @@ -246,24 +247,24 @@ private: */ ResultStatus LoadExeFS(); - bool is_exefs_loaded = false; - bool is_compressed = false; - - u32 entry_point = 0; - u32 code_size = 0; - u32 stack_size = 0; - u32 bss_size = 0; - u32 core_version = 0; - u8 priority = 0; - u8 resource_limit_category = 0; - u32 ncch_offset = 0; // Offset to NCCH header, can be 0 or after NCSD header - u32 exefs_offset = 0; - - NCCH_Header ncch_header; - ExeFs_Header exefs_header; + bool is_exefs_loaded = false; + bool is_compressed = false; + + u32 entry_point = 0; + u32 code_size = 0; + u32 stack_size = 0; + u32 bss_size = 0; + u32 core_version = 0; + u8 priority = 0; + u8 resource_limit_category = 0; + u32 ncch_offset = 0; // Offset to NCCH header, can be 0 or after NCSD header + u32 exefs_offset = 0; + + NCCH_Header ncch_header; + ExeFs_Header exefs_header; ExHeader_Header exheader_header; - std::string filepath; + std::string filepath; }; } // namespace Loader diff --git a/src/core/loader/smdh.h b/src/core/loader/smdh.h index 2011abda2..ab665ea82 100644 --- a/src/core/loader/smdh.h +++ b/src/core/loader/smdh.h @@ -56,7 +56,7 @@ struct SMDH { Italian = 4, Spanish = 5, SimplifiedChinese = 6, - Korean= 7, + Korean = 7, Dutch = 8, Portuguese = 9, Russian = 10, |