| | |
| | |
| |
|
| | #pragma once |
| |
|
| | #include <array> |
| | #include <optional> |
| | #include <type_traits> |
| | #include "common/common_types.h" |
| | #include "common/swap.h" |
| | #include "core/file_sys/patch_manager.h" |
| | #include "core/loader/loader.h" |
| |
|
| | namespace Core { |
| | class System; |
| | } |
| |
|
| | namespace Core::NCE { |
| | class Patcher; |
| | } |
| |
|
| | namespace Kernel { |
| | class KProcess; |
| | } |
| |
|
| | namespace Loader { |
| |
|
| | struct NSOSegmentHeader { |
| | u32_le offset; |
| | u32_le location; |
| | u32_le size; |
| | union { |
| | u32_le alignment; |
| | u32_le bss_size; |
| | }; |
| | }; |
| | static_assert(sizeof(NSOSegmentHeader) == 0x10, "NsoSegmentHeader has incorrect size."); |
| |
|
| | struct NSOHeader { |
| | using SHA256Hash = std::array<u8, 0x20>; |
| |
|
| | struct RODataRelativeExtent { |
| | u32_le data_offset; |
| | u32_le size; |
| | }; |
| |
|
| | u32_le magic; |
| | u32_le version; |
| | u32 reserved; |
| | u32_le flags; |
| | std::array<NSOSegmentHeader, 3> segments; |
| | std::array<u8, 0x20> build_id; |
| | std::array<u32_le, 3> segments_compressed_size; |
| | std::array<u8, 0x1C> padding; |
| | RODataRelativeExtent api_info_extent; |
| | RODataRelativeExtent dynstr_extent; |
| | RODataRelativeExtent dynsyn_extent; |
| | std::array<SHA256Hash, 3> segment_hashes; |
| |
|
| | bool IsSegmentCompressed(size_t segment_num) const; |
| | }; |
| | static_assert(sizeof(NSOHeader) == 0x100, "NSOHeader has incorrect size."); |
| | static_assert(std::is_trivially_copyable_v<NSOHeader>, "NSOHeader must be trivially copyable."); |
| |
|
| | constexpr u32 NSO_ARGUMENT_DATA_ALLOCATION_SIZE = 0x9000; |
| |
|
| | struct NSOArgumentHeader { |
| | u32_le allocated_size; |
| | u32_le actual_size; |
| | INSERT_PADDING_BYTES(0x18); |
| | }; |
| | static_assert(sizeof(NSOArgumentHeader) == 0x20, "NSOArgumentHeader has incorrect size."); |
| |
|
| | |
| | class AppLoader_NSO final : public AppLoader { |
| | public: |
| | explicit AppLoader_NSO(FileSys::VirtualFile file_); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | static FileType IdentifyType(const FileSys::VirtualFile& in_file); |
| |
|
| | FileType GetFileType() const override { |
| | return IdentifyType(file); |
| | } |
| |
|
| | static std::optional<VAddr> LoadModule(Kernel::KProcess& process, Core::System& system, |
| | const FileSys::VfsFile& nso_file, VAddr load_base, |
| | bool should_pass_arguments, bool load_into_process, |
| | std::optional<FileSys::PatchManager> pm = {}, |
| | std::vector<Core::NCE::Patcher>* patches = nullptr, |
| | s32 patch_index = -1); |
| |
|
| | LoadResult Load(Kernel::KProcess& process, Core::System& system) override; |
| |
|
| | ResultStatus ReadNSOModules(Modules& out_modules) override; |
| |
|
| | private: |
| | Modules modules; |
| | }; |
| |
|
| | } |
| |
|