summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/physical_memory.h5
-rw-r--r--src/core/hle/kernel/vm_manager.cpp37
-rw-r--r--src/core/loader/elf.cpp3
-rw-r--r--src/core/loader/kip.cpp5
-rw-r--r--src/core/loader/nso.cpp12
-rw-r--r--src/core/memory.cpp11
-rw-r--r--src/core/memory.h16
7 files changed, 54 insertions, 35 deletions
diff --git a/src/core/hle/kernel/physical_memory.h b/src/core/hle/kernel/physical_memory.h
index 090565310..b689e8e8b 100644
--- a/src/core/hle/kernel/physical_memory.h
+++ b/src/core/hle/kernel/physical_memory.h
@@ -14,6 +14,9 @@ namespace Kernel {
14// - Second to ensure all host backing memory used is aligned to 256 bytes due 14// - Second to ensure all host backing memory used is aligned to 256 bytes due
15// to strict alignment restrictions on GPU memory. 15// to strict alignment restrictions on GPU memory.
16 16
17using PhysicalMemory = std::vector<u8, Common::AlignmentAllocator<u8, 256>>; 17using PhysicalMemoryVector = std::vector<u8, Common::AlignmentAllocator<u8, 256>>;
18class PhysicalMemory final : public PhysicalMemoryVector {
19 using PhysicalMemoryVector::PhysicalMemoryVector;
20};
18 21
19} // namespace Kernel 22} // namespace Kernel
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index a9a20ef76..0b3500fce 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cstring>
6#include <iterator> 7#include <iterator>
7#include <utility> 8#include <utility>
8#include "common/alignment.h" 9#include "common/alignment.h"
@@ -269,18 +270,9 @@ ResultVal<VAddr> VMManager::SetHeapSize(u64 size) {
269 // If necessary, expand backing vector to cover new heap extents in 270 // If necessary, expand backing vector to cover new heap extents in
270 // the case of allocating. Otherwise, shrink the backing memory, 271 // the case of allocating. Otherwise, shrink the backing memory,
271 // if a smaller heap has been requested. 272 // if a smaller heap has been requested.
272 const u64 old_heap_size = GetCurrentHeapSize(); 273 heap_memory->resize(size);
273 if (size > old_heap_size) { 274 heap_memory->shrink_to_fit();
274 const u64 alloc_size = size - old_heap_size; 275 RefreshMemoryBlockMappings(heap_memory.get());
275
276 heap_memory->insert(heap_memory->end(), alloc_size, 0);
277 RefreshMemoryBlockMappings(heap_memory.get());
278 } else if (size < old_heap_size) {
279 heap_memory->resize(size);
280 heap_memory->shrink_to_fit();
281
282 RefreshMemoryBlockMappings(heap_memory.get());
283 }
284 276
285 heap_end = heap_region_base + size; 277 heap_end = heap_region_base + size;
286 ASSERT(GetCurrentHeapSize() == heap_memory->size()); 278 ASSERT(GetCurrentHeapSize() == heap_memory->size());
@@ -752,24 +744,20 @@ void VMManager::MergeAdjacentVMA(VirtualMemoryArea& left, const VirtualMemoryAre
752 // Always merge allocated memory blocks, even when they don't share the same backing block. 744 // Always merge allocated memory blocks, even when they don't share the same backing block.
753 if (left.type == VMAType::AllocatedMemoryBlock && 745 if (left.type == VMAType::AllocatedMemoryBlock &&
754 (left.backing_block != right.backing_block || left.offset + left.size != right.offset)) { 746 (left.backing_block != right.backing_block || left.offset + left.size != right.offset)) {
755 const auto right_begin = right.backing_block->begin() + right.offset;
756 const auto right_end = right_begin + right.size;
757 747
758 // Check if we can save work. 748 // Check if we can save work.
759 if (left.offset == 0 && left.size == left.backing_block->size()) { 749 if (left.offset == 0 && left.size == left.backing_block->size()) {
760 // Fast case: left is an entire backing block. 750 // Fast case: left is an entire backing block.
761 left.backing_block->insert(left.backing_block->end(), right_begin, right_end); 751 left.backing_block->resize(left.size + right.size);
752 std::memcpy(left.backing_block->data() + left.size,
753 right.backing_block->data() + right.offset, right.size);
762 } else { 754 } else {
763 // Slow case: make a new memory block for left and right. 755 // Slow case: make a new memory block for left and right.
764 const auto left_begin = left.backing_block->begin() + left.offset;
765 const auto left_end = left_begin + left.size;
766 const auto left_size = static_cast<std::size_t>(std::distance(left_begin, left_end));
767 const auto right_size = static_cast<std::size_t>(std::distance(right_begin, right_end));
768
769 auto new_memory = std::make_shared<PhysicalMemory>(); 756 auto new_memory = std::make_shared<PhysicalMemory>();
770 new_memory->reserve(left_size + right_size); 757 new_memory->resize(left.size + right.size);
771 new_memory->insert(new_memory->end(), left_begin, left_end); 758 std::memcpy(new_memory->data(), left.backing_block->data() + left.offset, left.size);
772 new_memory->insert(new_memory->end(), right_begin, right_end); 759 std::memcpy(new_memory->data() + left.size, right.backing_block->data() + right.offset,
760 right.size);
773 761
774 left.backing_block = std::move(new_memory); 762 left.backing_block = std::move(new_memory);
775 left.offset = 0; 763 left.offset = 0;
@@ -792,8 +780,7 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
792 memory.UnmapRegion(page_table, vma.base, vma.size); 780 memory.UnmapRegion(page_table, vma.base, vma.size);
793 break; 781 break;
794 case VMAType::AllocatedMemoryBlock: 782 case VMAType::AllocatedMemoryBlock:
795 memory.MapMemoryRegion(page_table, vma.base, vma.size, 783 memory.MapMemoryRegion(page_table, vma.base, vma.size, *vma.backing_block, vma.offset);
796 vma.backing_block->data() + vma.offset);
797 break; 784 break;
798 case VMAType::BackingMemory: 785 case VMAType::BackingMemory:
799 memory.MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory); 786 memory.MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory);
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index f1795fdd6..8908e5328 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -335,7 +335,8 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) {
335 codeset_segment->addr = segment_addr; 335 codeset_segment->addr = segment_addr;
336 codeset_segment->size = aligned_size; 336 codeset_segment->size = aligned_size;
337 337
338 memcpy(&program_image[current_image_position], GetSegmentPtr(i), p->p_filesz); 338 std::memcpy(program_image.data() + current_image_position, GetSegmentPtr(i),
339 p->p_filesz);
339 current_image_position += aligned_size; 340 current_image_position += aligned_size;
340 } 341 }
341 } 342 }
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp
index 474b55cb1..092103abe 100644
--- a/src/core/loader/kip.cpp
+++ b/src/core/loader/kip.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring>
5#include "core/file_sys/kernel_executable.h" 6#include "core/file_sys/kernel_executable.h"
6#include "core/file_sys/program_metadata.h" 7#include "core/file_sys/program_metadata.h"
7#include "core/gdbstub/gdbstub.h" 8#include "core/gdbstub/gdbstub.h"
@@ -76,8 +77,8 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process) {
76 segment.addr = offset; 77 segment.addr = offset;
77 segment.offset = offset; 78 segment.offset = offset;
78 segment.size = PageAlignSize(static_cast<u32>(data.size())); 79 segment.size = PageAlignSize(static_cast<u32>(data.size()));
79 program_image.resize(offset); 80 program_image.resize(offset + data.size());
80 program_image.insert(program_image.end(), data.begin(), data.end()); 81 std::memcpy(program_image.data() + offset, data.data(), data.size());
81 }; 82 };
82 83
83 load_segment(codeset.CodeSegment(), kip->GetTextSection(), kip->GetTextOffset()); 84 load_segment(codeset.CodeSegment(), kip->GetTextSection(), kip->GetTextOffset());
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index f629892ae..515c5accb 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cinttypes> 5#include <cinttypes>
6#include <cstring>
6#include <vector> 7#include <vector>
7 8
8#include "common/common_funcs.h" 9#include "common/common_funcs.h"
@@ -96,8 +97,9 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
96 if (nso_header.IsSegmentCompressed(i)) { 97 if (nso_header.IsSegmentCompressed(i)) {
97 data = DecompressSegment(data, nso_header.segments[i]); 98 data = DecompressSegment(data, nso_header.segments[i]);
98 } 99 }
99 program_image.resize(nso_header.segments[i].location); 100 program_image.resize(nso_header.segments[i].location + data.size());
100 program_image.insert(program_image.end(), data.begin(), data.end()); 101 std::memcpy(program_image.data() + nso_header.segments[i].location, data.data(),
102 data.size());
101 codeset.segments[i].addr = nso_header.segments[i].location; 103 codeset.segments[i].addr = nso_header.segments[i].location;
102 codeset.segments[i].offset = nso_header.segments[i].location; 104 codeset.segments[i].offset = nso_header.segments[i].location;
103 codeset.segments[i].size = PageAlignSize(static_cast<u32>(data.size())); 105 codeset.segments[i].size = PageAlignSize(static_cast<u32>(data.size()));
@@ -139,12 +141,12 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
139 std::vector<u8> pi_header; 141 std::vector<u8> pi_header;
140 pi_header.insert(pi_header.begin(), reinterpret_cast<u8*>(&nso_header), 142 pi_header.insert(pi_header.begin(), reinterpret_cast<u8*>(&nso_header),
141 reinterpret_cast<u8*>(&nso_header) + sizeof(NSOHeader)); 143 reinterpret_cast<u8*>(&nso_header) + sizeof(NSOHeader));
142 pi_header.insert(pi_header.begin() + sizeof(NSOHeader), program_image.begin(), 144 pi_header.insert(pi_header.begin() + sizeof(NSOHeader), program_image.data(),
143 program_image.end()); 145 program_image.data() + program_image.size());
144 146
145 pi_header = pm->PatchNSO(pi_header, file.GetName()); 147 pi_header = pm->PatchNSO(pi_header, file.GetName());
146 148
147 std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.begin()); 149 std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.data());
148 } 150 }
149 151
150 // Apply cheats if they exist and the program has a valid title ID 152 // Apply cheats if they exist and the program has a valid title ID
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 3c2a29d9b..f0888327f 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -14,6 +14,7 @@
14#include "common/swap.h" 14#include "common/swap.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#include "core/core.h" 16#include "core/core.h"
17#include "core/hle/kernel/physical_memory.h"
17#include "core/hle/kernel/process.h" 18#include "core/hle/kernel/process.h"
18#include "core/hle/kernel/vm_manager.h" 19#include "core/hle/kernel/vm_manager.h"
19#include "core/memory.h" 20#include "core/memory.h"
@@ -38,6 +39,11 @@ struct Memory::Impl {
38 system.ArmInterface(3).PageTableChanged(*current_page_table, address_space_width); 39 system.ArmInterface(3).PageTableChanged(*current_page_table, address_space_width);
39 } 40 }
40 41
42 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size,
43 Kernel::PhysicalMemory& memory, VAddr offset) {
44 MapMemoryRegion(page_table, base, size, memory.data() + offset);
45 }
46
41 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, u8* target) { 47 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, u8* target) {
42 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size); 48 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
43 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base); 49 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
@@ -601,6 +607,11 @@ void Memory::SetCurrentPageTable(Kernel::Process& process) {
601 impl->SetCurrentPageTable(process); 607 impl->SetCurrentPageTable(process);
602} 608}
603 609
610void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size,
611 Kernel::PhysicalMemory& memory, VAddr offset) {
612 impl->MapMemoryRegion(page_table, base, size, memory, offset);
613}
614
604void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, u8* target) { 615void Memory::MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, u8* target) {
605 impl->MapMemoryRegion(page_table, base, size, target); 616 impl->MapMemoryRegion(page_table, base, size, target);
606} 617}
diff --git a/src/core/memory.h b/src/core/memory.h
index 1428a6d60..8913a9da4 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -19,8 +19,9 @@ class System;
19} 19}
20 20
21namespace Kernel { 21namespace Kernel {
22class PhysicalMemory;
22class Process; 23class Process;
23} 24} // namespace Kernel
24 25
25namespace Memory { 26namespace Memory {
26 27
@@ -66,6 +67,19 @@ public:
66 void SetCurrentPageTable(Kernel::Process& process); 67 void SetCurrentPageTable(Kernel::Process& process);
67 68
68 /** 69 /**
70 * Maps an physical buffer onto a region of the emulated process address space.
71 *
72 * @param page_table The page table of the emulated process.
73 * @param base The address to start mapping at. Must be page-aligned.
74 * @param size The amount of bytes to map. Must be page-aligned.
75 * @param memory Physical buffer with the memory backing the mapping. Must be of length
76 * at least `size + offset`.
77 * @param offset The offset within the physical memory. Must be page-aligned.
78 */
79 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size,
80 Kernel::PhysicalMemory& memory, VAddr offset);
81
82 /**
69 * Maps an allocated buffer onto a region of the emulated process address space. 83 * Maps an allocated buffer onto a region of the emulated process address space.
70 * 84 *
71 * @param page_table The page table of the emulated process. 85 * @param page_table The page table of the emulated process.