blob: 0910f891581643c4e449c128ab79c16c1c022198 [file] [log] [blame]
philippef54cb662015-05-10 22:19:31 +00001#include <stdlib.h>
2#include <stdio.h>
3#include <assert.h>
4#include <string.h>
5#include "helgrind/helgrind.h"
6
7#define MAX 1000000
8static unsigned char shadow[MAX];
9
10
11#define V(cond, testline) \
12 do { if (!(cond)) \
13 fprintf (stderr, "Test at line %d Failed verif at line %d: " #cond "\n", \
14 testline, __LINE__); } \
15 while (0)
16
17#define CHK(a1,a2,a3,a4) check(__LINE__,a1,a2,a3,a4)
18/* Check that [p, p+len[ has access access.
19 If heap, check that one byte before and after is unaccessible */
20static void check (int testline, void *p, int len, unsigned char access, int heap)
21{
22 int i;
23 long int r;
24
25 assert (len < 1000000); // Do not exceed the shadow array
26
27 if (len == 0 && p == NULL)
28 return;
29 // malloc(0) can return a ptr or NULL.
30 // Let's not check NULL
31
32 r = VALGRIND_HG_GET_ABITS (p, shadow, len);
33 V (r == VALGRIND_HG_GET_ABITS (p, NULL, len), testline);
34 V (access == 0xff ? r == len : r == 0, testline);
35 for (i = 0; i < len; i++)
36 V(shadow[i] == access, testline);
37 if (heap) {
38 /* Check the range starting 1 byte before. */
39 r = VALGRIND_HG_GET_ABITS (p-1, shadow, len+1);
40 V (r == VALGRIND_HG_GET_ABITS (p-1, NULL, len+1), testline);
41 V (access == 0xff ? r == len : r == 0, testline);
42 V (shadow[0] == 0x00, testline);
43 for (i = 1; i < len+1; i++)
44 V (shadow[i] == access, testline);
45 /* Same but one byte after. We need special cases for
46 a len 0,*/
47 r = VALGRIND_HG_GET_ABITS (p+1, shadow, len);
48 V (r == VALGRIND_HG_GET_ABITS (p+1, NULL, len), testline);
49 if (len == 0)
50 V (r == 0, testline);
51 else
52 V (access == 0xff ? r == len-1 : r == 0, testline);
53 for (i = 0; i < len-1; i++)
54 V(shadow[i] == access, testline);
55 if (len != 0)
56 V(shadow[len-1] == 0x00, testline);
57 }
58}
59
60/* return an address on the stack, with big var on the stack,
61 to ensure it is really unaddressable when calling check. */
62static void* popped_stack_address(void)
63{
64 char s[MAX];
65 memcpy(s, shadow, MAX);
66 char *p;
67
68 p = &s[MAX/2-1-s[0]];
69 CHK(p, 1, 0xFF, 0);
70 return p;
71}
72
73int main ( void )
74{
75 char *p;
76
77 /* Basic test for an heap object */
78 fprintf(stderr, "basic heap test\n");
79 p = malloc (100);
80 CHK (p, 100, 0xff, 1);
81 free (p);
82 CHK (p, 100, 0x00, 1);
83
84 /* Basic test for some code : verify 50 bytes of check function code
85 is accessible. */
86 fprintf(stderr, "code test\n");
87 CHK (check, 50, 0xff, 0);
88
89 /* Check something on the stack */
90 fprintf(stderr, "stack test\n");
91 CHK (&p, sizeof(p), 0xff, 0);
92
93
94 /* Now shake the heap, to verify various sizes */
95 fprintf(stderr, "doing many heap blocks\n");
96 int i;
97 int j;
98# define X 200
99# define Y 4
100 void *ptr[X][Y];
101 int sz[X][Y];
102 int f[X][Y]; // already freed or not ?
103 for (i = 0; i < X; i++) {
104 for (j = 0; j < Y; j++) {
105 f[i][j] = 1;
106 // A SecMap represents 8Kb. We test the boundaries
107 // around such secmap (X/2 bytes before and after)
108 // We test with blocks covering from 0 till Y-1 secmaps
109 sz[i][j] = j * 8192 - (j == 0 ? 0 : X/2) + i;
110 ptr[i][j] = malloc(sz[i][j]);
111 CHK(ptr[i][j],sz[i][j], 0xff, 1);
112 }
113 }
114 /* Shake and check when doing random free */
115 fprintf(stderr, "random heap free and checks\n");
116 for (i = 0; i < X*Y/10; i++) {
117 int x = rand() % X;
118 int y = rand() % Y;
119 if (f[x][y]) {
120 CHK(ptr[x][y],sz[x][y], 0xff, 1);
121 free(ptr[x][y]);
122 f[x][y] = 0;
123 }
124 CHK(ptr[x][y],sz[x][y], 0x00, 1);
125 }
126
127#if 0
128 /* Check that a use after return gives unaddressable. */
129 CHK (popped_stack_address(), 1, 0x00, 0);
130 /* Well well, it seems helgrind keeps the stack accessible */
131#endif
132 (void) popped_stack_address();
133
134 return 0;
135}
136