mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	nso/nro: Add NSO arguments structure to data section
Only added if arguments string is non-empty and a pass is requested by loader.
This commit is contained in:
		
							parent
							
								
									6e4d2e672d
								
							
						
					
					
						commit
						e09505ff61
					
				@ -3,6 +3,7 @@
 | 
				
			|||||||
// Refer to the license.txt file included.
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cinttypes>
 | 
					#include <cinttypes>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
#include "common/common_funcs.h"
 | 
					#include "common/common_funcs.h"
 | 
				
			||||||
#include "common/file_util.h"
 | 
					#include "common/file_util.h"
 | 
				
			||||||
#include "common/logging/log.h"
 | 
					#include "common/logging/log.h"
 | 
				
			||||||
@ -140,7 +141,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process)
 | 
				
			|||||||
        const FileSys::VirtualFile module_file = dir->GetFile(module);
 | 
					        const FileSys::VirtualFile module_file = dir->GetFile(module);
 | 
				
			||||||
        if (module_file != nullptr) {
 | 
					        if (module_file != nullptr) {
 | 
				
			||||||
            const VAddr load_addr = next_load_addr;
 | 
					            const VAddr load_addr = next_load_addr;
 | 
				
			||||||
            next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr, pm);
 | 
					            next_load_addr =
 | 
				
			||||||
 | 
					                AppLoader_NSO::LoadModule(module_file, load_addr, std::strcmp(module, "rtld") == 0, pm);
 | 
				
			||||||
            LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
 | 
					            LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
 | 
				
			||||||
            // Register module with GDBStub
 | 
					            // Register module with GDBStub
 | 
				
			||||||
            GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
 | 
					            GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,9 @@
 | 
				
			|||||||
#include "core/hle/kernel/process.h"
 | 
					#include "core/hle/kernel/process.h"
 | 
				
			||||||
#include "core/hle/kernel/vm_manager.h"
 | 
					#include "core/hle/kernel/vm_manager.h"
 | 
				
			||||||
#include "core/loader/nro.h"
 | 
					#include "core/loader/nro.h"
 | 
				
			||||||
 | 
					#include "core/loader/nso.h"
 | 
				
			||||||
#include "core/memory.h"
 | 
					#include "core/memory.h"
 | 
				
			||||||
 | 
					#include "core/settings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Loader {
 | 
					namespace Loader {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -150,6 +152,17 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
 | 
				
			|||||||
        codeset->segments[i].size = PageAlignSize(nro_header.segments[i].size);
 | 
					        codeset->segments[i].size = PageAlignSize(nro_header.segments[i].size);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!Settings::values.program_args.empty()) {
 | 
				
			||||||
 | 
					        const auto arg_data = Settings::values.program_args;
 | 
				
			||||||
 | 
					        codeset->DataSegment().size += 0x9000;
 | 
				
			||||||
 | 
					        NSOArgumentHeader args_header{0x9000, arg_data.size(), {}};
 | 
				
			||||||
 | 
					        program_image.resize(static_cast<u32>(program_image.size()) + 0x9000);
 | 
				
			||||||
 | 
					        std::memcpy(program_image.data() + program_image.size() - 0x9000, &args_header,
 | 
				
			||||||
 | 
					                    sizeof(NSOArgumentHeader));
 | 
				
			||||||
 | 
					        std::memcpy(program_image.data() + program_image.size() - 0x8FE0, arg_data.data(),
 | 
				
			||||||
 | 
					                    arg_data.size());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Read MOD header
 | 
					    // Read MOD header
 | 
				
			||||||
    ModHeader mod_header{};
 | 
					    ModHeader mod_header{};
 | 
				
			||||||
    // Default .bss to NRO header bss size if MOD0 section doesn't exist
 | 
					    // Default .bss to NRO header bss size if MOD0 section doesn't exist
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@
 | 
				
			|||||||
#include "core/hle/kernel/vm_manager.h"
 | 
					#include "core/hle/kernel/vm_manager.h"
 | 
				
			||||||
#include "core/loader/nso.h"
 | 
					#include "core/loader/nso.h"
 | 
				
			||||||
#include "core/memory.h"
 | 
					#include "core/memory.h"
 | 
				
			||||||
 | 
					#include "core/settings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Loader {
 | 
					namespace Loader {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -94,6 +95,7 @@ static constexpr u32 PageAlignSize(u32 size) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base,
 | 
					VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base,
 | 
				
			||||||
 | 
					                                bool should_pass_arguments,
 | 
				
			||||||
                                boost::optional<FileSys::PatchManager> pm) {
 | 
					                                boost::optional<FileSys::PatchManager> pm) {
 | 
				
			||||||
    if (file == nullptr)
 | 
					    if (file == nullptr)
 | 
				
			||||||
        return {};
 | 
					        return {};
 | 
				
			||||||
@ -125,6 +127,17 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base,
 | 
				
			|||||||
        codeset->segments[i].size = PageAlignSize(static_cast<u32>(data.size()));
 | 
					        codeset->segments[i].size = PageAlignSize(static_cast<u32>(data.size()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (should_pass_arguments && !Settings::values.program_args.empty()) {
 | 
				
			||||||
 | 
					        const auto arg_data = Settings::values.program_args;
 | 
				
			||||||
 | 
					        codeset->DataSegment().size += 0x9000;
 | 
				
			||||||
 | 
					        NSOArgumentHeader args_header{0x9000, arg_data.size(), {}};
 | 
				
			||||||
 | 
					        program_image.resize(static_cast<u32>(program_image.size()) + 0x9000);
 | 
				
			||||||
 | 
					        std::memcpy(program_image.data() + program_image.size() - 0x9000, &args_header,
 | 
				
			||||||
 | 
					                    sizeof(NSOArgumentHeader));
 | 
				
			||||||
 | 
					        std::memcpy(program_image.data() + program_image.size() - 0x8FE0, arg_data.data(),
 | 
				
			||||||
 | 
					                    arg_data.size());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // MOD header pointer is at .text offset + 4
 | 
					    // MOD header pointer is at .text offset + 4
 | 
				
			||||||
    u32 module_offset;
 | 
					    u32 module_offset;
 | 
				
			||||||
    std::memcpy(&module_offset, program_image.data() + 4, sizeof(u32));
 | 
					    std::memcpy(&module_offset, program_image.data() + 4, sizeof(u32));
 | 
				
			||||||
@ -172,7 +185,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::Process& process) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Load module
 | 
					    // Load module
 | 
				
			||||||
    const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
 | 
					    const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
 | 
				
			||||||
    LoadModule(file, base_address);
 | 
					    LoadModule(file, base_address, true);
 | 
				
			||||||
    LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address);
 | 
					    LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    process.Run(base_address, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE);
 | 
					    process.Run(base_address, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE);
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Loader {
 | 
					namespace Loader {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct NSOArgumentHeader {
 | 
				
			||||||
 | 
					    u32_le allocated_size;
 | 
				
			||||||
 | 
					    u32_le actual_size;
 | 
				
			||||||
 | 
					    INSERT_PADDING_BYTES(0x18);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static_assert(sizeof(NSOArgumentHeader) == 0x20, "NSOArgumentHeader has incorrect size.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Loads an NSO file
 | 
					/// Loads an NSO file
 | 
				
			||||||
class AppLoader_NSO final : public AppLoader, Linker {
 | 
					class AppLoader_NSO final : public AppLoader, Linker {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@ -27,7 +34,7 @@ public:
 | 
				
			|||||||
        return IdentifyType(file);
 | 
					        return IdentifyType(file);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static VAddr LoadModule(FileSys::VirtualFile file, VAddr load_base,
 | 
					    static VAddr LoadModule(FileSys::VirtualFile file, VAddr load_base, bool should_pass_arguments,
 | 
				
			||||||
                            boost::optional<FileSys::PatchManager> pm = boost::none);
 | 
					                            boost::optional<FileSys::PatchManager> pm = boost::none);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ResultStatus Load(Kernel::Process& process) override;
 | 
					    ResultStatus Load(Kernel::Process& process) override;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user