From 06facfc567c9c5f5e136071715ad4f7b3b061e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 17 Aug 2019 11:52:09 +0200 Subject: [PATCH] Android: Get our base pointer in a saner way than YOLO, if possible. Should help #12249. --- Common/MemArenaAndroid.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Common/MemArenaAndroid.cpp b/Common/MemArenaAndroid.cpp index 0ff75317cf..31eda9d3d0 100644 --- a/Common/MemArenaAndroid.cpp +++ b/Common/MemArenaAndroid.cpp @@ -19,6 +19,7 @@ #ifdef __ANDROID__ +#include "base/logging.h" #include "MemoryUtil.h" #include "MemArena.h" #include "StringUtils.h" @@ -102,12 +103,28 @@ void MemArena::ReleaseView(void* view, size_t size) { u8* MemArena::Find4GBBase() { #if PPSSPP_ARCH(64BIT) - // Just grab some random 4GB... - return reinterpret_cast(0x2300000000ULL); + // We should probably just go look in /proc/self/maps for some free space. + // But let's try the anonymous mmap trick, just like on 32-bit, but bigger and + // aligned to 4GB for the movk trick. We can ensure that we get an aligned 4GB + // address by grabbing 8GB and aligning the pointer. + const uint64_t EIGHT_GIGS = 0x200000000ULL; + void *base = mmap(0, EIGHT_GIGS, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); + if (base) { + ILOG("base: %p", base); + uint64_t aligned_base = ((uint64_t)base + 0xFFFFFFFF) & ~0xFFFFFFFFULL; + ILOG("aligned_base: %p", (void *)aligned_base); + munmap(base, EIGHT_GIGS); + return reinterpret_cast(aligned_base); + } else { + u8 *hardcoded_ptr = reinterpret_cast(0x2300000000ULL); + ILOG("Failed to anonymously map 8GB. Fall back to the hardcoded pointer %p.", hardcoded_ptr); + // Just grab some random 4GB... + // This has been known to fail lately though, see issue #12249. + return hardcoded_ptr; + } #else // Address masking is used in 32-bit mode, so we can get away with less memory. - void* base = mmap(0, 0x10000000, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_SHARED, -1, 0); + void* base = mmap(0, 0x10000000, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); if (base == MAP_FAILED) { PanicAlert("Failed to map 256 MB of memory space: %s", strerror(errno)); return 0;