13 /* This function returns true if the interval [old,new]
14 * intersects the 'len'-sized interval below &libc.auxv
15 * (interpreted as the main-thread stack) or below &b
16 * (the current stack). It is used to defend against
17 * buggy brk implementations that can cross the stack. */
19 static int traverses_stack_p(uintptr_t old
, uintptr_t new)
21 const uintptr_t len
= 8<<20;
24 b
= (uintptr_t)libc
.auxv
;
25 a
= b
> len
? b
-len
: 0;
26 if (new>a
&& old
<b
) return 1;
29 a
= b
> len
? b
-len
: 0;
30 if (new>a
&& old
<b
) return 1;
35 static volatile int lock
[1];
36 volatile int *const __bump_lockptr
= lock
;
38 static void *__simple_malloc(size_t n
)
40 static uintptr_t brk
, cur
, end
;
41 static unsigned mmap_step
;
51 while (align
<n
&& align
<ALIGN
)
56 cur
+= -cur
& align
-1;
59 size_t req
= n
- (end
-cur
) + PAGE_SIZE
-1 & -PAGE_SIZE
;
62 brk
= __syscall(SYS_brk
, 0);
63 brk
+= -brk
& PAGE_SIZE
-1;
67 if (brk
== end
&& req
< SIZE_MAX
-brk
68 && !traverses_stack_p(brk
, brk
+req
)
69 && __syscall(SYS_brk
, brk
+req
)==brk
+req
) {
73 req
= n
+ PAGE_SIZE
-1 & -PAGE_SIZE
;
74 /* Only make a new area rather than individual mmap
75 * if wasted space would be over 1/8 of the map. */
77 /* Geometric area size growth up to 64 pages,
78 * bounding waste by 1/8 of the area. */
79 size_t min
= PAGE_SIZE
<<(mmap_step
/2);
80 if (min
-n
> end
-cur
) {
89 void *mem
= __mmap(0, req
, PROT_READ
|PROT_WRITE
,
90 MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
91 if (mem
== MAP_FAILED
|| !new_area
) {
93 return mem
==MAP_FAILED
? 0 : mem
;
106 weak_alias(__simple_malloc
, __libc_malloc_impl
);
108 void *__libc_malloc(size_t n
)
110 return __libc_malloc_impl(n
);
113 static void *default_malloc(size_t n
)
115 return __libc_malloc_impl(n
);
118 weak_alias(default_malloc
, malloc
);