nso.h 2.7 KB

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