From 313cc36fecbcc0fd55ee9c81776071b62326b7e2 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Fri, 5 Jul 2019 21:49:11 -0400
Subject: [PATCH] kernel/vm_manager: Handle stack/TLS IO region placement
 better

Handles the placement of the stack a little nicer compared to the
previous code, which was off in a few ways. e.g.

The stack (new map) region, shouldn't be the width of the entire address
space if the size of the region calculation ends up being zero. It
should be placed at the same location as the TLS IO region and also have
the same size.

In the event the TLS IO region contains a size of zero, we should also
be doing the same thing. This fixes our memory layout a little bit and
also resolves some cases where assertions can trigger due to the memory
layout being incorrect.
---
 src/core/hle/kernel/vm_manager.cpp | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 3df5ccb7fb..568f49c3fd 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -628,6 +628,8 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
     u64 new_map_region_size = 0;
     u64 tls_io_region_size = 0;
 
+    u64 stack_and_tls_io_end = 0;
+
     switch (type) {
     case FileSys::ProgramAddressSpaceType::Is32Bit:
     case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
@@ -643,6 +645,7 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
             map_region_size = 0;
             heap_region_size = 0x80000000;
         }
+        stack_and_tls_io_end = 0x40000000;
         break;
     case FileSys::ProgramAddressSpaceType::Is36Bit:
         address_space_width = 36;
@@ -652,6 +655,7 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
         aslr_region_end = aslr_region_base + 0xFF8000000;
         map_region_size = 0x180000000;
         heap_region_size = 0x180000000;
+        stack_and_tls_io_end = 0x80000000;
         break;
     case FileSys::ProgramAddressSpaceType::Is39Bit:
         address_space_width = 39;
@@ -669,6 +673,8 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
         return;
     }
 
+    const u64 stack_and_tls_io_begin = aslr_region_base;
+
     address_space_base = 0;
     address_space_end = 1ULL << address_space_width;
 
@@ -686,8 +692,13 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
     tls_io_region_end = tls_io_region_base + tls_io_region_size;
 
     if (new_map_region_size == 0) {
-        new_map_region_base = address_space_base;
-        new_map_region_end = address_space_end;
+        new_map_region_base = stack_and_tls_io_begin;
+        new_map_region_end = stack_and_tls_io_end;
+    }
+
+    if (tls_io_region_size == 0) {
+        tls_io_region_base = stack_and_tls_io_begin;
+        tls_io_region_end = stack_and_tls_io_end;
     }
 }