diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 9ba4d0368..2c60dbac9 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -72,33 +72,34 @@ private: class DynarmicUserCallbacks final : public Dynarmic::A32::UserCallbacks { public: explicit DynarmicUserCallbacks(ARM_Dynarmic& parent) - : parent(parent), timing(parent.system.CoreTiming()), svc_context(parent.system) {} + : parent(parent), timing(parent.system.CoreTiming()), svc_context(parent.system), + memory(parent.system.Memory()) {} ~DynarmicUserCallbacks() = default; std::uint8_t MemoryRead8(VAddr vaddr) override { - return Memory::Read8(vaddr); + return memory.Read8(vaddr); } std::uint16_t MemoryRead16(VAddr vaddr) override { - return Memory::Read16(vaddr); + return memory.Read16(vaddr); } std::uint32_t MemoryRead32(VAddr vaddr) override { - return Memory::Read32(vaddr); + return memory.Read32(vaddr); } std::uint64_t MemoryRead64(VAddr vaddr) override { - return Memory::Read64(vaddr); + return memory.Read64(vaddr); } void MemoryWrite8(VAddr vaddr, std::uint8_t value) override { - Memory::Write8(vaddr, value); + memory.Write8(vaddr, value); } void MemoryWrite16(VAddr vaddr, std::uint16_t value) override { - Memory::Write16(vaddr, value); + memory.Write16(vaddr, value); } void MemoryWrite32(VAddr vaddr, std::uint32_t value) override { - Memory::Write32(vaddr, value); + memory.Write32(vaddr, value); } void MemoryWrite64(VAddr vaddr, std::uint64_t value) override { - Memory::Write64(vaddr, value); + memory.Write64(vaddr, value); } void InterpreterFallback(VAddr pc, std::size_t num_instructions) override { @@ -159,6 +160,7 @@ public: ARM_Dynarmic& parent; Core::Timing& timing; Kernel::SVCContext svc_context; + Memory::MemorySystem& memory; }; ARM_Dynarmic::ARM_Dynarmic(Core::System& system, PrivilegeMode initial_mode) diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 4854eb23e..adb126b95 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -811,7 +811,7 @@ MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64)); static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr, ARM_INST_PTR& inst_base) { u32 inst_size = 4; - u32 inst = Memory::Read32(phys_addr & 0xFFFFFFFC); + u32 inst = Core::System::GetInstance().Memory().Read32(phys_addr & 0xFFFFFFFC); // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM // instruction diff --git a/src/core/arm/skyeye_common/armstate.cpp b/src/core/arm/skyeye_common/armstate.cpp index a6920c89b..9c29783fc 100644 --- a/src/core/arm/skyeye_common/armstate.cpp +++ b/src/core/arm/skyeye_common/armstate.cpp @@ -191,13 +191,13 @@ static void CheckMemoryBreakpoint(u32 address, GDBStub::BreakpointType type) { u8 ARMul_State::ReadMemory8(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - return Memory::Read8(address); + return Core::System::GetInstance().Memory().Read8(address); } u16 ARMul_State::ReadMemory16(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - u16 data = Memory::Read16(address); + u16 data = Core::System::GetInstance().Memory().Read16(address); if (InBigEndianMode()) data = Common::swap16(data); @@ -208,7 +208,7 @@ u16 ARMul_State::ReadMemory16(u32 address) const { u32 ARMul_State::ReadMemory32(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - u32 data = Memory::Read32(address); + u32 data = Core::System::GetInstance().Memory().Read32(address); if (InBigEndianMode()) data = Common::swap32(data); @@ -219,7 +219,7 @@ u32 ARMul_State::ReadMemory32(u32 address) const { u64 ARMul_State::ReadMemory64(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - u64 data = Memory::Read64(address); + u64 data = Core::System::GetInstance().Memory().Read64(address); if (InBigEndianMode()) data = Common::swap64(data); @@ -230,7 +230,7 @@ u64 ARMul_State::ReadMemory64(u32 address) const { void ARMul_State::WriteMemory8(u32 address, u8 data) { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write); - Memory::Write8(address, data); + Core::System::GetInstance().Memory().Write8(address, data); } void ARMul_State::WriteMemory16(u32 address, u16 data) { @@ -239,7 +239,7 @@ void ARMul_State::WriteMemory16(u32 address, u16 data) { if (InBigEndianMode()) data = Common::swap16(data); - Memory::Write16(address, data); + Core::System::GetInstance().Memory().Write16(address, data); } void ARMul_State::WriteMemory32(u32 address, u32 data) { @@ -248,7 +248,7 @@ void ARMul_State::WriteMemory32(u32 address, u32 data) { if (InBigEndianMode()) data = Common::swap32(data); - Memory::Write32(address, data); + Core::System::GetInstance().Memory().Write32(address, data); } void ARMul_State::WriteMemory64(u32 address, u64 data) { @@ -257,7 +257,7 @@ void ARMul_State::WriteMemory64(u32 address, u64 data) { if (InBigEndianMode()) data = Common::swap64(data); - Memory::Write64(address, data); + Core::System::GetInstance().Memory().Write64(address, data); } // Reads from the CP15 registers. Used with implementation of the MRC instruction. diff --git a/src/core/cheats/gateway_cheat.cpp b/src/core/cheats/gateway_cheat.cpp index 06fb41485..af7e0f8cf 100644 --- a/src/core/cheats/gateway_cheat.cpp +++ b/src/core/cheats/gateway_cheat.cpp @@ -49,9 +49,10 @@ static inline std::enable_if_t> CompOp(const GatewayCheat: } } -static inline void LoadOffsetOp(const GatewayCheat::CheatLine& line, State& state) { +static inline void LoadOffsetOp(Memory::MemorySystem& memory, const GatewayCheat::CheatLine& line, + State& state) { u32 addr = line.address + state.offset; - state.offset = Memory::Read32(addr); + state.offset = memory.Read32(addr); } static inline void LoopOp(const GatewayCheat::CheatLine& line, State& state) { @@ -154,7 +155,7 @@ static inline void PatchOp(const GatewayCheat::CheatLine& line, State& state, Co state.current_line_nr++; } first = !first; - Memory::Write32(addr, tmp); + system.Memory().Write32(addr, tmp); addr += 4; num_bytes -= 4; } @@ -162,7 +163,7 @@ static inline void PatchOp(const GatewayCheat::CheatLine& line, State& state, Co u32 tmp = (first ? cheat_lines[state.current_line_nr].first : cheat_lines[state.current_line_nr].value) >> bit_offset; - Memory::Write8(addr, tmp); + system.Memory().Write8(addr, tmp); addr += 1; num_bytes -= 1; bit_offset += 8; @@ -205,6 +206,14 @@ GatewayCheat::~GatewayCheat() = default; void GatewayCheat::Execute(Core::System& system) { State state; + Memory::MemorySystem& memory = system.Memory(); + auto Read8 = [&memory](VAddr addr) { return memory.Read8(addr); }; + auto Read16 = [&memory](VAddr addr) { return memory.Read16(addr); }; + auto Read32 = [&memory](VAddr addr) { return memory.Read32(addr); }; + auto Write8 = [&memory](VAddr addr, u8 value) { memory.Write8(addr, value); }; + auto Write16 = [&memory](VAddr addr, u16 value) { memory.Write16(addr, value); }; + auto Write32 = [&memory](VAddr addr, u32 value) { memory.Write32(addr, value); }; + for (state.current_line_nr = 0; state.current_line_nr < cheat_lines.size(); state.current_line_nr++) { auto line = cheat_lines[state.current_line_nr]; @@ -247,63 +256,61 @@ void GatewayCheat::Execute(Core::System& system) { break; case CheatType::Write32: // 0XXXXXXX YYYYYYYY - word[XXXXXXX+offset] = YYYYYYYY - WriteOp(line, state, &Memory::Write32, system); + WriteOp(line, state, Write32, system); break; case CheatType::Write16: // 1XXXXXXX 0000YYYY - half[XXXXXXX+offset] = YYYY - WriteOp(line, state, &Memory::Write16, system); + WriteOp(line, state, Write16, system); break; case CheatType::Write8: // 2XXXXXXX 000000YY - byte[XXXXXXX+offset] = YY - WriteOp(line, state, &Memory::Write8, system); + WriteOp(line, state, Write8, system); break; case CheatType::GreaterThan32: // 3XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY > word[XXXXXXX] ;unsigned - CompOp(line, state, &Memory::Read32, - [&line](u32 val) -> bool { return line.value > val; }); + CompOp(line, state, Read32, [&line](u32 val) -> bool { return line.value > val; }); break; case CheatType::LessThan32: // 4XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY < word[XXXXXXX] ;unsigned - CompOp(line, state, &Memory::Read32, - [&line](u32 val) -> bool { return line.value < val; }); + CompOp(line, state, Read32, [&line](u32 val) -> bool { return line.value < val; }); break; case CheatType::EqualTo32: // 5XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY == word[XXXXXXX] ;unsigned - CompOp(line, state, &Memory::Read32, + CompOp(line, state, Read32, [&line](u32 val) -> bool { return line.value == val; }); break; case CheatType::NotEqualTo32: // 6XXXXXXX YYYYYYYY - Execute next block IF YYYYYYYY != word[XXXXXXX] ;unsigned - CompOp(line, state, &Memory::Read32, + CompOp(line, state, Read32, [&line](u32 val) -> bool { return line.value != val; }); break; case CheatType::GreaterThan16WithMask: // 7XXXXXXX ZZZZYYYY - Execute next block IF YYYY > ((not ZZZZ) AND half[XXXXXXX]) - CompOp(line, state, &Memory::Read16, [&line](u16 val) -> bool { + CompOp(line, state, Read16, [&line](u16 val) -> bool { return static_cast(line.value) > (static_cast(~line.value >> 16) & val); }); break; case CheatType::LessThan16WithMask: // 8XXXXXXX ZZZZYYYY - Execute next block IF YYYY < ((not ZZZZ) AND half[XXXXXXX]) - CompOp(line, state, &Memory::Read16, [&line](u16 val) -> bool { + CompOp(line, state, Read16, [&line](u16 val) -> bool { return static_cast(line.value) < (static_cast(~line.value >> 16) & val); }); break; case CheatType::EqualTo16WithMask: // 9XXXXXXX ZZZZYYYY - Execute next block IF YYYY = ((not ZZZZ) AND half[XXXXXXX]) - CompOp(line, state, &Memory::Read16, [&line](u16 val) -> bool { + CompOp(line, state, Read16, [&line](u16 val) -> bool { return static_cast(line.value) == (static_cast(~line.value >> 16) & val); }); break; case CheatType::NotEqualTo16WithMask: // AXXXXXXX ZZZZYYYY - Execute next block IF YYYY <> ((not ZZZZ) AND half[XXXXXXX]) - CompOp(line, state, &Memory::Read16, [&line](u16 val) -> bool { + CompOp(line, state, Read16, [&line](u16 val) -> bool { return static_cast(line.value) != (static_cast(~line.value >> 16) & val); }); break; case CheatType::LoadOffset: // BXXXXXXX 00000000 - offset = word[XXXXXXX+offset] - LoadOffsetOp(line, state); + LoadOffsetOp(system.Memory(), line, state); break; case CheatType::Loop: { // C0000000 YYYYYYYY - LOOP next block YYYYYYYY times @@ -343,32 +350,32 @@ void GatewayCheat::Execute(Core::System& system) { } case CheatType::IncrementiveWrite32: { // D6000000 XXXXXXXX – (32bit) [XXXXXXXX+offset] = reg ; offset += 4 - IncrementiveWriteOp(line, state, &Memory::Write32, system); + IncrementiveWriteOp(line, state, Write32, system); break; } case CheatType::IncrementiveWrite16: { // D7000000 XXXXXXXX – (16bit) [XXXXXXXX+offset] = reg & 0xffff ; offset += 2 - IncrementiveWriteOp(line, state, &Memory::Write16, system); + IncrementiveWriteOp(line, state, Write16, system); break; } case CheatType::IncrementiveWrite8: { // D8000000 XXXXXXXX – (16bit) [XXXXXXXX+offset] = reg & 0xff ; offset++ - IncrementiveWriteOp(line, state, &Memory::Write8, system); + IncrementiveWriteOp(line, state, Write8, system); break; } case CheatType::Load32: { // D9000000 XXXXXXXX – reg = [XXXXXXXX+offset] - LoadOp(line, state, &Memory::Read32); + LoadOp(line, state, Read32); break; } case CheatType::Load16: { // DA000000 XXXXXXXX – reg = [XXXXXXXX+offset] & 0xFFFF - LoadOp(line, state, &Memory::Read16); + LoadOp(line, state, Read16); break; } case CheatType::Load8: { // DB000000 XXXXXXXX – reg = [XXXXXXXX+offset] & 0xFF - LoadOp(line, state, &Memory::Read8); + LoadOp(line, state, Read8); break; } case CheatType::AddOffset: { diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index d391da208..cc5404570 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -65,7 +65,7 @@ SharedPtr AddressArbiter::ResumeHighestPriorityThread(VAddr address) { return thread; } -AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel) {} +AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} AddressArbiter::~AddressArbiter() {} SharedPtr KernelSystem::CreateAddressArbiter(std::string name) { @@ -103,31 +103,31 @@ ResultCode AddressArbiter::ArbitrateAddress(SharedPtr thread, Arbitratio // Wait current thread (acquire the arbiter)... case ArbitrationType::WaitIfLessThan: - if ((s32)Memory::Read32(address) < value) { + if ((s32)kernel.memory.Read32(address) < value) { WaitThread(std::move(thread), address); } break; case ArbitrationType::WaitIfLessThanWithTimeout: - if ((s32)Memory::Read32(address) < value) { + if ((s32)kernel.memory.Read32(address) < value) { thread->wakeup_callback = timeout_callback; thread->WakeAfterDelay(nanoseconds); WaitThread(std::move(thread), address); } break; case ArbitrationType::DecrementAndWaitIfLessThan: { - s32 memory_value = Memory::Read32(address); + s32 memory_value = kernel.memory.Read32(address); if (memory_value < value) { // Only change the memory value if the thread should wait - Memory::Write32(address, (s32)memory_value - 1); + kernel.memory.Write32(address, (s32)memory_value - 1); WaitThread(std::move(thread), address); } break; } case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: { - s32 memory_value = Memory::Read32(address); + s32 memory_value = kernel.memory.Read32(address); if (memory_value < value) { // Only change the memory value if the thread should wait - Memory::Write32(address, (s32)memory_value - 1); + kernel.memory.Write32(address, (s32)memory_value - 1); thread->wakeup_callback = timeout_callback; thread->WakeAfterDelay(nanoseconds); WaitThread(std::move(thread), address); diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index cdfa64ec2..ac01749f7 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -52,6 +52,8 @@ private: explicit AddressArbiter(KernelSystem& kernel); ~AddressArbiter() override; + KernelSystem& kernel; + /// Puts the thread to wait on the specified arbitration address under this address arbiter. void WaitThread(SharedPtr thread, VAddr wait_address); diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 660361720..1e414c397 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -352,7 +352,7 @@ ResultCode SVC::ConnectToPort(Handle* out_handle, VAddr port_name_address) { static constexpr std::size_t PortNameMaxLength = 11; // Read 1 char beyond the max allowed port name to detect names that are too long. - std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); + std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1); if (port_name.size() > PortNameMaxLength) return ERR_PORT_NAME_TOO_LONG; @@ -467,7 +467,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle std::vector objects(handle_count); for (int i = 0; i < handle_count; ++i) { - Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); + Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); auto object = kernel.GetCurrentProcess()->handle_table.Get(handle); if (object == nullptr) return ERR_INVALID_HANDLE; @@ -636,7 +636,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co SharedPtr current_process = kernel.GetCurrentProcess(); for (int i = 0; i < handle_count; ++i) { - Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); + Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); auto object = current_process->handle_table.Get(handle); if (object == nullptr) return ERR_INVALID_HANDLE; @@ -646,7 +646,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co // We are also sending a command reply. // Do not send a reply if the command id in the command buffer is 0xFFFF. Thread* thread = kernel.GetThreadManager().GetCurrentThread(); - u32 cmd_buff_header = Memory::Read32(thread->GetCommandBufferAddress()); + u32 cmd_buff_header = memory.Read32(thread->GetCommandBufferAddress()); IPC::Header header{cmd_buff_header}; if (reply_target != 0 && header.command_id != 0xFFFF) { auto session = current_process->handle_table.Get(reply_target); @@ -832,9 +832,9 @@ ResultCode SVC::GetResourceLimitCurrentValues(VAddr values, Handle resource_limi return ERR_INVALID_HANDLE; for (unsigned int i = 0; i < name_count; ++i) { - u32 name = Memory::Read32(names + i * sizeof(u32)); + u32 name = memory.Read32(names + i * sizeof(u32)); s64 value = resource_limit->GetCurrentResourceValue(name); - Memory::Write64(values + i * sizeof(u64), value); + memory.Write64(values + i * sizeof(u64), value); } return RESULT_SUCCESS; @@ -852,9 +852,9 @@ ResultCode SVC::GetResourceLimitLimitValues(VAddr values, Handle resource_limit_ return ERR_INVALID_HANDLE; for (unsigned int i = 0; i < name_count; ++i) { - u32 name = Memory::Read32(names + i * sizeof(u32)); + u32 name = memory.Read32(names + i * sizeof(u32)); s64 value = resource_limit->GetMaxResourceValue(name); - Memory::Write64(values + i * sizeof(u64), value); + memory.Write64(values + i * sizeof(u64), value); } return RESULT_SUCCESS; diff --git a/src/core/hle/service/ldr_ro/cro_helper.cpp b/src/core/hle/service/ldr_ro/cro_helper.cpp index 19308d08d..3d4a97d9f 100644 --- a/src/core/hle/service/ldr_ro/cro_helper.cpp +++ b/src/core/hle/service/ldr_ro/cro_helper.cpp @@ -71,11 +71,11 @@ ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType reloc break; case RelocationType::AbsoluteAddress: case RelocationType::AbsoluteAddress2: - Memory::Write32(target_address, symbol_address + addend); + memory.Write32(target_address, symbol_address + addend); Core::CPU().InvalidateCacheRange(target_address, sizeof(u32)); break; case RelocationType::RelativeAddress: - Memory::Write32(target_address, symbol_address + addend - target_future_address); + memory.Write32(target_address, symbol_address + addend - target_future_address); Core::CPU().InvalidateCacheRange(target_address, sizeof(u32)); break; case RelocationType::ThumbBranch: @@ -98,7 +98,7 @@ ResultCode CROHelper::ClearRelocation(VAddr target_address, RelocationType reloc case RelocationType::AbsoluteAddress: case RelocationType::AbsoluteAddress2: case RelocationType::RelativeAddress: - Memory::Write32(target_address, 0); + memory.Write32(target_address, 0); Core::CPU().InvalidateCacheRange(target_address, sizeof(u32)); break; case RelocationType::ThumbBranch: @@ -188,7 +188,7 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const { ExportNamedSymbolEntry symbol_entry; GetEntry(found_id, symbol_entry); - if (Memory::ReadCString(symbol_entry.name_offset, export_strings_size) != name) + if (memory.ReadCString(symbol_entry.name_offset, export_strings_size) != name) return 0; return SegmentTagToAddress(symbol_entry.symbol_position); @@ -761,7 +761,7 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) { ResultCode result = ForEachAutoLinkCRO( process, memory, crs_address, [&](CROHelper source) -> ResultVal { std::string symbol_name = - Memory::ReadCString(entry.name_offset, import_strings_size); + memory.ReadCString(entry.name_offset, import_strings_size); u32 symbol_address = source.FindExportNamedSymbol(symbol_name); if (symbol_address != 0) { @@ -858,7 +858,7 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) { for (u32 i = 0; i < import_module_num; ++i) { ImportModuleEntry entry; GetEntry(i, entry); - std::string want_cro_name = Memory::ReadCString(entry.name_offset, import_strings_size); + std::string want_cro_name = memory.ReadCString(entry.name_offset, import_strings_size); ResultCode result = ForEachAutoLinkCRO( process, memory, crs_address, [&](CROHelper source) -> ResultVal { @@ -921,7 +921,7 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { if (!relocation_entry.is_batch_resolved) { std::string symbol_name = - Memory::ReadCString(entry.name_offset, target_import_strings_size); + memory.ReadCString(entry.name_offset, target_import_strings_size); u32 symbol_address = FindExportNamedSymbol(symbol_name); if (symbol_address != 0) { LOG_TRACE(Service_LDR, " exports symbol \"{}\"", symbol_name); @@ -952,7 +952,7 @@ ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) { if (relocation_entry.is_batch_resolved) { std::string symbol_name = - Memory::ReadCString(entry.name_offset, target_import_strings_size); + memory.ReadCString(entry.name_offset, target_import_strings_size); u32 symbol_address = FindExportNamedSymbol(symbol_name); if (symbol_address != 0) { LOG_TRACE(Service_LDR, " unexports symbol \"{}\"", symbol_name); @@ -976,7 +976,7 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) { ImportModuleEntry entry; target.GetEntry(i, entry); - if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) + if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name) continue; LOG_INFO(Service_LDR, "CRO \"{}\" exports {} indexed symbols to \"{}\"", module_name, @@ -1025,7 +1025,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) { ImportModuleEntry entry; target.GetEntry(i, entry); - if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) + if (memory.ReadCString(entry.name_offset, target_import_string_size) != module_name) continue; LOG_DEBUG(Service_LDR, "CRO \"{}\" unexports indexed symbols to \"{}\"", module_name, @@ -1069,7 +1069,7 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) { Memory::ReadBlock(process, relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); - if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") { + if (memory.ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") { ResultCode result = ForEachAutoLinkCRO( process, memory, crs_address, [&](CROHelper source) -> ResultVal { u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_"); @@ -1108,9 +1108,9 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) { * @param size the size of the string (table), including the terminating 0 * @returns ResultCode RESULT_SUCCESS if the size matches, otherwise error code. */ -static ResultCode VerifyStringTableLength(VAddr address, u32 size) { +static ResultCode VerifyStringTableLength(Memory::MemorySystem& memory, VAddr address, u32 size) { if (size != 0) { - if (Memory::Read8(address + size - 1) != 0) + if (memory.Read8(address + size - 1) != 0) return CROFormatError(0x0B); } return RESULT_SUCCESS; @@ -1126,7 +1126,7 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment return result; } - result = VerifyStringTableLength(GetField(ModuleNameOffset), GetField(ModuleNameSize)); + result = VerifyStringTableLength(memory, GetField(ModuleNameOffset), GetField(ModuleNameSize)); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error verifying module name {:08X}", result.raw); return result; @@ -1155,7 +1155,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment return result; } - result = VerifyStringTableLength(GetField(ExportStringsOffset), GetField(ExportStringsSize)); + result = + VerifyStringTableLength(memory, GetField(ExportStringsOffset), GetField(ExportStringsSize)); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error verifying export strings {:08X}", result.raw); return result; @@ -1191,7 +1192,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment return result; } - result = VerifyStringTableLength(GetField(ImportStringsOffset), GetField(ImportStringsSize)); + result = + VerifyStringTableLength(memory, GetField(ImportStringsOffset), GetField(ImportStringsSize)); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error verifying import strings {:08X}", result.raw); return result; diff --git a/src/core/hle/service/ldr_ro/cro_helper.h b/src/core/hle/service/ldr_ro/cro_helper.h index d3a6e3d9a..e868a66c8 100644 --- a/src/core/hle/service/ldr_ro/cro_helper.h +++ b/src/core/hle/service/ldr_ro/cro_helper.h @@ -44,7 +44,7 @@ public: : module_address(cro_address), process(process), memory(memory) {} std::string ModuleName() const { - return Memory::ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize)); + return memory.ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize)); } u32 GetFileSize() const { @@ -408,11 +408,11 @@ private: } u32 GetField(HeaderField field) const { - return Memory::Read32(Field(field)); + return memory.Read32(Field(field)); } void SetField(HeaderField field, u32 value) { - Memory::Write32(Field(field), value); + memory.Write32(Field(field), value); } /** diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 8c260c1f7..cf545ec8e 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -114,7 +114,7 @@ template T ReadMMIO(MMIORegionPointer mmio_handler, VAddr addr); template -T Read(const VAddr vaddr) { +T MemorySystem::Read(const VAddr vaddr) { const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; if (page_pointer) { // NOTE: Avoid adding any extra logic to this fast-path block @@ -152,7 +152,7 @@ template void WriteMMIO(MMIORegionPointer mmio_handler, VAddr addr, const T data); template -void Write(const VAddr vaddr, const T data) { +void MemorySystem::Write(const VAddr vaddr, const T data) { u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; if (page_pointer) { // NOTE: Avoid adding any extra logic to this fast-path block @@ -224,7 +224,7 @@ u8* MemorySystem::GetPointer(const VAddr vaddr) { return nullptr; } -std::string ReadCString(VAddr vaddr, std::size_t max_length) { +std::string MemorySystem::ReadCString(VAddr vaddr, std::size_t max_length) { std::string string; string.reserve(max_length); for (std::size_t i = 0; i < max_length; ++i) { @@ -417,19 +417,19 @@ void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { CheckRegion(VRAM_VADDR, VRAM_VADDR_END, VRAM_PADDR); } -u8 Read8(const VAddr addr) { +u8 MemorySystem::Read8(const VAddr addr) { return Read(addr); } -u16 Read16(const VAddr addr) { +u16 MemorySystem::Read16(const VAddr addr) { return Read(addr); } -u32 Read32(const VAddr addr) { +u32 MemorySystem::Read32(const VAddr addr) { return Read(addr); } -u64 Read64(const VAddr addr) { +u64 MemorySystem::Read64(const VAddr addr) { return Read(addr); } @@ -483,19 +483,19 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_ } } -void Write8(const VAddr addr, const u8 data) { +void MemorySystem::Write8(const VAddr addr, const u8 data) { Write(addr, data); } -void Write16(const VAddr addr, const u16 data) { +void MemorySystem::Write16(const VAddr addr, const u16 data) { Write(addr, data); } -void Write32(const VAddr addr, const u32 data) { +void MemorySystem::Write32(const VAddr addr, const u32 data) { Write(addr, data); } -void Write64(const VAddr addr, const u64 data) { +void MemorySystem::Write64(const VAddr addr, const u64 data) { Write(addr, data); } diff --git a/src/core/memory.h b/src/core/memory.h index ffafc4c1c..f99067705 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -180,16 +180,6 @@ enum : VAddr { extern std::array fcram; -u8 Read8(VAddr addr); -u16 Read16(VAddr addr); -u32 Read32(VAddr addr); -u64 Read64(VAddr addr); - -void Write8(VAddr addr, u8 data); -void Write16(VAddr addr, u16 data); -void Write32(VAddr addr, u32 data); -void Write64(VAddr addr, u64 data); - void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, std::size_t size); void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, std::size_t size); @@ -198,8 +188,6 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, void CopyBlock(const Kernel::Process& src_process, const Kernel::Process& dest_process, VAddr src_addr, VAddr dest_addr, std::size_t size); -std::string ReadCString(VAddr vaddr, std::size_t max_length); - /** * Mark each page touching the region as cached. */ @@ -241,6 +229,18 @@ public: void SetCurrentPageTable(PageTable* page_table); PageTable* GetCurrentPageTable(); + u8 Read8(VAddr addr); + u16 Read16(VAddr addr); + u32 Read32(VAddr addr); + u64 Read64(VAddr addr); + + void Write8(VAddr addr, u8 data); + void Write16(VAddr addr, u16 data); + void Write32(VAddr addr, u32 data); + void Write64(VAddr addr, u64 data); + + std::string ReadCString(VAddr vaddr, std::size_t max_length); + /// Determines if the given VAddr is valid for the specified process. bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); @@ -255,6 +255,13 @@ public: /// Gets offset in FCRAM from a pointer inside FCRAM range u32 GetFCRAMOffset(u8* pointer); + +private: + template + T Read(const VAddr vaddr); + + template + void Write(const VAddr vaddr, const T data); }; } // namespace Memory