mirror of
https://github.com/Lime3DS/Lime3DS
synced 2025-01-03 21:10:49 -06:00
cf9bb90ae3
* code: Use std::span when possible * code: Prefix memcpy and memcmp with std::
150 lines
5 KiB
C++
150 lines
5 KiB
C++
// 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 <span>
|
|
#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<const u32> 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<u32> compatible_TID;
|
|
std::vector<u8> text_section;
|
|
std::vector<u8> data_section;
|
|
std::vector<u8> rodata_section;
|
|
|
|
std::vector<u32> exe_load_func;
|
|
u32_le exe_load_args[4];
|
|
};
|
|
} // namespace FileSys
|