deconstructed_rom_directory.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <cinttypes>
  5. #include "common/common_funcs.h"
  6. #include "common/file_util.h"
  7. #include "common/logging/log.h"
  8. #include "core/file_sys/content_archive.h"
  9. #include "core/gdbstub/gdbstub.h"
  10. #include "core/hle/kernel/process.h"
  11. #include "core/hle/kernel/resource_limit.h"
  12. #include "core/hle/service/filesystem/filesystem.h"
  13. #include "core/loader/deconstructed_rom_directory.h"
  14. #include "core/loader/nso.h"
  15. #include "core/memory.h"
  16. namespace Loader {
  17. AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file)
  18. : AppLoader(std::move(file)) {}
  19. AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(
  20. FileSys::VirtualDir directory)
  21. : AppLoader(directory->GetFile("main")), dir(std::move(directory)) {}
  22. FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) {
  23. if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) {
  24. return FileType::DeconstructedRomDirectory;
  25. }
  26. return FileType::Error;
  27. }
  28. ResultStatus AppLoader_DeconstructedRomDirectory::Load(
  29. Kernel::SharedPtr<Kernel::Process>& process) {
  30. if (is_loaded) {
  31. return ResultStatus::ErrorAlreadyLoaded;
  32. }
  33. if (dir == nullptr) {
  34. if (file == nullptr)
  35. return ResultStatus::ErrorInvalidFormat;
  36. dir = file->GetContainingDirectory();
  37. }
  38. const FileSys::VirtualFile npdm = dir->GetFile("main.npdm");
  39. if (npdm == nullptr)
  40. return ResultStatus::ErrorInvalidFormat;
  41. ResultStatus result = metadata.Load(npdm);
  42. if (result != ResultStatus::Success) {
  43. return result;
  44. }
  45. metadata.Print();
  46. const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()};
  47. if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) {
  48. return ResultStatus::ErrorUnsupportedArch;
  49. }
  50. // Load NSO modules
  51. VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR};
  52. for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
  53. "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
  54. const FileSys::VirtualFile module_file = dir->GetFile(module);
  55. if (module_file != nullptr) {
  56. const VAddr load_addr = next_load_addr;
  57. next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr);
  58. LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
  59. // Register module with GDBStub
  60. GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
  61. }
  62. }
  63. process->program_id = metadata.GetTitleID();
  64. process->svc_access_mask.set();
  65. process->address_mappings = default_address_mappings;
  66. process->resource_limit =
  67. Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
  68. process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(),
  69. metadata.GetMainThreadStackSize());
  70. // Find the RomFS by searching for a ".romfs" file in this directory
  71. const auto& files = dir->GetFiles();
  72. const auto romfs_iter =
  73. std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) {
  74. return file->GetName().find(".romfs") != std::string::npos;
  75. });
  76. // Register the RomFS if a ".romfs" file was found
  77. if (romfs_iter != files.end() && *romfs_iter != nullptr) {
  78. romfs = *romfs_iter;
  79. Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this));
  80. }
  81. is_loaded = true;
  82. return ResultStatus::Success;
  83. }
  84. ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) {
  85. if (romfs == nullptr)
  86. return ResultStatus::ErrorNotUsed;
  87. dir = romfs;
  88. return ResultStatus::Success;
  89. }
  90. } // namespace Loader