mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-05-13 21:47:02 +02:00
[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:
parent
f8712e50e6
commit
06a08de68a
18 changed files with 122 additions and 212 deletions
|
|
@ -7,9 +7,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/physical_memory.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
|
|
@ -97,8 +97,7 @@ struct CodeSet final {
|
|||
#endif
|
||||
|
||||
/// The overall data that backs this code set.
|
||||
Kernel::PhysicalMemory memory;
|
||||
|
||||
std::vector<u8> memory;
|
||||
/// The segments that comprise this code set.
|
||||
std::array<Segment, 3> segments;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "common/alignment.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
// This encapsulation serves 2 purposes:
|
||||
// - First, to encapsulate host physical memory under a single type and set an
|
||||
// standard for managing it.
|
||||
// - Second to ensure all host backing memory used is aligned to 256 bytes due
|
||||
// to strict alignment restrictions on GPU memory.
|
||||
|
||||
using PhysicalMemoryVector = std::vector<u8, Common::AlignmentAllocator<u8, 256>>;
|
||||
class PhysicalMemory final : public PhysicalMemoryVector {
|
||||
using PhysicalMemoryVector::PhysicalMemoryVector;
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -93,7 +96,7 @@ union Error::ErrorArguments {
|
|||
|
||||
namespace {
|
||||
template <typename T>
|
||||
void CopyArgumentData(const std::vector<u8>& data, T& variable) {
|
||||
void CopyArgumentData(std::span<const u8> data, T& variable) {
|
||||
ASSERT(data.size() >= sizeof(T));
|
||||
std::memcpy(&variable, data.data(), sizeof(T));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -775,7 +778,7 @@ Result SoftwareKeyboard::RequestExit() {
|
|||
|
||||
// Inline Software Keyboard Requests
|
||||
|
||||
void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) {
|
||||
void SoftwareKeyboard::RequestFinalize(std::span<const u8> request_data) {
|
||||
LOG_DEBUG(Service_AM, "Processing Request: Finalize");
|
||||
|
||||
ChangeState(SwkbdState::NotInitialized);
|
||||
|
|
@ -783,17 +786,17 @@ void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) {
|
|||
ExitKeyboard();
|
||||
}
|
||||
|
||||
void SoftwareKeyboard::RequestSetUserWordInfo(const std::vector<u8>& request_data) {
|
||||
void SoftwareKeyboard::RequestSetUserWordInfo(std::span<const u8> request_data) {
|
||||
LOG_WARNING(Service_AM, "SetUserWordInfo is not implemented.");
|
||||
|
||||
ReplyReleasedUserWordInfo();
|
||||
}
|
||||
|
||||
void SoftwareKeyboard::RequestSetCustomizeDic(const std::vector<u8>& request_data) {
|
||||
void SoftwareKeyboard::RequestSetCustomizeDic(std::span<const u8> request_data) {
|
||||
LOG_WARNING(Service_AM, "SetCustomizeDic is not implemented.");
|
||||
}
|
||||
|
||||
void SoftwareKeyboard::RequestCalc(const std::vector<u8>& request_data) {
|
||||
void SoftwareKeyboard::RequestCalc(std::span<const u8> request_data) {
|
||||
LOG_DEBUG(Service_AM, "Processing Request: Calc");
|
||||
|
||||
ASSERT(request_data.size() >= sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArgCommon));
|
||||
|
|
@ -930,17 +933,17 @@ void SoftwareKeyboard::RequestCalcNew() {
|
|||
}
|
||||
}
|
||||
|
||||
void SoftwareKeyboard::RequestSetCustomizedDictionaries(const std::vector<u8>& request_data) {
|
||||
void SoftwareKeyboard::RequestSetCustomizedDictionaries(std::span<const u8> request_data) {
|
||||
LOG_WARNING(Service_AM, "SetCustomizedDictionaries is not implemented.");
|
||||
}
|
||||
|
||||
void SoftwareKeyboard::RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data) {
|
||||
void SoftwareKeyboard::RequestUnsetCustomizedDictionaries(std::span<const u8> request_data) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) Processing Request: UnsetCustomizedDictionaries");
|
||||
|
||||
ReplyUnsetCustomizedDictionaries();
|
||||
}
|
||||
|
||||
void SoftwareKeyboard::RequestSetChangedStringV2Flag(const std::vector<u8>& request_data) {
|
||||
void SoftwareKeyboard::RequestSetChangedStringV2Flag(std::span<const u8> request_data) {
|
||||
LOG_DEBUG(Service_AM, "Processing Request: SetChangedStringV2Flag");
|
||||
|
||||
ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + 1);
|
||||
|
|
@ -948,7 +951,7 @@ void SoftwareKeyboard::RequestSetChangedStringV2Flag(const std::vector<u8>& requ
|
|||
std::memcpy(&use_changed_string_v2, request_data.data() + sizeof(SwkbdRequestCommand), 1);
|
||||
}
|
||||
|
||||
void SoftwareKeyboard::RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data) {
|
||||
void SoftwareKeyboard::RequestSetMovedCursorV2Flag(std::span<const u8> request_data) {
|
||||
LOG_DEBUG(Service_AM, "Processing Request: SetMovedCursorV2Flag");
|
||||
|
||||
ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + 1);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -124,16 +127,16 @@ private:
|
|||
|
||||
// Inline Software Keyboard Requests
|
||||
|
||||
void RequestFinalize(const std::vector<u8>& request_data);
|
||||
void RequestSetUserWordInfo(const std::vector<u8>& request_data);
|
||||
void RequestSetCustomizeDic(const std::vector<u8>& request_data);
|
||||
void RequestCalc(const std::vector<u8>& request_data);
|
||||
void RequestFinalize(std::span<const u8> request_data);
|
||||
void RequestSetUserWordInfo(std::span<const u8> request_data);
|
||||
void RequestSetCustomizeDic(std::span<const u8> request_data);
|
||||
void RequestCalc(std::span<const u8> request_data);
|
||||
void RequestCalcOld();
|
||||
void RequestCalcNew();
|
||||
void RequestSetCustomizedDictionaries(const std::vector<u8>& request_data);
|
||||
void RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data);
|
||||
void RequestSetChangedStringV2Flag(const std::vector<u8>& request_data);
|
||||
void RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data);
|
||||
void RequestSetCustomizedDictionaries(std::span<const u8> request_data);
|
||||
void RequestUnsetCustomizedDictionaries(std::span<const u8> request_data);
|
||||
void RequestSetChangedStringV2Flag(std::span<const u8> request_data);
|
||||
void RequestSetMovedCursorV2Flag(std::span<const u8> request_data);
|
||||
|
||||
// Inline Software Keyboard Replies
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
|
|
@ -34,22 +34,21 @@ namespace Service::AM::Frontend {
|
|||
namespace {
|
||||
|
||||
template <typename T>
|
||||
void ParseRawValue(T& value, const std::vector<u8>& data) {
|
||||
void ParseRawValue(T& value, std::span<const u8> data) {
|
||||
static_assert(std::is_trivially_copyable_v<T>,
|
||||
"It's undefined behavior to use memcpy with non-trivially copyable objects");
|
||||
std::memcpy(&value, data.data(), data.size());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ParseRawValue(const std::vector<u8>& data) {
|
||||
T ParseRawValue(std::span<const u8> data) {
|
||||
T value;
|
||||
ParseRawValue(value, data);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string ParseStringValue(const std::vector<u8>& data) {
|
||||
return Common::StringFromFixedZeroTerminatedBuffer(reinterpret_cast<const char*>(data.data()),
|
||||
data.size());
|
||||
std::string ParseStringValue(std::span<const u8> data) {
|
||||
return Common::StringFromFixedZeroTerminatedBuffer(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
}
|
||||
|
||||
std::string GetMainURL(const std::string& url) {
|
||||
|
|
@ -72,7 +71,7 @@ std::string ResolveURL(const std::string& url) {
|
|||
return url.substr(0, index) + "lp1" + url.substr(index + 1);
|
||||
}
|
||||
|
||||
WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_arg_header) {
|
||||
WebArgInputTLVMap ReadWebArgs(std::span<const u8> web_arg, WebArgHeader& web_arg_header) {
|
||||
std::memcpy(&web_arg_header, web_arg.data(), sizeof(WebArgHeader));
|
||||
|
||||
if (web_arg.size() == sizeof(WebArgHeader)) {
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ private:
|
|||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
u64 ReadLeb128(const std::vector<u8>& data, std::size_t& offset) {
|
||||
u64 ReadLeb128(std::span<const u8> data, std::size_t& offset) {
|
||||
u64 result{};
|
||||
u32 shift{};
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ private:
|
|||
return result;
|
||||
}
|
||||
|
||||
std::optional<std::string> ReadString(const std::vector<u8>& data, std::size_t& offset,
|
||||
std::optional<std::string> ReadString(std::span<const u8> data, std::size_t& offset,
|
||||
std::size_t length) {
|
||||
if (length == 0) {
|
||||
return std::nullopt;
|
||||
|
|
@ -193,7 +193,7 @@ private:
|
|||
return output;
|
||||
}
|
||||
|
||||
u32_le ReadAsU32(const std::vector<u8>& data, std::size_t& offset, std::size_t length) {
|
||||
u32_le ReadAsU32(std::span<const u8> data, std::size_t& offset, std::size_t length) {
|
||||
ASSERT(length == sizeof(u32));
|
||||
u32_le output{};
|
||||
std::memcpy(&output, data.data() + offset, sizeof(u32));
|
||||
|
|
@ -201,7 +201,7 @@ private:
|
|||
return output;
|
||||
}
|
||||
|
||||
u64_le ReadAsU64(const std::vector<u8>& data, std::size_t& offset, std::size_t length) {
|
||||
u64_le ReadAsU64(std::span<const u8> data, std::size_t& offset, std::size_t length) {
|
||||
ASSERT(length == sizeof(u64));
|
||||
u64_le output{};
|
||||
std::memcpy(&output, data.data() + offset, sizeof(u64));
|
||||
|
|
@ -209,7 +209,7 @@ private:
|
|||
return output;
|
||||
}
|
||||
|
||||
void ParseLog(const LogPacketHeaderEntry entry, const std::vector<u8>& log_data) {
|
||||
void ParseLog(const LogPacketHeaderEntry entry, std::span<const u8> log_data) {
|
||||
// Possible entries
|
||||
std::optional<std::string> text_log;
|
||||
std::optional<u32> line_number;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||
|
|
@ -21,7 +21,6 @@
|
|||
#include "core/file_sys/system_archive/system_archive.h"
|
||||
#include "core/hle/kernel/k_shared_memory.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/physical_memory.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/ns/platform_service_manager.h"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue