1 /* 2 +----------------------------------------------------------------------+ 3 | Zend Engine | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 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@php.net> | 16 | Zeev Suraski <zeev@php.net> | 17 | Dmitry Stogov <zeev@php.net> | 18 +----------------------------------------------------------------------+ 19 */ 20 21 #ifndef ZEND_PORTABILITY_H 22 #define ZEND_PORTABILITY_H 23 24 #ifdef __cplusplus 25 #define BEGIN_EXTERN_C() extern "C" { 26 #define END_EXTERN_C() } 27 #else 28 #define BEGIN_EXTERN_C() 29 #define END_EXTERN_C() 30 #endif 31 32 /* 33 * general definitions 34 */ 35 36 #ifdef ZEND_WIN32 37 # include "zend_config.w32.h" 38 # define ZEND_PATHS_SEPARATOR ';' 39 #elif defined(__riscos__) 40 # include <zend_config.h> 41 # define ZEND_PATHS_SEPARATOR ';' 42 #else 43 # include <zend_config.h> 44 # define ZEND_PATHS_SEPARATOR ':' 45 #endif 46 47 #include "../TSRM/TSRM.h" 48 49 #include <stdio.h> 50 #include <assert.h> 51 #include <math.h> 52 53 #ifdef HAVE_UNIX_H 54 # include <unix.h> 55 #endif 56 57 #include <stdarg.h> 58 #include <stddef.h> 59 60 #ifdef HAVE_DLFCN_H 61 # include <dlfcn.h> 62 #endif 63 64 #include <limits.h> 65 66 #if HAVE_ALLOCA_H && !defined(_ALLOCA_H) 67 # include <alloca.h> 68 #endif 69 70 #if defined(ZEND_WIN32) && !defined(__clang__) 71 #include <intrin.h> 72 #endif 73 74 #include "zend_range_check.h" 75 76 /* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */ 77 #ifdef __GNUC__ 78 # define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) 79 #else 80 # define ZEND_GCC_VERSION 0 81 #endif 82 83 /* Compatibility with non-clang compilers */ 84 #ifndef __has_attribute 85 # define __has_attribute(x) 0 86 #endif 87 #ifndef __has_builtin 88 # define __has_builtin(x) 0 89 #endif 90 #ifndef __has_feature 91 # define __has_feature(x) 0 92 #endif 93 94 #if defined(ZEND_WIN32) && !defined(__clang__) 95 # define ZEND_ASSUME(c) __assume(c) 96 #elif ((defined(__GNUC__) && ZEND_GCC_VERSION >= 4005) || __has_builtin(__builtin_unreachable)) && PHP_HAVE_BUILTIN_EXPECT 97 # define ZEND_ASSUME(c) do { \ 98 if (__builtin_expect(!(c), 0)) __builtin_unreachable(); \ 99 } while (0) 100 #else 101 # define ZEND_ASSUME(c) 102 #endif 103 104 #if ZEND_DEBUG 105 # define ZEND_ASSERT(c) assert(c) 106 #else 107 # define ZEND_ASSERT(c) ZEND_ASSUME(c) 108 #endif 109 110 #if ZEND_DEBUG 111 # define ZEND_UNREACHABLE() do {ZEND_ASSERT(0); ZEND_ASSUME(0);} while (0) 112 #else 113 # define ZEND_UNREACHABLE() ZEND_ASSUME(0) 114 #endif 115 116 /* Only use this macro if you know for sure that all of the switches values 117 are covered by its case statements */ 118 #define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_UNREACHABLE(); break; 119 120 #if defined(__GNUC__) && __GNUC__ >= 4 121 # define ZEND_IGNORE_VALUE(x) (({ __typeof__ (x) __x = (x); (void) __x; })) 122 #else 123 # define ZEND_IGNORE_VALUE(x) ((void) (x)) 124 #endif 125 126 #define zend_quiet_write(...) ZEND_IGNORE_VALUE(write(__VA_ARGS__)) 127 128 /* all HAVE_XXX test have to be after the include of zend_config above */ 129 130 #if defined(HAVE_LIBDL) && !defined(ZEND_WIN32) 131 132 # if __has_feature(address_sanitizer) 133 # define __SANITIZE_ADDRESS__ 134 # endif 135 136 # ifndef RTLD_LAZY 137 # define RTLD_LAZY 1 /* Solaris 1, FreeBSD's (2.1.7.1 and older) */ 138 # endif 139 140 # ifndef RTLD_GLOBAL 141 # define RTLD_GLOBAL 0 142 # endif 143 144 # ifdef PHP_USE_RTLD_NOW 145 # define PHP_RTLD_MODE RTLD_NOW 146 # else 147 # define PHP_RTLD_MODE RTLD_LAZY 148 # endif 149 150 # if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT) 151 # define DL_LOAD(libname) dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT) 152 # elif defined(RTLD_DEEPBIND) && !defined(__SANITIZE_ADDRESS__) && !__has_feature(memory_sanitizer) 153 # define DL_LOAD(libname) dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_DEEPBIND) 154 # else 155 # define DL_LOAD(libname) dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL) 156 # endif 157 # define DL_UNLOAD dlclose 158 # if defined(DLSYM_NEEDS_UNDERSCORE) 159 # define DL_FETCH_SYMBOL(h,s) dlsym((h), "_" s) 160 # else 161 # define DL_FETCH_SYMBOL dlsym 162 # endif 163 # define DL_ERROR dlerror 164 # define DL_HANDLE void * 165 # define ZEND_EXTENSIONS_SUPPORT 1 166 #elif defined(ZEND_WIN32) 167 # define DL_LOAD(libname) LoadLibrary(libname) 168 # define DL_FETCH_SYMBOL GetProcAddress 169 # define DL_UNLOAD FreeLibrary 170 # define DL_HANDLE HMODULE 171 # define ZEND_EXTENSIONS_SUPPORT 1 172 #else 173 # define DL_HANDLE void * 174 # define ZEND_EXTENSIONS_SUPPORT 0 175 #endif 176 177 /* AIX requires this to be the first thing in the file. */ 178 #ifndef __GNUC__ 179 # ifndef HAVE_ALLOCA_H 180 # ifdef _AIX 181 # pragma alloca 182 # else 183 # ifndef alloca /* predefined by HP cc +Olibcalls */ 184 char *alloca(); 185 # endif 186 # endif 187 # endif 188 #endif 189 190 #if ZEND_GCC_VERSION >= 2096 || __has_attribute(__malloc__) 191 # define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) 192 #else 193 # define ZEND_ATTRIBUTE_MALLOC 194 #endif 195 196 #if ZEND_GCC_VERSION >= 4003 || __has_attribute(alloc_size) 197 # define ZEND_ATTRIBUTE_ALLOC_SIZE(X) __attribute__ ((alloc_size(X))) 198 # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) __attribute__ ((alloc_size(X,Y))) 199 #else 200 # define ZEND_ATTRIBUTE_ALLOC_SIZE(X) 201 # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) 202 #endif 203 204 #if ZEND_GCC_VERSION >= 2007 || __has_attribute(format) 205 # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first))) 206 #else 207 # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) 208 #endif 209 210 #if (ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)) || __has_attribute(format) 211 # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first))) 212 #else 213 # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) 214 #endif 215 216 #if ZEND_GCC_VERSION >= 3001 || __has_attribute(deprecated) 217 # define ZEND_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) 218 #elif defined(ZEND_WIN32) 219 # define ZEND_ATTRIBUTE_DEPRECATED __declspec(deprecated) 220 #else 221 # define ZEND_ATTRIBUTE_DEPRECATED 222 #endif 223 224 #if ZEND_GCC_VERSION >= 4003 || __has_attribute(unused) 225 # define ZEND_ATTRIBUTE_UNUSED __attribute__((unused)) 226 #else 227 # define ZEND_ATTRIBUTE_UNUSED 228 #endif 229 230 #if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003 231 # define ZEND_COLD __attribute__((cold)) 232 # define ZEND_HOT __attribute__((hot)) 233 # ifdef __OPTIMIZE__ 234 # define ZEND_OPT_SIZE __attribute__((optimize("Os"))) 235 # define ZEND_OPT_SPEED __attribute__((optimize("Ofast"))) 236 # else 237 # define ZEND_OPT_SIZE 238 # define ZEND_OPT_SPEED 239 # endif 240 #else 241 # define ZEND_COLD 242 # define ZEND_HOT 243 # define ZEND_OPT_SIZE 244 # define ZEND_OPT_SPEED 245 #endif 246 247 #if defined(__GNUC__) && ZEND_GCC_VERSION >= 5000 248 # define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((unused)); 249 # define ZEND_ATTRIBUTE_COLD_LABEL __attribute__((cold)); 250 # define ZEND_ATTRIBUTE_HOT_LABEL __attribute__((hot)); 251 #else 252 # define ZEND_ATTRIBUTE_UNUSED_LABEL 253 # define ZEND_ATTRIBUTE_COLD_LABEL 254 # define ZEND_ATTRIBUTE_HOT_LABEL 255 #endif 256 257 #if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__) 258 # define ZEND_FASTCALL __attribute__((fastcall)) 259 #elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700 260 # define ZEND_FASTCALL __fastcall 261 #elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__) 262 # define ZEND_FASTCALL __vectorcall 263 #else 264 # define ZEND_FASTCALL 265 #endif 266 267 #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn) 268 # define HAVE_NORETURN 269 # define ZEND_NORETURN __attribute__((noreturn)) 270 #elif defined(ZEND_WIN32) 271 # define HAVE_NORETURN 272 # define ZEND_NORETURN __declspec(noreturn) 273 #else 274 # define ZEND_NORETURN 275 #endif 276 277 #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) 278 # define HAVE_NORETURN_ALIAS 279 # define HAVE_ATTRIBUTE_WEAK 280 #endif 281 282 #if ZEND_GCC_VERSION >= 3001 || __has_builtin(__builtin_constant_p) 283 # define HAVE_BUILTIN_CONSTANT_P 284 #endif 285 286 #ifdef HAVE_BUILTIN_CONSTANT_P 287 # define ZEND_CONST_COND(_condition, _default) \ 288 (__builtin_constant_p(_condition) ? (_condition) : (_default)) 289 #else 290 # define ZEND_CONST_COND(_condition, _default) \ 291 (_default) 292 #endif 293 294 #if ZEND_DEBUG || defined(ZEND_WIN32_NEVER_INLINE) 295 # define zend_always_inline inline 296 # define zend_never_inline 297 #else 298 # if defined(__GNUC__) 299 # if __GNUC__ >= 3 300 # define zend_always_inline inline __attribute__((always_inline)) 301 # define zend_never_inline __attribute__((noinline)) 302 # else 303 # define zend_always_inline inline 304 # define zend_never_inline 305 # endif 306 # elif defined(_MSC_VER) 307 # define zend_always_inline __forceinline 308 # define zend_never_inline __declspec(noinline) 309 # else 310 # if __has_attribute(always_inline) 311 # define zend_always_inline inline __attribute__((always_inline)) 312 # else 313 # define zend_always_inline inline 314 # endif 315 # if __has_attribute(noinline) 316 # define zend_never_inline __attribute__((noinline)) 317 # else 318 # define zend_never_inline 319 # endif 320 # endif 321 #endif /* ZEND_DEBUG */ 322 323 #ifdef PHP_HAVE_BUILTIN_EXPECT 324 # define EXPECTED(condition) __builtin_expect(!!(condition), 1) 325 # define UNEXPECTED(condition) __builtin_expect(!!(condition), 0) 326 #else 327 # define EXPECTED(condition) (condition) 328 # define UNEXPECTED(condition) (condition) 329 #endif 330 331 #ifndef XtOffsetOf 332 # define XtOffsetOf(s_type, field) offsetof(s_type, field) 333 #endif 334 335 #if (defined(HAVE_ALLOCA) || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN) 336 # define ZEND_ALLOCA_MAX_SIZE (32 * 1024) 337 # define ALLOCA_FLAG(name) \ 338 zend_bool name; 339 # define SET_ALLOCA_FLAG(name) \ 340 name = 1 341 # define do_alloca_ex(size, limit, use_heap) \ 342 ((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size)) 343 # define do_alloca(size, use_heap) \ 344 do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap) 345 # define free_alloca(p, use_heap) \ 346 do { if (UNEXPECTED(use_heap)) efree(p); } while (0) 347 #else 348 # define ALLOCA_FLAG(name) 349 # define SET_ALLOCA_FLAG(name) 350 # define do_alloca(p, use_heap) emalloc(p) 351 # define free_alloca(p, use_heap) efree(p) 352 #endif 353 354 #ifdef HAVE_SIGSETJMP 355 # define SETJMP(a) sigsetjmp(a, 0) 356 # define LONGJMP(a,b) siglongjmp(a, b) 357 # define JMP_BUF sigjmp_buf 358 #else 359 # define SETJMP(a) setjmp(a) 360 # define LONGJMP(a,b) longjmp(a, b) 361 # define JMP_BUF jmp_buf 362 #endif 363 364 #if ZEND_DEBUG 365 # define ZEND_FILE_LINE_D const char *__zend_filename, const uint32_t __zend_lineno 366 # define ZEND_FILE_LINE_DC , ZEND_FILE_LINE_D 367 # define ZEND_FILE_LINE_ORIG_D const char *__zend_orig_filename, const uint32_t __zend_orig_lineno 368 # define ZEND_FILE_LINE_ORIG_DC , ZEND_FILE_LINE_ORIG_D 369 # define ZEND_FILE_LINE_RELAY_C __zend_filename, __zend_lineno 370 # define ZEND_FILE_LINE_RELAY_CC , ZEND_FILE_LINE_RELAY_C 371 # define ZEND_FILE_LINE_C __FILE__, __LINE__ 372 # define ZEND_FILE_LINE_CC , ZEND_FILE_LINE_C 373 # define ZEND_FILE_LINE_EMPTY_C NULL, 0 374 # define ZEND_FILE_LINE_EMPTY_CC , ZEND_FILE_LINE_EMPTY_C 375 # define ZEND_FILE_LINE_ORIG_RELAY_C __zend_orig_filename, __zend_orig_lineno 376 # define ZEND_FILE_LINE_ORIG_RELAY_CC , ZEND_FILE_LINE_ORIG_RELAY_C 377 #else 378 # define ZEND_FILE_LINE_D void 379 # define ZEND_FILE_LINE_DC 380 # define ZEND_FILE_LINE_ORIG_D void 381 # define ZEND_FILE_LINE_ORIG_DC 382 # define ZEND_FILE_LINE_RELAY_C 383 # define ZEND_FILE_LINE_RELAY_CC 384 # define ZEND_FILE_LINE_C 385 # define ZEND_FILE_LINE_CC 386 # define ZEND_FILE_LINE_EMPTY_C 387 # define ZEND_FILE_LINE_EMPTY_CC 388 # define ZEND_FILE_LINE_ORIG_RELAY_C 389 # define ZEND_FILE_LINE_ORIG_RELAY_CC 390 #endif /* ZEND_DEBUG */ 391 392 #if ZEND_DEBUG 393 # define Z_DBG(expr) (expr) 394 #else 395 # define Z_DBG(expr) 396 #endif 397 398 #ifdef ZTS 399 # define ZTS_V 1 400 #else 401 # define ZTS_V 0 402 #endif 403 404 #ifndef LONG_MAX 405 # define LONG_MAX 2147483647L 406 #endif 407 408 #ifndef LONG_MIN 409 # define LONG_MIN (- LONG_MAX - 1) 410 #endif 411 412 #define MAX_LENGTH_OF_DOUBLE 32 413 414 #undef MIN 415 #undef MAX 416 #define MAX(a, b) (((a)>(b))?(a):(b)) 417 #define MIN(a, b) (((a)<(b))?(a):(b)) 418 419 #define ZEND_BIT_TEST(bits, bit) \ 420 (((bits)[(bit) / (sizeof((bits)[0])*8)] >> ((bit) & (sizeof((bits)[0])*8-1))) & 1) 421 422 #define ZEND_INFINITY INFINITY 423 424 #define ZEND_NAN NAN 425 426 #if defined(__cplusplus) && __cplusplus >= 201103L 427 extern "C++" { 428 # include <cmath> 429 } 430 # define zend_isnan std::isnan 431 # define zend_isinf std::isinf 432 # define zend_finite std::isfinite 433 #else 434 # include <math.h> 435 # define zend_isnan(a) isnan(a) 436 # define zend_isinf(a) isinf(a) 437 # define zend_finite(a) isfinite(a) 438 #endif 439 440 #define ZEND_STRL(str) (str), (sizeof(str)-1) 441 #define ZEND_STRS(str) (str), (sizeof(str)) 442 #define ZEND_NORMALIZE_BOOL(n) \ 443 ((n) ? (((n)<0) ? -1 : 1) : 0) 444 #define ZEND_TRUTH(x) ((x) ? 1 : 0) 445 #define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b)) 446 447 #define ZEND_MAX_RESERVED_RESOURCES 6 448 449 /* excpt.h on Digital Unix 4.0 defines function_table */ 450 #undef function_table 451 452 #ifdef ZEND_WIN32 453 #define ZEND_SECURE_ZERO(var, size) RtlSecureZeroMemory((var), (size)) 454 #else 455 #define ZEND_SECURE_ZERO(var, size) explicit_bzero((var), (size)) 456 #endif 457 458 /* This check should only be used on network socket, not file descriptors */ 459 #ifdef ZEND_WIN32 460 #define ZEND_VALID_SOCKET(sock) (INVALID_SOCKET != (sock)) 461 #else 462 #define ZEND_VALID_SOCKET(sock) ((sock) >= 0) 463 #endif 464 465 /* Intrinsics macros start. */ 466 467 /* Memory sanitizer is incompatible with ifunc resolvers. Even if the resolver 468 * is marked as no_sanitize("memory") it will still be instrumented and crash. */ 469 #if __has_feature(memory_sanitizer) || __has_feature(thread_sanitizer) || \ 470 __has_feature(dataflow_sanitizer) 471 # undef HAVE_FUNC_ATTRIBUTE_IFUNC 472 #endif 473 474 /* Only use ifunc resolvers if we have __builtin_cpu_supports() and __builtin_cpu_init(), 475 * otherwise the use of zend_cpu_supports() may not be safe inside ifunc resolvers. */ 476 #if defined(HAVE_FUNC_ATTRIBUTE_IFUNC) && defined(HAVE_FUNC_ATTRIBUTE_TARGET) && \ 477 defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && defined(PHP_HAVE_BUILTIN_CPU_INIT) 478 # define ZEND_INTRIN_HAVE_IFUNC_TARGET 1 479 #endif 480 481 #if (defined(__i386__) || defined(__x86_64__)) 482 # if defined(HAVE_TMMINTRIN_H) 483 # define PHP_HAVE_SSSE3 484 # endif 485 486 # if defined(HAVE_NMMINTRIN_H) 487 # define PHP_HAVE_SSE4_2 488 # endif 489 490 # if defined(HAVE_WMMINTRIN_H) 491 # define PHP_HAVE_PCLMUL 492 # endif 493 494 /* 495 * AVX2 support was added in gcc 4.7, but AVX2 intrinsics don't work in 496 * __attribute__((target("avx2"))) functions until gcc 4.9. 497 */ 498 # if defined(HAVE_IMMINTRIN_H) && \ 499 (defined(__llvm__) || defined(__clang__) || (defined(__GNUC__) && ZEND_GCC_VERSION >= 4009)) 500 # define PHP_HAVE_AVX2 501 # endif 502 #endif 503 504 #ifdef __SSSE3__ 505 /* Instructions compiled directly. */ 506 # define ZEND_INTRIN_SSSE3_NATIVE 1 507 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSSE3)) || defined(ZEND_WIN32) 508 /* Function resolved by ifunc or MINIT. */ 509 # define ZEND_INTRIN_SSSE3_RESOLVER 1 510 #endif 511 512 /* Do not use for conditional declaration of API functions! */ 513 #if defined(ZEND_INTRIN_SSSE3_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) 514 # define ZEND_INTRIN_SSSE3_FUNC_PROTO 1 515 #elif defined(ZEND_INTRIN_SSSE3_RESOLVER) 516 # define ZEND_INTRIN_SSSE3_FUNC_PTR 1 517 #endif 518 519 #ifdef ZEND_INTRIN_SSSE3_RESOLVER 520 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET 521 # define ZEND_INTRIN_SSSE3_FUNC_DECL(func) ZEND_API func __attribute__((target("ssse3"))) 522 # else 523 # define ZEND_INTRIN_SSSE3_FUNC_DECL(func) func 524 # endif 525 #else 526 # define ZEND_INTRIN_SSSE3_FUNC_DECL(func) 527 #endif 528 529 #ifdef __SSE4_2__ 530 /* Instructions compiled directly. */ 531 # define ZEND_INTRIN_SSE4_2_NATIVE 1 532 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSE4_2)) || defined(ZEND_WIN32) 533 /* Function resolved by ifunc or MINIT. */ 534 # define ZEND_INTRIN_SSE4_2_RESOLVER 1 535 #endif 536 537 /* Do not use for conditional declaration of API functions! */ 538 #if defined(ZEND_INTRIN_SSE4_2_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) 539 # define ZEND_INTRIN_SSE4_2_FUNC_PROTO 1 540 #elif defined(ZEND_INTRIN_SSE4_2_RESOLVER) 541 # define ZEND_INTRIN_SSE4_2_FUNC_PTR 1 542 #endif 543 544 #ifdef ZEND_INTRIN_SSE4_2_RESOLVER 545 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET 546 # define ZEND_INTRIN_SSE4_2_FUNC_DECL(func) ZEND_API func __attribute__((target("sse4.2"))) 547 # else 548 # define ZEND_INTRIN_SSE4_2_FUNC_DECL(func) func 549 # endif 550 #else 551 # define ZEND_INTRIN_SSE4_2_FUNC_DECL(func) 552 #endif 553 554 #ifdef __PCLMUL__ 555 /* Instructions compiled directly. */ 556 # define ZEND_INTRIN_PCLMUL_NATIVE 1 557 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_PCLMUL)) || defined(ZEND_WIN32) 558 /* Function resolved by ifunc or MINIT. */ 559 # define ZEND_INTRIN_PCLMUL_RESOLVER 1 560 #endif 561 562 /* Do not use for conditional declaration of API functions! */ 563 #if defined(ZEND_INTRIN_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000)) 564 /* __builtin_cpu_supports has pclmul from gcc9 */ 565 # define ZEND_INTRIN_PCLMUL_FUNC_PROTO 1 566 #elif defined(ZEND_INTRIN_PCLMUL_RESOLVER) 567 # define ZEND_INTRIN_PCLMUL_FUNC_PTR 1 568 #endif 569 570 #ifdef ZEND_INTRIN_PCLMUL_RESOLVER 571 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET 572 # define ZEND_INTRIN_PCLMUL_FUNC_DECL(func) ZEND_API func __attribute__((target("pclmul"))) 573 # else 574 # define ZEND_INTRIN_PCLMUL_FUNC_DECL(func) func 575 # endif 576 #else 577 # define ZEND_INTRIN_PCLMUL_FUNC_DECL(func) 578 #endif 579 580 #if defined(ZEND_INTRIN_SSE4_2_NATIVE) && defined(ZEND_INTRIN_PCLMUL_NATIVE) 581 /* Instructions compiled directly. */ 582 # define ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE 1 583 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSE4_2) && defined(PHP_HAVE_PCLMUL)) || defined(ZEND_WIN32) 584 /* Function resolved by ifunc or MINIT. */ 585 # define ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER 1 586 #endif 587 588 /* Do not use for conditional declaration of API functions! */ 589 #if defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000)) 590 /* __builtin_cpu_supports has pclmul from gcc9 */ 591 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PROTO 1 592 #elif defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER) 593 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR 1 594 #endif 595 596 #ifdef ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER 597 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET 598 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(func) ZEND_API func __attribute__((target("sse4.2,pclmul"))) 599 # else 600 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(func) func 601 # endif 602 #else 603 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(func) 604 #endif 605 606 #ifdef __AVX2__ 607 # define ZEND_INTRIN_AVX2_NATIVE 1 608 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_AVX2)) || defined(ZEND_WIN32) 609 # define ZEND_INTRIN_AVX2_RESOLVER 1 610 #endif 611 612 /* Do not use for conditional declaration of API functions! */ 613 #if defined(ZEND_INTRIN_AVX2_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) 614 # define ZEND_INTRIN_AVX2_FUNC_PROTO 1 615 #elif defined(ZEND_INTRIN_AVX2_RESOLVER) 616 # define ZEND_INTRIN_AVX2_FUNC_PTR 1 617 #endif 618 619 #ifdef ZEND_INTRIN_AVX2_RESOLVER 620 # ifdef HAVE_FUNC_ATTRIBUTE_TARGET 621 # define ZEND_INTRIN_AVX2_FUNC_DECL(func) ZEND_API func __attribute__((target("avx2"))) 622 # else 623 # define ZEND_INTRIN_AVX2_FUNC_DECL(func) func 624 # endif 625 #else 626 # define ZEND_INTRIN_AVX2_FUNC_DECL(func) 627 #endif 628 629 /* Intrinsics macros end. */ 630 631 #ifdef ZEND_WIN32 632 # define ZEND_SET_ALIGNED(alignment, decl) __declspec(align(alignment)) decl 633 #elif defined(HAVE_ATTRIBUTE_ALIGNED) 634 # define ZEND_SET_ALIGNED(alignment, decl) decl __attribute__ ((__aligned__ (alignment))) 635 #else 636 # define ZEND_SET_ALIGNED(alignment, decl) decl 637 #endif 638 639 #define ZEND_SLIDE_TO_ALIGNED(alignment, ptr) (((zend_uintptr_t)(ptr) + ((alignment)-1)) & ~((alignment)-1)) 640 #define ZEND_SLIDE_TO_ALIGNED16(ptr) ZEND_SLIDE_TO_ALIGNED(Z_UL(16), ptr) 641 642 #ifdef ZEND_WIN32 643 # define _ZEND_EXPAND_VA(a) a 644 # define ZEND_EXPAND_VA(code) _ZEND_EXPAND_VA(code) 645 #else 646 # define ZEND_EXPAND_VA(code) code 647 #endif 648 649 /* On CPU with few registers, it's cheaper to reload value then use spill slot */ 650 #if defined(__i386__) || (defined(_WIN32) && !defined(_WIN64)) 651 # define ZEND_PREFER_RELOAD 652 #endif 653 654 #if defined(ZEND_WIN32) && defined(_DEBUG) 655 # define ZEND_IGNORE_LEAKS_BEGIN() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & ~_CRTDBG_ALLOC_MEM_DF) 656 # define ZEND_IGNORE_LEAKS_END() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_ALLOC_MEM_DF) 657 #else 658 # define ZEND_IGNORE_LEAKS_BEGIN() 659 # define ZEND_IGNORE_LEAKS_END() 660 #endif 661 662 /* MSVC yields C4090 when a (const T **) is passed to a (void *); ZEND_VOIDP works around that */ 663 #ifdef _MSC_VER 664 # define ZEND_VOIDP(ptr) ((void *) ptr) 665 #else 666 # define ZEND_VOIDP(ptr) (ptr) 667 #endif 668 669 #endif /* ZEND_PORTABILITY_H */ 670