1 /* Test for the brk syscall wrapper. */
2 
3 #include <assert.h>
4 #include <errno.h>
5 #include <stddef.h>
6 #include <sys/syscall.h>
7 
8 /* Data segment end. */
9 extern int _end;
10 static char *begin = (char *)&_end;
11 
12 __attribute__((noinline))
test_begin(void)13 static int test_begin(void)
14 {
15    int res = 0;
16    int tmp;
17 
18    /* Check that a value at the break is inaccessible. */
19    if (*begin)
20       res++;
21 
22    /* Allocate one byte and check that the last byte is accessible and
23       initialized. */
24    tmp = syscall(SYS_brk, begin + 1);
25    assert(tmp != -1);
26    if (*begin)
27       res++;
28 
29    /* Deallocate one byte and check that the last byte is now inaccessible. */
30    tmp = syscall(SYS_brk, begin);
31    assert(tmp != -1);
32    if (*begin)
33       res++;
34 
35    return res;
36 }
37 
38 __attribute__((noinline))
test_updown(void)39 static void test_updown(void)
40 {
41    int tmp;
42    size_t i;
43 
44 #define MAX_SIZE 8192
45    /* Run up phase. */
46    for (i = 0; i < MAX_SIZE; i++) {
47       tmp = syscall(SYS_brk, begin + i);
48       assert(tmp != -1);
49    }
50 
51    /* Run down phase. */
52    for (i = 0; i < MAX_SIZE; i++) {
53       tmp = syscall(SYS_brk, begin + MAX_SIZE - 1 - i);
54       assert(tmp != -1);
55    }
56 #undef MAX_SIZE
57 }
58 
59 __attribute__((noinline))
test_range(void)60 static void test_range(void)
61 {
62    int tmp;
63 
64    tmp = syscall(SYS_brk, begin - 1);
65    assert(tmp == -1);
66    assert(errno == ENOMEM);
67 
68    /* Unified limit for 64-bit and 32-bit version. */
69    unsigned long long impossible_limit = 0xffffff4fffffffULL;
70    tmp = syscall(SYS_brk, impossible_limit);
71    assert(tmp == -1);
72    assert(errno == ENOMEM);
73 }
74 
main(void)75 int main(void)
76 {
77    int res;
78    res = test_begin();
79    test_updown();
80    test_range();
81    return res;
82 }
83 
84