]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/memcheck/tests/custom_alloc.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / memcheck / tests / custom_alloc.c
1 #include <unistd.h>
2 #include "tests/sys_mman.h"
3 #include <assert.h>
4 #include <stdlib.h>
5
6 #include "../memcheck.h"
7
8 #define SUPERBLOCK_SIZE    100000
9
10 //-------------------------------------------------------------------------
11 // Allocator
12 //-------------------------------------------------------------------------
13
14 void* get_superblock(void)
15 {
16    void* p = mmap( 0, SUPERBLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
17                    MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );
18
19    assert(p != ((void*)(-1)));
20
21    // Mark it no access;  although it's addressible we don't want the 
22    // program to be using it unless its handed out by custom_alloc()
23
24    // with redzones, better not to have it
25    VALGRIND_MAKE_MEM_NOACCESS(p, SUPERBLOCK_SIZE);
26
27    return p;
28 }
29
30 // has a redzone
31 static void* custom_alloc(int size)
32 {
33 #define RZ  8
34    static void* hp     = 0;    // current heap pointer
35    static void* hp_lim = 0;    // maximum usable byte in current block
36    int          size2  = size + RZ*2;
37    void*        p;
38
39    if (hp + size2 > hp_lim) {
40       hp = get_superblock();
41       hp_lim = hp + SUPERBLOCK_SIZE - 1;
42    }  
43
44    p = hp + RZ;
45    hp += size2;
46
47    VALGRIND_MALLOCLIKE_BLOCK( p, size, RZ, /*is_zeroed*/1 );
48    return (void*)p;
49 }     
50
51 static void custom_free(void* p)
52 {
53    // don't actually free any memory... but mark it as freed
54    VALGRIND_FREELIKE_BLOCK( p, RZ );
55 }
56
57
58
59
60 //-------------------------------------------------------------------------
61 // Rest
62 //-------------------------------------------------------------------------
63
64 void make_leak(void)
65 {
66    int* array2 __attribute__((unused)) = custom_alloc(sizeof(int) * 10);
67    array2 = 0;          // leak
68    return;
69 }
70
71 int main(void)
72 {
73    int *array, *array3;
74    int x;
75
76    array = custom_alloc(sizeof(int) * 10);
77    array[8]  = 8;
78    array[9]  = 8;
79    array[10] = 10;      // invalid write (ok w/o MALLOCLIKE -- in superblock)
80
81    VALGRIND_RESIZEINPLACE_BLOCK(array, sizeof(int) * 10, sizeof(int) * 5, RZ);
82    array[4] = 7;
83    array[5] = 9; // invalid write
84
85    // Make the entire array defined again such that it can be verified whether
86    // the red zone is marked properly when resizing in place.
87    VALGRIND_MAKE_MEM_DEFINED(array, sizeof(int) * 10);
88
89    VALGRIND_RESIZEINPLACE_BLOCK(array, sizeof(int) * 5, sizeof(int) * 7, RZ);
90    if (array[5]) array[4]++; // uninitialized read of array[5]
91    array[5]  = 11;
92    array[6]  = 7;
93    array[7] = 8; // invalid write
94
95    // invalid realloc
96    VALGRIND_RESIZEINPLACE_BLOCK(array+1, sizeof(int) * 7, sizeof(int) * 8, RZ);
97
98    custom_free(array);  // ok
99
100    custom_free((void*)0x1);  // invalid free
101
102    array3 = malloc(sizeof(int) * 10);
103    custom_free(array3); // mismatched free (ok without MALLOCLIKE)
104
105    make_leak();
106    x = array[0];        // use after free (ok without MALLOCLIKE/MAKE_MEM_NOACCESS)
107                         // (nb: initialised because is_zeroed==1 above)
108                         // unfortunately not identified as being in a free'd
109                         // block because the freeing of the block and shadow
110                         // chunk isn't postponed.
111
112    // Bug 137073: passing 0 to MALLOCLIKE_BLOCK was causing an assertion
113    // failure.  Test for this (and likewise for FREELIKE_BLOCK).
114    VALGRIND_MALLOCLIKE_BLOCK(0,0,0,0);
115    VALGRIND_FREELIKE_BLOCK(0,0);
116    
117    return x;
118
119    // leak from make_leak()
120 }
121
122 #undef RZ