/* Test for the brk syscall wrapper. */
#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <sys/syscall.h>
/* Data segment end. */
extern int _end;
static char *begin = (char *)&_end;
__attribute__((noinline))
static int test_begin(void)
{
int res = 0;
int tmp;
/* Check that a value at the break is inaccessible. */
if (*begin)
res++;
/* Allocate one byte and check that the last byte is accessible and
initialized. */
tmp = syscall(SYS_brk, begin + 1);
assert(tmp != -1);
if (*begin)
res++;
/* Deallocate one byte and check that the last byte is now inaccessible. */
tmp = syscall(SYS_brk, begin);
assert(tmp != -1);
if (*begin)
res++;
return res;
}
__attribute__((noinline))
static void test_updown(void)
{
int tmp;
size_t i;
#define MAX_SIZE 8192
/* Run up phase. */
for (i = 0; i < MAX_SIZE; i++) {
tmp = syscall(SYS_brk, begin + i);
assert(tmp != -1);
}
/* Run down phase. */
for (i = 0; i < MAX_SIZE; i++) {
tmp = syscall(SYS_brk, begin + MAX_SIZE - 1 - i);
assert(tmp != -1);
}
#undef MAX_SIZE
}
__attribute__((noinline))
static void test_range(void)
{
int tmp;
tmp = syscall(SYS_brk, begin - 1);
assert(tmp == -1);
assert(errno == ENOMEM);
/* Unified limit for 64-bit and 32-bit version. */
unsigned long long impossible_limit = 0xffffff4fffffffULL;
tmp = syscall(SYS_brk, impossible_limit);
assert(tmp == -1);
assert(errno == ENOMEM);
}
int main(void)
{
int res;
res = test_begin();
test_updown();
test_range();
return res;
}