mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	loader: Add DeconstructedRomDirectory for game dumps.
This commit is contained in:
		
							parent
							
								
									023aef053c
								
							
						
					
					
						commit
						e75aba3ed0
					
				@ -149,6 +149,8 @@ add_library(core STATIC
 | 
				
			|||||||
    hw/hw.h
 | 
					    hw/hw.h
 | 
				
			||||||
    hw/lcd.cpp
 | 
					    hw/lcd.cpp
 | 
				
			||||||
    hw/lcd.h
 | 
					    hw/lcd.h
 | 
				
			||||||
 | 
					    loader/deconstructed_rom_directory.cpp
 | 
				
			||||||
 | 
					    loader/deconstructed_rom_directory.h
 | 
				
			||||||
    loader/elf.cpp
 | 
					    loader/elf.cpp
 | 
				
			||||||
    loader/elf.h
 | 
					    loader/elf.h
 | 
				
			||||||
    loader/linker.cpp
 | 
					    loader/linker.cpp
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										101
									
								
								src/core/loader/deconstructed_rom_directory.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/core/loader/deconstructed_rom_directory.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,101 @@
 | 
				
			|||||||
 | 
					// Copyright 2018 yuzu emulator team
 | 
				
			||||||
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/common_funcs.h"
 | 
				
			||||||
 | 
					#include "common/common_paths.h"
 | 
				
			||||||
 | 
					#include "common/logging/log.h"
 | 
				
			||||||
 | 
					#include "common/string_util.h"
 | 
				
			||||||
 | 
					#include "core/hle/kernel/process.h"
 | 
				
			||||||
 | 
					#include "core/hle/kernel/resource_limit.h"
 | 
				
			||||||
 | 
					#include "core/loader/deconstructed_rom_directory.h"
 | 
				
			||||||
 | 
					#include "core/loader/nso.h"
 | 
				
			||||||
 | 
					#include "core/memory.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Loader {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FileType AppLoader_DeconstructedRomDirectory::IdentifyType(FileUtil::IOFile& file,
 | 
				
			||||||
 | 
					                                                           const std::string& filepath) {
 | 
				
			||||||
 | 
					    bool is_main_found{};
 | 
				
			||||||
 | 
					    bool is_rtld_found{};
 | 
				
			||||||
 | 
					    bool is_sdk_found{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto callback = [&](unsigned* num_entries_out, const std::string& directory,
 | 
				
			||||||
 | 
					                              const std::string& virtual_name) -> bool {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Skip directories
 | 
				
			||||||
 | 
					        std::string physical_name = directory + virtual_name;
 | 
				
			||||||
 | 
					        if (FileUtil::IsDirectory(physical_name)) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Verify filename
 | 
				
			||||||
 | 
					        if (Common::ToLower(virtual_name) == "main") {
 | 
				
			||||||
 | 
					            is_main_found = true;
 | 
				
			||||||
 | 
					        } else if (Common::ToLower(virtual_name) == "rtld") {
 | 
				
			||||||
 | 
					            is_rtld_found = true;
 | 
				
			||||||
 | 
					        } else if (Common::ToLower(virtual_name) == "sdk") {
 | 
				
			||||||
 | 
					            is_sdk_found = true;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // Contrinue searching
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Verify file is an NSO
 | 
				
			||||||
 | 
					        FileUtil::IOFile file(physical_name, "rb");
 | 
				
			||||||
 | 
					        if (AppLoader_NSO::IdentifyType(file, physical_name) != FileType::NSO) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // We are done if we've found and verified all required NSOs
 | 
				
			||||||
 | 
					        return !(is_main_found && is_rtld_found && is_sdk_found);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Search the directory recursively, looking for the required modules
 | 
				
			||||||
 | 
					    const std::string directory = filepath.substr(0, filepath.find_last_of("/\\")) + DIR_SEP;
 | 
				
			||||||
 | 
					    FileUtil::ForeachDirectoryEntry(nullptr, directory, callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_main_found && is_rtld_found && is_sdk_found) {
 | 
				
			||||||
 | 
					        return FileType::DeconstructedRomDirectory;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return FileType::Error;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ResultStatus AppLoader_DeconstructedRomDirectory::Load(
 | 
				
			||||||
 | 
					    Kernel::SharedPtr<Kernel::Process>& process) {
 | 
				
			||||||
 | 
					    if (is_loaded) {
 | 
				
			||||||
 | 
					        return ResultStatus::ErrorAlreadyLoaded;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!file.IsOpen()) {
 | 
				
			||||||
 | 
					        return ResultStatus::Error;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    process = Kernel::Process::Create("main");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Load NSO modules
 | 
				
			||||||
 | 
					    VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR};
 | 
				
			||||||
 | 
					    for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
 | 
				
			||||||
 | 
					                               "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
 | 
				
			||||||
 | 
					        const std::string path =
 | 
				
			||||||
 | 
					            filepath.substr(0, filepath.find_last_of("/\\")) + DIR_SEP + module;
 | 
				
			||||||
 | 
					        const VAddr load_addr = next_load_addr;
 | 
				
			||||||
 | 
					        next_load_addr = AppLoader_NSO::LoadModule(path, load_addr);
 | 
				
			||||||
 | 
					        if (next_load_addr) {
 | 
				
			||||||
 | 
					            LOG_DEBUG(Loader, "loaded module %s @ 0x%llx", module, load_addr);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            next_load_addr = load_addr;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    process->svc_access_mask.set();
 | 
				
			||||||
 | 
					    process->address_mappings = default_address_mappings;
 | 
				
			||||||
 | 
					    process->resource_limit =
 | 
				
			||||||
 | 
					        Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
 | 
				
			||||||
 | 
					    process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    is_loaded = true;
 | 
				
			||||||
 | 
					    return ResultStatus::Success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Loader
 | 
				
			||||||
							
								
								
									
										44
									
								
								src/core/loader/deconstructed_rom_directory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/core/loader/deconstructed_rom_directory.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					// Copyright 2018 yuzu emulator team
 | 
				
			||||||
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					#include "common/file_util.h"
 | 
				
			||||||
 | 
					#include "core/hle/kernel/kernel.h"
 | 
				
			||||||
 | 
					#include "core/loader/loader.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Loader {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This class loads a "deconstructed ROM directory", which are the typical format we see for Switch
 | 
				
			||||||
 | 
					 * game dumps. The path should be a "main" NSO, which must be in a directory that contains the other
 | 
				
			||||||
 | 
					 * standard ExeFS NSOs (e.g. rtld, sdk, etc.). It will automatically find and load these.
 | 
				
			||||||
 | 
					 * Furthermore, it will look for the first .istorage file (optionally) and use this for the RomFS.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class AppLoader_DeconstructedRomDirectory final : public AppLoader {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    AppLoader_DeconstructedRomDirectory(FileUtil::IOFile&& file, std::string filepath)
 | 
				
			||||||
 | 
					        : AppLoader(std::move(file)), filepath(std::move(filepath)) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the type of the file
 | 
				
			||||||
 | 
					     * @param file FileUtil::IOFile open file
 | 
				
			||||||
 | 
					     * @param filepath Path of the file that we are opening.
 | 
				
			||||||
 | 
					     * @return FileType found, or FileType::Error if this loader doesn't know it
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static FileType IdentifyType(FileUtil::IOFile& file, const std::string& filepath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FileType GetFileType() override {
 | 
				
			||||||
 | 
					        return IdentifyType(file, filepath);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    std::string filepath;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Loader
 | 
				
			||||||
@ -7,6 +7,7 @@
 | 
				
			|||||||
#include "common/logging/log.h"
 | 
					#include "common/logging/log.h"
 | 
				
			||||||
#include "common/string_util.h"
 | 
					#include "common/string_util.h"
 | 
				
			||||||
#include "core/hle/kernel/process.h"
 | 
					#include "core/hle/kernel/process.h"
 | 
				
			||||||
 | 
					#include "core/loader/deconstructed_rom_directory.h"
 | 
				
			||||||
#include "core/loader/elf.h"
 | 
					#include "core/loader/elf.h"
 | 
				
			||||||
#include "core/loader/nro.h"
 | 
					#include "core/loader/nro.h"
 | 
				
			||||||
#include "core/loader/nso.h"
 | 
					#include "core/loader/nso.h"
 | 
				
			||||||
@ -29,6 +30,7 @@ FileType IdentifyFile(FileUtil::IOFile& file, const std::string& filepath) {
 | 
				
			|||||||
    if (FileType::Error != type)                                                                   \
 | 
					    if (FileType::Error != type)                                                                   \
 | 
				
			||||||
        return type;
 | 
					        return type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CHECK_TYPE(DeconstructedRomDirectory)
 | 
				
			||||||
    CHECK_TYPE(ELF)
 | 
					    CHECK_TYPE(ELF)
 | 
				
			||||||
    CHECK_TYPE(NSO)
 | 
					    CHECK_TYPE(NSO)
 | 
				
			||||||
    CHECK_TYPE(NRO)
 | 
					    CHECK_TYPE(NRO)
 | 
				
			||||||
@ -69,6 +71,8 @@ const char* GetFileTypeString(FileType type) {
 | 
				
			|||||||
        return "NRO";
 | 
					        return "NRO";
 | 
				
			||||||
    case FileType::NSO:
 | 
					    case FileType::NSO:
 | 
				
			||||||
        return "NSO";
 | 
					        return "NSO";
 | 
				
			||||||
 | 
					    case FileType::DeconstructedRomDirectory:
 | 
				
			||||||
 | 
					        return "Directory";
 | 
				
			||||||
    case FileType::Error:
 | 
					    case FileType::Error:
 | 
				
			||||||
    case FileType::Unknown:
 | 
					    case FileType::Unknown:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -102,6 +106,10 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileUtil::IOFile&& file, FileTyp
 | 
				
			|||||||
    case FileType::NRO:
 | 
					    case FileType::NRO:
 | 
				
			||||||
        return std::make_unique<AppLoader_NRO>(std::move(file), filepath);
 | 
					        return std::make_unique<AppLoader_NRO>(std::move(file), filepath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // NX deconstructed ROM directory.
 | 
				
			||||||
 | 
					    case FileType::DeconstructedRomDirectory:
 | 
				
			||||||
 | 
					        return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file), filepath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        return nullptr;
 | 
					        return nullptr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,7 @@ enum class FileType {
 | 
				
			|||||||
    ELF,
 | 
					    ELF,
 | 
				
			||||||
    NSO,
 | 
					    NSO,
 | 
				
			||||||
    NRO,
 | 
					    NRO,
 | 
				
			||||||
 | 
					    DeconstructedRomDirectory,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user