[core/loader] prevent program_image reallocations in NSO+KIP loading methods (#3639)

also changes some methods to std::span<> as well, but mainly std::vector<> in the NSO/KIP loading stuff is not needed to be memcpy'ed and memmove'd around
this should save a marginal amount of loading time (RDR1)

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3639
Reviewed-by: DraVee <dravee@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie
2026-02-28 01:06:33 +01:00
committed by crueter
parent f8712e50e6
commit 06a08de68a
18 changed files with 122 additions and 212 deletions
+12 -16
View File
@@ -176,11 +176,9 @@ struct ProcessContext {
// Calculate hash.
Sha256Hash hash;
{
const u64 size = nro_header->GetSize();
const u64 size = nro_header->m_size;
std::vector<u8> nro_data(size);
m_process->GetMemory().ReadBlock(base_address, nro_data.data(), size);
u32 hash_len = 0;
EVP_Digest(nro_data.data(), nro_data.size(), hash.data(), &hash_len, EVP_sha256(), nullptr);
}
@@ -204,9 +202,7 @@ struct ProcessContext {
R_THROW(RO::ResultNotAuthorized);
}
Result ValidateNro(ModuleId* out_module_id, u64* out_rx_size, u64* out_ro_size,
u64* out_rw_size, u64 base_address, u64 expected_nro_size,
u64 expected_bss_size) {
Result ValidateNro(ModuleId* out_module_id, u64* out_rx_size, u64* out_ro_size, u64* out_rw_size, u64 base_address, u64 expected_nro_size, u64 expected_bss_size) {
// Ensure we have a process to work on.
R_UNLESS(m_process != nullptr, RO::ResultInvalidProcess);
@@ -215,17 +211,17 @@ struct ProcessContext {
m_process->GetMemory().ReadBlock(base_address, std::addressof(header), sizeof(header));
// Validate header.
R_UNLESS(header.IsMagicValid(), RO::ResultInvalidNro);
R_UNLESS(header.m_magic == NRO_HEADER_MAGIC, RO::ResultInvalidNro);
// Read sizes from header.
const u64 nro_size = header.GetSize();
const u64 text_ofs = header.GetTextOffset();
const u64 text_size = header.GetTextSize();
const u64 ro_ofs = header.GetRoOffset();
const u64 ro_size = header.GetRoSize();
const u64 rw_ofs = header.GetRwOffset();
const u64 rw_size = header.GetRwSize();
const u64 bss_size = header.GetBssSize();
const u64 nro_size = header.m_size;
const u64 text_ofs = header.m_text_offset;
const u64 text_size = header.m_text_size;
const u64 ro_ofs = header.m_ro_offset;
const u64 ro_size = header.m_ro_size;
const u64 rw_ofs = header.m_rw_offset;
const u64 rw_size = header.m_rw_size;
const u64 bss_size = header.m_bss_size;
// Validate sizes meet expected.
R_UNLESS(nro_size == expected_nro_size, RO::ResultInvalidNro);
@@ -251,7 +247,7 @@ struct ProcessContext {
R_TRY(this->ValidateHasNroHash(base_address, std::addressof(header)));
// Check if NRO has already been loaded.
const ModuleId* module_id = header.GetModuleId();
const ModuleId* module_id = std::addressof(header.m_module_id);
R_UNLESS(R_FAILED(this->GetNroInfoByModuleId(nullptr, module_id)), RO::ResultAlreadyLoaded);
// Apply patches to NRO.
+5 -46
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -112,52 +115,8 @@ private:
};
static_assert(sizeof(NrrHeader) == 0x350, "NrrHeader has wrong size");
class NroHeader {
public:
static constexpr u32 Magic = Common::MakeMagic('N', 'R', 'O', '0');
public:
bool IsMagicValid() const {
return m_magic == Magic;
}
u32 GetSize() const {
return m_size;
}
u32 GetTextOffset() const {
return m_text_offset;
}
u32 GetTextSize() const {
return m_text_size;
}
u32 GetRoOffset() const {
return m_ro_offset;
}
u32 GetRoSize() const {
return m_ro_size;
}
u32 GetRwOffset() const {
return m_rw_offset;
}
u32 GetRwSize() const {
return m_rw_size;
}
u32 GetBssSize() const {
return m_bss_size;
}
const ModuleId* GetModuleId() const {
return std::addressof(m_module_id);
}
private:
static constexpr u32 NRO_HEADER_MAGIC = Common::MakeMagic('N', 'R', 'O', '0');
struct NroHeader {
u32 m_entrypoint_insn;
u32 m_mod_offset;
INSERT_PADDING_BYTES_NOINIT(0x8);