1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 :
8 : /*
9 : * NaCl Safety Macro Definitions
10 : */
11 : #ifndef NATIVE_CLIENT_SRC_INCLUDE_NACL_MACROS_H_
12 : #define NATIVE_CLIENT_SRC_INCLUDE_NACL_MACROS_H_ 1
13 :
14 : #include <stdio.h>
15 : #include <stdlib.h>
16 :
17 : #define NACL_TO_STRING_INTERNAL(v) #v
18 : #define NACL_TO_STRING(v) NACL_TO_STRING_INTERNAL(v)
19 :
20 : #define NACL_CONCAT_INTERNAL(a, b) a ## b
21 : #define NACL_CONCAT(a, b) NACL_CONCAT_INTERNAL(a, b)
22 :
23 : /*****************************************************************************
24 : * Safety macros *
25 : *****************************************************************************/
26 :
27 : #define NACL_ARRAY_SIZE_UNSAFE(arr) ((sizeof arr)/sizeof arr[0])
28 :
29 : /*
30 : * ASSERT_IS_ARRAY(arr) generates a somewhat opaque compile-time
31 : * error if arr is a non-array pointer. This protects against
32 : * situations where one writes code like:
33 : *
34 : * foo.h: struct Foo { char buffer[BUFFERSIZE]; size_t sofar; ... };
35 : *
36 : * foo.c: got = read(d, fp->buffer + fp->sofar, sizeof fp->buffer - fp->sofar);
37 : * if (-1 == got) { ... }
38 : * fp->sofar += got;
39 : *
40 : * for (ix = 0; ix < sizeof arr/sizeof arr[0]; ++ix) { ... }
41 : *
42 : * and have it break and create a security problem when somebody later
43 : * changes Foo to dynamically allocate buffer, viz,
44 : *
45 : * foo.h: struct Foo { char *buffer; size_t sofar; ... };
46 : *
47 : * and now sizeof fp->buffer is 4 or 8, with size_t (type of sizeof)
48 : * being unsigned, when fp->sofar is larger than 4 or 8, getting an
49 : * enormous maximum read size being used. Such bugs can remain
50 : * undiscovered when conforming implementations of protocol engines
51 : * are used where the actual amount sent is small and would never
52 : * cause a buffer overflow, but an adversarial implementation would be
53 : * able to clobber the heap. The solution is to write:
54 : *
55 : * foo.c: NACL_ASSERT_IS_ARRAY(fp->buffer);
56 : * got = read(d, fp->buffer + fp->sofar, sizeof fp->buffer - fp->sofar);
57 : * if (-1 == got) { ... }
58 : * fp->sofar += got;
59 : *
60 : * for (ix = 0; ix < NACL_ARRAY_SIZE(arr); ++ix) { ... }
61 : *
62 : * and when foo.h is modified, it will generate a compile-time error
63 : * alerting the engineer makin the change that the read code will need to
64 : * be modified.
65 : */
66 :
67 : #ifdef __cplusplus
68 : /*
69 : * C++ version is taken from chrome's basictypes.h, and renamed to
70 : * avoid collision in case of multiple includes. NACL_ARRAY_SIZE
71 : * relies on template matching failure if the argument is not an
72 : * array.
73 : */
74 : template <typename T, size_t N>
75 : char (&NaClArraySizeHelper(T (&array)[N]))[N];
76 :
77 : #ifndef _MSC_VER
78 : template <typename T, size_t N>
79 : char (&NaClArraySizeHelper(const T (&array)[N]))[N];
80 : #endif /* _MSC_VER */
81 :
82 : #define NACL_ARRAY_SIZE(array) (sizeof(NaClArraySizeHelper(array)))
83 :
84 : /*
85 : * Dead code elimination will get rid of this if there are no
86 : * compile-time errors generated by ARRAY_SIZE.
87 : */
88 : #define NACL_ASSERT_IS_ARRAY(array) \
89 : do { \
90 : char __array__[NACL_ARRAY_SIZE(array)]; \
91 : if (0 == sizeof __array__) { \
92 : abort(); \
93 : } \
94 : } while (0)
95 :
96 : #else /* __cplusplus */
97 :
98 : /*
99 : * The C version uses the fact that __builtin_types_compatible_p can
100 : * be used to discriminate between T * and T *const. (Note that this
101 : * difference is not a top-level qualifier difference as mentioned in
102 : * the gcc info node; that would apply to T * versus T const *.) In
103 : * the assertion statement version (NACL_ASSERT_IS_ARRAY), we use this
104 : * to declare an array, and ISO C forbids a negative-sized array.
105 : */
106 : # if __GNUC__
107 :
108 : # define NACL_ASSERT_IS_ARRAY_HELPER(arr) \
109 : sizeof(char[1-2*__builtin_types_compatible_p(__typeof__(&arr[0]), \
110 : __typeof__(arr))])
111 :
112 : # define NACL_ASSERT_IS_ARRAY(arr) \
113 : ((void) NACL_ASSERT_IS_ARRAY_HELPER(arr))
114 :
115 : # define NACL_ARRAY_SIZE(arr) \
116 : (NACL_ASSERT_IS_ARRAY_HELPER(arr) ? NACL_ARRAY_SIZE_UNSAFE(arr) : 0)
117 :
118 : # else /* __GNUC__ */
119 :
120 : /*
121 : * Not gcc. So far, we only compile NaCl under gcc and visual studio,
122 : * but if/when a new compiler is introduced that's capable of doing
123 : * compile-time checking (or we figure out how to do it w/ visual
124 : * studio), check for those compilers here, and enable the
125 : * corresponding compile-failure tests in
126 : * src/trusted/service_runtime/build.scons.
127 : */
128 :
129 : # define NACL_ASSERT_IS_ARRAY(arr)
130 : # define NACL_ARRAY_SIZE(arr) NACL_ARRAY_SIZE_UNSAFE(arr)
131 : # endif /* __GNUC__ */
132 : #endif /* __cplusplus */
133 :
134 : /*
135 : * NACL_ASSERT_IS_POINTER(arr) generates a somewhat opaque compile-time
136 : * error if lvalue is not a pointer lvalue but is instead an actual
137 : * array (which is a T * const object). This is complementary to
138 : * NACL_ASSERT_IS_ARRAY.
139 : */
140 : #define NACL_ASSERT_IS_POINTER(ptr) do { if (0) { ++ptr; } } while (0)
141 :
142 : /*
143 : * NACL_ASSERT_SAME_SIZE(t1, t2) verifies that the two types have the same size
144 : * (as reported by sizeof). When the check fails it generates a somewhat
145 : * opaque warning, mitigated by the variable's name.
146 : *
147 : * Examples:
148 : * NACL_ASSERT_SAME_SIZE(void *, char *); // Likely to succeed!
149 : * NACL_ASSERT_SAME_SIZE(char, long); // Unlikely to succeed
150 : */
151 : #define NACL_ASSERT_SAME_SIZE(t1, t2) \
152 : NACL_COMPILE_TIME_ASSERT(sizeof(t1) == sizeof(t2))
153 :
154 : /*
155 : * NACL_COMPILE_TIME_ASSERT(boolexp) verifies that the argument
156 : * boolexp is true. The check occurs at compile time.
157 : *
158 : * Example:
159 : *
160 : * NACL_COMPILE_TIME_ASSERT(NACL_MAX_VAL(int32_t) <= SIZE_T_MAX)
161 : *
162 : * to explicitly state the assumption that an int32_t expression -- if
163 : * containing a non-negative number -- will fit in a size_t variable.
164 : *
165 : * We don't use an array type here because GCC supports variable-length
166 : * arrays and so an expression that is not actually compile-time constant
167 : * could be used and not get any compile-time error. The size of a bitfield
168 : * can never be anything but a compile-time constant, so we use that instead.
169 : * MSVC doesn't support VLAs, so we use the array trick there.
170 : */
171 : #if defined(OS_WIN)
172 : #define NACL_COMPILE_TIME_ASSERT(boolexp) \
173 : do { \
174 : /* @IGNORE_LINES_FOR_CODE_HYGIENE[1] */ \
175 : char compile_time_assert[(boolexp) ? 1 : -1]; \
176 : (void) compile_time_assert; \
177 : } while (0)
178 : #else /* !OS_WIN */
179 : #define NACL_COMPILE_TIME_ASSERT(boolexp) \
180 : do { \
181 : struct { \
182 : unsigned int compile_time_assert: (boolexp) ? 1 : -1; \
183 : } compile_time_assert; \
184 : (void) compile_time_assert; \
185 : } while (0)
186 : #endif /* OS_WIN */
187 :
188 : /*****************************************************************************
189 : * MAX/MIN macros for integral types *
190 : ****************************************************************************/
191 :
192 : /*
193 : * For NACL_MAX_VAL, T must be a type where u ## T is the unsigned
194 : * version of the type.
195 : *
196 : * These macros rely on -1 being signed extended to the width of T (or
197 : * u ## T), and on two's complement representation of integers.
198 : *
199 : * Generally, stdint.h's INT16_MAX etc can be used, but these are
200 : * useful for macros that take a type parameter and need the max or
201 : * min value for the type, since then the macro would not have to also take
202 : * the max or min value as additional parameter(s).
203 : */
204 : #define NACL_UMAX_VAL(T) ((T) -1)
205 : #define NACL_MAX_VAL(T) ((T) (((u ## T) -1) >> 1))
206 : #define NACL_UMIN_VAL(T) ((T) 0)
207 : #define NACL_MIN_VAL(T) ((T) ~NACL_MAX_VAL(T))
208 :
209 :
210 : /*****************************************************************************
211 : * Readability macros *
212 : ****************************************************************************/
213 :
214 : #define NACL_NANOS_PER_MICRO (1000)
215 : #define NACL_100_NANOS_PER_MILLI (10 * 1000)
216 : #define NACL_NANOS_PER_MILLI (1000 * 1000)
217 : #define NACL_MICROS_PER_MILLI (1000)
218 : #define NACL_NANOS_PER_UNIT (1000 * 1000 * 1000)
219 : #define NACL_MICROS_PER_UNIT (1000 * 1000)
220 : #define NACL_MILLIS_PER_UNIT (1000)
221 : #define NACL_UNIT_CONVERT_ROUND(v, m) (((v) + (m) - 1)/(m))
222 :
223 : #define NACL_NO_FILE_DESC (-1)
224 : #define NACL_NO_URL ""
225 : #define NACL_NO_FILE_PATH ""
226 :
227 : #define NACL_HTTP_STATUS_OK 200
228 :
229 : /*****************************************************************************
230 : * C++ coding convention macros *
231 : ****************************************************************************/
232 :
233 : #ifdef __cplusplus
234 : /*
235 : * A macro to disallow the default constructor.
236 : * This should be used in the private: declarations for a class
237 : */
238 : #define NACL_DISALLOW_DEFAULT(TypeName) \
239 : TypeName();
240 :
241 : /*
242 : * A macro to disallow the copy constructor and operator= functions.
243 : * This should be used in the private: declarations for a class
244 : */
245 : #define NACL_DISALLOW_COPY_AND_ASSIGN(TypeName) \
246 : TypeName(const TypeName&); \
247 : void operator=(const TypeName&)
248 :
249 : /*
250 : * A macro to disallow the default, copy constructor and operator= functions.
251 : * This should be used in the private: declarations for a class
252 : */
253 : #define NACL_DISALLOW_DEFAULT_COPY_AND_ASSIGN(TypeName) \
254 : NACL_DISALLOW_DEFAULT(TypeName) \
255 : NACL_DISALLOW_COPY_AND_ASSIGN(TypeName)
256 :
257 : /* A macro to use in place of unimplemented sections of code. */
258 : #define NACL_UNIMPLEMENTED() \
259 : fprintf(stderr, "%s:%d: unimplemented\n", __FILE__, __LINE__); \
260 : exit(1);
261 :
262 : /* A macro to use to detect when control reaches a statement it should not. */
263 : #define NACL_NOTREACHED() \
264 : fprintf(stderr, "%s:%d: should not reach here\n", __FILE__, __LINE__); \
265 : exit(1);
266 :
267 : /* A macro to mark code that has not been tested manually or automatically. */
268 : #define NACL_UNTESTED() \
269 : fprintf(stderr, "%s:%d: reached untested code\n", __FILE__, __LINE__); \
270 : exit(1);
271 :
272 : // nacl_bit_cast<Dest,Source> is a template function that implements the
273 : // equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
274 : // very low-level functions like the protobuf library and fast math
275 : // support.
276 : //
277 : // float f = 3.14159265358979;
278 : // int i = nacl_bit_cast<int32>(f);
279 : // // i = 0x40490fdb
280 : //
281 : // The classical address-casting method is:
282 : //
283 : // // WRONG
284 : // float f = 3.14159265358979; // WRONG
285 : // int i = * reinterpret_cast<int*>(&f); // WRONG
286 : //
287 : // The address-casting method actually produces undefined behavior
288 : // according to ISO C++ specification section 3.10 -15 -. Roughly, this
289 : // section says: if an object in memory has one type, and a program
290 : // accesses it with a different type, then the result is undefined
291 : // behavior for most values of "different type".
292 : //
293 : // This is true for any cast syntax, either *(int*)&f or
294 : // *reinterpret_cast<int*>(&f). And it is particularly true for
295 : // conversions betweeen integral lvalues and floating-point lvalues.
296 : //
297 : // The purpose of 3.10 -15- is to allow optimizing compilers to assume
298 : // that expressions with different types refer to different memory. gcc
299 : // 4.0.1 has an optimizer that takes advantage of this. So a
300 : // non-conforming program quietly produces wildly incorrect output.
301 : //
302 : // The problem is not the use of reinterpret_cast. The problem is type
303 : // punning: holding an object in memory of one type and reading its bits
304 : // back using a different type.
305 : //
306 : // The C++ standard is more subtle and complex than this, but that
307 : // is the basic idea.
308 : //
309 : // Anyways ...
310 : //
311 : // nacl_bit_cast<> calls memcpy() which is blessed by the standard,
312 : // especially by the example in section 3.9 . Also, of course,
313 : // nacl_bit_cast<> wraps up the nasty logic in one place.
314 : //
315 : // Fortunately memcpy() is very fast. In optimized mode, with a
316 : // constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
317 : // code with the minimal amount of data movement. On a 32-bit system,
318 : // memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
319 : // compiles to two loads and two stores.
320 : //
321 : // I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
322 : //
323 : // WARNING: if Dest or Source is a non-POD type, the result of the memcpy
324 : // is likely to surprise you.
325 :
326 : template <class Dest, class Source>
327 0 : inline Dest nacl_bit_cast(const Source& source) {
328 : // A compile error here means your Dest and Source have different sizes.
329 0 : NACL_ASSERT_SAME_SIZE(Dest, Source);
330 :
331 : Dest dest;
332 0 : memcpy(&dest, &source, sizeof(dest));
333 0 : return dest;
334 0 : }
335 :
336 : #endif /* __cplusplus */
337 :
338 : #endif /* NATIVE_CLIENT_SRC_INCLUDE_NACL_MACROS_H_ */
|