1 /* 2 +----------------------------------------------------------------------+ 3 | Zend Engine | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1998-2017 Zend Technologies Ltd. (http://www.zend.com) | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 2.00 of the Zend license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | http://www.zend.com/license/2_00.txt. | 11 | If you did not receive a copy of the Zend license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@zend.com so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 | Authors: Andi Gutmans <andi@zend.com> | 16 | Zeev Suraski <zeev@zend.com> | 17 | Dmitry Stogov <zeev@zend.com> | 18 +----------------------------------------------------------------------+ 19 */ 20 21 /* $Id$ */ 22 23 #ifndef ZEND_PORTABILITY_H 24 #define ZEND_PORTABILITY_H 25 26 #ifdef __cplusplus 27 #define BEGIN_EXTERN_C() extern "C" { 28 #define END_EXTERN_C() } 29 #else 30 #define BEGIN_EXTERN_C() 31 #define END_EXTERN_C() 32 #endif 33 34 /* 35 * general definitions 36 */ 37 38 #ifdef ZEND_WIN32 39 # include "zend_config.w32.h" 40 # define ZEND_PATHS_SEPARATOR ';' 41 #elif defined(NETWARE) 42 # include <zend_config.h> 43 # define ZEND_PATHS_SEPARATOR ';' 44 #elif defined(__riscos__) 45 # include <zend_config.h> 46 # define ZEND_PATHS_SEPARATOR ';' 47 #else 48 # include <zend_config.h> 49 # define ZEND_PATHS_SEPARATOR ':' 50 #endif 51 52 #include "../TSRM/TSRM.h" 53 54 #include <stdio.h> 55 #include <assert.h> 56 57 #ifdef HAVE_UNIX_H 58 # include <unix.h> 59 #endif 60 61 #ifdef HAVE_STDARG_H 62 # include <stdarg.h> 63 #endif 64 65 #ifdef HAVE_DLFCN_H 66 # include <dlfcn.h> 67 #endif 68 69 #ifdef HAVE_LIMITS_H 70 # include <limits.h> 71 #endif 72 73 #if HAVE_ALLOCA_H && !defined(_ALLOCA_H) 74 # include <alloca.h> 75 #endif 76 77 #if defined(ZEND_WIN32) 78 #include <intrin.h> 79 #endif 80 81 #include "zend_range_check.h" 82 83 /* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */ 84 #ifdef __GNUC__ 85 # define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) 86 #else 87 # define ZEND_GCC_VERSION 0 88 #endif 89 90 /* Compatibility with non-clang compilers */ 91 #ifndef __has_attribute 92 # define __has_attribute(x) 0 93 #endif 94 #ifndef __has_builtin 95 # define __has_builtin(x) 0 96 #endif 97 98 #if defined(ZEND_WIN32) && !defined(__clang__) 99 # define ZEND_ASSUME(c) __assume(c) 100 #elif ((defined(__GNUC__) && ZEND_GCC_VERSION >= 4005) || __has_builtin(__builtin_unreachable)) && PHP_HAVE_BUILTIN_EXPECT 101 # define ZEND_ASSUME(c) do { \ 102 if (__builtin_expect(!(c), 0)) __builtin_unreachable(); \ 103 } while (0) 104 #else 105 # define ZEND_ASSUME(c) 106 #endif 107 108 #if ZEND_DEBUG 109 # define ZEND_ASSERT(c) assert(c) 110 #else 111 # define ZEND_ASSERT(c) ZEND_ASSUME(c) 112 #endif 113 114 /* Only use this macro if you know for sure that all of the switches values 115 are covered by its case statements */ 116 #if ZEND_DEBUG 117 # define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSERT(0); break; 118 #else 119 # define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSUME(0); break; 120 #endif 121 122 #if defined(__GNUC__) && __GNUC__ >= 4 123 # define ZEND_IGNORE_VALUE(x) (({ __typeof__ (x) __x = (x); (void) __x; })) 124 #else 125 # define ZEND_IGNORE_VALUE(x) ((void) (x)) 126 #endif 127 128 #define zend_quiet_write(...) ZEND_IGNORE_VALUE(write(__VA_ARGS__)) 129 130 /* all HAVE_XXX test have to be after the include of zend_config above */ 131 132 #if defined(HAVE_LIBDL) && !defined(ZEND_WIN32) 133 134 # if defined(__has_feature) 135 # if __has_feature(address_sanitizer) 136 # define __SANITIZE_ADDRESS__ 137 # endif 138 # endif 139 140 # ifndef RTLD_LAZY 141 # define RTLD_LAZY 1 /* Solaris 1, FreeBSD's (2.1.7.1 and older) */ 142 # endif 143 144 # ifndef RTLD_GLOBAL 145 # define RTLD_GLOBAL 0 146 # endif 147 148 # if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT) 149 # define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT) 150 # elif defined(RTLD_DEEPBIND) && !defined(__SANITIZE_ADDRESS__) 151 # define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND) 152 # else 153 # define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL) 154 # endif 155 # define DL_UNLOAD dlclose 156 # if defined(DLSYM_NEEDS_UNDERSCORE) 157 # define DL_FETCH_SYMBOL(h,s) dlsym((h), "_" s) 158 # else 159 # define DL_FETCH_SYMBOL dlsym 160 # endif 161 # define DL_ERROR dlerror 162 # define DL_HANDLE void * 163 # define ZEND_EXTENSIONS_SUPPORT 1 164 #elif defined(ZEND_WIN32) 165 # define DL_LOAD(libname) LoadLibrary(libname) 166 # define DL_FETCH_SYMBOL GetProcAddress 167 # define DL_UNLOAD FreeLibrary 168 # define DL_HANDLE HMODULE 169 # define ZEND_EXTENSIONS_SUPPORT 1 170 #else 171 # define DL_HANDLE void * 172 # define ZEND_EXTENSIONS_SUPPORT 0 173 #endif 174 175 /* AIX requires this to be the first thing in the file. */ 176 #ifndef __GNUC__ 177 # ifndef HAVE_ALLOCA_H 178 # ifdef _AIX 179 # pragma alloca 180 # else 181 # ifndef alloca /* predefined by HP cc +Olibcalls */ 182 char *alloca(); 183 # endif 184 # endif 185 # endif 186 #endif 187 188 #if ZEND_GCC_VERSION >= 2096 || __has_attribute(__malloc__) 189 # define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) 190 #else 191 # define ZEND_ATTRIBUTE_MALLOC 192 #endif 193 194 #if ZEND_GCC_VERSION >= 4003 || __has_attribute(alloc_size) 195 # define ZEND_ATTRIBUTE_ALLOC_SIZE(X) __attribute__ ((alloc_size(X))) 196 # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) __attribute__ ((alloc_size(X,Y))) 197 #else 198 # define ZEND_ATTRIBUTE_ALLOC_SIZE(X) 199 # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) 200 #endif 201 202 /* Format string checks are disabled by default, because we use custom format modifiers (like %p), 203 * which cause a large amount of false positives. You can enable format checks by adding 204 * -DZEND_CHECK_FORMAT_STRINGS to CFLAGS. */ 205 206 #if defined(ZEND_CHECK_FORMAT_STRINGS) && (ZEND_GCC_VERSION >= 2007 || __has_attribute(format)) 207 # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first))) 208 #else 209 # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) 210 #endif 211 212 #if defined(ZEND_CHECK_FORMAT_STRINGS) && ((ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)) || __has_attribute(format)) 213 # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first))) 214 #else 215 # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) 216 #endif 217 218 #if ZEND_GCC_VERSION >= 3001 || __has_attribute(deprecated) 219 # define ZEND_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) 220 #elif defined(ZEND_WIN32) 221 # define ZEND_ATTRIBUTE_DEPRECATED __declspec(deprecated) 222 #else 223 # define ZEND_ATTRIBUTE_DEPRECATED 224 #endif 225 226 #if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003 227 # define ZEND_ATTRIBUTE_UNUSED __attribute__((unused)) 228 # define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((cold, unused)); 229 # define ZEND_COLD __attribute__((cold)) 230 # define ZEND_HOT __attribute__((hot)) 231 #else 232 # define ZEND_ATTRIBUTE_UNUSED 233 # define ZEND_ATTRIBUTE_UNUSED_LABEL 234 # define ZEND_COLD 235 # define ZEND_HOT 236 #endif 237 238 #if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__) 239 # define ZEND_FASTCALL __attribute__((fastcall)) 240 #elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700 241 # define ZEND_FASTCALL __fastcall 242 #elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__) 243 # define ZEND_FASTCALL __vectorcall 244 #else 245 # define ZEND_FASTCALL 246 #endif 247 248 #ifndef restrict 249 # if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 250 # else 251 # define __restrict__ 252 # endif 253 # define restrict __restrict__ 254 #endif 255 256 #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn) 257 # define HAVE_NORETURN 258 # define ZEND_NORETURN __attribute__((noreturn)) 259 #elif defined(ZEND_WIN32) 260 # define HAVE_NORETURN 261 # define ZEND_NORETURN __declspec(noreturn) 262 #else 263 # define ZEND_NORETURN 264 #endif 265 266 #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) 267 # define HAVE_NORETURN_ALIAS 268 # define HAVE_ATTRIBUTE_WEAK 269 #endif 270 271 #if ZEND_GCC_VERSION >= 3001 || __has_builtin(__builtin_constant_p) 272 # define HAVE_BUILTIN_CONSTANT_P 273 #endif 274 275 #ifdef HAVE_BUILTIN_CONSTANT_P 276 # define ZEND_CONST_COND(_condition, _default) \ 277 (__builtin_constant_p(_condition) ? (_condition) : (_default)) 278 #else 279 # define ZEND_CONST_COND(_condition, _default) \ 280 (_default) 281 #endif 282 283 #if ZEND_DEBUG 284 # define zend_always_inline inline 285 # define zend_never_inline 286 #else 287 # if defined(__GNUC__) 288 # if __GNUC__ >= 3 289 # define zend_always_inline inline __attribute__((always_inline)) 290 # define zend_never_inline __attribute__((noinline)) 291 # else 292 # define zend_always_inline inline 293 # define zend_never_inline 294 # endif 295 # elif defined(_MSC_VER) 296 # define zend_always_inline __forceinline 297 # define zend_never_inline 298 # else 299 # if __has_attribute(always_inline) 300 # define zend_always_inline inline __attribute__((always_inline)) 301 # else 302 # define zend_always_inline inline 303 # endif 304 # if __has_attribute(noinline) 305 # define zend_never_inline __attribute__((noinline)) 306 # else 307 # define zend_never_inline 308 # endif 309 # endif 310 #endif /* ZEND_DEBUG */ 311 312 #if PHP_HAVE_BUILTIN_EXPECT 313 # define EXPECTED(condition) __builtin_expect(!!(condition), 1) 314 # define UNEXPECTED(condition) __builtin_expect(!!(condition), 0) 315 #else 316 # define EXPECTED(condition) (condition) 317 # define UNEXPECTED(condition) (condition) 318 #endif 319 320 #ifndef XtOffsetOf 321 # if defined(CRAY) || (defined(__ARMCC_VERSION) && !defined(LINUX)) 322 # ifdef __STDC__ 323 # define XtOffset(p_type, field) _Offsetof(p_type, field) 324 # else 325 # ifdef CRAY2 326 # define XtOffset(p_type, field) \ 327 (sizeof(int)*((unsigned int)&(((p_type)NULL)->field))) 328 329 # else /* !CRAY2 */ 330 331 # define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field)) 332 333 # endif /* !CRAY2 */ 334 # endif /* __STDC__ */ 335 # else /* ! (CRAY || __arm) */ 336 337 # define XtOffset(p_type, field) \ 338 ((zend_long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL))) 339 340 # endif /* !CRAY */ 341 342 # ifdef offsetof 343 # define XtOffsetOf(s_type, field) offsetof(s_type, field) 344 # else 345 # define XtOffsetOf(s_type, field) XtOffset(s_type*, field) 346 # endif 347 348 #endif 349 350 #if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN) 351 # define ZEND_ALLOCA_MAX_SIZE (32 * 1024) 352 # define ALLOCA_FLAG(name) \ 353 zend_bool name; 354 # define SET_ALLOCA_FLAG(name) \ 355 name = 1 356 # define do_alloca_ex(size, limit, use_heap) \ 357 ((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size)) 358 # define do_alloca(size, use_heap) \ 359 do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap) 360 # define free_alloca(p, use_heap) \ 361 do { if (UNEXPECTED(use_heap)) efree(p); } while (0) 362 #else 363 # define ALLOCA_FLAG(name) 364 # define SET_ALLOCA_FLAG(name) 365 # define do_alloca(p, use_heap) emalloc(p) 366 # define free_alloca(p, use_heap) efree(p) 367 #endif 368 369 #ifdef HAVE_SIGSETJMP 370 # define SETJMP(a) sigsetjmp(a, 0) 371 # define LONGJMP(a,b) siglongjmp(a, b) 372 # define JMP_BUF sigjmp_buf 373 #else 374 # define SETJMP(a) setjmp(a) 375 # define LONGJMP(a,b) longjmp(a, b) 376 # define JMP_BUF jmp_buf 377 #endif 378 379 #if ZEND_DEBUG 380 # define ZEND_FILE_LINE_D const char *__zend_filename, const uint __zend_lineno 381 # define ZEND_FILE_LINE_DC , ZEND_FILE_LINE_D 382 # define ZEND_FILE_LINE_ORIG_D const char *__zend_orig_filename, const uint __zend_orig_lineno 383 # define ZEND_FILE_LINE_ORIG_DC , ZEND_FILE_LINE_ORIG_D 384 # define ZEND_FILE_LINE_RELAY_C __zend_filename, __zend_lineno 385 # define ZEND_FILE_LINE_RELAY_CC , ZEND_FILE_LINE_RELAY_C 386 # define ZEND_FILE_LINE_C __FILE__, __LINE__ 387 # define ZEND_FILE_LINE_CC , ZEND_FILE_LINE_C 388 # define ZEND_FILE_LINE_EMPTY_C NULL, 0 389 # define ZEND_FILE_LINE_EMPTY_CC , ZEND_FILE_LINE_EMPTY_C 390 # define ZEND_FILE_LINE_ORIG_RELAY_C __zend_orig_filename, __zend_orig_lineno 391 # define ZEND_FILE_LINE_ORIG_RELAY_CC , ZEND_FILE_LINE_ORIG_RELAY_C 392 #else 393 # define ZEND_FILE_LINE_D 394 # define ZEND_FILE_LINE_DC 395 # define ZEND_FILE_LINE_ORIG_D 396 # define ZEND_FILE_LINE_ORIG_DC 397 # define ZEND_FILE_LINE_RELAY_C 398 # define ZEND_FILE_LINE_RELAY_CC 399 # define ZEND_FILE_LINE_C 400 # define ZEND_FILE_LINE_CC 401 # define ZEND_FILE_LINE_EMPTY_C 402 # define ZEND_FILE_LINE_EMPTY_CC 403 # define ZEND_FILE_LINE_ORIG_RELAY_C 404 # define ZEND_FILE_LINE_ORIG_RELAY_CC 405 #endif /* ZEND_DEBUG */ 406 407 #if ZEND_DEBUG 408 # define Z_DBG(expr) (expr) 409 #else 410 # define Z_DBG(expr) 411 #endif 412 413 #ifdef ZTS 414 # define ZTS_V 1 415 #else 416 # define ZTS_V 0 417 #endif 418 419 #ifndef LONG_MAX 420 # define LONG_MAX 2147483647L 421 #endif 422 423 #ifndef LONG_MIN 424 # define LONG_MIN (- LONG_MAX - 1) 425 #endif 426 427 #define MAX_LENGTH_OF_DOUBLE 32 428 429 #undef MIN 430 #undef MAX 431 #define MAX(a, b) (((a)>(b))?(a):(b)) 432 #define MIN(a, b) (((a)<(b))?(a):(b)) 433 #define ZEND_STRL(str) (str), (sizeof(str)-1) 434 #define ZEND_STRS(str) (str), (sizeof(str)) 435 #define ZEND_NORMALIZE_BOOL(n) \ 436 ((n) ? (((n)<0) ? -1 : 1) : 0) 437 #define ZEND_TRUTH(x) ((x) ? 1 : 0) 438 #define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b)) 439 440 #define ZEND_MAX_RESERVED_RESOURCES 4 441 442 /* excpt.h on Digital Unix 4.0 defines function_table */ 443 #undef function_table 444 445 #ifdef ZEND_WIN32 446 #define ZEND_SECURE_ZERO(var, size) RtlSecureZeroMemory((var), (size)) 447 #else 448 #define ZEND_SECURE_ZERO(var, size) memset((var), 0, (size)) 449 #endif 450 451 /* This check should only be used on network socket, not file descriptors */ 452 #ifdef ZEND_WIN32 453 #define ZEND_VALID_SOCKET(sock) (INVALID_SOCKET != (sock)) 454 #else 455 #define ZEND_VALID_SOCKET(sock) ((sock) >= 0) 456 #endif 457 458 #endif /* ZEND_PORTABILITY_H */ 459 460 /* 461 * Local variables: 462 * tab-width: 4 463 * c-basic-offset: 4 464 * indent-tabs-mode: t 465 * End: 466 */ 467