mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-24 20:36:24 -05:00
vm_manager: Remove cheat-specific ranges from VMManager
This commit is contained in:
parent
7053546687
commit
52ac6419da
10 changed files with 56 additions and 77 deletions
|
@ -450,8 +450,10 @@ Tegra::DebugContext* System::GetGPUDebugContext() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::RegisterCheatList(const std::vector<FileSys::CheatList>& list,
|
void System::RegisterCheatList(const std::vector<FileSys::CheatList>& list,
|
||||||
const std::string& build_id) {
|
const std::string& build_id, VAddr code_region_start,
|
||||||
impl->cheat_engine = std::make_unique<FileSys::CheatEngine>(list, build_id);
|
VAddr code_region_end) {
|
||||||
|
impl->cheat_engine =
|
||||||
|
std::make_unique<FileSys::CheatEngine>(list, build_id, code_region_start, code_region_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::SetFilesystem(std::shared_ptr<FileSys::VfsFilesystem> vfs) {
|
void System::SetFilesystem(std::shared_ptr<FileSys::VfsFilesystem> vfs) {
|
||||||
|
|
|
@ -254,8 +254,8 @@ public:
|
||||||
|
|
||||||
std::shared_ptr<FileSys::VfsFilesystem> GetFilesystem() const;
|
std::shared_ptr<FileSys::VfsFilesystem> GetFilesystem() const;
|
||||||
|
|
||||||
void RegisterCheatList(const std::vector<FileSys::CheatList>& list,
|
void RegisterCheatList(const std::vector<FileSys::CheatList>& list, const std::string& build_id,
|
||||||
const std::string& build_id);
|
VAddr code_region_start, VAddr code_region_end);
|
||||||
|
|
||||||
void SetProfileSelector(std::unique_ptr<Frontend::ProfileSelectApplet> applet);
|
void SetProfileSelector(std::unique_ptr<Frontend::ProfileSelectApplet> applet);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
constexpr u64 CHEAT_ENGINE_TICKS = CoreTiming::BASE_CLOCK_RATE / 60;
|
constexpr u64 CHEAT_ENGINE_TICKS = Core::Timing::BASE_CLOCK_RATE / 60;
|
||||||
constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF;
|
constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF;
|
||||||
|
|
||||||
u64 Cheat::Address() const {
|
u64 Cheat::Address() const {
|
||||||
|
@ -82,7 +82,7 @@ CheatList::CheatList(ProgramSegment master, ProgramSegment standard)
|
||||||
|
|
||||||
bool CheatList::EvaluateConditional(const Cheat& cheat) const {
|
bool CheatList::EvaluateConditional(const Cheat& cheat) const {
|
||||||
using ComparisonFunction = bool (*)(u64, u64);
|
using ComparisonFunction = bool (*)(u64, u64);
|
||||||
constexpr ComparisonFunction comparison_functions[] = {
|
constexpr std::array<ComparisonFunction, 6> comparison_functions{
|
||||||
[](u64 a, u64 b) { return a > b; }, [](u64 a, u64 b) { return a >= b; },
|
[](u64 a, u64 b) { return a > b; }, [](u64 a, u64 b) { return a >= b; },
|
||||||
[](u64 a, u64 b) { return a < b; }, [](u64 a, u64 b) { return a <= b; },
|
[](u64 a, u64 b) { return a < b; }, [](u64 a, u64 b) { return a <= b; },
|
||||||
[](u64 a, u64 b) { return a == b; }, [](u64 a, u64 b) { return a != b; },
|
[](u64 a, u64 b) { return a == b; }, [](u64 a, u64 b) { return a != b; },
|
||||||
|
@ -103,7 +103,7 @@ bool CheatList::EvaluateConditional(const Cheat& cheat) const {
|
||||||
const auto press_state =
|
const auto press_state =
|
||||||
applet_resource
|
applet_resource
|
||||||
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)
|
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)
|
||||||
.GetPressState();
|
.GetAndResetPressState();
|
||||||
return ((press_state & cheat.KeypadValue()) & KEYPAD_BITMASK) != 0;
|
return ((press_state & cheat.KeypadValue()) & KEYPAD_BITMASK) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ bool CheatList::EvaluateConditional(const Cheat& cheat) const {
|
||||||
const auto offset =
|
const auto offset =
|
||||||
cheat.memory_type == MemoryType::MainNSO ? main_region_begin : heap_region_begin;
|
cheat.memory_type == MemoryType::MainNSO ? main_region_begin : heap_region_begin;
|
||||||
ASSERT(static_cast<u8>(cheat.comparison_op.Value()) < 6);
|
ASSERT(static_cast<u8>(cheat.comparison_op.Value()) < 6);
|
||||||
const auto* function = comparison_functions[static_cast<u8>(cheat.comparison_op.Value())];
|
auto* function = comparison_functions[static_cast<u8>(cheat.comparison_op.Value())];
|
||||||
const auto addr = cheat.Address() + offset;
|
const auto addr = cheat.Address() + offset;
|
||||||
|
|
||||||
return function(reader(cheat.width, SanitizeAddress(addr)), cheat.ValueWidth(8));
|
return function(reader(cheat.width, SanitizeAddress(addr)), cheat.ValueWidth(8));
|
||||||
|
@ -157,7 +157,7 @@ void CheatList::ProcessBlockPairs(const Block& block) {
|
||||||
void CheatList::WriteImmediate(const Cheat& cheat) {
|
void CheatList::WriteImmediate(const Cheat& cheat) {
|
||||||
const auto offset =
|
const auto offset =
|
||||||
cheat.memory_type == MemoryType::MainNSO ? main_region_begin : heap_region_begin;
|
cheat.memory_type == MemoryType::MainNSO ? main_region_begin : heap_region_begin;
|
||||||
auto& register_3 = scratch.at(cheat.register_3);
|
const auto& register_3 = scratch.at(cheat.register_3);
|
||||||
|
|
||||||
const auto addr = cheat.Address() + offset + register_3;
|
const auto addr = cheat.Address() + offset + register_3;
|
||||||
LOG_DEBUG(Common_Filesystem, "writing value={:016X} to addr={:016X}", addr,
|
LOG_DEBUG(Common_Filesystem, "writing value={:016X} to addr={:016X}", addr,
|
||||||
|
@ -166,12 +166,14 @@ void CheatList::WriteImmediate(const Cheat& cheat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheatList::BeginConditional(const Cheat& cheat) {
|
void CheatList::BeginConditional(const Cheat& cheat) {
|
||||||
if (!EvaluateConditional(cheat)) {
|
if (EvaluateConditional(cheat)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto iter = block_pairs.find(current_index);
|
const auto iter = block_pairs.find(current_index);
|
||||||
ASSERT(iter != block_pairs.end());
|
ASSERT(iter != block_pairs.end());
|
||||||
current_index = iter->second - 1;
|
current_index = iter->second - 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void CheatList::EndConditional(const Cheat& cheat) {
|
void CheatList::EndConditional(const Cheat& cheat) {
|
||||||
LOG_DEBUG(Common_Filesystem, "Ending conditional block.");
|
LOG_DEBUG(Common_Filesystem, "Ending conditional block.");
|
||||||
|
@ -218,7 +220,7 @@ void CheatList::LoadIndexed(const Cheat& cheat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheatList::StoreIndexed(const Cheat& cheat) {
|
void CheatList::StoreIndexed(const Cheat& cheat) {
|
||||||
auto& register_3 = scratch.at(cheat.register_3);
|
const auto& register_3 = scratch.at(cheat.register_3);
|
||||||
|
|
||||||
const auto addr =
|
const auto addr =
|
||||||
register_3 + (cheat.add_additional_register.Value() ? scratch.at(cheat.register_6) : 0);
|
register_3 + (cheat.add_additional_register.Value() ? scratch.at(cheat.register_6) : 0);
|
||||||
|
@ -229,14 +231,14 @@ void CheatList::StoreIndexed(const Cheat& cheat) {
|
||||||
|
|
||||||
void CheatList::RegisterArithmetic(const Cheat& cheat) {
|
void CheatList::RegisterArithmetic(const Cheat& cheat) {
|
||||||
using ArithmeticFunction = u64 (*)(u64, u64);
|
using ArithmeticFunction = u64 (*)(u64, u64);
|
||||||
constexpr ArithmeticFunction arithmetic_functions[] = {
|
constexpr std::array<ArithmeticFunction, 5> arithmetic_functions{
|
||||||
[](u64 a, u64 b) { return a + b; }, [](u64 a, u64 b) { return a - b; },
|
[](u64 a, u64 b) { return a + b; }, [](u64 a, u64 b) { return a - b; },
|
||||||
[](u64 a, u64 b) { return a * b; }, [](u64 a, u64 b) { return a << b; },
|
[](u64 a, u64 b) { return a * b; }, [](u64 a, u64 b) { return a << b; },
|
||||||
[](u64 a, u64 b) { return a >> b; },
|
[](u64 a, u64 b) { return a >> b; },
|
||||||
};
|
};
|
||||||
|
|
||||||
using ArithmeticOverflowCheck = bool (*)(u64, u64);
|
using ArithmeticOverflowCheck = bool (*)(u64, u64);
|
||||||
constexpr ArithmeticOverflowCheck arithmetic_overflow_checks[] = {
|
constexpr std::array<ArithmeticOverflowCheck, 5> arithmetic_overflow_checks{
|
||||||
[](u64 a, u64 b) { return a > (std::numeric_limits<u64>::max() - b); }, // a + b
|
[](u64 a, u64 b) { return a > (std::numeric_limits<u64>::max() - b); }, // a + b
|
||||||
[](u64 a, u64 b) { return a > (std::numeric_limits<u64>::max() + b); }, // a - b
|
[](u64 a, u64 b) { return a > (std::numeric_limits<u64>::max() + b); }, // a - b
|
||||||
[](u64 a, u64 b) { return a > (std::numeric_limits<u64>::max() / b); }, // a * b
|
[](u64 a, u64 b) { return a > (std::numeric_limits<u64>::max() / b); }, // a * b
|
||||||
|
@ -250,8 +252,8 @@ void CheatList::RegisterArithmetic(const Cheat& cheat) {
|
||||||
auto& register_3 = scratch.at(cheat.register_3);
|
auto& register_3 = scratch.at(cheat.register_3);
|
||||||
|
|
||||||
ASSERT(static_cast<u8>(cheat.arithmetic_op.Value()) < 5);
|
ASSERT(static_cast<u8>(cheat.arithmetic_op.Value()) < 5);
|
||||||
const auto* function = arithmetic_functions[static_cast<u8>(cheat.arithmetic_op.Value())];
|
auto* function = arithmetic_functions[static_cast<u8>(cheat.arithmetic_op.Value())];
|
||||||
const auto* overflow_function =
|
auto* overflow_function =
|
||||||
arithmetic_overflow_checks[static_cast<u8>(cheat.arithmetic_op.Value())];
|
arithmetic_overflow_checks[static_cast<u8>(cheat.arithmetic_op.Value())];
|
||||||
LOG_DEBUG(Common_Filesystem, "performing arithmetic with register={:01X}, value={:016X}",
|
LOG_DEBUG(Common_Filesystem, "performing arithmetic with register={:01X}, value={:016X}",
|
||||||
cheat.register_3, cheat.ValueWidth(4));
|
cheat.register_3, cheat.ValueWidth(4));
|
||||||
|
@ -267,12 +269,13 @@ void CheatList::RegisterArithmetic(const Cheat& cheat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheatList::BeginConditionalInput(const Cheat& cheat) {
|
void CheatList::BeginConditionalInput(const Cheat& cheat) {
|
||||||
if (!EvaluateConditional(cheat)) {
|
if (EvaluateConditional(cheat))
|
||||||
|
return;
|
||||||
|
|
||||||
const auto iter = block_pairs.find(current_index);
|
const auto iter = block_pairs.find(current_index);
|
||||||
ASSERT(iter != block_pairs.end());
|
ASSERT(iter != block_pairs.end());
|
||||||
current_index = iter->second - 1;
|
current_index = iter->second - 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
VAddr CheatList::SanitizeAddress(VAddr in) const {
|
VAddr CheatList::SanitizeAddress(VAddr in) const {
|
||||||
if ((in < main_region_begin || in >= main_region_end) &&
|
if ((in < main_region_begin || in >= main_region_end) &&
|
||||||
|
@ -290,7 +293,7 @@ VAddr CheatList::SanitizeAddress(VAddr in) const {
|
||||||
|
|
||||||
void CheatList::ExecuteSingleCheat(const Cheat& cheat) {
|
void CheatList::ExecuteSingleCheat(const Cheat& cheat) {
|
||||||
using CheatOperationFunction = void (CheatList::*)(const Cheat&);
|
using CheatOperationFunction = void (CheatList::*)(const Cheat&);
|
||||||
constexpr CheatOperationFunction cheat_operation_functions[] = {
|
constexpr std::array<CheatOperationFunction, 9> cheat_operation_functions{
|
||||||
&CheatList::WriteImmediate, &CheatList::BeginConditional,
|
&CheatList::WriteImmediate, &CheatList::BeginConditional,
|
||||||
&CheatList::EndConditional, &CheatList::Loop,
|
&CheatList::EndConditional, &CheatList::Loop,
|
||||||
&CheatList::LoadImmediate, &CheatList::LoadIndexed,
|
&CheatList::LoadImmediate, &CheatList::LoadIndexed,
|
||||||
|
@ -346,7 +349,7 @@ CheatList TextCheatParser::Parse(const std::vector<u8>& data) const {
|
||||||
if (!line.empty() && (line[0] == '[' || line[0] == '{')) {
|
if (!line.empty() && (line[0] == '[' || line[0] == '{')) {
|
||||||
const auto master = line[0] == '{';
|
const auto master = line[0] == '{';
|
||||||
const auto begin = master ? line.find('{') : line.find('[');
|
const auto begin = master ? line.find('{') : line.find('[');
|
||||||
const auto end = master ? line.find_last_of('}') : line.find_last_of(']');
|
const auto end = master ? line.rfind('}') : line.rfind(']');
|
||||||
|
|
||||||
ASSERT(begin != std::string::npos && end != std::string::npos);
|
ASSERT(begin != std::string::npos && end != std::string::npos);
|
||||||
|
|
||||||
|
@ -422,7 +425,7 @@ std::array<u8, 16> TextCheatParser::ParseSingleLineCheat(const std::string& line
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 MemoryReadImpl(u8 width, VAddr addr) {
|
u64 MemoryReadImpl(u32 width, VAddr addr) {
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case 1:
|
case 1:
|
||||||
return Memory::Read8(addr);
|
return Memory::Read8(addr);
|
||||||
|
@ -438,7 +441,7 @@ u64 MemoryReadImpl(u8 width, VAddr addr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryWriteImpl(u8 width, VAddr addr, u64 value) {
|
void MemoryWriteImpl(u32 width, VAddr addr, u64 value) {
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case 1:
|
case 1:
|
||||||
Memory::Write8(addr, static_cast<u8>(value));
|
Memory::Write8(addr, static_cast<u8>(value));
|
||||||
|
@ -457,31 +460,34 @@ void MemoryWriteImpl(u8 width, VAddr addr, u64 value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CheatEngine::CheatEngine(std::vector<CheatList> cheats, const std::string& build_id)
|
CheatEngine::CheatEngine(std::vector<CheatList> cheats, const std::string& build_id,
|
||||||
|
VAddr code_region_start, VAddr code_region_end)
|
||||||
: cheats(std::move(cheats)) {
|
: cheats(std::move(cheats)) {
|
||||||
event = CoreTiming::RegisterEvent(
|
auto& core_timing{Core::System::GetInstance().CoreTiming()};
|
||||||
|
event = core_timing.RegisterEvent(
|
||||||
"CheatEngine::FrameCallback::" + build_id,
|
"CheatEngine::FrameCallback::" + build_id,
|
||||||
[this](u64 userdata, s64 cycles_late) { FrameCallback(userdata, cycles_late); });
|
[this](u64 userdata, s64 cycles_late) { FrameCallback(userdata, cycles_late); });
|
||||||
CoreTiming::ScheduleEvent(CHEAT_ENGINE_TICKS, event);
|
core_timing.ScheduleEvent(CHEAT_ENGINE_TICKS, event);
|
||||||
|
|
||||||
const auto& vm_manager = Core::System::GetInstance().CurrentProcess()->VMManager();
|
const auto& vm_manager = Core::System::GetInstance().CurrentProcess()->VMManager();
|
||||||
for (auto& list : this->cheats) {
|
for (auto& list : this->cheats) {
|
||||||
list.SetMemoryParameters(
|
list.SetMemoryParameters(code_region_start, vm_manager.GetHeapRegionBaseAddress(),
|
||||||
vm_manager.GetMainCodeRegionBaseAddress(), vm_manager.GetHeapRegionBaseAddress(),
|
code_region_end, vm_manager.GetHeapRegionEndAddress(),
|
||||||
vm_manager.GetMainCodeRegionEndAddress(), vm_manager.GetHeapRegionEndAddress(),
|
|
||||||
&MemoryWriteImpl, &MemoryReadImpl);
|
&MemoryWriteImpl, &MemoryReadImpl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CheatEngine::~CheatEngine() {
|
CheatEngine::~CheatEngine() {
|
||||||
CoreTiming::UnscheduleEvent(event, 0);
|
auto& core_timing{Core::System::GetInstance().CoreTiming()};
|
||||||
|
core_timing.UnscheduleEvent(event, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheatEngine::FrameCallback(u64 userdata, int cycles_late) {
|
void CheatEngine::FrameCallback(u64 userdata, int cycles_late) {
|
||||||
for (auto& list : cheats)
|
for (auto& list : cheats)
|
||||||
list.Execute();
|
list.Execute();
|
||||||
|
|
||||||
CoreTiming::ScheduleEvent(CHEAT_ENGINE_TICKS - cycles_late, event);
|
auto& core_timing{Core::System::GetInstance().CoreTiming()};
|
||||||
|
core_timing.ScheduleEvent(CHEAT_ENGINE_TICKS - cycles_late, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace CoreTiming {
|
namespace Core::Timing {
|
||||||
struct EventType;
|
struct EventType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +123,9 @@ public:
|
||||||
using ProgramSegment = std::vector<std::pair<std::string, Block>>;
|
using ProgramSegment = std::vector<std::pair<std::string, Block>>;
|
||||||
|
|
||||||
// (width in bytes, address, value)
|
// (width in bytes, address, value)
|
||||||
using MemoryWriter = void (*)(u8, VAddr, u64);
|
using MemoryWriter = void (*)(u32, VAddr, u64);
|
||||||
// (width in bytes, address) -> value
|
// (width in bytes, address) -> value
|
||||||
using MemoryReader = u64 (*)(u8, VAddr);
|
using MemoryReader = u64 (*)(u32, VAddr);
|
||||||
|
|
||||||
void SetMemoryParameters(VAddr main_begin, VAddr heap_begin, VAddr main_end, VAddr heap_end,
|
void SetMemoryParameters(VAddr main_begin, VAddr heap_begin, VAddr main_end, VAddr heap_end,
|
||||||
MemoryWriter writer, MemoryReader reader);
|
MemoryWriter writer, MemoryReader reader);
|
||||||
|
@ -212,13 +212,14 @@ private:
|
||||||
// Class that encapsulates a CheatList and manages its interaction with memory and CoreTiming
|
// Class that encapsulates a CheatList and manages its interaction with memory and CoreTiming
|
||||||
class CheatEngine final {
|
class CheatEngine final {
|
||||||
public:
|
public:
|
||||||
CheatEngine(std::vector<CheatList> cheats, const std::string& build_id);
|
CheatEngine(std::vector<CheatList> cheats, const std::string& build_id, VAddr code_region_start,
|
||||||
|
VAddr code_region_end);
|
||||||
~CheatEngine();
|
~CheatEngine();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void FrameCallback(u64 userdata, int cycles_late);
|
void FrameCallback(u64 userdata, int cycles_late);
|
||||||
|
|
||||||
CoreTiming::EventType* event;
|
Core::Timing::EventType* event;
|
||||||
|
|
||||||
std::vector<CheatList> cheats;
|
std::vector<CheatList> cheats;
|
||||||
};
|
};
|
||||||
|
|
|
@ -786,23 +786,6 @@ u64 VMManager::GetNewMapRegionSize() const {
|
||||||
return new_map_region_end - new_map_region_base;
|
return new_map_region_end - new_map_region_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMManager::SetMainCodeRegion(VAddr begin, VAddr end) {
|
|
||||||
main_code_region_base = begin;
|
|
||||||
main_code_region_end = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
VAddr VMManager::GetMainCodeRegionBaseAddress() const {
|
|
||||||
return main_code_region_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
VAddr VMManager::GetMainCodeRegionEndAddress() const {
|
|
||||||
return main_code_region_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 VMManager::GetMainCodeRegionSize() const {
|
|
||||||
return main_code_region_end - main_code_region_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
VAddr VMManager::GetTLSIORegionBaseAddress() const {
|
VAddr VMManager::GetTLSIORegionBaseAddress() const {
|
||||||
return tls_io_region_base;
|
return tls_io_region_base;
|
||||||
}
|
}
|
||||||
|
|
|
@ -480,14 +480,6 @@ public:
|
||||||
/// Gets the total size of the new map region in bytes.
|
/// Gets the total size of the new map region in bytes.
|
||||||
u64 GetNewMapRegionSize() const;
|
u64 GetNewMapRegionSize() const;
|
||||||
|
|
||||||
void SetMainCodeRegion(VAddr begin, VAddr end);
|
|
||||||
|
|
||||||
VAddr GetMainCodeRegionBaseAddress() const;
|
|
||||||
|
|
||||||
VAddr GetMainCodeRegionEndAddress() const;
|
|
||||||
|
|
||||||
u64 GetMainCodeRegionSize() const;
|
|
||||||
|
|
||||||
/// Gets the base address of the TLS IO region.
|
/// Gets the base address of the TLS IO region.
|
||||||
VAddr GetTLSIORegionBaseAddress() const;
|
VAddr GetTLSIORegionBaseAddress() const;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
#include "controllers/controller_base.h"
|
#include "controllers/controller_base.h"
|
||||||
|
|
|
@ -147,10 +147,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process)
|
||||||
|
|
||||||
const VAddr load_addr = next_load_addr;
|
const VAddr load_addr = next_load_addr;
|
||||||
const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
|
const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
|
||||||
const bool should_register_data_segment = std::strcmp(module, "main") == 0;
|
|
||||||
const auto tentative_next_load_addr =
|
const auto tentative_next_load_addr =
|
||||||
AppLoader_NSO::LoadModule(process, *module_file, load_addr, should_pass_arguments,
|
AppLoader_NSO::LoadModule(process, *module_file, load_addr, should_pass_arguments, pm);
|
||||||
should_register_data_segment, pm);
|
|
||||||
if (!tentative_next_load_addr) {
|
if (!tentative_next_load_addr) {
|
||||||
return ResultStatus::ErrorLoadingNSO;
|
return ResultStatus::ErrorLoadingNSO;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,6 @@ static constexpr u32 PageAlignSize(u32 size) {
|
||||||
std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
|
std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
|
||||||
const FileSys::VfsFile& file, VAddr load_base,
|
const FileSys::VfsFile& file, VAddr load_base,
|
||||||
bool should_pass_arguments,
|
bool should_pass_arguments,
|
||||||
bool should_register_data_region,
|
|
||||||
std::optional<FileSys::PatchManager> pm) {
|
std::optional<FileSys::PatchManager> pm) {
|
||||||
if (file.GetSize() < sizeof(NsoHeader))
|
if (file.GetSize() < sizeof(NsoHeader))
|
||||||
return {};
|
return {};
|
||||||
|
@ -156,10 +155,6 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
|
||||||
const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)};
|
const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)};
|
||||||
program_image.resize(image_size);
|
program_image.resize(image_size);
|
||||||
|
|
||||||
if (should_register_data_region) {
|
|
||||||
process.VMManager().SetMainCodeRegion(load_base, load_base + program_image.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply patches if necessary
|
// Apply patches if necessary
|
||||||
if (pm && (pm->HasNSOPatch(nso_header.build_id) || Settings::values.dump_nso)) {
|
if (pm && (pm->HasNSOPatch(nso_header.build_id) || Settings::values.dump_nso)) {
|
||||||
std::vector<u8> pi_header(program_image.size() + 0x100);
|
std::vector<u8> pi_header(program_image.size() + 0x100);
|
||||||
|
@ -176,7 +171,8 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
|
||||||
const auto cheats = pm->CreateCheatList(nso_header.build_id);
|
const auto cheats = pm->CreateCheatList(nso_header.build_id);
|
||||||
if (!cheats.empty()) {
|
if (!cheats.empty()) {
|
||||||
Core::System::GetInstance().RegisterCheatList(
|
Core::System::GetInstance().RegisterCheatList(
|
||||||
cheats, Common::HexArrayToString(nso_header.build_id));
|
cheats, Common::HexArrayToString(nso_header.build_id), load_base,
|
||||||
|
load_base + program_image.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +193,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();
|
||||||
if (!LoadModule(process, *file, base_address, true, true)) {
|
if (!LoadModule(process, *file, base_address, true)) {
|
||||||
return ResultStatus::ErrorLoadingNSO;
|
return ResultStatus::ErrorLoadingNSO;
|
||||||
}
|
}
|
||||||
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address);
|
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address);
|
||||||
|
|
|
@ -43,7 +43,6 @@ public:
|
||||||
|
|
||||||
static std::optional<VAddr> LoadModule(Kernel::Process& process, const FileSys::VfsFile& file,
|
static std::optional<VAddr> LoadModule(Kernel::Process& process, const FileSys::VfsFile& file,
|
||||||
VAddr load_base, bool should_pass_arguments,
|
VAddr load_base, bool should_pass_arguments,
|
||||||
bool should_register_data_segment,
|
|
||||||
std::optional<FileSys::PatchManager> pm = {});
|
std::optional<FileSys::PatchManager> pm = {});
|
||||||
|
|
||||||
ResultStatus Load(Kernel::Process& process) override;
|
ResultStatus Load(Kernel::Process& process) override;
|
||||||
|
|
Loading…
Reference in a new issue