10 #define MIN(a,b) ( ((a)<(b)) ? (a) : (b) )
12 static unsigned fill_a_buffer_memset(void) __attribute__((noinline
));
13 static unsigned fill_a_buffer_memwipe(void) __attribute__((noinline
));
14 static unsigned fill_a_buffer_nothing(void) __attribute__((noinline
));
15 static unsigned fill_heap_buffer_memset(void) __attribute__((noinline
));
16 static unsigned fill_heap_buffer_memwipe(void) __attribute__((noinline
));
17 static unsigned fill_heap_buffer_nothing(void) __attribute__((noinline
));
18 static unsigned check_a_buffer(void) __attribute__((noinline
));
22 #define FILL_BUFFER_IMPL() \
26 /* Fill up a 1k buffer with a recognizable pattern. */ \
27 for (i = 0; i < 2048; i += strlen(s)) { \
28 memcpy(buf+i, s, MIN(strlen(s), 2048-i)); \
31 /* Use the buffer as input to a computation so the above can't get */ \
32 /* optimized away. */ \
33 for (i = 0; i < 2048; ++i) { \
34 sum += (unsigned char)buf[i]; \
38 fill_a_buffer_memset(void)
42 memset(buf
, 0, sizeof(buf
));
47 fill_a_buffer_memwipe(void)
51 memwipe(buf
, 0, sizeof(buf
));
56 fill_a_buffer_nothing(void)
64 vmemeq(volatile char *a
, const char *b
, size_t n
)
77 volatile char buf
[1024];
80 /* See if this buffer has the string in it.
82 YES, THIS DOES INVOKE UNDEFINED BEHAVIOR BY READING FROM AN UNINITIALIZED
85 If you know a better way to figure out whether the compiler eliminated
86 the memset/memwipe calls or not, please let me know.
88 for (i
= 0; i
< sizeof(buf
); ++i
) {
89 if (vmemeq(buf
+i
, s
, strlen(s
)))
96 static char *heap_buf
= NULL
;
99 fill_heap_buffer_memset(void)
101 char *buf
= heap_buf
= malloc(2048);
103 memset(buf
, 0, 2048);
109 fill_heap_buffer_memwipe(void)
111 char *buf
= heap_buf
= malloc(2048);
113 memwipe(buf
, 0, 2048);
119 fill_heap_buffer_nothing(void)
121 char *buf
= heap_buf
= malloc(2048);
128 check_heap_buffer(void)
132 volatile char *buf
= heap_buf
;
134 /* See if this buffer has the string in it.
136 YES, THIS DOES INVOKE UNDEFINED BEHAVIOR BY READING FROM A FREED BUFFER.
138 If you know a better way to figure out whether the compiler eliminated
139 the memset/memwipe calls or not, please let me know.
141 for (i
= 0; i
< sizeof(buf
); ++i
) {
142 if (vmemeq(buf
+i
, s
, strlen(s
)))
149 static struct testcase
{
151 unsigned (*fill_fn
)(void);
152 unsigned (*check_fn
)(void);
154 { "nil", fill_a_buffer_nothing
, check_a_buffer
},
155 { "nil-heap", fill_heap_buffer_nothing
, check_heap_buffer
},
156 { "memset", fill_a_buffer_memset
, check_a_buffer
},
157 { "memset-heap", fill_heap_buffer_memset
, check_heap_buffer
},
158 { "memwipe", fill_a_buffer_memwipe
, check_a_buffer
},
159 { "memwipe-heap", fill_heap_buffer_memwipe
, check_heap_buffer
},
164 main(int argc
, char **argv
)
170 (void) argc
; (void) argv
;
172 s
= "squamous haberdasher gallimaufry";
174 memset(found
, 0, sizeof(found
));
176 for (i
= 0; testcases
[i
].name
; ++i
) {
177 x
= testcases
[i
].fill_fn();
178 found
[i
] = testcases
[i
].check_fn();
180 x2
= fill_a_buffer_nothing();
187 if (!working
|| !found
[0] || !found
[1]) {
188 printf("It appears that this test case may not give you reliable "
189 "information. Sorry.\n");
192 if (!found
[2] && !found
[3]) {
193 printf("It appears that memset is good enough on this platform. Good.\n");
196 if (found
[4] || found
[5]) {
197 printf("ERROR: memwipe does not wipe data!\n");
200 printf("OKAY: memwipe seems to work.");