mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2024-11-27 12:04:16 +01:00
Memory: move block operations into class
This commit is contained in:
parent
323990d402
commit
2582d64fb3
@ -409,7 +409,8 @@ static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
|
|||||||
|
|
||||||
LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:08x} bytes at {:08x} of type {}",
|
LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:08x} bytes at {:08x} of type {}",
|
||||||
bp->second.len, bp->second.addr, static_cast<int>(type));
|
bp->second.len, bp->second.addr, static_cast<int>(type));
|
||||||
Memory::WriteBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), bp->second.addr,
|
Core::System::GetInstance().Memory().WriteBlock(
|
||||||
|
*Core::System::GetInstance().Kernel().GetCurrentProcess(), bp->second.addr,
|
||||||
bp->second.inst.data(), bp->second.inst.size());
|
bp->second.inst.data(), bp->second.inst.size());
|
||||||
Core::CPU().ClearInstructionCache();
|
Core::CPU().ClearInstructionCache();
|
||||||
p.erase(addr);
|
p.erase(addr);
|
||||||
@ -837,8 +838,8 @@ static void ReadMemory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> data(len);
|
std::vector<u8> data(len);
|
||||||
Memory::ReadBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, data.data(),
|
Core::System::GetInstance().Memory().ReadBlock(
|
||||||
len);
|
*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, data.data(), len);
|
||||||
|
|
||||||
MemToGdbHex(reply, data.data(), len);
|
MemToGdbHex(reply, data.data(), len);
|
||||||
reply[len * 2] = '\0';
|
reply[len * 2] = '\0';
|
||||||
@ -863,8 +864,8 @@ static void WriteMemory() {
|
|||||||
std::vector<u8> data(len);
|
std::vector<u8> data(len);
|
||||||
|
|
||||||
GdbHexToMem(data.data(), len_pos + 1, len);
|
GdbHexToMem(data.data(), len_pos + 1, len);
|
||||||
Memory::WriteBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, data.data(),
|
Core::System::GetInstance().Memory().WriteBlock(
|
||||||
len);
|
*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, data.data(), len);
|
||||||
Core::CPU().ClearInstructionCache();
|
Core::CPU().ClearInstructionCache();
|
||||||
SendReply("OK");
|
SendReply("OK");
|
||||||
}
|
}
|
||||||
@ -917,11 +918,13 @@ static bool CommitBreakpoint(BreakpointType type, VAddr addr, u32 len) {
|
|||||||
breakpoint.active = true;
|
breakpoint.active = true;
|
||||||
breakpoint.addr = addr;
|
breakpoint.addr = addr;
|
||||||
breakpoint.len = len;
|
breakpoint.len = len;
|
||||||
Memory::ReadBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr,
|
Core::System::GetInstance().Memory().ReadBlock(
|
||||||
breakpoint.inst.data(), breakpoint.inst.size());
|
*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, breakpoint.inst.data(),
|
||||||
|
breakpoint.inst.size());
|
||||||
static constexpr std::array<u8, 4> btrap{0x70, 0x00, 0x20, 0xe1};
|
static constexpr std::array<u8, 4> btrap{0x70, 0x00, 0x20, 0xe1};
|
||||||
Memory::WriteBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr,
|
Core::System::GetInstance().Memory().WriteBlock(
|
||||||
btrap.data(), btrap.size());
|
*Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, btrap.data(),
|
||||||
|
btrap.size());
|
||||||
Core::CPU().ClearInstructionCache();
|
Core::CPU().ClearInstructionCache();
|
||||||
p.insert({addr, breakpoint});
|
p.insert({addr, breakpoint});
|
||||||
|
|
||||||
|
@ -48,11 +48,12 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
|
|||||||
// the translation might need to read from it in order to retrieve the StaticBuffer
|
// the translation might need to read from it in order to retrieve the StaticBuffer
|
||||||
// target addresses.
|
// target addresses.
|
||||||
std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2 * IPC::MAX_STATIC_BUFFERS> cmd_buff;
|
std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2 * IPC::MAX_STATIC_BUFFERS> cmd_buff;
|
||||||
Memory::ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
Memory::MemorySystem& memory = Core::System::GetInstance().Memory();
|
||||||
|
memory.ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
||||||
cmd_buff.size() * sizeof(u32));
|
cmd_buff.size() * sizeof(u32));
|
||||||
context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process);
|
context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process);
|
||||||
// Copy the translated command buffer back into the thread's command buffer area.
|
// Copy the translated command buffer back into the thread's command buffer area.
|
||||||
Memory::WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
memory.WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
||||||
cmd_buff.size() * sizeof(u32));
|
cmd_buff.size() * sizeof(u32));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -142,7 +143,8 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
|
|||||||
|
|
||||||
// Copy the input buffer into our own vector and store it.
|
// Copy the input buffer into our own vector and store it.
|
||||||
std::vector<u8> data(buffer_info.size);
|
std::vector<u8> data(buffer_info.size);
|
||||||
Memory::ReadBlock(src_process, source_address, data.data(), data.size());
|
Core::System::GetInstance().Memory().ReadBlock(src_process, source_address, data.data(),
|
||||||
|
data.size());
|
||||||
|
|
||||||
AddStaticBuffer(buffer_info.buffer_id, std::move(data));
|
AddStaticBuffer(buffer_info.buffer_id, std::move(data));
|
||||||
cmd_buf[i++] = source_address;
|
cmd_buf[i++] = source_address;
|
||||||
@ -209,7 +211,8 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf,
|
|||||||
|
|
||||||
ASSERT_MSG(target_descriptor.size >= data.size(), "Static buffer data is too big");
|
ASSERT_MSG(target_descriptor.size >= data.size(), "Static buffer data is too big");
|
||||||
|
|
||||||
Memory::WriteBlock(dst_process, target_address, data.data(), data.size());
|
Core::System::GetInstance().Memory().WriteBlock(dst_process, target_address,
|
||||||
|
data.data(), data.size());
|
||||||
|
|
||||||
dst_cmdbuf[i++] = target_address;
|
dst_cmdbuf[i++] = target_address;
|
||||||
break;
|
break;
|
||||||
@ -242,13 +245,15 @@ MappedBuffer::MappedBuffer(const Process& process, u32 descriptor, VAddr address
|
|||||||
void MappedBuffer::Read(void* dest_buffer, std::size_t offset, std::size_t size) {
|
void MappedBuffer::Read(void* dest_buffer, std::size_t offset, std::size_t size) {
|
||||||
ASSERT(perms & IPC::R);
|
ASSERT(perms & IPC::R);
|
||||||
ASSERT(offset + size <= this->size);
|
ASSERT(offset + size <= this->size);
|
||||||
Memory::ReadBlock(*process, address + static_cast<VAddr>(offset), dest_buffer, size);
|
Core::System::GetInstance().Memory().ReadBlock(*process, address + static_cast<VAddr>(offset),
|
||||||
|
dest_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t size) {
|
void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t size) {
|
||||||
ASSERT(perms & IPC::W);
|
ASSERT(perms & IPC::W);
|
||||||
ASSERT(offset + size <= this->size);
|
ASSERT(offset + size <= this->size);
|
||||||
Memory::WriteBlock(*process, address + static_cast<VAddr>(offset), src_buffer, size);
|
Core::System::GetInstance().Memory().WriteBlock(*process, address + static_cast<VAddr>(offset),
|
||||||
|
src_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/ipc.h"
|
#include "core/hle/ipc.h"
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/ipc.h"
|
#include "core/hle/kernel/ipc.h"
|
||||||
@ -19,13 +20,13 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
|||||||
VAddr src_address, VAddr dst_address,
|
VAddr src_address, VAddr dst_address,
|
||||||
std::vector<MappedBufferContext>& mapped_buffer_context,
|
std::vector<MappedBufferContext>& mapped_buffer_context,
|
||||||
bool reply) {
|
bool reply) {
|
||||||
|
Memory::MemorySystem& memory = Core::System::GetInstance().Memory();
|
||||||
auto& src_process = src_thread->owner_process;
|
auto& src_process = src_thread->owner_process;
|
||||||
auto& dst_process = dst_thread->owner_process;
|
auto& dst_process = dst_thread->owner_process;
|
||||||
|
|
||||||
IPC::Header header;
|
IPC::Header header;
|
||||||
// TODO(Subv): Replace by Memory::Read32 when possible.
|
// TODO(Subv): Replace by Memory::Read32 when possible.
|
||||||
Memory::ReadBlock(*src_process, src_address, &header.raw, sizeof(header.raw));
|
memory.ReadBlock(*src_process, src_address, &header.raw, sizeof(header.raw));
|
||||||
|
|
||||||
std::size_t untranslated_size = 1u + header.normal_params_size;
|
std::size_t untranslated_size = 1u + header.normal_params_size;
|
||||||
std::size_t command_size = untranslated_size + header.translate_params_size;
|
std::size_t command_size = untranslated_size + header.translate_params_size;
|
||||||
@ -34,7 +35,7 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
|||||||
ASSERT(command_size <= IPC::COMMAND_BUFFER_LENGTH);
|
ASSERT(command_size <= IPC::COMMAND_BUFFER_LENGTH);
|
||||||
|
|
||||||
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
||||||
Memory::ReadBlock(*src_process, src_address, cmd_buf.data(), command_size * sizeof(u32));
|
memory.ReadBlock(*src_process, src_address, cmd_buf.data(), command_size * sizeof(u32));
|
||||||
|
|
||||||
std::size_t i = untranslated_size;
|
std::size_t i = untranslated_size;
|
||||||
while (i < command_size) {
|
while (i < command_size) {
|
||||||
@ -90,7 +91,7 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
|||||||
VAddr static_buffer_src_address = cmd_buf[i];
|
VAddr static_buffer_src_address = cmd_buf[i];
|
||||||
|
|
||||||
std::vector<u8> data(bufferInfo.size);
|
std::vector<u8> data(bufferInfo.size);
|
||||||
Memory::ReadBlock(*src_process, static_buffer_src_address, data.data(), data.size());
|
memory.ReadBlock(*src_process, static_buffer_src_address, data.data(), data.size());
|
||||||
|
|
||||||
// Grab the address that the target thread set up to receive the response static buffer
|
// Grab the address that the target thread set up to receive the response static buffer
|
||||||
// and write our data there. The static buffers area is located right after the command
|
// and write our data there. The static buffers area is located right after the command
|
||||||
@ -106,7 +107,7 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
|||||||
|
|
||||||
u32 static_buffer_offset = IPC::COMMAND_BUFFER_LENGTH * sizeof(u32) +
|
u32 static_buffer_offset = IPC::COMMAND_BUFFER_LENGTH * sizeof(u32) +
|
||||||
sizeof(StaticBuffer) * bufferInfo.buffer_id;
|
sizeof(StaticBuffer) * bufferInfo.buffer_id;
|
||||||
Memory::ReadBlock(*dst_process, dst_address + static_buffer_offset, &target_buffer,
|
memory.ReadBlock(*dst_process, dst_address + static_buffer_offset, &target_buffer,
|
||||||
sizeof(target_buffer));
|
sizeof(target_buffer));
|
||||||
|
|
||||||
// Note: The real kernel doesn't seem to have any error recovery mechanisms for this
|
// Note: The real kernel doesn't seem to have any error recovery mechanisms for this
|
||||||
@ -114,7 +115,7 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
|||||||
ASSERT_MSG(target_buffer.descriptor.size >= data.size(),
|
ASSERT_MSG(target_buffer.descriptor.size >= data.size(),
|
||||||
"Static buffer data is too big");
|
"Static buffer data is too big");
|
||||||
|
|
||||||
Memory::WriteBlock(*dst_process, target_buffer.address, data.data(), data.size());
|
memory.WriteBlock(*dst_process, target_buffer.address, data.data(), data.size());
|
||||||
|
|
||||||
cmd_buf[i++] = target_buffer.address;
|
cmd_buf[i++] = target_buffer.address;
|
||||||
break;
|
break;
|
||||||
@ -153,7 +154,7 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
|||||||
|
|
||||||
if (permissions != IPC::MappedBufferPermissions::R) {
|
if (permissions != IPC::MappedBufferPermissions::R) {
|
||||||
// Copy the modified buffer back into the target process
|
// Copy the modified buffer back into the target process
|
||||||
Memory::CopyBlock(*src_process, *dst_process, found->target_address,
|
memory.CopyBlock(*src_process, *dst_process, found->target_address,
|
||||||
found->source_address, size);
|
found->source_address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
|||||||
Memory::PAGE_SIZE, Kernel::MemoryState::Reserved);
|
Memory::PAGE_SIZE, Kernel::MemoryState::Reserved);
|
||||||
|
|
||||||
auto buffer = std::make_unique<u8[]>(num_pages * Memory::PAGE_SIZE);
|
auto buffer = std::make_unique<u8[]>(num_pages * Memory::PAGE_SIZE);
|
||||||
Memory::ReadBlock(*src_process, source_address, buffer.get() + page_offset, size);
|
memory.ReadBlock(*src_process, source_address, buffer.get() + page_offset, size);
|
||||||
|
|
||||||
// Map the page(s) into the target process' address space.
|
// Map the page(s) into the target process' address space.
|
||||||
target_address =
|
target_address =
|
||||||
@ -215,7 +216,7 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory::WriteBlock(*dst_process, dst_address, cmd_buf.data(), command_size * sizeof(u32));
|
memory.WriteBlock(*dst_process, dst_address, cmd_buf.data(), command_size * sizeof(u32));
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) {
|
|||||||
auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
|
auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
|
||||||
MemoryState memory_state) {
|
MemoryState memory_state) {
|
||||||
HeapAllocate(segment.addr, segment.size, permissions, memory_state, true);
|
HeapAllocate(segment.addr, segment.size, permissions, memory_state, true);
|
||||||
Memory::WriteBlock(*this, segment.addr, codeset->memory->data() + segment.offset,
|
kernel.memory.WriteBlock(*this, segment.addr, codeset->memory->data() + segment.offset,
|
||||||
segment.size);
|
segment.size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -802,7 +802,7 @@ void SVC::OutputDebugString(VAddr address, s32 len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string string(len, ' ');
|
std::string string(len, ' ');
|
||||||
Memory::ReadBlock(*kernel.GetCurrentProcess(), address, string.data(), len);
|
memory.ReadBlock(*kernel.GetCurrentProcess(), address, string.data(), len);
|
||||||
LOG_DEBUG(Debug_Emulated, "{}", string);
|
LOG_DEBUG(Debug_Emulated, "{}", string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ ResultVal<SharedPtr<Thread>> KernelSystem::CreateThread(std::string name, VAddr
|
|||||||
thread->tls_address = Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE +
|
thread->tls_address = Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE +
|
||||||
available_slot * Memory::TLS_ENTRY_SIZE;
|
available_slot * Memory::TLS_ENTRY_SIZE;
|
||||||
|
|
||||||
Memory::ZeroBlock(owner_process, thread->tls_address, Memory::TLS_ENTRY_SIZE);
|
memory.ZeroBlock(owner_process, thread->tls_address, Memory::TLS_ENTRY_SIZE);
|
||||||
|
|
||||||
// TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used
|
// TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used
|
||||||
// to initialize the context
|
// to initialize the context
|
||||||
|
@ -113,7 +113,7 @@ void Module::CompletionEventCallBack(u64 port_id, s64) {
|
|||||||
if (copy_length <= 0) {
|
if (copy_length <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Memory::WriteBlock(*port.dest_process, dest_ptr, src_ptr, copy_length);
|
system.Memory().WriteBlock(*port.dest_process, dest_ptr, src_ptr, copy_length);
|
||||||
dest_ptr += copy_length;
|
dest_ptr += copy_length;
|
||||||
dest_size_left -= copy_length;
|
dest_size_left -= copy_length;
|
||||||
src_ptr += original_width;
|
src_ptr += original_width;
|
||||||
@ -125,7 +125,7 @@ void Module::CompletionEventCallBack(u64 port_id, s64) {
|
|||||||
LOG_ERROR(Service_CAM, "The destination size ({}) doesn't match the source ({})!",
|
LOG_ERROR(Service_CAM, "The destination size ({}) doesn't match the source ({})!",
|
||||||
port.dest_size, buffer_size);
|
port.dest_size, buffer_size);
|
||||||
}
|
}
|
||||||
Memory::WriteBlock(*port.dest_process, port.dest, buffer.data(),
|
system.Memory().WriteBlock(*port.dest_process, port.dest, buffer.data(),
|
||||||
std::min<std::size_t>(port.dest_size, buffer_size));
|
std::min<std::size_t>(port.dest_size, buffer_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,6 +491,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
|
|||||||
// GX request DMA - typically used for copying memory from GSP heap to VRAM
|
// GX request DMA - typically used for copying memory from GSP heap to VRAM
|
||||||
case CommandId::REQUEST_DMA: {
|
case CommandId::REQUEST_DMA: {
|
||||||
MICROPROFILE_SCOPE(GPU_GSP_DMA);
|
MICROPROFILE_SCOPE(GPU_GSP_DMA);
|
||||||
|
Memory::MemorySystem& memory = Core::System::GetInstance().Memory();
|
||||||
|
|
||||||
// TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever
|
// TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever
|
||||||
// possible/likely
|
// possible/likely
|
||||||
@ -502,7 +503,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
|
|||||||
|
|
||||||
// TODO(Subv): These memory accesses should not go through the application's memory mapping.
|
// TODO(Subv): These memory accesses should not go through the application's memory mapping.
|
||||||
// They should go through the GSP module's memory mapping.
|
// They should go through the GSP module's memory mapping.
|
||||||
Memory::CopyBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(),
|
memory.CopyBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(),
|
||||||
command.dma_request.dest_address, command.dma_request.source_address,
|
command.dma_request.dest_address, command.dma_request.source_address,
|
||||||
command.dma_request.size);
|
command.dma_request.size);
|
||||||
SignalInterrupt(InterruptId::DMA);
|
SignalInterrupt(InterruptId::DMA);
|
||||||
|
@ -55,7 +55,7 @@ VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SegmentEntry entry;
|
SegmentEntry entry;
|
||||||
GetEntry(segment_tag.segment_index, entry);
|
GetEntry(memory, segment_tag.segment_index, entry);
|
||||||
|
|
||||||
if (segment_tag.offset_into_segment >= entry.size)
|
if (segment_tag.offset_into_segment >= entry.size)
|
||||||
return 0;
|
return 0;
|
||||||
@ -121,7 +121,7 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
|
|||||||
VAddr relocation_address = batch;
|
VAddr relocation_address = batch;
|
||||||
while (true) {
|
while (true) {
|
||||||
RelocationEntry relocation;
|
RelocationEntry relocation;
|
||||||
Memory::ReadBlock(process, relocation_address, &relocation, sizeof(RelocationEntry));
|
memory.ReadBlock(process, relocation_address, &relocation, sizeof(RelocationEntry));
|
||||||
|
|
||||||
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
||||||
if (relocation_target == 0) {
|
if (relocation_target == 0) {
|
||||||
@ -142,9 +142,9 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
RelocationEntry relocation;
|
RelocationEntry relocation;
|
||||||
Memory::ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
memory.ReadBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
||||||
relocation.is_batch_resolved = reset ? 0 : 1;
|
relocation.is_batch_resolved = reset ? 0 : 1;
|
||||||
Memory::WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
memory.WriteBlock(process, batch, &relocation, sizeof(RelocationEntry));
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,13 +154,13 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
|
|||||||
|
|
||||||
std::size_t len = name.size();
|
std::size_t len = name.size();
|
||||||
ExportTreeEntry entry;
|
ExportTreeEntry entry;
|
||||||
GetEntry(0, entry);
|
GetEntry(memory, 0, entry);
|
||||||
ExportTreeEntry::Child next;
|
ExportTreeEntry::Child next;
|
||||||
next.raw = entry.left.raw;
|
next.raw = entry.left.raw;
|
||||||
u32 found_id;
|
u32 found_id;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
GetEntry(next.next_index, entry);
|
GetEntry(memory, next.next_index, entry);
|
||||||
|
|
||||||
if (next.is_end) {
|
if (next.is_end) {
|
||||||
found_id = entry.export_table_index;
|
found_id = entry.export_table_index;
|
||||||
@ -186,7 +186,7 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
|
|||||||
|
|
||||||
u32 export_strings_size = GetField(ExportStringsSize);
|
u32 export_strings_size = GetField(ExportStringsSize);
|
||||||
ExportNamedSymbolEntry symbol_entry;
|
ExportNamedSymbolEntry symbol_entry;
|
||||||
GetEntry(found_id, symbol_entry);
|
GetEntry(memory, 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 0;
|
||||||
@ -279,7 +279,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
|
|||||||
u32 segment_num = GetField(SegmentNum);
|
u32 segment_num = GetField(SegmentNum);
|
||||||
for (u32 i = 0; i < segment_num; ++i) {
|
for (u32 i = 0; i < segment_num; ++i) {
|
||||||
SegmentEntry segment;
|
SegmentEntry segment;
|
||||||
GetEntry(i, segment);
|
GetEntry(memory, i, segment);
|
||||||
if (segment.type == SegmentType::Data) {
|
if (segment.type == SegmentType::Data) {
|
||||||
if (segment.size != 0) {
|
if (segment.size != 0) {
|
||||||
if (segment.size > data_segment_size)
|
if (segment.size > data_segment_size)
|
||||||
@ -298,7 +298,7 @@ ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_
|
|||||||
if (segment.offset > module_address + cro_size)
|
if (segment.offset > module_address + cro_size)
|
||||||
return CROFormatError(0x19);
|
return CROFormatError(0x19);
|
||||||
}
|
}
|
||||||
SetEntry(i, segment);
|
SetEntry(memory, i, segment);
|
||||||
}
|
}
|
||||||
return MakeResult<u32>(prev_data_segment + module_address);
|
return MakeResult<u32>(prev_data_segment + module_address);
|
||||||
}
|
}
|
||||||
@ -310,7 +310,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
|
|||||||
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
|
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
|
||||||
for (u32 i = 0; i < export_named_symbol_num; ++i) {
|
for (u32 i = 0; i < export_named_symbol_num; ++i) {
|
||||||
ExportNamedSymbolEntry entry;
|
ExportNamedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.name_offset != 0) {
|
if (entry.name_offset != 0) {
|
||||||
entry.name_offset += module_address;
|
entry.name_offset += module_address;
|
||||||
@ -320,7 +320,7 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -329,7 +329,7 @@ ResultCode CROHelper::VerifyExportTreeTable() const {
|
|||||||
u32 tree_num = GetField(ExportTreeNum);
|
u32 tree_num = GetField(ExportTreeNum);
|
||||||
for (u32 i = 0; i < tree_num; ++i) {
|
for (u32 i = 0; i < tree_num; ++i) {
|
||||||
ExportTreeEntry entry;
|
ExportTreeEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.left.next_index >= tree_num || entry.right.next_index >= tree_num) {
|
if (entry.left.next_index >= tree_num || entry.right.next_index >= tree_num) {
|
||||||
return CROFormatError(0x11);
|
return CROFormatError(0x11);
|
||||||
@ -353,7 +353,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
|
|||||||
u32 module_num = GetField(ImportModuleNum);
|
u32 module_num = GetField(ImportModuleNum);
|
||||||
for (u32 i = 0; i < module_num; ++i) {
|
for (u32 i = 0; i < module_num; ++i) {
|
||||||
ImportModuleEntry entry;
|
ImportModuleEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.name_offset != 0) {
|
if (entry.name_offset != 0) {
|
||||||
entry.name_offset += module_address;
|
entry.name_offset += module_address;
|
||||||
@ -379,7 +379,7 @@ ResultCode CROHelper::RebaseImportModuleTable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -395,7 +395,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
|
|||||||
u32 num = GetField(ImportNamedSymbolNum);
|
u32 num = GetField(ImportNamedSymbolNum);
|
||||||
for (u32 i = 0; i < num; ++i) {
|
for (u32 i = 0; i < num; ++i) {
|
||||||
ImportNamedSymbolEntry entry;
|
ImportNamedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.name_offset != 0) {
|
if (entry.name_offset != 0) {
|
||||||
entry.name_offset += module_address;
|
entry.name_offset += module_address;
|
||||||
@ -413,7 +413,7 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -427,7 +427,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
|
|||||||
u32 num = GetField(ImportIndexedSymbolNum);
|
u32 num = GetField(ImportIndexedSymbolNum);
|
||||||
for (u32 i = 0; i < num; ++i) {
|
for (u32 i = 0; i < num; ++i) {
|
||||||
ImportIndexedSymbolEntry entry;
|
ImportIndexedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.relocation_batch_offset != 0) {
|
if (entry.relocation_batch_offset != 0) {
|
||||||
entry.relocation_batch_offset += module_address;
|
entry.relocation_batch_offset += module_address;
|
||||||
@ -437,7 +437,7 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -451,7 +451,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
|
|||||||
u32 num = GetField(ImportAnonymousSymbolNum);
|
u32 num = GetField(ImportAnonymousSymbolNum);
|
||||||
for (u32 i = 0; i < num; ++i) {
|
for (u32 i = 0; i < num; ++i) {
|
||||||
ImportAnonymousSymbolEntry entry;
|
ImportAnonymousSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.relocation_batch_offset != 0) {
|
if (entry.relocation_batch_offset != 0) {
|
||||||
entry.relocation_batch_offset += module_address;
|
entry.relocation_batch_offset += module_address;
|
||||||
@ -461,7 +461,7 @@ ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -476,14 +476,14 @@ ResultCode CROHelper::ResetExternalRelocations() {
|
|||||||
ExternalRelocationEntry relocation;
|
ExternalRelocationEntry relocation;
|
||||||
|
|
||||||
// Verifies that the last relocation is the end of a batch
|
// Verifies that the last relocation is the end of a batch
|
||||||
GetEntry(external_relocation_num - 1, relocation);
|
GetEntry(memory, external_relocation_num - 1, relocation);
|
||||||
if (!relocation.is_batch_end) {
|
if (!relocation.is_batch_end) {
|
||||||
return CROFormatError(0x12);
|
return CROFormatError(0x12);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool batch_begin = true;
|
bool batch_begin = true;
|
||||||
for (u32 i = 0; i < external_relocation_num; ++i) {
|
for (u32 i = 0; i < external_relocation_num; ++i) {
|
||||||
GetEntry(i, relocation);
|
GetEntry(memory, i, relocation);
|
||||||
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
||||||
|
|
||||||
if (relocation_target == 0) {
|
if (relocation_target == 0) {
|
||||||
@ -500,7 +500,7 @@ ResultCode CROHelper::ResetExternalRelocations() {
|
|||||||
if (batch_begin) {
|
if (batch_begin) {
|
||||||
// resets to unresolved state
|
// resets to unresolved state
|
||||||
relocation.is_batch_resolved = 0;
|
relocation.is_batch_resolved = 0;
|
||||||
SetEntry(i, relocation);
|
SetEntry(memory, i, relocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if current is an end, then the next is a beginning
|
// if current is an end, then the next is a beginning
|
||||||
@ -516,7 +516,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
|
|||||||
|
|
||||||
bool batch_begin = true;
|
bool batch_begin = true;
|
||||||
for (u32 i = 0; i < external_relocation_num; ++i) {
|
for (u32 i = 0; i < external_relocation_num; ++i) {
|
||||||
GetEntry(i, relocation);
|
GetEntry(memory, i, relocation);
|
||||||
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
VAddr relocation_target = SegmentTagToAddress(relocation.target_position);
|
||||||
|
|
||||||
if (relocation_target == 0) {
|
if (relocation_target == 0) {
|
||||||
@ -532,7 +532,7 @@ ResultCode CROHelper::ClearExternalRelocations() {
|
|||||||
if (batch_begin) {
|
if (batch_begin) {
|
||||||
// resets to unresolved state
|
// resets to unresolved state
|
||||||
relocation.is_batch_resolved = 0;
|
relocation.is_batch_resolved = 0;
|
||||||
SetEntry(i, relocation);
|
SetEntry(memory, i, relocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if current is an end, then the next is a beginning
|
// if current is an end, then the next is a beginning
|
||||||
@ -554,7 +554,7 @@ ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) {
|
|||||||
offset_export_num);
|
offset_export_num);
|
||||||
for (u32 i = 0; i < offset_export_num; ++i) {
|
for (u32 i = 0; i < offset_export_num; ++i) {
|
||||||
StaticAnonymousSymbolEntry entry;
|
StaticAnonymousSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
u32 batch_address = entry.relocation_batch_offset + module_address;
|
u32 batch_address = entry.relocation_batch_offset + module_address;
|
||||||
|
|
||||||
if (batch_address < static_relocation_table_offset ||
|
if (batch_address < static_relocation_table_offset ||
|
||||||
@ -579,7 +579,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
|
|||||||
u32 internal_relocation_num = GetField(InternalRelocationNum);
|
u32 internal_relocation_num = GetField(InternalRelocationNum);
|
||||||
for (u32 i = 0; i < internal_relocation_num; ++i) {
|
for (u32 i = 0; i < internal_relocation_num; ++i) {
|
||||||
InternalRelocationEntry relocation;
|
InternalRelocationEntry relocation;
|
||||||
GetEntry(i, relocation);
|
GetEntry(memory, i, relocation);
|
||||||
VAddr target_addressB = SegmentTagToAddress(relocation.target_position);
|
VAddr target_addressB = SegmentTagToAddress(relocation.target_position);
|
||||||
if (target_addressB == 0) {
|
if (target_addressB == 0) {
|
||||||
return CROFormatError(0x15);
|
return CROFormatError(0x15);
|
||||||
@ -587,7 +587,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
|
|||||||
|
|
||||||
VAddr target_address;
|
VAddr target_address;
|
||||||
SegmentEntry target_segment;
|
SegmentEntry target_segment;
|
||||||
GetEntry(relocation.target_position.segment_index, target_segment);
|
GetEntry(memory, relocation.target_position.segment_index, target_segment);
|
||||||
|
|
||||||
if (target_segment.type == SegmentType::Data) {
|
if (target_segment.type == SegmentType::Data) {
|
||||||
// If the relocation is to the .data segment, we need to relocate it in the old buffer
|
// If the relocation is to the .data segment, we need to relocate it in the old buffer
|
||||||
@ -602,7 +602,7 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SegmentEntry symbol_segment;
|
SegmentEntry symbol_segment;
|
||||||
GetEntry(relocation.symbol_segment, symbol_segment);
|
GetEntry(memory, relocation.symbol_segment, symbol_segment);
|
||||||
LOG_TRACE(Service_LDR, "Internally relocates 0x{:08X} with 0x{:08X}", target_address,
|
LOG_TRACE(Service_LDR, "Internally relocates 0x{:08X} with 0x{:08X}", target_address,
|
||||||
symbol_segment.offset);
|
symbol_segment.offset);
|
||||||
ResultCode result = ApplyRelocation(target_address, relocation.type, relocation.addend,
|
ResultCode result = ApplyRelocation(target_address, relocation.type, relocation.addend,
|
||||||
@ -619,7 +619,7 @@ ResultCode CROHelper::ClearInternalRelocations() {
|
|||||||
u32 internal_relocation_num = GetField(InternalRelocationNum);
|
u32 internal_relocation_num = GetField(InternalRelocationNum);
|
||||||
for (u32 i = 0; i < internal_relocation_num; ++i) {
|
for (u32 i = 0; i < internal_relocation_num; ++i) {
|
||||||
InternalRelocationEntry relocation;
|
InternalRelocationEntry relocation;
|
||||||
GetEntry(i, relocation);
|
GetEntry(memory, i, relocation);
|
||||||
VAddr target_address = SegmentTagToAddress(relocation.target_position);
|
VAddr target_address = SegmentTagToAddress(relocation.target_position);
|
||||||
|
|
||||||
if (target_address == 0) {
|
if (target_address == 0) {
|
||||||
@ -639,13 +639,13 @@ void CROHelper::UnrebaseImportAnonymousSymbolTable() {
|
|||||||
u32 num = GetField(ImportAnonymousSymbolNum);
|
u32 num = GetField(ImportAnonymousSymbolNum);
|
||||||
for (u32 i = 0; i < num; ++i) {
|
for (u32 i = 0; i < num; ++i) {
|
||||||
ImportAnonymousSymbolEntry entry;
|
ImportAnonymousSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.relocation_batch_offset != 0) {
|
if (entry.relocation_batch_offset != 0) {
|
||||||
entry.relocation_batch_offset -= module_address;
|
entry.relocation_batch_offset -= module_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,13 +653,13 @@ void CROHelper::UnrebaseImportIndexedSymbolTable() {
|
|||||||
u32 num = GetField(ImportIndexedSymbolNum);
|
u32 num = GetField(ImportIndexedSymbolNum);
|
||||||
for (u32 i = 0; i < num; ++i) {
|
for (u32 i = 0; i < num; ++i) {
|
||||||
ImportIndexedSymbolEntry entry;
|
ImportIndexedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.relocation_batch_offset != 0) {
|
if (entry.relocation_batch_offset != 0) {
|
||||||
entry.relocation_batch_offset -= module_address;
|
entry.relocation_batch_offset -= module_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,7 +667,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
|
|||||||
u32 num = GetField(ImportNamedSymbolNum);
|
u32 num = GetField(ImportNamedSymbolNum);
|
||||||
for (u32 i = 0; i < num; ++i) {
|
for (u32 i = 0; i < num; ++i) {
|
||||||
ImportNamedSymbolEntry entry;
|
ImportNamedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.name_offset != 0) {
|
if (entry.name_offset != 0) {
|
||||||
entry.name_offset -= module_address;
|
entry.name_offset -= module_address;
|
||||||
@ -677,7 +677,7 @@ void CROHelper::UnrebaseImportNamedSymbolTable() {
|
|||||||
entry.relocation_batch_offset -= module_address;
|
entry.relocation_batch_offset -= module_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,7 +685,7 @@ void CROHelper::UnrebaseImportModuleTable() {
|
|||||||
u32 module_num = GetField(ImportModuleNum);
|
u32 module_num = GetField(ImportModuleNum);
|
||||||
for (u32 i = 0; i < module_num; ++i) {
|
for (u32 i = 0; i < module_num; ++i) {
|
||||||
ImportModuleEntry entry;
|
ImportModuleEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.name_offset != 0) {
|
if (entry.name_offset != 0) {
|
||||||
entry.name_offset -= module_address;
|
entry.name_offset -= module_address;
|
||||||
@ -699,7 +699,7 @@ void CROHelper::UnrebaseImportModuleTable() {
|
|||||||
entry.import_anonymous_symbol_table_offset -= module_address;
|
entry.import_anonymous_symbol_table_offset -= module_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,13 +707,13 @@ void CROHelper::UnrebaseExportNamedSymbolTable() {
|
|||||||
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
|
u32 export_named_symbol_num = GetField(ExportNamedSymbolNum);
|
||||||
for (u32 i = 0; i < export_named_symbol_num; ++i) {
|
for (u32 i = 0; i < export_named_symbol_num; ++i) {
|
||||||
ExportNamedSymbolEntry entry;
|
ExportNamedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
|
|
||||||
if (entry.name_offset != 0) {
|
if (entry.name_offset != 0) {
|
||||||
entry.name_offset -= module_address;
|
entry.name_offset -= module_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, entry);
|
SetEntry(memory, i, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,7 +721,7 @@ void CROHelper::UnrebaseSegmentTable() {
|
|||||||
u32 segment_num = GetField(SegmentNum);
|
u32 segment_num = GetField(SegmentNum);
|
||||||
for (u32 i = 0; i < segment_num; ++i) {
|
for (u32 i = 0; i < segment_num; ++i) {
|
||||||
SegmentEntry segment;
|
SegmentEntry segment;
|
||||||
GetEntry(i, segment);
|
GetEntry(memory, i, segment);
|
||||||
|
|
||||||
if (segment.type == SegmentType::BSS) {
|
if (segment.type == SegmentType::BSS) {
|
||||||
segment.offset = 0;
|
segment.offset = 0;
|
||||||
@ -729,7 +729,7 @@ void CROHelper::UnrebaseSegmentTable() {
|
|||||||
segment.offset -= module_address;
|
segment.offset -= module_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntry(i, segment);
|
SetEntry(memory, i, segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,10 +751,10 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) {
|
|||||||
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
||||||
for (u32 i = 0; i < symbol_import_num; ++i) {
|
for (u32 i = 0; i < symbol_import_num; ++i) {
|
||||||
ImportNamedSymbolEntry entry;
|
ImportNamedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||||
ExternalRelocationEntry relocation_entry;
|
ExternalRelocationEntry relocation_entry;
|
||||||
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||||
sizeof(ExternalRelocationEntry));
|
sizeof(ExternalRelocationEntry));
|
||||||
|
|
||||||
if (!relocation_entry.is_batch_resolved) {
|
if (!relocation_entry.is_batch_resolved) {
|
||||||
@ -794,10 +794,10 @@ ResultCode CROHelper::ResetImportNamedSymbol() {
|
|||||||
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
||||||
for (u32 i = 0; i < symbol_import_num; ++i) {
|
for (u32 i = 0; i < symbol_import_num; ++i) {
|
||||||
ImportNamedSymbolEntry entry;
|
ImportNamedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||||
ExternalRelocationEntry relocation_entry;
|
ExternalRelocationEntry relocation_entry;
|
||||||
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||||
sizeof(ExternalRelocationEntry));
|
sizeof(ExternalRelocationEntry));
|
||||||
|
|
||||||
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
||||||
@ -815,10 +815,10 @@ ResultCode CROHelper::ResetImportIndexedSymbol() {
|
|||||||
u32 import_num = GetField(ImportIndexedSymbolNum);
|
u32 import_num = GetField(ImportIndexedSymbolNum);
|
||||||
for (u32 i = 0; i < import_num; ++i) {
|
for (u32 i = 0; i < import_num; ++i) {
|
||||||
ImportIndexedSymbolEntry entry;
|
ImportIndexedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||||
ExternalRelocationEntry relocation_entry;
|
ExternalRelocationEntry relocation_entry;
|
||||||
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||||
sizeof(ExternalRelocationEntry));
|
sizeof(ExternalRelocationEntry));
|
||||||
|
|
||||||
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
||||||
@ -836,10 +836,10 @@ ResultCode CROHelper::ResetImportAnonymousSymbol() {
|
|||||||
u32 import_num = GetField(ImportAnonymousSymbolNum);
|
u32 import_num = GetField(ImportAnonymousSymbolNum);
|
||||||
for (u32 i = 0; i < import_num; ++i) {
|
for (u32 i = 0; i < import_num; ++i) {
|
||||||
ImportAnonymousSymbolEntry entry;
|
ImportAnonymousSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||||
ExternalRelocationEntry relocation_entry;
|
ExternalRelocationEntry relocation_entry;
|
||||||
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||||
sizeof(ExternalRelocationEntry));
|
sizeof(ExternalRelocationEntry));
|
||||||
|
|
||||||
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
ResultCode result = ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
|
||||||
@ -857,7 +857,7 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
|
|||||||
u32 import_module_num = GetField(ImportModuleNum);
|
u32 import_module_num = GetField(ImportModuleNum);
|
||||||
for (u32 i = 0; i < import_module_num; ++i) {
|
for (u32 i = 0; i < import_module_num; ++i) {
|
||||||
ImportModuleEntry entry;
|
ImportModuleEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, 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(
|
ResultCode result = ForEachAutoLinkCRO(
|
||||||
@ -867,9 +867,9 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
|
|||||||
ModuleName(), entry.import_indexed_symbol_num, source.ModuleName());
|
ModuleName(), entry.import_indexed_symbol_num, source.ModuleName());
|
||||||
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
||||||
ImportIndexedSymbolEntry im;
|
ImportIndexedSymbolEntry im;
|
||||||
entry.GetImportIndexedSymbolEntry(process, j, im);
|
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
|
||||||
ExportIndexedSymbolEntry ex;
|
ExportIndexedSymbolEntry ex;
|
||||||
source.GetEntry(im.index, ex);
|
source.GetEntry(memory, im.index, ex);
|
||||||
u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position);
|
u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position);
|
||||||
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
|
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
|
||||||
ResultCode result =
|
ResultCode result =
|
||||||
@ -884,7 +884,7 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
|
|||||||
ModuleName(), entry.import_anonymous_symbol_num, source.ModuleName());
|
ModuleName(), entry.import_anonymous_symbol_num, source.ModuleName());
|
||||||
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
||||||
ImportAnonymousSymbolEntry im;
|
ImportAnonymousSymbolEntry im;
|
||||||
entry.GetImportAnonymousSymbolEntry(process, j, im);
|
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
|
||||||
u32 symbol_address = source.SegmentTagToAddress(im.symbol_position);
|
u32 symbol_address = source.SegmentTagToAddress(im.symbol_position);
|
||||||
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
|
LOG_TRACE(Service_LDR, " Imports 0x{:08X}", symbol_address);
|
||||||
ResultCode result =
|
ResultCode result =
|
||||||
@ -913,10 +913,10 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) {
|
|||||||
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
|
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
|
||||||
for (u32 i = 0; i < target_symbol_import_num; ++i) {
|
for (u32 i = 0; i < target_symbol_import_num; ++i) {
|
||||||
ImportNamedSymbolEntry entry;
|
ImportNamedSymbolEntry entry;
|
||||||
target.GetEntry(i, entry);
|
target.GetEntry(memory, i, entry);
|
||||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||||
ExternalRelocationEntry relocation_entry;
|
ExternalRelocationEntry relocation_entry;
|
||||||
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||||
sizeof(ExternalRelocationEntry));
|
sizeof(ExternalRelocationEntry));
|
||||||
|
|
||||||
if (!relocation_entry.is_batch_resolved) {
|
if (!relocation_entry.is_batch_resolved) {
|
||||||
@ -944,10 +944,10 @@ ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) {
|
|||||||
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
|
u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
|
||||||
for (u32 i = 0; i < target_symbol_import_num; ++i) {
|
for (u32 i = 0; i < target_symbol_import_num; ++i) {
|
||||||
ImportNamedSymbolEntry entry;
|
ImportNamedSymbolEntry entry;
|
||||||
target.GetEntry(i, entry);
|
target.GetEntry(memory, i, entry);
|
||||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||||
ExternalRelocationEntry relocation_entry;
|
ExternalRelocationEntry relocation_entry;
|
||||||
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||||
sizeof(ExternalRelocationEntry));
|
sizeof(ExternalRelocationEntry));
|
||||||
|
|
||||||
if (relocation_entry.is_batch_resolved) {
|
if (relocation_entry.is_batch_resolved) {
|
||||||
@ -974,7 +974,7 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
|
|||||||
u32 target_import_module_num = target.GetField(ImportModuleNum);
|
u32 target_import_module_num = target.GetField(ImportModuleNum);
|
||||||
for (u32 i = 0; i < target_import_module_num; ++i) {
|
for (u32 i = 0; i < target_import_module_num; ++i) {
|
||||||
ImportModuleEntry entry;
|
ImportModuleEntry entry;
|
||||||
target.GetEntry(i, entry);
|
target.GetEntry(memory, 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;
|
continue;
|
||||||
@ -983,9 +983,9 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
|
|||||||
entry.import_indexed_symbol_num, target.ModuleName());
|
entry.import_indexed_symbol_num, target.ModuleName());
|
||||||
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
||||||
ImportIndexedSymbolEntry im;
|
ImportIndexedSymbolEntry im;
|
||||||
entry.GetImportIndexedSymbolEntry(process, j, im);
|
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
|
||||||
ExportIndexedSymbolEntry ex;
|
ExportIndexedSymbolEntry ex;
|
||||||
GetEntry(im.index, ex);
|
GetEntry(memory, im.index, ex);
|
||||||
u32 symbol_address = SegmentTagToAddress(ex.symbol_position);
|
u32 symbol_address = SegmentTagToAddress(ex.symbol_position);
|
||||||
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
|
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
|
||||||
ResultCode result =
|
ResultCode result =
|
||||||
@ -1000,7 +1000,7 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
|
|||||||
entry.import_anonymous_symbol_num, target.ModuleName());
|
entry.import_anonymous_symbol_num, target.ModuleName());
|
||||||
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
||||||
ImportAnonymousSymbolEntry im;
|
ImportAnonymousSymbolEntry im;
|
||||||
entry.GetImportAnonymousSymbolEntry(process, j, im);
|
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
|
||||||
u32 symbol_address = SegmentTagToAddress(im.symbol_position);
|
u32 symbol_address = SegmentTagToAddress(im.symbol_position);
|
||||||
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
|
LOG_TRACE(Service_LDR, " exports symbol 0x{:08X}", symbol_address);
|
||||||
ResultCode result =
|
ResultCode result =
|
||||||
@ -1023,7 +1023,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
|
|||||||
u32 target_import_module_num = target.GetField(ImportModuleNum);
|
u32 target_import_module_num = target.GetField(ImportModuleNum);
|
||||||
for (u32 i = 0; i < target_import_module_num; ++i) {
|
for (u32 i = 0; i < target_import_module_num; ++i) {
|
||||||
ImportModuleEntry entry;
|
ImportModuleEntry entry;
|
||||||
target.GetEntry(i, entry);
|
target.GetEntry(memory, 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;
|
continue;
|
||||||
@ -1032,7 +1032,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
|
|||||||
target.ModuleName());
|
target.ModuleName());
|
||||||
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
|
||||||
ImportIndexedSymbolEntry im;
|
ImportIndexedSymbolEntry im;
|
||||||
entry.GetImportIndexedSymbolEntry(process, j, im);
|
entry.GetImportIndexedSymbolEntry(process, memory, j, im);
|
||||||
ResultCode result =
|
ResultCode result =
|
||||||
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
|
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
@ -1045,7 +1045,7 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
|
|||||||
target.ModuleName());
|
target.ModuleName());
|
||||||
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
|
||||||
ImportAnonymousSymbolEntry im;
|
ImportAnonymousSymbolEntry im;
|
||||||
entry.GetImportAnonymousSymbolEntry(process, j, im);
|
entry.GetImportAnonymousSymbolEntry(process, memory, j, im);
|
||||||
ResultCode result =
|
ResultCode result =
|
||||||
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
|
target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
@ -1063,10 +1063,10 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
|
|||||||
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
u32 symbol_import_num = GetField(ImportNamedSymbolNum);
|
||||||
for (u32 i = 0; i < symbol_import_num; ++i) {
|
for (u32 i = 0; i < symbol_import_num; ++i) {
|
||||||
ImportNamedSymbolEntry entry;
|
ImportNamedSymbolEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
VAddr relocation_addr = entry.relocation_batch_offset;
|
VAddr relocation_addr = entry.relocation_batch_offset;
|
||||||
ExternalRelocationEntry relocation_entry;
|
ExternalRelocationEntry relocation_entry;
|
||||||
Memory::ReadBlock(process, relocation_addr, &relocation_entry,
|
memory.ReadBlock(process, relocation_addr, &relocation_entry,
|
||||||
sizeof(ExternalRelocationEntry));
|
sizeof(ExternalRelocationEntry));
|
||||||
|
|
||||||
if (memory.ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
|
if (memory.ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
|
||||||
@ -1266,11 +1266,11 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
|
|||||||
// so we do the same
|
// so we do the same
|
||||||
if (GetField(SegmentNum) >= 2) { // means we have .data segment
|
if (GetField(SegmentNum) >= 2) { // means we have .data segment
|
||||||
SegmentEntry entry;
|
SegmentEntry entry;
|
||||||
GetEntry(2, entry);
|
GetEntry(memory, 2, entry);
|
||||||
ASSERT(entry.type == SegmentType::Data);
|
ASSERT(entry.type == SegmentType::Data);
|
||||||
data_segment_address = entry.offset;
|
data_segment_address = entry.offset;
|
||||||
entry.offset = GetField(DataOffset);
|
entry.offset = GetField(DataOffset);
|
||||||
SetEntry(2, entry);
|
SetEntry(memory, 2, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SCOPE_EXIT({
|
SCOPE_EXIT({
|
||||||
@ -1278,9 +1278,9 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
|
|||||||
if (link_on_load_bug_fix) {
|
if (link_on_load_bug_fix) {
|
||||||
if (GetField(SegmentNum) >= 2) {
|
if (GetField(SegmentNum) >= 2) {
|
||||||
SegmentEntry entry;
|
SegmentEntry entry;
|
||||||
GetEntry(2, entry);
|
GetEntry(memory, 2, entry);
|
||||||
entry.offset = data_segment_address;
|
entry.offset = data_segment_address;
|
||||||
SetEntry(2, entry);
|
SetEntry(memory, 2, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1516,7 +1516,7 @@ std::tuple<VAddr, u32> CROHelper::GetExecutablePages() const {
|
|||||||
u32 segment_num = GetField(SegmentNum);
|
u32 segment_num = GetField(SegmentNum);
|
||||||
for (u32 i = 0; i < segment_num; ++i) {
|
for (u32 i = 0; i < segment_num; ++i) {
|
||||||
SegmentEntry entry;
|
SegmentEntry entry;
|
||||||
GetEntry(i, entry);
|
GetEntry(memory, i, entry);
|
||||||
if (entry.type == SegmentType::Code && entry.size != 0) {
|
if (entry.type == SegmentType::Code && entry.size != 0) {
|
||||||
VAddr begin = Common::AlignDown(entry.offset, Memory::PAGE_SIZE);
|
VAddr begin = Common::AlignDown(entry.offset, Memory::PAGE_SIZE);
|
||||||
VAddr end = Common::AlignUp(entry.offset + entry.size, Memory::PAGE_SIZE);
|
VAddr end = Common::AlignUp(entry.offset + entry.size, Memory::PAGE_SIZE);
|
||||||
|
@ -318,17 +318,17 @@ private:
|
|||||||
|
|
||||||
static constexpr HeaderField TABLE_OFFSET_FIELD = ImportModuleTableOffset;
|
static constexpr HeaderField TABLE_OFFSET_FIELD = ImportModuleTableOffset;
|
||||||
|
|
||||||
void GetImportIndexedSymbolEntry(Kernel::Process& process, u32 index,
|
void GetImportIndexedSymbolEntry(Kernel::Process& process, Memory::MemorySystem& memory,
|
||||||
ImportIndexedSymbolEntry& entry) {
|
u32 index, ImportIndexedSymbolEntry& entry) {
|
||||||
Memory::ReadBlock(process,
|
memory.ReadBlock(process,
|
||||||
import_indexed_symbol_table_offset +
|
import_indexed_symbol_table_offset +
|
||||||
index * sizeof(ImportIndexedSymbolEntry),
|
index * sizeof(ImportIndexedSymbolEntry),
|
||||||
&entry, sizeof(ImportIndexedSymbolEntry));
|
&entry, sizeof(ImportIndexedSymbolEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetImportAnonymousSymbolEntry(Kernel::Process& process, u32 index,
|
void GetImportAnonymousSymbolEntry(Kernel::Process& process, Memory::MemorySystem& memory,
|
||||||
ImportAnonymousSymbolEntry& entry) {
|
u32 index, ImportAnonymousSymbolEntry& entry) {
|
||||||
Memory::ReadBlock(process,
|
memory.ReadBlock(process,
|
||||||
import_anonymous_symbol_table_offset +
|
import_anonymous_symbol_table_offset +
|
||||||
index * sizeof(ImportAnonymousSymbolEntry),
|
index * sizeof(ImportAnonymousSymbolEntry),
|
||||||
&entry, sizeof(ImportAnonymousSymbolEntry));
|
&entry, sizeof(ImportAnonymousSymbolEntry));
|
||||||
@ -423,8 +423,8 @@ private:
|
|||||||
* indicating which table the entry is in.
|
* indicating which table the entry is in.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void GetEntry(std::size_t index, T& data) const {
|
void GetEntry(Memory::MemorySystem& memory, std::size_t index, T& data) const {
|
||||||
Memory::ReadBlock(process,
|
memory.ReadBlock(process,
|
||||||
GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
|
GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
|
||||||
&data, sizeof(T));
|
&data, sizeof(T));
|
||||||
}
|
}
|
||||||
@ -437,8 +437,8 @@ private:
|
|||||||
* indicating which table the entry is in.
|
* indicating which table the entry is in.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetEntry(std::size_t index, const T& data) {
|
void SetEntry(Memory::MemorySystem& memory, std::size_t index, const T& data) {
|
||||||
Memory::WriteBlock(process,
|
memory.WriteBlock(process,
|
||||||
GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
|
GetField(T::TABLE_OFFSET_FIELD) + static_cast<u32>(index * sizeof(T)),
|
||||||
&data, sizeof(T));
|
&data, sizeof(T));
|
||||||
}
|
}
|
||||||
|
@ -433,8 +433,8 @@ u64 MemorySystem::Read64(const VAddr addr) {
|
|||||||
return Read<u64_le>(addr);
|
return Read<u64_le>(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
|
void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_addr,
|
||||||
const std::size_t size) {
|
void* dest_buffer, const std::size_t size) {
|
||||||
auto& page_table = process.vm_manager.page_table;
|
auto& page_table = process.vm_manager.page_table;
|
||||||
|
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
@ -499,8 +499,8 @@ void MemorySystem::Write64(const VAddr addr, const u64 data) {
|
|||||||
Write<u64_le>(addr, data);
|
Write<u64_le>(addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer,
|
void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_addr,
|
||||||
const std::size_t size) {
|
const void* src_buffer, const std::size_t size) {
|
||||||
auto& page_table = process.vm_manager.page_table;
|
auto& page_table = process.vm_manager.page_table;
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
std::size_t page_index = dest_addr >> PAGE_BITS;
|
std::size_t page_index = dest_addr >> PAGE_BITS;
|
||||||
@ -547,7 +547,8 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) {
|
void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_addr,
|
||||||
|
const std::size_t size) {
|
||||||
auto& page_table = process.vm_manager.page_table;
|
auto& page_table = process.vm_manager.page_table;
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
std::size_t page_index = dest_addr >> PAGE_BITS;
|
std::size_t page_index = dest_addr >> PAGE_BITS;
|
||||||
@ -595,7 +596,7 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
|
void MemorySystem::CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
auto& page_table = process.vm_manager.page_table;
|
auto& page_table = process.vm_manager.page_table;
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
@ -647,8 +648,9 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyBlock(const Kernel::Process& src_process, const Kernel::Process& dest_process,
|
void MemorySystem::CopyBlock(const Kernel::Process& src_process,
|
||||||
VAddr src_addr, VAddr dest_addr, std::size_t size) {
|
const Kernel::Process& dest_process, VAddr src_addr, VAddr dest_addr,
|
||||||
|
std::size_t size) {
|
||||||
auto& page_table = src_process.vm_manager.page_table;
|
auto& page_table = src_process.vm_manager.page_table;
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
std::size_t page_index = src_addr >> PAGE_BITS;
|
std::size_t page_index = src_addr >> PAGE_BITS;
|
||||||
|
@ -180,14 +180,6 @@ enum : VAddr {
|
|||||||
|
|
||||||
extern std::array<u8, Memory::FCRAM_N3DS_SIZE> fcram;
|
extern std::array<u8, Memory::FCRAM_N3DS_SIZE> fcram;
|
||||||
|
|
||||||
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);
|
|
||||||
void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, const std::size_t size);
|
|
||||||
void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, std::size_t size);
|
|
||||||
void CopyBlock(const Kernel::Process& src_process, const Kernel::Process& dest_process,
|
|
||||||
VAddr src_addr, VAddr dest_addr, std::size_t size);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark each page touching the region as cached.
|
* Mark each page touching the region as cached.
|
||||||
*/
|
*/
|
||||||
@ -239,6 +231,16 @@ public:
|
|||||||
void Write32(VAddr addr, u32 data);
|
void Write32(VAddr addr, u32 data);
|
||||||
void Write64(VAddr addr, u64 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);
|
||||||
|
void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, const std::size_t size);
|
||||||
|
void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
|
||||||
|
std::size_t size);
|
||||||
|
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);
|
std::string ReadCString(VAddr vaddr, std::size_t max_length);
|
||||||
|
|
||||||
/// Determines if the given VAddr is valid for the specified process.
|
/// Determines if the given VAddr is valid for the specified process.
|
||||||
|
@ -30,7 +30,8 @@ void RPCServer::HandleReadMemory(Packet& packet, u32 address, u32 data_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: Memory read occurs asynchronously from the state of the emulator
|
// Note: Memory read occurs asynchronously from the state of the emulator
|
||||||
Memory::ReadBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), address,
|
Core::System::GetInstance().Memory().ReadBlock(
|
||||||
|
*Core::System::GetInstance().Kernel().GetCurrentProcess(), address,
|
||||||
packet.GetPacketData().data(), data_size);
|
packet.GetPacketData().data(), data_size);
|
||||||
packet.SetPacketDataSize(data_size);
|
packet.SetPacketDataSize(data_size);
|
||||||
packet.SendReply();
|
packet.SendReply();
|
||||||
@ -42,8 +43,8 @@ void RPCServer::HandleWriteMemory(Packet& packet, u32 address, const u8* data, u
|
|||||||
(address >= Memory::HEAP_VADDR && address <= Memory::HEAP_VADDR_END) ||
|
(address >= Memory::HEAP_VADDR && address <= Memory::HEAP_VADDR_END) ||
|
||||||
(address >= Memory::N3DS_EXTRA_RAM_VADDR && address <= Memory::N3DS_EXTRA_RAM_VADDR_END)) {
|
(address >= Memory::N3DS_EXTRA_RAM_VADDR && address <= Memory::N3DS_EXTRA_RAM_VADDR_END)) {
|
||||||
// Note: Memory write occurs asynchronously from the state of the emulator
|
// Note: Memory write occurs asynchronously from the state of the emulator
|
||||||
Memory::WriteBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), address, data,
|
Core::System::GetInstance().Memory().WriteBlock(
|
||||||
data_size);
|
*Core::System::GetInstance().Kernel().GetCurrentProcess(), address, data, data_size);
|
||||||
// If the memory happens to be executable code, make sure the changes become visible
|
// If the memory happens to be executable code, make sure the changes become visible
|
||||||
Core::CPU().InvalidateCacheRange(address, data_size);
|
Core::CPU().InvalidateCacheRange(address, data_size);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user