12 /* This function returns true if the interval [old,new]
13 * intersects the 'len'-sized interval below &libc.auxv
14 * (interpreted as the main-thread stack) or below &b
15 * (the current stack). It is used to defend against
16 * buggy brk implementations that can cross the stack. */
18 static int traverses_stack_p(uintptr_t old
, uintptr_t new)
20 const uintptr_t len
= 8<<20;
23 b
= (uintptr_t)libc
.auxv
;
24 a
= b
> len
? b
-len
: 0;
25 if (new>a
&& old
<b
) return 1;
28 a
= b
> len
? b
-len
: 0;
29 if (new>a
&& old
<b
) return 1;
34 static void *__simple_malloc(size_t n
)
36 static uintptr_t brk
, cur
, end
;
37 static volatile int lock
[1];
38 static unsigned mmap_step
;
48 while (align
<n
&& align
<ALIGN
)
53 cur
+= -cur
& align
-1;
56 size_t req
= n
- (end
-cur
) + PAGE_SIZE
-1 & -PAGE_SIZE
;
59 brk
= __syscall(SYS_brk
, 0);
60 brk
+= -brk
& PAGE_SIZE
-1;
64 if (brk
== end
&& req
< SIZE_MAX
-brk
65 && !traverses_stack_p(brk
, brk
+req
)
66 && __syscall(SYS_brk
, brk
+req
)==brk
+req
) {
70 req
= n
+ PAGE_SIZE
-1 & -PAGE_SIZE
;
71 /* Only make a new area rather than individual mmap
72 * if wasted space would be over 1/8 of the map. */
74 /* Geometric area size growth up to 64 pages,
75 * bounding waste by 1/8 of the area. */
76 size_t min
= PAGE_SIZE
<<(mmap_step
/2);
77 if (min
-n
> end
-cur
) {
86 void *mem
= __mmap(0, req
, PROT_READ
|PROT_WRITE
,
87 MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
88 if (mem
== MAP_FAILED
|| !new_area
) {
90 return mem
==MAP_FAILED
? 0 : mem
;
103 weak_alias(__simple_malloc
, malloc
);
105 static void *__simple_calloc(size_t m
, size_t n
)
107 if (n
&& m
> (size_t)-1/n
) {
111 return __simple_malloc(n
* m
);
114 weak_alias(__simple_calloc
, calloc
);