-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Expand file tree
/
Copy pathzend_call_stack.h
More file actions
135 lines (118 loc) · 3.82 KB
/
Copy pathzend_call_stack.h
File metadata and controls
135 lines (118 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright © Zend Technologies Ltd., a subsidiary company of |
| Perforce Software, Inc., and Contributors. |
+----------------------------------------------------------------------+
| This source file is subject to the Modified BSD License that is |
| bundled with this package in the file LICENSE, and is available |
| through the World Wide Web at <https://www.php.net/license/>. |
| |
| SPDX-License-Identifier: BSD-3-Clause |
+----------------------------------------------------------------------+
| Authors: Arnaud Le Blanc <arnaud.lb@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_CALL_STACK_H
#define ZEND_CALL_STACK_H
#include "zend.h"
#include "zend_portability.h"
#ifdef _MSC_VER
# include <intrin.h>
#endif
#ifdef __APPLE__
# include <pthread.h>
#endif
#ifdef _MSC_VER
#include <intrin.h>
#endif
#ifdef ZEND_CHECK_STACK_LIMIT
typedef struct _zend_call_stack {
void *base; /* high address of the stack */
size_t max_size;
} zend_call_stack;
ZEND_API void zend_call_stack_init(void);
ZEND_API bool zend_call_stack_get(zend_call_stack *stack);
/** Returns an approximation of the current stack position */
static zend_always_inline void *zend_call_stack_position(void) {
#ifdef _MSC_VER
return _AddressOfReturnAddress();
#elif defined(PHP_HAVE_BUILTIN_FRAME_ADDRESS)
return __builtin_frame_address(0);
#else
void *a;
void *pos = (void*)&a;
return pos;
#endif
}
static zend_always_inline bool zend_call_stack_overflowed(void *stack_limit) {
return (uintptr_t) zend_call_stack_position() <= (uintptr_t) stack_limit;
}
static inline void* zend_call_stack_limit(void *base, size_t size, size_t reserved_size)
{
if (UNEXPECTED(size > (uintptr_t)base)) {
return (void*)0;
}
base = (int8_t*)base - size;
if (UNEXPECTED(UINTPTR_MAX - (uintptr_t)base < reserved_size)) {
return (void*)UINTPTR_MAX;
}
return (int8_t*)base + reserved_size;
}
static inline size_t zend_call_stack_default_size(void)
{
#ifdef __linux__
return 8 * 1024 * 1024;
#endif
#if defined(__FreeBSD__) || defined(__NetBSD__)
return 4 * 1024 * 1024;
#endif
#if defined(__DragonFly__)
return 2 * 1024 * 1024;
#endif
#ifdef __OpenBSD__
return 512 * 1024;
#endif
#ifdef __APPLE__
// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html
if (pthread_main_np()) {
return 8 * 1024 * 1024;
}
return 512 * 1024;
#endif
#ifdef __HAIKU__
return 64 * 4096;
#endif
#ifdef __sun
return 8 * 4096;
#endif
#ifdef _AIX
/*
* default pthread stack limit is 96 KB on 32-bit, 192 KB on 64-bit
* https://www.ibm.com/docs/en/aix/7.1.0?topic=programming-threads-library-options
*/
#ifdef HAVE_PTHREAD_GETTHRDS_NP /* if we have pthread linked (not in libc) */
if (pthread_self() != 1) {
#ifdef __64BIT__
return 192 * 1024;
#else
return 96 * 1024;
#endif
}
#endif
/*
* default AIX ulimit -s value is allegedly 32 MB, default values per:
* https://www.ibm.com/docs/en/aix/7.1.0?topic=u-ulimit-command
* N.B.: the the file uses 512b blocks, but the command uses kilobytes
* https://www.ibm.com/support/pages/ibm-aix-security-ulimit-and-ulimit-d-output-differs-value-etcsecuritylimits
*
* note PASE uses an unlimited stack size by default, which is capped
* at the PowerPC segment size (256 MB)
*/
return 32 * 1024 * 1024;
#endif
return 2 * 1024 * 1024;
}
#endif /* ZEND_CHECK_STACK_LIMIT */
#endif /* ZEND_CALL_STACK_H */