more import fixing

This commit is contained in:
ownedbywuigi 2025-07-08 06:13:08 +01:00
parent 2016ea50df
commit bbc104bb56
4 changed files with 502 additions and 13 deletions

147
common/common_funcs.h Executable file
View file

@ -0,0 +1,147 @@
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <iterator>
#if !defined(ARCHITECTURE_x86_64)
#include <cstdlib> // for exit
#endif
#include "common_types.h"
/// Textually concatenates two tokens. The double-expansion is required by the C preprocessor.
#define CONCAT2(x, y) DO_CONCAT2(x, y)
#define DO_CONCAT2(x, y) x##y
/// Helper macros to insert unused bytes or words to properly align structs. These values will be
/// zero-initialized.
#define INSERT_PADDING_BYTES(num_bytes) \
[[maybe_unused]] std::array<u8, num_bytes> CONCAT2(pad, __LINE__) {}
#define INSERT_PADDING_WORDS(num_words) \
[[maybe_unused]] std::array<u32, num_words> CONCAT2(pad, __LINE__) {}
/// These are similar to the INSERT_PADDING_* macros but do not zero-initialize the contents.
/// This keeps the structure trivial to construct.
#define INSERT_PADDING_BYTES_NOINIT(num_bytes) \
[[maybe_unused]] std::array<u8, num_bytes> CONCAT2(pad, __LINE__)
#define INSERT_PADDING_WORDS_NOINIT(num_words) \
[[maybe_unused]] std::array<u32, num_words> CONCAT2(pad, __LINE__)
#ifndef _MSC_VER
#if defined(ARCHITECTURE_x86_64)
#define Crash() __asm__ __volatile__("int $3")
#elif defined(ARCHITECTURE_arm64)
#define Crash() __asm__ __volatile__("brk #0")
#else
#define Crash() exit(1)
#endif
#define LTO_NOINLINE __attribute__((noinline))
#else // _MSC_VER
#define LTO_NOINLINE
// Locale Cross-Compatibility
#define locale_t _locale_t
extern "C" {
__declspec(dllimport) void __stdcall DebugBreak(void);
}
#define Crash() DebugBreak()
#endif // _MSC_VER ndef
#define DECLARE_ENUM_FLAG_OPERATORS(type) \
[[nodiscard]] constexpr type operator|(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) | static_cast<T>(b)); \
} \
[[nodiscard]] constexpr type operator&(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) & static_cast<T>(b)); \
} \
[[nodiscard]] constexpr type operator^(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \
} \
[[nodiscard]] constexpr type operator<<(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) << static_cast<T>(b)); \
} \
[[nodiscard]] constexpr type operator>>(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) >> static_cast<T>(b)); \
} \
constexpr type& operator|=(type& a, type b) noexcept { \
a = a | b; \
return a; \
} \
constexpr type& operator&=(type& a, type b) noexcept { \
a = a & b; \
return a; \
} \
constexpr type& operator^=(type& a, type b) noexcept { \
a = a ^ b; \
return a; \
} \
constexpr type& operator<<=(type& a, type b) noexcept { \
a = a << b; \
return a; \
} \
constexpr type& operator>>=(type& a, type b) noexcept { \
a = a >> b; \
return a; \
} \
[[nodiscard]] constexpr type operator~(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(~static_cast<T>(key)); \
} \
[[nodiscard]] constexpr bool True(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<T>(key) != 0; \
} \
[[nodiscard]] constexpr bool False(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<T>(key) == 0; \
}
#define YUZU_NON_COPYABLE(cls) \
cls(const cls&) = delete; \
cls& operator=(const cls&) = delete
#define YUZU_NON_MOVEABLE(cls) \
cls(cls&&) = delete; \
cls& operator=(cls&&) = delete
namespace Common {
[[nodiscard]] constexpr u32 MakeMagic(char a, char b, char c, char d) {
return u32(a) | u32(b) << 8 | u32(c) << 16 | u32(d) << 24;
}
[[nodiscard]] constexpr u64 MakeMagic(char a, char b, char c, char d, char e, char f, char g,
char h) {
return u64(a) << 0 | u64(b) << 8 | u64(c) << 16 | u64(d) << 24 | u64(e) << 32 | u64(f) << 40 |
u64(g) << 48 | u64(h) << 56;
}
// std::size() does not support zero-size C arrays. We're fixing that.
template <class C>
constexpr auto Size(const C& c) -> decltype(c.size()) {
return std::size(c);
}
template <class C>
constexpr std::size_t Size(const C& c) {
if constexpr (sizeof(C) == 0) {
return 0;
} else {
return std::size(c);
}
}
} // namespace Common

View file

@ -5,9 +5,9 @@
#include <fmt/format.h>
#include "../common/fs/path_util.h"
#include "core/fs/bis_factory.h"
#include "core/fs/registered_cache.h"
#include "core/fs/vfs/vfs.h"
#include "bis_factory.h"
#include "registered_cache.h"
#include "vfs/vfs.h"
namespace FileSys {

View file

@ -8,16 +8,16 @@
#include <fmt/ostream.h>
#include "common/logging/log.h"
#include "core/crypto/key_manager.h"
#include "core/fs/card_image.h"
#include "core/fs/content_archive.h"
#include "core/fs/nca_metadata.h"
#include "core/fs/partition_filesystem.h"
#include "core/fs/submission_package.h"
#include "core/fs/vfs/vfs_offset.h"
#include "core/fs/vfs/vfs_vector.h"
#include "core/loader/loader.h"
#include "../common/logging/log.h"
#include "crypto/key_manager.h"
#include "card_image.h"
#include "content_archive.h"
#include "nca_metadata.h"
#include "partition_filesystem.h"
#include "submission_package.h"
#include "vfs/vfs_offset.h"
#include "vfs/vfs_vector.h"
#include "loader/loader.h"
namespace FileSys {

342
core/loader/loader.h Executable file
View file

@ -0,0 +1,342 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <functional>
#include <iosfwd>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "fs/control_metadata.h"
#include "fs/vfs/vfs.h"
namespace Core {
class System;
}
namespace FileSys {
class NACP;
} // namespace FileSys
namespace Kernel {
struct AddressMapping;
class KProcess;
} // namespace Kernel
namespace Loader {
/// File types supported by CTR
enum class FileType {
Error,
Unknown,
NSO,
NRO,
NCA,
NSP,
XCI,
NAX,
KIP,
DeconstructedRomDirectory,
};
/**
* Identifies the type of a bootable file based on the magic value in its header.
* @param file open file
* @return FileType of file
*/
FileType IdentifyFile(FileSys::VirtualFile file);
/**
* Guess the type of a bootable file from its name
* @param name String name of bootable file
* @return FileType of file. Note: this will return FileType::Unknown if it is unable to determine
* a filetype, and will never return FileType::Error.
*/
FileType GuessFromFilename(const std::string& name);
/**
* Convert a FileType into a string which can be displayed to the user.
*/
std::string GetFileTypeString(FileType type);
/// Return type for functions in Loader namespace
enum class ResultStatus : u16 {
Success,
ErrorAlreadyLoaded,
ErrorNotImplemented,
ErrorNotInitialized,
ErrorBadNPDMHeader,
ErrorBadACIDHeader,
ErrorBadACIHeader,
ErrorBadFileAccessControl,
ErrorBadFileAccessHeader,
ErrorBadKernelCapabilityDescriptors,
ErrorBadPFSHeader,
ErrorIncorrectPFSFileSize,
ErrorBadNCAHeader,
ErrorMissingProductionKeyFile,
ErrorMissingHeaderKey,
ErrorIncorrectHeaderKey,
ErrorNCA2,
ErrorNCA0,
ErrorMissingTitlekey,
ErrorMissingTitlekek,
ErrorInvalidRightsID,
ErrorMissingKeyAreaKey,
ErrorIncorrectKeyAreaKey,
ErrorIncorrectTitlekeyOrTitlekek,
ErrorXCIMissingProgramNCA,
ErrorNCANotProgram,
ErrorNoExeFS,
ErrorBadXCIHeader,
ErrorXCIMissingPartition,
ErrorNullFile,
ErrorMissingNPDM,
Error32BitISA,
ErrorUnableToParseKernelMetadata,
ErrorNoRomFS,
ErrorIncorrectELFFileSize,
ErrorLoadingNRO,
ErrorLoadingNSO,
ErrorNoIcon,
ErrorNoControl,
ErrorBadNAXHeader,
ErrorIncorrectNAXFileSize,
ErrorNAXKeyHMACFailed,
ErrorNAXValidationHMACFailed,
ErrorNAXKeyDerivationFailed,
ErrorNAXInconvertibleToNCA,
ErrorBadNAXFilePath,
ErrorMissingSDSeed,
ErrorMissingSDKEKSource,
ErrorMissingAESKEKGenerationSource,
ErrorMissingAESKeyGenerationSource,
ErrorMissingSDSaveKeySource,
ErrorMissingSDNCAKeySource,
ErrorNSPMissingProgramNCA,
ErrorBadBKTRHeader,
ErrorBKTRSubsectionNotAfterRelocation,
ErrorBKTRSubsectionNotAtEnd,
ErrorBadRelocationBlock,
ErrorBadSubsectionBlock,
ErrorBadRelocationBuckets,
ErrorBadSubsectionBuckets,
ErrorMissingBKTRBaseRomFS,
ErrorNoPackedUpdate,
ErrorBadKIPHeader,
ErrorBLZDecompressionFailed,
ErrorBadINIHeader,
ErrorINITooManyKIPs,
ErrorIntegrityVerificationNotImplemented,
ErrorIntegrityVerificationFailed,
};
std::string GetResultStatusString(ResultStatus status);
std::ostream& operator<<(std::ostream& os, ResultStatus status);
/// Interface for loading an application
class AppLoader {
public:
YUZU_NON_COPYABLE(AppLoader);
YUZU_NON_MOVEABLE(AppLoader);
struct LoadParameters {
s32 main_thread_priority;
u64 main_thread_stack_size;
};
using LoadResult = std::pair<ResultStatus, std::optional<LoadParameters>>;
explicit AppLoader(FileSys::VirtualFile file_);
virtual ~AppLoader();
/**
* Returns the type of this file
*
* @return FileType corresponding to the loaded file
*/
virtual FileType GetFileType() const = 0;
/**
* Load the application and return the created Process instance
*
* @param process The newly created process.
* @param system The system that this process is being loaded under.
*
* @return The status result of the operation.
*/
virtual LoadResult Load(Kernel::KProcess& process, Core::System& system) = 0;
/**
* Try to verify the integrity of the file.
*/
virtual ResultStatus VerifyIntegrity(std::function<bool(size_t, size_t)> progress_callback) {
return ResultStatus::ErrorIntegrityVerificationNotImplemented;
}
/**
* Get the code (typically .code section) of the application
*
* @param[out] buffer Reference to buffer to store data
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadCode(std::vector<u8>& buffer) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get the icon (typically icon section) of the application
*
* @param[out] buffer Reference to buffer to store data
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadIcon(std::vector<u8>& buffer) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get the banner (typically banner section) of the application
* In the context of NX, this is the animation that displays in the bottom right of the screen
* when a game boots. Stored in GIF format.
*
* @param[out] buffer Reference to buffer to store data
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadBanner(std::vector<u8>& buffer) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get the logo (typically logo section) of the application
* In the context of NX, this is the static image that displays in the top left of the screen
* when a game boots. Stored in JPEG format.
*
* @param[out] buffer Reference to buffer to store data
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadLogo(std::vector<u8>& buffer) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get the program id of the application
*
* @param[out] out_program_id Reference to store program id into
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadProgramId(u64& out_program_id) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get the program ids of the application
*
* @param[out] out_program_ids Reference to store program ids into
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadProgramIds(std::vector<u64>& out_program_ids) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get the RomFS of the application
* Since the RomFS can be huge, we return a file reference instead of copying to a buffer
*
* @param[out] out_file The directory containing the RomFS
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get the raw update of the application, should it come packed with one
*
* @param[out] out_file The raw update NCA file (Program-type)
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get whether or not updates can be applied to the RomFS.
* By default, this is true, however for formats where it cannot be guaranteed that the RomFS is
* the base game it should be set to false.
*
* @return bool indicating whether or not the RomFS is updatable.
*/
virtual bool IsRomFSUpdatable() const {
return true;
}
/**
* Get the title of the application
*
* @param[out] title Reference to store the application title into
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadTitle(std::string& title) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get the control data (CNMT) of the application
*
* @param[out] control Reference to store the application control data into
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadControlData(FileSys::NACP& control) {
return ResultStatus::ErrorNotImplemented;
}
/**
* Get the RomFS of the manual of the application
*
* @param[out] out_file The raw manual RomFS of the game
*
* @return ResultStatus result of function
*/
virtual ResultStatus ReadManualRomFS(FileSys::VirtualFile& out_file) {
return ResultStatus::ErrorNotImplemented;
}
using Modules = std::map<VAddr, std::string>;
virtual ResultStatus ReadNSOModules(Modules& modules) {
return ResultStatus::ErrorNotImplemented;
}
protected:
FileSys::VirtualFile file;
bool is_loaded = false;
};
/**
* Identifies a bootable file and return a suitable loader
*
* @param system The system context.
* @param file The bootable file.
* @param program_index Specifies the index within the container of the program to launch.
*
* @return the best loader for this file.
*/
std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file,
u64 program_id = 0, std::size_t program_index = 0);
} // namespace Loader