Skip to content

Commit 5290d64

Browse files
committed
allocateHeaps: clamp app heap to heap VMA area size
Heap allocation is limited to 96MiB by kernel, which breaks this function on N3DS when using higher memory modes. Grow linear heap instead, if user didn't force linear heap size.
1 parent 9b55eda commit 5290d64

1 file changed

Lines changed: 16 additions & 5 deletions

File tree

‎libctru/source/system/allocateHeaps.c‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
#include <3ds/os.h>
55
#include <3ds/result.h>
66

7-
#define HEAP_SPLIT_SIZE_CAP (24 << 20) // 24MB
8-
#define LINEAR_HEAP_SIZE_CAP (32 << 20) // 32MB
7+
#define HEAP_SPLIT_SIZE_CAP (24 << 20) // 24MiB
8+
#define LINEAR_HEAP_SIZE_CAP (32 << 20) // 32MiB
9+
#define HEAP_AREA_SIZE (OS_HEAP_AREA_END - OS_HEAP_AREA_BEGIN) // 96 MiB
910

1011
extern char* fake_heap_start;
1112
extern char* fake_heap_end;
@@ -38,7 +39,10 @@ void __attribute__((weak)) __system_allocateHeaps(void) {
3839
if (__ctru_heap_size + __ctru_linear_heap_size > remaining)
3940
svcBreak(USERBREAK_PANIC);
4041

41-
if (__ctru_heap_size == 0 && __ctru_linear_heap_size == 0) {
42+
bool auto_app_sz = __ctru_heap_size == 0;
43+
bool auto_linear_sz = __ctru_linear_heap_size == 0;
44+
45+
if (auto_app_sz && auto_linear_sz) {
4246
// Split available memory equally between linear and application heaps (with rounding in favor of the latter)
4347
__ctru_linear_heap_size = (remaining / 2) & ~0xFFF;
4448
__ctru_heap_size = remaining - __ctru_linear_heap_size;
@@ -54,12 +58,19 @@ void __attribute__((weak)) __system_allocateHeaps(void) {
5458
__ctru_heap_size = remaining - __ctru_linear_heap_size;
5559
}
5660
}
57-
} else if (__ctru_heap_size == 0) {
61+
} else if (auto_app_sz) {
5862
__ctru_heap_size = remaining - __ctru_linear_heap_size;
59-
} else if (__ctru_linear_heap_size == 0) {
63+
} else if (auto_linear_sz) {
6064
__ctru_linear_heap_size = remaining - __ctru_heap_size;
6165
}
6266

67+
if (__ctru_heap_size > HEAP_AREA_SIZE) {
68+
if (auto_linear_sz) {
69+
__ctru_linear_heap_size += __ctru_heap_size - HEAP_AREA_SIZE;
70+
}
71+
__ctru_heap_size = HEAP_AREA_SIZE;
72+
}
73+
6374
// Allocate the application heap
6475
rc = svcControlMemory(&__ctru_heap, OS_HEAP_AREA_BEGIN, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
6576
if (R_FAILED(rc))

0 commit comments

Comments
 (0)