memory: Dehardcode the use of fixed memory range constants
The locations of these can actually vary depending on the address space layout, so we shouldn't be using these when determining where to map memory or be using them as offsets for calculations. This keeps all the memory ranges flexible and malleable based off of the virtual memory manager instance state.
This commit is contained in:
parent
6c6f95d071
commit
83377113bf
11 changed files with 60 additions and 75 deletions
|
@ -37,7 +37,9 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_cpu.h"
|
#include "core/core_cpu.h"
|
||||||
#include "core/gdbstub/gdbstub.h"
|
#include "core/gdbstub/gdbstub.h"
|
||||||
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/kernel/scheduler.h"
|
#include "core/hle/kernel/scheduler.h"
|
||||||
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
|
@ -585,7 +587,8 @@ static void HandleQuery() {
|
||||||
strlen("Xfer:features:read:target.xml:")) == 0) {
|
strlen("Xfer:features:read:target.xml:")) == 0) {
|
||||||
SendReply(target_xml);
|
SendReply(target_xml);
|
||||||
} else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) {
|
} else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) {
|
||||||
std::string buffer = fmt::format("TextSeg={:0x}", Memory::PROCESS_IMAGE_VADDR);
|
const VAddr base_address = Core::CurrentProcess()->vm_manager.GetCodeRegionBaseAddress();
|
||||||
|
std::string buffer = fmt::format("TextSeg={:0x}", base_address);
|
||||||
SendReply(buffer.c_str());
|
SendReply(buffer.c_str());
|
||||||
} else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) {
|
} else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) {
|
||||||
std::string val = "m";
|
std::string val = "m";
|
||||||
|
@ -893,11 +896,11 @@ static void ReadMemory() {
|
||||||
static u8 reply[GDB_BUFFER_SIZE - 4];
|
static u8 reply[GDB_BUFFER_SIZE - 4];
|
||||||
|
|
||||||
auto start_offset = command_buffer + 1;
|
auto start_offset = command_buffer + 1;
|
||||||
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
|
const auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
|
||||||
VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
|
const VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
|
||||||
|
|
||||||
start_offset = addr_pos + 1;
|
start_offset = addr_pos + 1;
|
||||||
u64 len =
|
const u64 len =
|
||||||
HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
|
HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
|
||||||
|
|
||||||
LOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len);
|
LOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len);
|
||||||
|
@ -906,7 +909,9 @@ static void ReadMemory() {
|
||||||
SendReply("E01");
|
SendReply("E01");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr < Memory::PROCESS_IMAGE_VADDR || addr >= Memory::MAP_REGION_VADDR_END) {
|
const auto& vm_manager = Core::CurrentProcess()->vm_manager;
|
||||||
|
if (addr < vm_manager.GetCodeRegionBaseAddress() ||
|
||||||
|
addr >= vm_manager.GetMapRegionEndAddress()) {
|
||||||
return SendReply("E00");
|
return SendReply("E00");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
|
||||||
// TODO(bunnei): This is heap area that should be allocated by the kernel and not mapped as part
|
// TODO(bunnei): This is heap area that should be allocated by the kernel and not mapped as part
|
||||||
// of the user address space.
|
// of the user address space.
|
||||||
vm_manager
|
vm_manager
|
||||||
.MapMemoryBlock(Memory::STACK_AREA_VADDR_END - stack_size,
|
.MapMemoryBlock(vm_manager.GetTLSIORegionEndAddress() - stack_size,
|
||||||
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
|
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
|
||||||
MemoryState::Mapped)
|
MemoryState::Mapped)
|
||||||
.Unwrap();
|
.Unwrap();
|
||||||
|
@ -193,6 +193,7 @@ static std::tuple<std::size_t, std::size_t, bool> FindFreeThreadLocalSlot(
|
||||||
|
|
||||||
VAddr Process::MarkNextAvailableTLSSlotAsUsed(Thread& thread) {
|
VAddr Process::MarkNextAvailableTLSSlotAsUsed(Thread& thread) {
|
||||||
auto [available_page, available_slot, needs_allocation] = FindFreeThreadLocalSlot(tls_slots);
|
auto [available_page, available_slot, needs_allocation] = FindFreeThreadLocalSlot(tls_slots);
|
||||||
|
const VAddr tls_begin = vm_manager.GetTLSIORegionBaseAddress();
|
||||||
|
|
||||||
if (needs_allocation) {
|
if (needs_allocation) {
|
||||||
tls_slots.emplace_back(0); // The page is completely available at the start
|
tls_slots.emplace_back(0); // The page is completely available at the start
|
||||||
|
@ -205,18 +206,17 @@ VAddr Process::MarkNextAvailableTLSSlotAsUsed(Thread& thread) {
|
||||||
|
|
||||||
vm_manager.RefreshMemoryBlockMappings(tls_memory.get());
|
vm_manager.RefreshMemoryBlockMappings(tls_memory.get());
|
||||||
|
|
||||||
vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
|
vm_manager.MapMemoryBlock(tls_begin + available_page * Memory::PAGE_SIZE, tls_memory, 0,
|
||||||
tls_memory, 0, Memory::PAGE_SIZE, MemoryState::ThreadLocal);
|
Memory::PAGE_SIZE, MemoryState::ThreadLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_slots[available_page].set(available_slot);
|
tls_slots[available_page].set(available_slot);
|
||||||
|
|
||||||
return Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE +
|
return tls_begin + available_page * Memory::PAGE_SIZE + available_slot * Memory::TLS_ENTRY_SIZE;
|
||||||
available_slot * Memory::TLS_ENTRY_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::FreeTLSSlot(VAddr tls_address) {
|
void Process::FreeTLSSlot(VAddr tls_address) {
|
||||||
const VAddr tls_base = tls_address - Memory::TLS_AREA_VADDR;
|
const VAddr tls_base = tls_address - vm_manager.GetTLSIORegionBaseAddress();
|
||||||
const VAddr tls_page = tls_base / Memory::PAGE_SIZE;
|
const VAddr tls_page = tls_base / Memory::PAGE_SIZE;
|
||||||
const VAddr tls_slot = (tls_base % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
|
const VAddr tls_slot = (tls_base % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
|
||||||
|
|
||||||
|
@ -240,8 +240,8 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
|
ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
|
||||||
if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END ||
|
if (target < vm_manager.GetHeapRegionBaseAddress() ||
|
||||||
target + size < target) {
|
target + size > vm_manager.GetHeapRegionEndAddress() || target + size < target) {
|
||||||
return ERR_INVALID_ADDRESS;
|
return ERR_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,8 +276,8 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode Process::HeapFree(VAddr target, u32 size) {
|
ResultCode Process::HeapFree(VAddr target, u32 size) {
|
||||||
if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END ||
|
if (target < vm_manager.GetHeapRegionBaseAddress() ||
|
||||||
target + size < target) {
|
target + size > vm_manager.GetHeapRegionEndAddress() || target + size < target) {
|
||||||
return ERR_INVALID_ADDRESS;
|
return ERR_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/errors.h"
|
#include "core/hle/kernel/errors.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/shared_memory.h"
|
#include "core/hle/kernel/shared_memory.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
|
@ -71,7 +72,8 @@ SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
|
||||||
shared_memory->other_permissions = other_permissions;
|
shared_memory->other_permissions = other_permissions;
|
||||||
shared_memory->backing_block = std::move(heap_block);
|
shared_memory->backing_block = std::move(heap_block);
|
||||||
shared_memory->backing_block_offset = offset;
|
shared_memory->backing_block_offset = offset;
|
||||||
shared_memory->base_address = Memory::HEAP_VADDR + offset;
|
shared_memory->base_address =
|
||||||
|
kernel.CurrentProcess()->vm_manager.GetHeapRegionBaseAddress() + offset;
|
||||||
|
|
||||||
return shared_memory;
|
return shared_memory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,8 +51,9 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& process = *Core::CurrentProcess();
|
auto& process = *Core::CurrentProcess();
|
||||||
|
const VAddr heap_base = process.vm_manager.GetHeapRegionBaseAddress();
|
||||||
CASCADE_RESULT(*heap_addr,
|
CASCADE_RESULT(*heap_addr,
|
||||||
process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite));
|
process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite));
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,8 +262,9 @@ SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 pri
|
||||||
SetCurrentPageTable(&owner_process.vm_manager.page_table);
|
SetCurrentPageTable(&owner_process.vm_manager.page_table);
|
||||||
|
|
||||||
// Initialize new "main" thread
|
// Initialize new "main" thread
|
||||||
|
const VAddr stack_top = owner_process.vm_manager.GetTLSIORegionEndAddress();
|
||||||
auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0,
|
auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0,
|
||||||
Memory::STACK_AREA_VADDR_END, &owner_process);
|
stack_top, &owner_process);
|
||||||
|
|
||||||
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
|
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/loader/deconstructed_rom_directory.h"
|
#include "core/loader/deconstructed_rom_directory.h"
|
||||||
#include "core/loader/nso.h"
|
#include "core/loader/nso.h"
|
||||||
#include "core/memory.h"
|
|
||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
|
|
||||||
|
@ -134,7 +133,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
|
||||||
process->LoadFromMetadata(metadata);
|
process->LoadFromMetadata(metadata);
|
||||||
|
|
||||||
// Load NSO modules
|
// Load NSO modules
|
||||||
VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR};
|
const VAddr base_address = process->vm_manager.GetCodeRegionBaseAddress();
|
||||||
|
VAddr next_load_addr = base_address;
|
||||||
for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
|
for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
|
||||||
"subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
|
"subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
|
||||||
const FileSys::VirtualFile module_file = dir->GetFile(module);
|
const FileSys::VirtualFile module_file = dir->GetFile(module);
|
||||||
|
@ -147,8 +147,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(),
|
process->Run(base_address, metadata.GetMainThreadPriority(), metadata.GetMainThreadStackSize());
|
||||||
metadata.GetMainThreadStackSize());
|
|
||||||
|
|
||||||
// Find the RomFS by searching for a ".romfs" file in this directory
|
// Find the RomFS by searching for a ".romfs" file in this directory
|
||||||
const auto& files = dir->GetFiles();
|
const auto& files = dir->GetFiles();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
#include "core/loader/elf.h"
|
#include "core/loader/elf.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
|
@ -188,7 +189,7 @@ private:
|
||||||
|
|
||||||
u32* sectionAddrs;
|
u32* sectionAddrs;
|
||||||
bool relocate;
|
bool relocate;
|
||||||
u32 entryPoint;
|
VAddr entryPoint;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ElfReader(void* ptr);
|
explicit ElfReader(void* ptr);
|
||||||
|
@ -204,13 +205,13 @@ public:
|
||||||
ElfMachine GetMachine() const {
|
ElfMachine GetMachine() const {
|
||||||
return (ElfMachine)(header->e_machine);
|
return (ElfMachine)(header->e_machine);
|
||||||
}
|
}
|
||||||
u32 GetEntryPoint() const {
|
VAddr GetEntryPoint() const {
|
||||||
return entryPoint;
|
return entryPoint;
|
||||||
}
|
}
|
||||||
u32 GetFlags() const {
|
u32 GetFlags() const {
|
||||||
return (u32)(header->e_flags);
|
return (u32)(header->e_flags);
|
||||||
}
|
}
|
||||||
SharedPtr<CodeSet> LoadInto(u32 vaddr);
|
SharedPtr<CodeSet> LoadInto(VAddr vaddr);
|
||||||
|
|
||||||
int GetNumSegments() const {
|
int GetNumSegments() const {
|
||||||
return (int)(header->e_phnum);
|
return (int)(header->e_phnum);
|
||||||
|
@ -273,7 +274,7 @@ const char* ElfReader::GetSectionName(int section) const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
|
SharedPtr<CodeSet> ElfReader::LoadInto(VAddr vaddr) {
|
||||||
LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx);
|
LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx);
|
||||||
|
|
||||||
// Should we relocate?
|
// Should we relocate?
|
||||||
|
@ -288,11 +289,11 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
|
||||||
LOG_DEBUG(Loader, "{} segments:", header->e_phnum);
|
LOG_DEBUG(Loader, "{} segments:", header->e_phnum);
|
||||||
|
|
||||||
// First pass : Get the bits into RAM
|
// First pass : Get the bits into RAM
|
||||||
u32 base_addr = relocate ? vaddr : 0;
|
const VAddr base_addr = relocate ? vaddr : 0;
|
||||||
|
|
||||||
u32 total_image_size = 0;
|
u64 total_image_size = 0;
|
||||||
for (unsigned int i = 0; i < header->e_phnum; ++i) {
|
for (unsigned int i = 0; i < header->e_phnum; ++i) {
|
||||||
Elf32_Phdr* p = &segments[i];
|
const Elf32_Phdr* p = &segments[i];
|
||||||
if (p->p_type == PT_LOAD) {
|
if (p->p_type == PT_LOAD) {
|
||||||
total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF;
|
total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +306,7 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
|
||||||
SharedPtr<CodeSet> codeset = CodeSet::Create(kernel, "");
|
SharedPtr<CodeSet> codeset = CodeSet::Create(kernel, "");
|
||||||
|
|
||||||
for (unsigned int i = 0; i < header->e_phnum; ++i) {
|
for (unsigned int i = 0; i < header->e_phnum; ++i) {
|
||||||
Elf32_Phdr* p = &segments[i];
|
const Elf32_Phdr* p = &segments[i];
|
||||||
LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type,
|
LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type,
|
||||||
p->p_vaddr, p->p_filesz, p->p_memsz);
|
p->p_vaddr, p->p_filesz, p->p_memsz);
|
||||||
|
|
||||||
|
@ -332,8 +333,8 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 segment_addr = base_addr + p->p_vaddr;
|
const VAddr segment_addr = base_addr + p->p_vaddr;
|
||||||
u32 aligned_size = (p->p_memsz + 0xFFF) & ~0xFFF;
|
const u32 aligned_size = (p->p_memsz + 0xFFF) & ~0xFFF;
|
||||||
|
|
||||||
codeset_segment->offset = current_image_position;
|
codeset_segment->offset = current_image_position;
|
||||||
codeset_segment->addr = segment_addr;
|
codeset_segment->addr = segment_addr;
|
||||||
|
@ -394,8 +395,9 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
|
||||||
if (buffer.size() != file->GetSize())
|
if (buffer.size() != file->GetSize())
|
||||||
return ResultStatus::ErrorIncorrectELFFileSize;
|
return ResultStatus::ErrorIncorrectELFFileSize;
|
||||||
|
|
||||||
|
const VAddr base_address = process->vm_manager.GetCodeRegionBaseAddress();
|
||||||
ElfReader elf_reader(&buffer[0]);
|
ElfReader elf_reader(&buffer[0]);
|
||||||
SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR);
|
SharedPtr<CodeSet> codeset = elf_reader.LoadInto(base_address);
|
||||||
codeset->name = file->GetName();
|
codeset->name = file->GetName();
|
||||||
|
|
||||||
process->LoadModule(codeset, codeset->entrypoint);
|
process->LoadModule(codeset, codeset->entrypoint);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "core/gdbstub/gdbstub.h"
|
#include "core/gdbstub/gdbstub.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
#include "core/loader/nro.h"
|
#include "core/loader/nro.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
|
@ -180,13 +181,13 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load NRO
|
// Load NRO
|
||||||
static constexpr VAddr base_addr{Memory::PROCESS_IMAGE_VADDR};
|
const VAddr base_address = process->vm_manager.GetCodeRegionBaseAddress();
|
||||||
|
|
||||||
if (!LoadNro(file, base_addr)) {
|
if (!LoadNro(file, base_address)) {
|
||||||
return ResultStatus::ErrorLoadingNRO;
|
return ResultStatus::ErrorLoadingNRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
process->Run(base_addr, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE);
|
process->Run(base_address, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE);
|
||||||
|
|
||||||
is_loaded = true;
|
is_loaded = true;
|
||||||
return ResultStatus::Success;
|
return ResultStatus::Success;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "core/gdbstub/gdbstub.h"
|
#include "core/gdbstub/gdbstub.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
#include "core/loader/nso.h"
|
#include "core/loader/nso.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
|
@ -158,11 +159,11 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load module
|
// Load module
|
||||||
LoadModule(file, Memory::PROCESS_IMAGE_VADDR);
|
const VAddr base_address = process->vm_manager.GetCodeRegionBaseAddress();
|
||||||
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), Memory::PROCESS_IMAGE_VADDR);
|
LoadModule(file, base_address);
|
||||||
|
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address);
|
||||||
|
|
||||||
process->Run(Memory::PROCESS_IMAGE_VADDR, Kernel::THREADPRIO_DEFAULT,
|
process->Run(base_address, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE);
|
||||||
Memory::DEFAULT_STACK_SIZE);
|
|
||||||
|
|
||||||
is_loaded = true;
|
is_loaded = true;
|
||||||
return ResultStatus::Success;
|
return ResultStatus::Success;
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
#include "core/hle/lock.h"
|
#include "core/hle/lock.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/memory_setup.h"
|
#include "core/memory_setup.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/video_core.h"
|
|
||||||
|
|
||||||
namespace Memory {
|
namespace Memory {
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VAddr end = start + size;
|
const VAddr end = start + size;
|
||||||
|
|
||||||
const auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
|
const auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
|
||||||
if (start >= region_end || end <= region_start) {
|
if (start >= region_end || end <= region_start) {
|
||||||
|
@ -347,7 +347,7 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) {
|
||||||
|
|
||||||
const VAddr overlap_start = std::max(start, region_start);
|
const VAddr overlap_start = std::max(start, region_start);
|
||||||
const VAddr overlap_end = std::min(end, region_end);
|
const VAddr overlap_end = std::min(end, region_end);
|
||||||
const u64 overlap_size = overlap_end - overlap_start;
|
const VAddr overlap_size = overlap_end - overlap_start;
|
||||||
|
|
||||||
auto& rasterizer = system_instance.Renderer().Rasterizer();
|
auto& rasterizer = system_instance.Renderer().Rasterizer();
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
@ -363,8 +363,10 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CheckRegion(PROCESS_IMAGE_VADDR, PROCESS_IMAGE_VADDR_END);
|
const auto& vm_manager = Core::CurrentProcess()->vm_manager;
|
||||||
CheckRegion(HEAP_VADDR, HEAP_VADDR_END);
|
|
||||||
|
CheckRegion(vm_manager.GetCodeRegionBaseAddress(), vm_manager.GetCodeRegionEndAddress());
|
||||||
|
CheckRegion(vm_manager.GetHeapRegionBaseAddress(), vm_manager.GetHeapRegionEndAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 Read8(const VAddr addr) {
|
u8 Read8(const VAddr addr) {
|
||||||
|
|
|
@ -93,11 +93,6 @@ struct PageTable {
|
||||||
|
|
||||||
/// Virtual user-space memory regions
|
/// Virtual user-space memory regions
|
||||||
enum : VAddr {
|
enum : VAddr {
|
||||||
/// Where the application text, data and bss reside.
|
|
||||||
PROCESS_IMAGE_VADDR = 0x08000000,
|
|
||||||
PROCESS_IMAGE_MAX_SIZE = 0x08000000,
|
|
||||||
PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
|
|
||||||
|
|
||||||
/// Read-only page containing kernel and system configuration values.
|
/// Read-only page containing kernel and system configuration values.
|
||||||
CONFIG_MEMORY_VADDR = 0x1FF80000,
|
CONFIG_MEMORY_VADDR = 0x1FF80000,
|
||||||
CONFIG_MEMORY_SIZE = 0x00001000,
|
CONFIG_MEMORY_SIZE = 0x00001000,
|
||||||
|
@ -108,36 +103,12 @@ enum : VAddr {
|
||||||
SHARED_PAGE_SIZE = 0x00001000,
|
SHARED_PAGE_SIZE = 0x00001000,
|
||||||
SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
|
SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
|
||||||
|
|
||||||
/// Area where TLS (Thread-Local Storage) buffers are allocated.
|
/// TLS (Thread-Local Storage) related.
|
||||||
TLS_AREA_VADDR = 0x40000000,
|
|
||||||
TLS_ENTRY_SIZE = 0x200,
|
TLS_ENTRY_SIZE = 0x200,
|
||||||
TLS_AREA_SIZE = 0x10000000,
|
|
||||||
TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
|
|
||||||
|
|
||||||
/// Application stack
|
/// Application stack
|
||||||
STACK_AREA_VADDR = TLS_AREA_VADDR_END,
|
|
||||||
STACK_AREA_SIZE = 0x10000000,
|
|
||||||
STACK_AREA_VADDR_END = STACK_AREA_VADDR + STACK_AREA_SIZE,
|
|
||||||
DEFAULT_STACK_SIZE = 0x100000,
|
DEFAULT_STACK_SIZE = 0x100000,
|
||||||
|
|
||||||
/// Application heap
|
|
||||||
/// Size is confirmed to be a static value on fw 3.0.0
|
|
||||||
HEAP_VADDR = 0x108000000,
|
|
||||||
HEAP_SIZE = 0x180000000,
|
|
||||||
HEAP_VADDR_END = HEAP_VADDR + HEAP_SIZE,
|
|
||||||
|
|
||||||
/// New map region
|
|
||||||
/// Size is confirmed to be a static value on fw 3.0.0
|
|
||||||
NEW_MAP_REGION_VADDR = HEAP_VADDR_END,
|
|
||||||
NEW_MAP_REGION_SIZE = 0x80000000,
|
|
||||||
NEW_MAP_REGION_VADDR_END = NEW_MAP_REGION_VADDR + NEW_MAP_REGION_SIZE,
|
|
||||||
|
|
||||||
/// Map region
|
|
||||||
/// Size is confirmed to be a static value on fw 3.0.0
|
|
||||||
MAP_REGION_VADDR = NEW_MAP_REGION_VADDR_END,
|
|
||||||
MAP_REGION_SIZE = 0x1000000000,
|
|
||||||
MAP_REGION_VADDR_END = MAP_REGION_VADDR + MAP_REGION_SIZE,
|
|
||||||
|
|
||||||
/// Kernel Virtual Address Range
|
/// Kernel Virtual Address Range
|
||||||
KERNEL_REGION_VADDR = 0xFFFFFF8000000000,
|
KERNEL_REGION_VADDR = 0xFFFFFF8000000000,
|
||||||
KERNEL_REGION_SIZE = 0x7FFFE00000,
|
KERNEL_REGION_SIZE = 0x7FFFE00000,
|
||||||
|
|
Loading…
Reference in a new issue