nso.h 2.7 KB

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