xref: /llvm-project/compiler-rt/test/scudo/valloc.c (revision f7c5c0d87b8ae5e55006fd3a31994cd68d64f102)
1*f7c5c0d8SMitch Phillips // RUN: %clang_scudo %s -o %t
2*f7c5c0d8SMitch Phillips // RUN:                                                 %run %t valid   2>&1
3*f7c5c0d8SMitch Phillips // RUN:                                             not %run %t invalid 2>&1 | FileCheck %s
4*f7c5c0d8SMitch Phillips // RUN: %env_scudo_opts=allocator_may_return_null=1     %run %t invalid 2>&1
5*f7c5c0d8SMitch Phillips // UNSUPPORTED: android
6*f7c5c0d8SMitch Phillips 
7*f7c5c0d8SMitch Phillips // Tests that valloc and pvalloc work as intended.
8*f7c5c0d8SMitch Phillips 
9*f7c5c0d8SMitch Phillips #include <assert.h>
10*f7c5c0d8SMitch Phillips #include <errno.h>
11*f7c5c0d8SMitch Phillips #include <malloc.h>
12*f7c5c0d8SMitch Phillips #include <stdint.h>
13*f7c5c0d8SMitch Phillips #include <string.h>
14*f7c5c0d8SMitch Phillips #include <unistd.h>
15*f7c5c0d8SMitch Phillips 
round_up_to(size_t size,size_t alignment)16*f7c5c0d8SMitch Phillips size_t round_up_to(size_t size, size_t alignment) {
17*f7c5c0d8SMitch Phillips   return (size + alignment - 1) & ~(alignment - 1);
18*f7c5c0d8SMitch Phillips }
19*f7c5c0d8SMitch Phillips 
main(int argc,char ** argv)20*f7c5c0d8SMitch Phillips int main(int argc, char **argv) {
21*f7c5c0d8SMitch Phillips   void *p = NULL;
22*f7c5c0d8SMitch Phillips   size_t size, page_size;
23*f7c5c0d8SMitch Phillips 
24*f7c5c0d8SMitch Phillips   assert(argc == 2);
25*f7c5c0d8SMitch Phillips 
26*f7c5c0d8SMitch Phillips   page_size = sysconf(_SC_PAGESIZE);
27*f7c5c0d8SMitch Phillips   // Check that the page size is a power of two.
28*f7c5c0d8SMitch Phillips   assert((page_size & (page_size - 1)) == 0);
29*f7c5c0d8SMitch Phillips 
30*f7c5c0d8SMitch Phillips   if (!strcmp(argv[1], "valid")) {
31*f7c5c0d8SMitch Phillips     for (int i = (sizeof(void *) == 4) ? 3 : 4; i < 21; i++) {
32*f7c5c0d8SMitch Phillips       size = 1U << i;
33*f7c5c0d8SMitch Phillips       p = valloc(size - (2 * sizeof(void *)));
34*f7c5c0d8SMitch Phillips       assert(p);
35*f7c5c0d8SMitch Phillips       assert(((uintptr_t)p & (page_size - 1)) == 0);
36*f7c5c0d8SMitch Phillips       free(p);
37*f7c5c0d8SMitch Phillips       p = pvalloc(size - (2 * sizeof(void *)));
38*f7c5c0d8SMitch Phillips       assert(p);
39*f7c5c0d8SMitch Phillips       assert(((uintptr_t)p & (page_size - 1)) == 0);
40*f7c5c0d8SMitch Phillips       assert(malloc_usable_size(p) >= round_up_to(size, page_size));
41*f7c5c0d8SMitch Phillips       free(p);
42*f7c5c0d8SMitch Phillips       p = valloc(size);
43*f7c5c0d8SMitch Phillips       assert(p);
44*f7c5c0d8SMitch Phillips       assert(((uintptr_t)p & (page_size - 1)) == 0);
45*f7c5c0d8SMitch Phillips       free(p);
46*f7c5c0d8SMitch Phillips       p = pvalloc(size);
47*f7c5c0d8SMitch Phillips       assert(p);
48*f7c5c0d8SMitch Phillips       assert(((uintptr_t)p & (page_size - 1)) == 0);
49*f7c5c0d8SMitch Phillips       assert(malloc_usable_size(p) >= round_up_to(size, page_size));
50*f7c5c0d8SMitch Phillips       free(p);
51*f7c5c0d8SMitch Phillips     }
52*f7c5c0d8SMitch Phillips   }
53*f7c5c0d8SMitch Phillips   if (!strcmp(argv[1], "invalid")) {
54*f7c5c0d8SMitch Phillips     // Size passed to pvalloc overflows when rounded up.
55*f7c5c0d8SMitch Phillips     p = pvalloc((size_t)-1);
56*f7c5c0d8SMitch Phillips     // CHECK: Scudo ERROR: pvalloc parameters overflow
57*f7c5c0d8SMitch Phillips     assert(!p);
58*f7c5c0d8SMitch Phillips     assert(errno == ENOMEM);
59*f7c5c0d8SMitch Phillips     errno = 0;
60*f7c5c0d8SMitch Phillips     p = pvalloc((size_t)-page_size);
61*f7c5c0d8SMitch Phillips     assert(!p);
62*f7c5c0d8SMitch Phillips     assert(errno == ENOMEM);
63*f7c5c0d8SMitch Phillips   }
64*f7c5c0d8SMitch Phillips   return 0;
65*f7c5c0d8SMitch Phillips }
66