From b30a79c7fe3b33103256063dcff479b84c17ced8 Mon Sep 17 00:00:00 2001
From: Bananymous <oskari.alaranta@bananymous.com>
Date: Sat, 1 Feb 2025 22:25:22 +0200
Subject: [PATCH] Kernel: Temporary hack to "fix" munmap

My current munmap implementation does not support partial unmaps and
GCC relies on this behaviour. This patch removes unmapping if the
address and len does not fully contain the mmap region.
---
 kernel/kernel/Process.cpp | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp
index e6744a2a..f6ac31b0 100644
--- a/kernel/kernel/Process.cpp
+++ b/kernel/kernel/Process.cpp
@@ -1739,16 +1739,29 @@ namespace Kernel
 		if (len == 0)
 			return BAN::Error::from_errno(EINVAL);
 
-		vaddr_t vaddr = (vaddr_t)addr;
+		const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
 		if (vaddr % PAGE_SIZE != 0)
 			return BAN::Error::from_errno(EINVAL);
 
+		if (auto rem = len % PAGE_SIZE)
+			len += PAGE_SIZE - rem;
+
 		LockGuard _(m_process_lock);
 
-		// FIXME: We should only map partial regions
+		// FIXME: We should unmap partial regions.
+		//        This is a hack to only unmap if the whole mmap region
+		//        is contained within [addr, addr + len]
 		for (size_t i = 0; i < m_mapped_regions.size(); i++)
-			if (m_mapped_regions[i]->overlaps(vaddr, len))
-				m_mapped_regions.remove(i);
+		{
+			auto& region = m_mapped_regions[i];
+
+			const vaddr_t region_s = region->vaddr();
+			const vaddr_t region_e = region->vaddr() + region->size();
+			if (vaddr <= region_s && region_e <= vaddr + len)
+				m_mapped_regions.remove(i--);
+			else if (region->overlaps(vaddr, len))
+				dwarnln("TODO: partial region munmap");
+		}
 
 		return 0;
 	}