Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
0.alloc.cpp
Go to the documentation of this file.
1
27#include <setjmp.h> // for setjmp, longjmp
28#include <signal.h> // for signal
29#include <stddef.h> // for size_t
30
31#include <rw_alloc.h> // for rw_alloc, rw_free
32#include <rw_printf.h> // for rw_printf
33#include <rw_driver.h>
34
35static jmp_buf mark;
36
37extern "C" {
38
39static void
40sig_handler (int)
41{
42 longjmp (mark, -1);
43}
44
45}
46
47// on Cygwin use setjmp
48#if !defined (__CYGWIN__) && defined (sigsetjmp)
49#define SETJMP(env) sigsetjmp (env, 1)
50#else
51#define SETJMP(env) setjmp (env)
52#endif
53
54#define BEGIN_TEST_OVERRUN() \
55 (signal (SIGSEGV, sig_handler), \
56 (0 == SETJMP (mark)))
57
59{
60 size_t size_;
61 int index_;
62 int prot_;
63 const char* file_;
64 int line_;
65};
66
67void test (const TestCase& tcase)
68{
69 if (void* buf = rw_alloc (tcase.size_, tcase.prot_)) {
70
71 char* str = _RWSTD_STATIC_CAST (char*, buf);
72
73 bool protbelow = 0 != (tcase.prot_ & RW_PROT_BELOW);
74
75 bool isguardpage = (protbelow && 0 > tcase.index_)
76 || (!protbelow && tcase.index_ >= int (tcase.size_));
77
78 bool canread = (tcase.prot_ & RW_PROT_READ) && !isguardpage;
79
80 bool canwrite = (tcase.prot_ & RW_PROT_WRITE) && !isguardpage;
81
82 char c = 'a';
83
84 // check read access only if:
85 // tcase.prot_ & RW_PROT_READ != 0
86 // tcase.prot_ == RW_PROT_NONE
87 // tcase.prot_ & RW_PROT_WRITE != 0 and the
88 // accessed memory is placed in the guard page
89 if (tcase.prot_ & RW_PROT_READ || !canwrite) {
90 if (BEGIN_TEST_OVERRUN ()) {
91 c = str[tcase.index_];
92 rw_assert (canread, tcase.file_, tcase.line_,
93 "expected no read access, got read access");
94 } else
95 rw_assert (!canread, tcase.file_, tcase.line_,
96 "expected read access, got no read access");
97 }
98
99 if (BEGIN_TEST_OVERRUN ()) {
100 str[tcase.index_] = c;
101 rw_assert (canwrite, tcase.file_, tcase.line_,
102 "expected no write access, got write access");
103 } else
104 rw_assert (!canwrite, tcase.file_, tcase.line_,
105 "expected write access, got no write access");
106
107 rw_free (buf);
108 }
109}
110
111static int
112run_test (int, char**)
113{
114 const size_t BUF_SIZE = 10;
115
116 static const TestCase tcases[] = {
117
118#ifdef TEST
119#undef TEST
120#endif
121#define TEST(size, index, prot) \
122 { size, index, prot, __FILE__, __LINE__ }
123
124 TEST(BUF_SIZE, -1, RW_PROT_NONE),
125 TEST(BUF_SIZE, -1, RW_PROT_READ),
126 TEST(BUF_SIZE, -1, RW_PROT_WRITE),
127 TEST(BUF_SIZE, -1, RW_PROT_RDWR),
128
129 TEST(BUF_SIZE, -1, RW_PROT_NONE | RW_PROT_BELOW),
130 TEST(BUF_SIZE, -1, RW_PROT_READ | RW_PROT_BELOW),
131 TEST(BUF_SIZE, -1, RW_PROT_WRITE | RW_PROT_BELOW),
132 TEST(BUF_SIZE, -1, RW_PROT_RDWR | RW_PROT_BELOW),
133
134 TEST(BUF_SIZE, 0, RW_PROT_NONE),
135 TEST(BUF_SIZE, 0, RW_PROT_READ),
136 TEST(BUF_SIZE, 0, RW_PROT_WRITE),
137 TEST(BUF_SIZE, 0, RW_PROT_RDWR),
138
139 TEST(BUF_SIZE, 0, RW_PROT_NONE | RW_PROT_BELOW),
140 TEST(BUF_SIZE, 0, RW_PROT_READ | RW_PROT_BELOW),
141 TEST(BUF_SIZE, 0, RW_PROT_WRITE | RW_PROT_BELOW),
142 TEST(BUF_SIZE, 0, RW_PROT_RDWR | RW_PROT_BELOW),
143
144 TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_NONE),
145 TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_READ),
146 TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_WRITE),
147 TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_RDWR),
148
149 TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_NONE | RW_PROT_BELOW),
150 TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_READ | RW_PROT_BELOW),
151 TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_WRITE | RW_PROT_BELOW),
152 TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_RDWR | RW_PROT_BELOW),
153
154 TEST(BUF_SIZE, BUF_SIZE, RW_PROT_NONE),
155 TEST(BUF_SIZE, BUF_SIZE, RW_PROT_READ),
156 TEST(BUF_SIZE, BUF_SIZE, RW_PROT_WRITE),
157 TEST(BUF_SIZE, BUF_SIZE, RW_PROT_RDWR),
158
159 TEST(BUF_SIZE, BUF_SIZE, RW_PROT_NONE | RW_PROT_BELOW),
160 TEST(BUF_SIZE, BUF_SIZE, RW_PROT_READ | RW_PROT_BELOW),
161 TEST(BUF_SIZE, BUF_SIZE, RW_PROT_WRITE | RW_PROT_BELOW),
162 TEST(BUF_SIZE, BUF_SIZE, RW_PROT_RDWR | RW_PROT_BELOW)
163 };
164
165 for (size_t i = 0; i < sizeof (tcases) / sizeof (tcases[0]); ++i)
166 test (tcases [i]);
167
168 return 0;
169}
170
171
173int main (int argc, char *argv[])
174{
175 return rw_test (argc, argv, __FILE__,
176 "",
177 0,
178 run_test,
179 "",
180 (void*)0 /* sentinel */);
181}
#define TEST(size, index, prot)
#define BEGIN_TEST_OVERRUN()
Definition 0.alloc.cpp:54
#define i
Definition 17.names.cpp:126
#define buf
Definition 17.names.cpp:452
#define c
Definition 17.names.cpp:111
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define main
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
const char * str
Definition exec.cpp:170
@ RW_PROT_READ
Definition rw_alloc.h:35
@ RW_PROT_NONE
Definition rw_alloc.h:34
@ RW_PROT_WRITE
Definition rw_alloc.h:36
@ RW_PROT_RDWR
Definition rw_alloc.h:37
@ RW_PROT_BELOW
Definition rw_alloc.h:38
_TEST_EXPORT void rw_free(void *)
Definition alloc.cpp:621
_TEST_EXPORT void * rw_alloc(_RWSTD_SIZE_T, int=-1)
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
int index_
Definition 0.alloc.cpp:61
int line_
Definition 0.alloc.cpp:64
const char * file_
Definition 0.alloc.cpp:63
int prot_
Definition 0.alloc.cpp:62
size_t size_
Definition 0.alloc.cpp:60