// Copyright 2022 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. // Copyright 2022 The Pixellizer Group // // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and // associated documentation files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, publish, distribute, // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or // substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once #include #include "common/common_types.h" #include "common/swap.h" #include "core/file_sys/archive_backend.h" #include "core/hle/kernel/process.h" #include "core/hle/service/plgldr/plgldr.h" namespace Loader { enum class ResultStatus; } namespace FileUtil { class IOFile; } namespace FileSys { class FileBackend; class Plugin3GXLoader { public: Loader::ResultStatus Load(Service::PLGLDR::PLG_LDR::PluginLoaderContext& plg_context, Kernel::Process& process, Kernel::KernelSystem& kernel); struct PluginHeader { u32_le magic; u32_le version; u32_le heap_VA; u32_le heap_size; u32_le exe_size; // Include sizeof(PluginHeader) + .text + .rodata + .data + .bss (0x1000 // aligned too) u32_le is_default_plugin; u32_le plgldr_event; ///< Used for synchronization, unused in citra u32_le plgldr_reply; ///< Used for synchronization, unused in citra u32_le reserved[24]; u32_le config[32]; }; static_assert(sizeof(PluginHeader) == 0x100, "Invalid plugin header size"); static constexpr const char* _3GX_magic = "3GX$0002"; static constexpr u32 _3GX_exe_load_addr = 0x07000000; static constexpr u32 _3GX_heap_load_addr = 0x06000000; static constexpr u32 _3GX_fb_size = 0xA9000; private: Loader::ResultStatus Map(Service::PLGLDR::PLG_LDR::PluginLoaderContext& plg_context, Kernel::Process& process, Kernel::KernelSystem& kernel); static constexpr size_t bootloader_memory_size = 0x1000; static void MapBootloader(Kernel::Process& process, Kernel::KernelSystem& kernel, u32 memory_offset, std::span exe_load_func, const u32_le* exe_load_args, u32 checksum_size, u32 exe_checksum, bool no_flash); struct _3gx_Infos { enum class Compatibility { CONSOLE = 0, CITRA = 1, CONSOLE_CITRA = 2 }; u32_le author_len; u32_le author_msg_offset; u32_le title_len; u32_le title_msg_offset; u32_le summary_len; u32_le summary_msg_offset; u32_le description_len; u32_le description_msg_offset; union { u32_le raw; BitField<0, 1, u32_le> embedded_exe_func; BitField<1, 1, u32_le> embedded_swap_func; BitField<2, 2, u32_le> memory_region_size; BitField<4, 2, u32_le> compatibility; } flags; u32_le exe_load_checksum; u32_le builtin_load_exe_args[4]; u32_le builtin_swap_load_args[4]; }; struct _3gx_Targets { u32_le count; u32_le title_offsets; }; struct _3gx_Symtable { u32_le nb_symbols; u32_le symbols_offset; u32_le name_table_offset; }; struct _3gx_Executable { u32_le code_offset; u32_le rodata_offset; u32_le data_offset; u32_le code_size; u32_le rodata_size; u32_le data_size; u32_le bss_size; u32_le exe_load_func_offset; // NOP terminated u32_le swap_save_func_offset; // NOP terminated u32_le swap_load_func_offset; // NOP terminated }; struct _3gx_Header { u64_le magic; u32_le version; u32_le reserved; _3gx_Infos infos; _3gx_Executable executable; _3gx_Targets targets; _3gx_Symtable symtable; }; _3gx_Header header; std::string author; std::string title; std::string summary; std::string description; std::vector compatible_TID; std::vector text_section; std::vector data_section; std::vector rodata_section; std::vector exe_load_func; u32_le exe_load_args[4]; }; } // namespace FileSys