Skip to content

Commit a1b7204

Browse files
committed
Add pool allocator patch
1 parent b04fdf0 commit a1b7204

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

overlays/bootstrap.nix

+1
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ in {
282282
++ final.lib.optional (versionAtLeast "9.6.1" && versionLessThan"9.10" && (final.stdenv.targetPlatform != final.stdenv.hostPlatform)) ./patches/ghc/5c80a27488acfe3610ddfcb99a1e961002e386d0.patch
283283
++ final.lib.optional (versionAtLeast "9.6.1" && versionLessThan"9.10" && (final.stdenv.targetPlatform != final.stdenv.hostPlatform)) ./patches/ghc/f8beb54a1d5725bd0d8a4b0a909d1b41d742b50b.patch
284284
++ final.lib.optional (versionAtLeast "9.6" && versionLessThan "9.9" && (final.stdenv.targetPlatform.isAndroid && final.stdenv.targetPlatform.is32bit || final.stdenv.targetPlatform.isMusl)) ./patches/ghc/ghc-9.6-missing-symbols-deadbeef.patch
285+
++ final.lib.optional (versionAtLeast "9.6" && versionLessThan "9.9" && final.stdenv.targetPlatform.isMusl) ./patches/ghc/ghc-9.6-linker-pool-allocator.patch
285286
# These two patches are needed for libblst, which has now hidden symbols, which the linker doesn't know how to deal with.
286287
++ final.lib.optional (versionAtLeast "8.10" && versionLessThan "8.11") ./patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols.patch
287288
++ final.lib.optional (versionAtLeast "8.10" && versionLessThan "8.11") ./patches/ghc/ghc-8.10-0006-Adds-support-for-Hidden-symbols-2.patch
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
diff --git a/rts/Linker.c b/rts/Linker.c
2+
index b1c533a..ad76b30 100644
3+
--- a/rts/Linker.c
4+
+++ b/rts/Linker.c
5+
@@ -1839,6 +1839,7 @@ HsInt resolveObjs (void)
6+
{
7+
ACQUIRE_LOCK(&linker_mutex);
8+
HsInt r = resolveObjs_();
9+
+ memPoolProtect();
10+
RELEASE_LOCK(&linker_mutex);
11+
return r;
12+
}
13+
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
14+
index bab2ca3..5c9608c 100644
15+
--- a/rts/linker/Elf.c
16+
+++ b/rts/linker/Elf.c
17+
@@ -131,6 +131,56 @@
18+
https://refspecs.linuxfoundation.org/elf/gabi4+/contents.html
19+
20+
*/
21+
+void * memPoolAlloc(SectionKind kind, StgWord size);
22+
+
23+
+void * __pool = NULL;
24+
+void * __pool_rw_offset = NULL;
25+
+void * __pool_rx_offset = NULL;
26+
+
27+
+void memPoolProtect( void ) {
28+
+ if(__pool != NULL) {
29+
+ mprotect(__pool, 512*1024*1024, PROT_READ | PROT_WRITE);
30+
+ mprotect((void*)((uintptr_t)__pool + 512*1024*1024), 512*1024*1024, PROT_READ | PROT_WRITE | PROT_EXEC);
31+
+ }
32+
+}
33+
+
34+
+void * memPoolAlloc(SectionKind kind, StgWord size) {
35+
+ if(__pool == NULL) {
36+
+ // allocate 1 GB of virtual memory.
37+
+ __pool = mmapAnonForLinker(1024*1024*1024);
38+
+ if(__pool == NULL) {
39+
+ printf("Failed to allocate memory pool\n");
40+
+ fflush(stdout);
41+
+ return NULL;
42+
+ }
43+
+ __pool_rw_offset = (void*)((uintptr_t)__pool + 512*1024*1024);
44+
+ __pool_rx_offset = __pool_rw_offset;
45+
+ }
46+
+ // align to 64 bytes
47+
+ StgWord alignedSize = (size + 0x3f) & ~0x3f;
48+
+ void * ret = NULL;
49+
+
50+
+ if(kind == SECTIONKIND_CODE_OR_RODATA) {
51+
+ ret = __pool_rx_offset;
52+
+ // printf("Allocated RX %p\n", ret);
53+
+ __pool_rx_offset = (void*)((uintptr_t)__pool_rx_offset + alignedSize);
54+
+ if((uintptr_t)__pool_rx_offset > (uintptr_t)__pool + 1024*1024*1024) {
55+
+ printf("Out of memory pool\n");
56+
+ fflush(stdout);
57+
+ return NULL;
58+
+ }
59+
+ } else {
60+
+ __pool_rw_offset = (void*)((uintptr_t)__pool_rw_offset - alignedSize);
61+
+ ret = __pool_rw_offset;
62+
+ // printf("Allocated RW %p\n", ret);
63+
+ if((uintptr_t)__pool_rw_offset < (uintptr_t)__pool) {
64+
+ printf("Out of memory pool\n");
65+
+ fflush(stdout);
66+
+ return NULL;
67+
+ }
68+
+ }
69+
+ return ret;
70+
+}
71+
72+
#if defined(SHN_XINDEX)
73+
/* global variable which address is used to signal an uninitialised shndx_table */
74+
@@ -813,7 +863,8 @@ ocGetNames_ELF ( ObjectCode* oc )
75+
* address might be out of range for sections that are mmaped.
76+
*/
77+
alloc = SECTION_MMAP;
78+
- start = mmapAnonForLinker(size);
79+
+ start = memPoolAlloc(kind, size);
80+
+ // mmapAnonForLinker(size);
81+
if (start == NULL) {
82+
barf("failed to mmap memory for bss. "
83+
"errno = %d", errno);
84+
@@ -860,7 +911,8 @@ ocGetNames_ELF ( ObjectCode* oc )
85+
unsigned nstubs = numberOfStubsForSection(oc, i);
86+
unsigned stub_space = STUB_SIZE * nstubs;
87+
88+
- void * mem = mmapAnonForLinker(size+stub_space);
89+
+ void * mem = memPoolAlloc(kind, stub_space + size);
90+
+ // void * mem = mmapAnonForLinker(size+stub_space);
91+
92+
if( mem == MAP_FAILED ) {
93+
barf("failed to mmap allocated memory to load section %d. "
94+
@@ -967,7 +1019,8 @@ ocGetNames_ELF ( ObjectCode* oc )
95+
}
96+
void * common_mem = NULL;
97+
if(common_size > 0) {
98+
- common_mem = mmapAnonForLinker(common_size);
99+
+ common_mem = // mmapAnonForLinker(common_size);
100+
+ memPoolAlloc(SECTIONKIND_RWDATA, common_size);
101+
if (common_mem == NULL) {
102+
barf("ocGetNames_ELF: Failed to allocate memory for SHN_COMMONs");
103+
}
104+
@@ -2020,7 +2073,8 @@ ocResolve_ELF ( ObjectCode* oc )
105+
ocFlushInstructionCache( oc );
106+
#endif
107+
108+
- return ocMprotect_Elf(oc);
109+
+ // return ocMprotect_Elf(oc);
110+
+ return true;
111+
}
112+
113+
/*
114+
diff --git a/rts/linker/Elf.h b/rts/linker/Elf.h
115+
index 2b9ad87..cf7a541 100644
116+
--- a/rts/linker/Elf.h
117+
+++ b/rts/linker/Elf.h
118+
@@ -16,5 +16,6 @@ int ocRunFini_ELF ( ObjectCode* oc );
119+
int ocAllocateExtras_ELF ( ObjectCode *oc );
120+
void freeNativeCode_ELF ( ObjectCode *nc );
121+
void *loadNativeObj_ELF ( pathchar *path, char **errmsg );
122+
+void memPoolProtect ( void );
123+
124+
#include "EndPrivate.h"

0 commit comments

Comments
 (0)