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