nso.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <optional>
  6. #include <type_traits>
  7. #include "common/common_types.h"
  8. #include "common/swap.h"
  9. #include "core/file_sys/patch_manager.h"
  10. #include "core/loader/loader.h"
  11. namespace Core {
  12. class System;
  13. }
  14. namespace Kernel {
  15. class KProcess;
  16. }
  17. namespace Loader {
  18. struct NSOSegmentHeader {
  19. u32_le offset;
  20. u32_le location;
  21. u32_le size;
  22. union {
  23. u32_le alignment;
  24. u32_le bss_size;
  25. };
  26. };
  27. static_assert(sizeof(NSOSegmentHeader) == 0x10, "NsoSegmentHeader has incorrect size.");
  28. struct NSOHeader {
  29. using SHA256Hash = std::array<u8, 0x20>;
  30. struct RODataRelativeExtent {
  31. u32_le data_offset;
  32. u32_le size;
  33. };
  34. u32_le magic;
  35. u32_le version;
  36. u32 reserved;
  37. u32_le flags;
  38. std::array<NSOSegmentHeader, 3> segments; // Text, RoData, Data (in that order)
  39. std::array<u8, 0x20> build_id;
  40. std::array<u32_le, 3> segments_compressed_size;
  41. std::array<u8, 0x1C> padding;
  42. RODataRelativeExtent api_info_extent;
  43. RODataRelativeExtent dynstr_extent;
  44. RODataRelativeExtent dynsyn_extent;
  45. std::array<SHA256Hash, 3> segment_hashes;
  46. bool IsSegmentCompressed(size_t segment_num) const;
  47. };
  48. static_assert(sizeof(NSOHeader) == 0x100, "NSOHeader has incorrect size.");
  49. static_assert(std::is_trivially_copyable_v<NSOHeader>, "NSOHeader must be trivially copyable.");
  50. constexpr u32 NSO_ARGUMENT_DATA_ALLOCATION_SIZE = 0x9000;
  51. struct NSOArgumentHeader {
  52. u32_le allocated_size;
  53. u32_le actual_size;
  54. INSERT_PADDING_BYTES(0x18);
  55. };
  56. static_assert(sizeof(NSOArgumentHeader) == 0x20, "NSOArgumentHeader has incorrect size.");
  57. /// Loads an NSO file
  58. class AppLoader_NSO final : public AppLoader {
  59. public:
  60. explicit AppLoader_NSO(FileSys::VirtualFile file_);
  61. /**
  62. * Identifies whether or not the given file is a form of NSO file.
  63. *
  64. * @param in_file The file to be identified.
  65. *
  66. * @return FileType::NSO if found, or FileType::Error if some other type of file.
  67. */
  68. static FileType IdentifyType(const FileSys::VirtualFile& in_file);
  69. FileType GetFileType() const override {
  70. return IdentifyType(file);
  71. }
  72. static std::optional<VAddr> LoadModule(Kernel::KProcess& process, Core::System& system,
  73. const FileSys::VfsFile& nso_file, VAddr load_base,
  74. bool should_pass_arguments, bool load_into_process,
  75. std::optional<FileSys::PatchManager> pm = {});
  76. LoadResult Load(Kernel::KProcess& process, Core::System& system) override;
  77. ResultStatus ReadNSOModules(Modules& out_modules) override;
  78. private:
  79. Modules modules;
  80. };
  81. } // namespace Loader