mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-29 14:34:18 +01:00
Move SvcMap/UnmapMemory inside the memory manager
This commit is contained in:
parent
850f616dc7
commit
242e39dc4d
@ -500,6 +500,46 @@ namespace skyline::kernel {
|
||||
Logger::Error("Failed to free memory: {}", strerror(errno));
|
||||
}
|
||||
|
||||
void MemoryManager::SvcMapMemory(span<u8> source, span<u8> destination) {
|
||||
std::unique_lock lock{mutex};
|
||||
|
||||
MapInternal(std::pair<u8 *, ChunkDescriptor>(
|
||||
destination.data(),{
|
||||
.size = destination.size(),
|
||||
.permission = {true, true, false},
|
||||
.state = memory::states::Stack,
|
||||
.isSrcMergeDisallowed = true
|
||||
}));
|
||||
|
||||
std::memcpy(destination.data(), source.data(), source.size());
|
||||
|
||||
ForeachChunkinRange(source, [&](std::pair<u8 *, ChunkDescriptor> &desc) __attribute__((always_inline)) {
|
||||
desc.second.permission = {false, false, false};
|
||||
desc.second.attributes.isBorrowed = true;
|
||||
MapInternal(desc);
|
||||
});
|
||||
}
|
||||
|
||||
void MemoryManager::SvcUnmapMemory(span<u8> source, span<u8> destination) {
|
||||
std::unique_lock lock{mutex};
|
||||
|
||||
auto dstChunk = chunks.lower_bound(destination.data());
|
||||
if (destination.data() < dstChunk->first)
|
||||
--dstChunk;
|
||||
while (dstChunk->second.state.value == memory::states::Unmapped)
|
||||
++dstChunk;
|
||||
|
||||
if ((destination.data() + destination.size()) > dstChunk->first) [[likely]] {
|
||||
ForeachChunkinRange(span<u8>{source.data() + (dstChunk->first - destination.data()), dstChunk->second.size}, [&](std::pair<u8 *, ChunkDescriptor> &desc) __attribute__((always_inline)) {
|
||||
desc.second.permission = dstChunk->second.permission;
|
||||
desc.second.attributes.isBorrowed = false;
|
||||
MapInternal(desc);
|
||||
});
|
||||
|
||||
std::memcpy(source.data() + (dstChunk->first - destination.data()), dstChunk->first, dstChunk->second.size);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManager::AddRef(std::shared_ptr<type::KMemory> ptr) {
|
||||
memRefs.push_back(std::move(ptr));
|
||||
}
|
||||
|
@ -322,6 +322,10 @@ namespace skyline {
|
||||
*/
|
||||
void FreeMemory(span<u8> memory);
|
||||
|
||||
void SvcMapMemory(span<u8> source, span<u8> destination);
|
||||
|
||||
void SvcUnmapMemory(span<u8> source, span<u8> destination);
|
||||
|
||||
/**
|
||||
* @brief Adds a reference to shared memory, extending its lifetime until `RemoveRef` is called
|
||||
*/
|
||||
@ -346,7 +350,7 @@ namespace skyline {
|
||||
/**
|
||||
* @return If the supplied region is contained withing the accessible guest address space
|
||||
*/
|
||||
bool AddressSpaceContains(span<u8> region) const {
|
||||
constexpr bool AddressSpaceContains(span<u8> region) const {
|
||||
if (addressSpaceType == memory::AddressSpaceType::AddressSpace36Bit)
|
||||
return codeBase36Bit.contains(region) || base.contains(region);
|
||||
else
|
||||
|
@ -172,11 +172,7 @@ namespace skyline::kernel::svc {
|
||||
return;
|
||||
}
|
||||
|
||||
state.process->memory.MapStackMemory(span<u8>{destination, size});
|
||||
std::memcpy(destination, source, size);
|
||||
|
||||
state.process->memory.SetRegionPermission(span<u8>{source, size}, {false, false, false});
|
||||
state.process->memory.SetRegionBorrowed(span<u8>{source, size}, true);
|
||||
state.process->memory.SvcMapMemory(span<u8>{source, size}, span<u8>{destination, size});
|
||||
|
||||
Logger::Debug("Mapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", source, source + size, destination, destination + size, size);
|
||||
state.ctx->gpr.w0 = Result{};
|
||||
@ -205,18 +201,8 @@ namespace skyline::kernel::svc {
|
||||
return;
|
||||
}
|
||||
|
||||
auto dstChunk{state.process->memory.GetChunk(destination).value()};
|
||||
while (dstChunk.second.state.value == memory::states::Unmapped)
|
||||
dstChunk = state.process->memory.GetChunk(dstChunk.first + dstChunk.second.size).value();
|
||||
|
||||
if ((destination + size) > dstChunk.first) [[likely]] {
|
||||
state.process->memory.SetRegionPermission(span<u8>{source + (dstChunk.first - destination), dstChunk.second.size}, dstChunk.second.permission);
|
||||
state.process->memory.SetRegionBorrowed(span<u8>{source + (dstChunk.first - destination), dstChunk.second.size}, false);
|
||||
|
||||
std::memcpy(source + (dstChunk.first - destination), dstChunk.first, dstChunk.second.size);
|
||||
|
||||
state.process->memory.UnmapMemory(span<u8>{destination, size});
|
||||
}
|
||||
state.process->memory.SvcUnmapMemory(span<u8>{source, size}, span<u8>{destination, size});
|
||||
state.process->memory.UnmapMemory(span<u8>{destination, size});
|
||||
|
||||
Logger::Debug("Unmapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", destination, destination + size, source, source + size, size);
|
||||
state.ctx->gpr.w0 = Result{};
|
||||
|
Loading…
Reference in New Issue
Block a user