From 1aa969741dabecd3516ca79b2e7d3106cf9d3d9a Mon Sep 17 00:00:00 2001 From: ichfly Date: Sun, 7 Dec 2014 21:47:06 +0100 Subject: Loader: Add 3DSX support --- src/core/loader/3dsx.cpp | 236 +++++++++++++++++++++++++++++++++++++++++++++ src/core/loader/3dsx.h | 32 ++++++ src/core/loader/loader.cpp | 7 ++ src/core/loader/loader.h | 1 + 4 files changed, 276 insertions(+) create mode 100644 src/core/loader/3dsx.cpp create mode 100644 src/core/loader/3dsx.h (limited to 'src/core/loader') diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp new file mode 100644 index 000000000..7ef146359 --- /dev/null +++ b/src/core/loader/3dsx.cpp @@ -0,0 +1,236 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include +#include + +#include "core/file_sys/archive_romfs.h" +#include "core/loader/elf.h" +#include "core/loader/ncch.h" +#include "core/hle/kernel/archive.h" +#include "core/mem_map.h" + +#include "3dsx.h" + + +namespace Loader { + + +/** + * File layout: + * - File header + * - Code, rodata and data relocation table headers + * - Code segment + * - Rodata segment + * - Loadable (non-BSS) part of the data segment + * - Code relocation table + * - Rodata relocation table + * - Data relocation table + * + * Memory layout before relocations are applied: + * [0..codeSegSize) -> code segment + * [codeSegSize..rodataSegSize) -> rodata segment + * [rodataSegSize..dataSegSize) -> data segment + * + * Memory layout after relocations are applied: well, however the loader sets it up :) + * The entrypoint is always the start of the code segment. + * 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 +}; +static const u32 RELOCBUFSIZE = 512; + +// File header +static const u32 THREEDSX_MAGIC = 0x58534433; // '3DSX' +#pragma pack(1) +struct THREEDSX_Header +{ + u32 magic; + u16 header_size, reloc_hdr_size; + u32 format_ver; + u32 flags; + + // Sizes of the code, rodata and data segments + + // size of the BSS section (uninitialized latter half of the data segment) + u32 code_seg_size, rodata_seg_size, data_seg_size, bss_size; +}; + +// Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts. +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) + u32 cross_segment_relative; + // more? + + // Relocations are written in this order: + // - Absolute relocations + // - Relative relocations +}; + +// Relocation entry: from the current pointer, skip X words and patch Y words +struct THREEDSX_Reloc +{ + u16 skip, patch; +}; +#pragma pack() + +struct THREEloadinfo +{ + u8* seg_ptrs[3]; // code, rodata & data + u32 seg_addrs[3]; + u32 seg_sizes[3]; +}; + +class THREEDSXReader { +public: + static int Load3DSXFile(const std::string& filename, u32 base_addr); +}; + +static u32 TranslateAddr(u32 addr, THREEloadinfo *loadinfo, u32* offsets) +{ + if (addr < offsets[0]) + return loadinfo->seg_addrs[0] + addr; + if (addr < offsets[1]) + return loadinfo->seg_addrs[1] + addr - offsets[0]; + return loadinfo->seg_addrs[2] + addr - offsets[1]; +} + +int THREEDSXReader::Load3DSXFile(const std::string& filename, u32 base_addr) +{ + FileUtil::IOFile file(filename, "rb"); + if (!file.IsOpen()) { + return ERROR_FILE; + } + THREEDSX_Header hdr; + if (file.ReadBytes(&hdr, sizeof(hdr)) != sizeof(hdr)) + 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] }; + u32 data_load_size = (hdr.data_seg_size - hdr.bss_size + 0xFFF) &~0xFFF; + u32 bss_load_size = loadinfo.seg_sizes[2] - data_load_size; + u32 n_reloc_tables = hdr.reloc_hdr_size / 4; + std::vector all_mem(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + loadinfo.seg_sizes[2] + 3 * n_reloc_tables); + + loadinfo.seg_addrs[0] = base_addr; + loadinfo.seg_addrs[1] = loadinfo.seg_addrs[0] + loadinfo.seg_sizes[0]; + loadinfo.seg_addrs[2] = loadinfo.seg_addrs[1] + loadinfo.seg_sizes[1]; + loadinfo.seg_ptrs[0] = &all_mem[0]; + loadinfo.seg_ptrs[1] = loadinfo.seg_ptrs[0] + loadinfo.seg_sizes[0]; + loadinfo.seg_ptrs[2] = loadinfo.seg_ptrs[1] + loadinfo.seg_sizes[1]; + + // Skip header for future compatibility + file.Seek(hdr.header_size, SEEK_SET); + + // Read the relocation headers + u32* relocs = (u32*)(loadinfo.seg_ptrs[2] + hdr.data_seg_size); + + for (u32 current_segment = 0; current_segment < 3; current_segment++) { + if (file.ReadBytes(&relocs[current_segment*n_reloc_tables], n_reloc_tables * 4) != n_reloc_tables * 4) + return ERROR_READ; + } + + // Read the segments + if (file.ReadBytes(loadinfo.seg_ptrs[0], hdr.code_seg_size) != hdr.code_seg_size) + 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) + return ERROR_READ; + + // BSS clear + memset((char*)loadinfo.seg_ptrs[2] + hdr.data_seg_size - hdr.bss_size, 0, hdr.bss_size); + + // Relocate the segments + for (u32 current_segment = 0; current_segment < 3; current_segment++) { + for (u32 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); + continue; + } + static THREEDSX_Reloc reloc_table[RELOCBUFSIZE]; + + u32* pos = (u32*)loadinfo.seg_ptrs[current_segment]; + u32* end_pos = pos + (loadinfo.seg_sizes[current_segment] / 4); + + while (n_relocs) { + u32 remaining = std::min(RELOCBUFSIZE, n_relocs); + n_relocs -= remaining; + + if (file.ReadBytes(reloc_table, remaining*sizeof(THREEDSX_Reloc)) != remaining*sizeof(THREEDSX_Reloc)) + return ERROR_READ; + + for (u32 current_inprogress = 0; current_inprogress < remaining && pos < end_pos; current_inprogress++) { + DEBUG_LOG(LOADER, "(t=%d,skip=%u,patch=%u)\n", + current_segment_reloc_table, (u32)reloc_table[current_inprogress].skip, (u32)reloc_table[current_inprogress].patch); + pos += reloc_table[current_inprogress].skip; + s32 num_patches = reloc_table[current_inprogress].patch; + while (0 < num_patches && pos < end_pos) { + u32 in_addr = (char*)pos - (char*)&all_mem[0]; + u32 addr = TranslateAddr(*pos, &loadinfo, offsets); + DEBUG_LOG(LOADER, "Patching %08X <-- rel(%08X,%d) (%08X)\n", + base_addr + in_addr, addr, current_segment_reloc_table, *pos); + switch (current_segment_reloc_table) { + case 0: *pos = (addr); break; + case 1: *pos = (addr - in_addr); break; + default: break; //this should never happen + } + pos++; + num_patches--; + } + } + } + } + } + + // Write the data + memcpy(Memory::GetPointer(base_addr), &all_mem[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + loadinfo.seg_sizes[2]); + + DEBUG_LOG(LOADER, "CODE: %u pages\n", loadinfo.seg_sizes[0] / 0x1000); + DEBUG_LOG(LOADER, "RODATA: %u pages\n", loadinfo.seg_sizes[1] / 0x1000); + DEBUG_LOG(LOADER, "DATA: %u pages\n", data_load_size / 0x1000); + DEBUG_LOG(LOADER, "BSS: %u pages\n", bss_load_size / 0x1000); + + return ERROR_NONE; +} + + /// AppLoader_DSX constructor + AppLoader_THREEDSX::AppLoader_THREEDSX(const std::string& filename) : filename(filename) { + } + + /// AppLoader_DSX destructor + AppLoader_THREEDSX::~AppLoader_THREEDSX() { + } + + /** + * Loads a 3DSX file + * @return Success on success, otherwise Error + */ + ResultStatus AppLoader_THREEDSX::Load() { + INFO_LOG(LOADER, "Loading 3DSX file %s...", filename.c_str()); + FileUtil::IOFile file(filename, "rb"); + if (file.IsOpen()) { + + THREEDSXReader reader; + reader.Load3DSXFile(filename, 0x00100000); + Kernel::LoadExec(0x00100000); + } else { + return ResultStatus::Error; + } + return ResultStatus::Success; + } + +} // namespace Loader diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h new file mode 100644 index 000000000..848d3ef8a --- /dev/null +++ b/src/core/loader/3dsx.h @@ -0,0 +1,32 @@ +// Copyright 2014 Dolphin Emulator Project / Citra Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "common/common_types.h" +#include "core/loader/loader.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Loader namespace + +namespace Loader { + +/// Loads an 3DSX file +class AppLoader_THREEDSX final : public AppLoader { +public: + AppLoader_THREEDSX(const std::string& filename); + ~AppLoader_THREEDSX() override; + + /** + * Load the bootable file + * @return ResultStatus result of function + */ + ResultStatus Load() override; + +private: + std::string filename; + bool is_loaded; +}; + +} // namespace Loader diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index a268e021a..174397b05 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -5,6 +5,7 @@ #include #include "core/file_sys/archive_romfs.h" +#include "core/loader/3dsx.h" #include "core/loader/elf.h" #include "core/loader/ncch.h" #include "core/hle/kernel/archive.h" @@ -42,6 +43,8 @@ FileType IdentifyFile(const std::string &filename) { return FileType::CCI; } else if (extension == ".bin") { return FileType::BIN; + } else if (extension == ".3dsx") { + return FileType::THREEDSX; } return FileType::Unknown; } @@ -56,6 +59,10 @@ ResultStatus LoadFile(const std::string& filename) { switch (IdentifyFile(filename)) { + //3DSX file format... + case FileType::THREEDSX: + return AppLoader_THREEDSX(filename).Load(); + // Standard ELF file format... case FileType::ELF: return AppLoader_ELF(filename).Load(); diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 68f843005..0f836d285 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -22,6 +22,7 @@ enum class FileType { CIA, ELF, BIN, + THREEDSX, //3DSX }; /// Return type for functions in Loader namespace -- cgit v1.2.3 From 0600e2d8b5b30bd68c8b19cb1f2051e096e7caa9 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Fri, 5 Dec 2014 23:53:49 -0200 Subject: Convert old logging calls to new logging macros --- src/core/loader/3dsx.cpp | 14 +++++++------- src/core/loader/elf.cpp | 16 ++++++++-------- src/core/loader/loader.cpp | 6 +++--- src/core/loader/ncch.cpp | 34 +++++++++++++++++----------------- 4 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 7ef146359..f48d13530 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -174,14 +174,14 @@ int THREEDSXReader::Load3DSXFile(const std::string& filename, u32 base_addr) return ERROR_READ; for (u32 current_inprogress = 0; current_inprogress < remaining && pos < end_pos; current_inprogress++) { - DEBUG_LOG(LOADER, "(t=%d,skip=%u,patch=%u)\n", + LOG_TRACE(Loader, "(t=%d,skip=%u,patch=%u)\n", current_segment_reloc_table, (u32)reloc_table[current_inprogress].skip, (u32)reloc_table[current_inprogress].patch); pos += reloc_table[current_inprogress].skip; s32 num_patches = reloc_table[current_inprogress].patch; while (0 < num_patches && pos < end_pos) { u32 in_addr = (char*)pos - (char*)&all_mem[0]; u32 addr = TranslateAddr(*pos, &loadinfo, offsets); - DEBUG_LOG(LOADER, "Patching %08X <-- rel(%08X,%d) (%08X)\n", + LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)\n", base_addr + in_addr, addr, current_segment_reloc_table, *pos); switch (current_segment_reloc_table) { case 0: *pos = (addr); break; @@ -199,10 +199,10 @@ int THREEDSXReader::Load3DSXFile(const std::string& filename, u32 base_addr) // Write the data memcpy(Memory::GetPointer(base_addr), &all_mem[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + loadinfo.seg_sizes[2]); - DEBUG_LOG(LOADER, "CODE: %u pages\n", loadinfo.seg_sizes[0] / 0x1000); - DEBUG_LOG(LOADER, "RODATA: %u pages\n", loadinfo.seg_sizes[1] / 0x1000); - DEBUG_LOG(LOADER, "DATA: %u pages\n", data_load_size / 0x1000); - DEBUG_LOG(LOADER, "BSS: %u pages\n", bss_load_size / 0x1000); + LOG_DEBUG(Loader, "CODE: %u pages\n", loadinfo.seg_sizes[0] / 0x1000); + LOG_DEBUG(Loader, "RODATA: %u pages\n", loadinfo.seg_sizes[1] / 0x1000); + LOG_DEBUG(Loader, "DATA: %u pages\n", data_load_size / 0x1000); + LOG_DEBUG(Loader, "BSS: %u pages\n", bss_load_size / 0x1000); return ERROR_NONE; } @@ -220,7 +220,7 @@ int THREEDSXReader::Load3DSXFile(const std::string& filename, u32 base_addr) * @return Success on success, otherwise Error */ ResultStatus AppLoader_THREEDSX::Load() { - INFO_LOG(LOADER, "Loading 3DSX file %s...", filename.c_str()); + LOG_INFO(Loader, "Loading 3DSX file %s...", filename.c_str()); FileUtil::IOFile file(filename, "rb"); if (file.IsOpen()) { diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 63d2496ed..c95882f4a 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -254,18 +254,18 @@ const char *ElfReader::GetSectionName(int section) const { } bool ElfReader::LoadInto(u32 vaddr) { - DEBUG_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx); + LOG_DEBUG(Loader, "String section: %i", header->e_shstrndx); // Should we relocate? relocate = (header->e_type != ET_EXEC); if (relocate) { - DEBUG_LOG(MASTER_LOG, "Relocatable module"); + LOG_DEBUG(Loader, "Relocatable module"); entryPoint += vaddr; } else { - DEBUG_LOG(MASTER_LOG, "Prerelocated executable"); + LOG_DEBUG(Loader, "Prerelocated executable"); } - INFO_LOG(MASTER_LOG, "%i segments:", header->e_phnum); + LOG_DEBUG(Loader, "%i segments:", header->e_phnum); // First pass : Get the bits into RAM u32 segment_addr[32]; @@ -273,17 +273,17 @@ bool ElfReader::LoadInto(u32 vaddr) { for (int i = 0; i < header->e_phnum; i++) { Elf32_Phdr *p = segments + i; - INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, + LOG_DEBUG(Loader, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz); if (p->p_type == PT_LOAD) { segment_addr[i] = base_addr + p->p_vaddr; memcpy(Memory::GetPointer(segment_addr[i]), GetSegmentPtr(i), p->p_filesz); - INFO_LOG(MASTER_LOG, "Loadable Segment Copied to %08x, size %08x", segment_addr[i], + LOG_DEBUG(Loader, "Loadable Segment Copied to %08x, size %08x", segment_addr[i], p->p_memsz); } } - INFO_LOG(MASTER_LOG, "Done loading."); + LOG_DEBUG(Loader, "Done loading."); return true; } @@ -346,7 +346,7 @@ AppLoader_ELF::~AppLoader_ELF() { * @return True on success, otherwise false */ ResultStatus AppLoader_ELF::Load() { - INFO_LOG(LOADER, "Loading ELF file %s...", filename.c_str()); + LOG_INFO(Loader, "Loading ELF file %s...", filename.c_str()); if (is_loaded) return ResultStatus::ErrorAlreadyLoaded; diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 174397b05..3883e1307 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -23,7 +23,7 @@ namespace Loader { */ FileType IdentifyFile(const std::string &filename) { if (filename.size() == 0) { - ERROR_LOG(LOADER, "invalid filename %s", filename.c_str()); + LOG_ERROR(Loader, "invalid filename %s", filename.c_str()); return FileType::Error; } @@ -55,7 +55,7 @@ FileType IdentifyFile(const std::string &filename) { * @return ResultStatus result of function */ ResultStatus LoadFile(const std::string& filename) { - INFO_LOG(LOADER, "Loading file %s...", filename.c_str()); + LOG_INFO(Loader, "Loading file %s...", filename.c_str()); switch (IdentifyFile(filename)) { @@ -83,7 +83,7 @@ ResultStatus LoadFile(const std::string& filename) { // Raw BIN file format... case FileType::BIN: { - INFO_LOG(LOADER, "Loading BIN file %s...", filename.c_str()); + LOG_INFO(Loader, "Loading BIN file %s...", filename.c_str()); FileUtil::IOFile file(filename, "rb"); diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 343bb7523..ba9ba00c0 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -140,13 +140,13 @@ ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector& // Iterate through the ExeFs archive until we find the .code file... FileUtil::IOFile file(filename, "rb"); if (file.IsOpen()) { + LOG_DEBUG(Loader, "%d sections:", kMaxSections); for (int i = 0; i < kMaxSections; i++) { // Load the specified section... if (strcmp((const char*)exefs_header.section[i].name, name) == 0) { - INFO_LOG(LOADER, "ExeFS section %d:", i); - INFO_LOG(LOADER, " name: %s", exefs_header.section[i].name); - INFO_LOG(LOADER, " offset: 0x%08X", exefs_header.section[i].offset); - INFO_LOG(LOADER, " size: 0x%08X", exefs_header.section[i].size); + LOG_DEBUG(Loader, "%d - offset: 0x%08X, size: 0x%08X, name: %s", i, + exefs_header.section[i].offset, exefs_header.section[i].size, + exefs_header.section[i].name); s64 section_offset = (exefs_header.section[i].offset + exefs_offset + sizeof(ExeFs_Header)+ncch_offset); @@ -181,7 +181,7 @@ ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector& } } } else { - ERROR_LOG(LOADER, "Unable to read file %s!", filename.c_str()); + LOG_ERROR(Loader, "Unable to read file %s!", filename.c_str()); return ResultStatus::Error; } return ResultStatus::ErrorNotUsed; @@ -194,7 +194,7 @@ ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector& * @return True on success, otherwise false */ ResultStatus AppLoader_NCCH::Load() { - INFO_LOG(LOADER, "Loading NCCH file %s...", filename.c_str()); + LOG_INFO(Loader, "Loading NCCH file %s...", filename.c_str()); if (is_loaded) return ResultStatus::ErrorAlreadyLoaded; @@ -205,7 +205,7 @@ ResultStatus AppLoader_NCCH::Load() { // Skip NCSD header and load first NCCH (NCSD is just a container of NCCH files)... if (0 == memcmp(&ncch_header.magic, "NCSD", 4)) { - WARN_LOG(LOADER, "Only loading the first (bootable) NCCH within the NCSD file!"); + LOG_WARNING(Loader, "Only loading the first (bootable) NCCH within the NCSD file!"); ncch_offset = 0x4000; file.Seek(ncch_offset, 0); file.ReadBytes(&ncch_header, sizeof(NCCH_Header)); @@ -222,17 +222,17 @@ ResultStatus AppLoader_NCCH::Load() { is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; entry_point = exheader_header.codeset_info.text.address; - INFO_LOG(LOADER, "Name: %s", exheader_header.codeset_info.name); - INFO_LOG(LOADER, "Code compressed: %s", is_compressed ? "yes" : "no"); - INFO_LOG(LOADER, "Entry point: 0x%08X", entry_point); + LOG_INFO(Loader, "Name: %s", exheader_header.codeset_info.name); + LOG_DEBUG(Loader, "Code compressed: %s", is_compressed ? "yes" : "no"); + LOG_DEBUG(Loader, "Entry point: 0x%08X", entry_point); // Read ExeFS... exefs_offset = ncch_header.exefs_offset * kBlockSize; u32 exefs_size = ncch_header.exefs_size * kBlockSize; - INFO_LOG(LOADER, "ExeFS offset: 0x%08X", exefs_offset); - INFO_LOG(LOADER, "ExeFS size: 0x%08X", exefs_size); + LOG_DEBUG(Loader, "ExeFS offset: 0x%08X", exefs_offset); + LOG_DEBUG(Loader, "ExeFS size: 0x%08X", exefs_size); file.Seek(exefs_offset + ncch_offset, 0); file.ReadBytes(&exefs_header, sizeof(ExeFs_Header)); @@ -243,7 +243,7 @@ ResultStatus AppLoader_NCCH::Load() { return ResultStatus::Success; } else { - ERROR_LOG(LOADER, "Unable to read file %s!", filename.c_str()); + LOG_ERROR(Loader, "Unable to read file %s!", filename.c_str()); } return ResultStatus::Error; } @@ -297,8 +297,8 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::vector& buffer) const { u32 romfs_offset = ncch_offset + (ncch_header.romfs_offset * kBlockSize) + 0x1000; u32 romfs_size = (ncch_header.romfs_size * kBlockSize) - 0x1000; - INFO_LOG(LOADER, "RomFS offset: 0x%08X", romfs_offset); - INFO_LOG(LOADER, "RomFS size: 0x%08X", romfs_size); + LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset); + LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size); buffer.resize(romfs_size); @@ -307,10 +307,10 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::vector& buffer) const { return ResultStatus::Success; } - NOTICE_LOG(LOADER, "RomFS unused"); + LOG_DEBUG(Loader, "NCCH has no RomFS"); return ResultStatus::ErrorNotUsed; } else { - ERROR_LOG(LOADER, "Unable to read file %s!", filename.c_str()); + LOG_ERROR(Loader, "Unable to read file %s!", filename.c_str()); } return ResultStatus::Error; } -- cgit v1.2.3 From c72ccfa6db41039ef2eb0ce118fabe1b38da841e Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 14 Dec 2014 04:32:45 -0200 Subject: HLE: Move kernel/archive.* to service/fs/ --- src/core/loader/3dsx.cpp | 2 +- src/core/loader/loader.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index f48d13530..0437e5374 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -8,7 +8,7 @@ #include "core/file_sys/archive_romfs.h" #include "core/loader/elf.h" #include "core/loader/ncch.h" -#include "core/hle/kernel/archive.h" +#include "core/hle/service/fs/archive.h" #include "core/mem_map.h" #include "3dsx.h" diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 3883e1307..d7786f1b2 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -8,7 +8,7 @@ #include "core/loader/3dsx.h" #include "core/loader/elf.h" #include "core/loader/ncch.h" -#include "core/hle/kernel/archive.h" +#include "core/hle/service/fs/archive.h" #include "core/mem_map.h" //////////////////////////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From ca67bb7945bf358cf38242a04febfd3375760947 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 14 Dec 2014 05:55:11 -0200 Subject: HLE: Rename namespaces to match move & fix initialization order --- src/core/loader/loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/loader') diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index d7786f1b2..6ce752561 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -74,7 +74,7 @@ ResultStatus LoadFile(const std::string& filename) { // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { - Kernel::CreateArchive(new FileSys::Archive_RomFS(app_loader), "RomFS"); + Service::FS::CreateArchive(new FileSys::Archive_RomFS(app_loader), "RomFS"); return ResultStatus::Success; } break; -- cgit v1.2.3 From f6153679b0781eea084b22f3ceecc74b1fe6b018 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 02:44:04 -0200 Subject: Service.FS: Do archive registration using IdCode instead of name --- src/core/loader/loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/loader') diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 6ce752561..49f8c458d 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -74,7 +74,7 @@ ResultStatus LoadFile(const std::string& filename) { // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { - Service::FS::CreateArchive(new FileSys::Archive_RomFS(app_loader), "RomFS"); + Service::FS::CreateArchive(new FileSys::Archive_RomFS(app_loader), Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } break; -- cgit v1.2.3 From 83e6e4ffec9ca67fbca5536bb0ed7b4876ade0db Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 15 Dec 2014 06:41:02 -0200 Subject: FS.Archive: Clean up treatment of archives and their handles - Refactor FS::Archive internals to make Archive creation and lifetime management clearer. - Remove the "Archive as a File" hack. - Implement 64-bit Archive handles. --- src/core/loader/loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/loader') diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 49f8c458d..463dacca3 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -74,7 +74,7 @@ ResultStatus LoadFile(const std::string& filename) { // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { - Service::FS::CreateArchive(new FileSys::Archive_RomFS(app_loader), Service::FS::ArchiveIdCode::RomFS); + Service::FS::CreateArchive(std::make_unique(app_loader), Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } break; -- cgit v1.2.3 From ea9ce0fba776eef8f9e4f3a86e71256091732a14 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 16 Dec 2014 00:33:41 -0500 Subject: Filesystem/Archives: Implemented the SaveData archive The savedata for each game is stored in /savedata/ for NCCH files. ELF files and 3DSX files use the folder 0 because they have no ID information Got rid of the code duplication in File and Directory Files that deal with the host machine's file system now live in DiskFile, similarly for directories and DiskDirectory and archives with DiskArchive. FS_U: Use the correct error code when a file wasn't found --- src/core/loader/loader.cpp | 1 + src/core/loader/ncch.cpp | 4 ++++ src/core/loader/ncch.h | 6 ++++++ 3 files changed, 11 insertions(+) (limited to 'src/core/loader') diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 463dacca3..480274d23 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -74,6 +74,7 @@ ResultStatus LoadFile(const std::string& filename) { // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { + Kernel::g_program_id = app_loader.GetProgramId(); Service::FS::CreateArchive(std::make_unique(app_loader), Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index ba9ba00c0..4d23656ec 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -315,4 +315,8 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::vector& buffer) const { return ResultStatus::Error; } +u64 AppLoader_NCCH::GetProgramId() const { + return *reinterpret_cast(&ncch_header.program_id[0]); +} + } // namespace Loader diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 03116add8..2fe2a7d82 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -191,6 +191,12 @@ public: */ ResultStatus ReadRomFS(std::vector& buffer) const override; + /* + * Gets the program id from the NCCH header + * @return u64 Program id + */ + u64 GetProgramId() const; + private: /** -- cgit v1.2.3 From 82528ba7df7bb8b2a6d89c416a66aee5c39f7f66 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 20 Dec 2014 03:21:23 -0200 Subject: Common: Add a clone of std::make_unique --- src/core/loader/loader.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 480274d23..b3b58da72 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -2,7 +2,9 @@ // Licensed under GPLv2 // Refer to the license.txt file included. -#include +#include + +#include "common/make_unique.h" #include "core/file_sys/archive_romfs.h" #include "core/loader/3dsx.h" @@ -75,7 +77,7 @@ ResultStatus LoadFile(const std::string& filename) { // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { Kernel::g_program_id = app_loader.GetProgramId(); - Service::FS::CreateArchive(std::make_unique(app_loader), Service::FS::ArchiveIdCode::RomFS); + Service::FS::CreateArchive(Common::make_unique(app_loader), Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } break; -- cgit v1.2.3 From e7956926147d2d2ac6741aee8a150466a5438ca3 Mon Sep 17 00:00:00 2001 From: Chin Date: Fri, 19 Dec 2014 22:16:34 -0500 Subject: Clean up some warnings --- src/core/loader/3dsx.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 0437e5374..3d84fc5da 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -223,9 +223,7 @@ int THREEDSXReader::Load3DSXFile(const std::string& filename, u32 base_addr) LOG_INFO(Loader, "Loading 3DSX file %s...", filename.c_str()); FileUtil::IOFile file(filename, "rb"); if (file.IsOpen()) { - - THREEDSXReader reader; - reader.Load3DSXFile(filename, 0x00100000); + THREEDSXReader::Load3DSXFile(filename, 0x00100000); Kernel::LoadExec(0x00100000); } else { return ResultStatus::Error; -- cgit v1.2.3 From ebfd831ccba32bce097491db3d6bdff0be05935e Mon Sep 17 00:00:00 2001 From: purpasmart96 Date: Tue, 16 Dec 2014 21:38:14 -0800 Subject: License change --- src/core/loader/3dsx.cpp | 2 +- src/core/loader/3dsx.h | 2 +- src/core/loader/elf.cpp | 4 ++-- src/core/loader/elf.h | 4 ++-- src/core/loader/loader.cpp | 2 +- src/core/loader/loader.h | 2 +- src/core/loader/ncch.cpp | 2 +- src/core/loader/ncch.h | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 0437e5374..5a4f7e7d9 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2+ +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h index 848d3ef8a..da8836662 100644 --- a/src/core/loader/3dsx.h +++ b/src/core/loader/3dsx.h @@ -1,5 +1,5 @@ // Copyright 2014 Dolphin Emulator Project / Citra Emulator Project -// Licensed under GPLv2+ +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index c95882f4a..354335014 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -1,5 +1,5 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 +// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index 5ae88439a..c221cce6d 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -1,5 +1,5 @@ -// Copyright 2013 Dolphin Emulator Project / Citra Emulator Project -// Licensed under GPLv2 +// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 480274d23..74a29ac61 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 0f836d285..ec5534d41 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 4d23656ec..0dc21699e 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 2fe2a7d82..fd9258970 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -1,5 +1,5 @@ // Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once -- cgit v1.2.3