yuzu-emu
/
yuzu
Archived
1
0
Fork 0

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:
Lioncash 2018-09-24 20:01:45 -04:00
parent 6c6f95d071
commit 83377113bf
11 changed files with 60 additions and 75 deletions

View File

@ -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");
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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,