php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
zend_extensions.c
Go to the documentation of this file.
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 +----------------------------------------------------------------------+
18*/
19
20#include "zend_extensions.h"
21#include "zend_system_id.h"
22
27static int last_resource_number;
28
30{
31#if ZEND_EXTENSIONS_SUPPORT
33
34 handle = DL_LOAD(path);
35 if (!handle) {
36#ifndef ZEND_WIN32
37 fprintf(stderr, "Failed loading %s: %s\n", path, DL_ERROR());
38#else
39 fprintf(stderr, "Failed loading %s\n", path);
40 /* See http://support.microsoft.com/kb/190351 */
41 fflush(stderr);
42#endif
43 return FAILURE;
44 }
45#ifdef ZEND_WIN32
46 char *err;
49 return FAILURE;
50 }
51#endif
53#else
54 fprintf(stderr, "Extensions are not supported on this platform.\n");
55/* See http://support.microsoft.com/kb/190351 */
56#ifdef ZEND_WIN32
57 fflush(stderr);
58#endif
59 return FAILURE;
60#endif
61}
62
64{
65#if ZEND_EXTENSIONS_SUPPORT
66 zend_extension *new_extension;
67
68 const zend_extension_version_info *extension_version_info = (const zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info");
69 if (!extension_version_info) {
70 extension_version_info = (const zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "_extension_version_info");
71 }
72 new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry");
73 if (!new_extension) {
74 new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "_zend_extension_entry");
75 }
76 if (!extension_version_info || !new_extension) {
77 fprintf(stderr, "%s doesn't appear to be a valid Zend extension\n", path);
78/* See http://support.microsoft.com/kb/190351 */
79#ifdef ZEND_WIN32
80 fflush(stderr);
81#endif
82 DL_UNLOAD(handle);
83 return FAILURE;
84 }
85
86 /* allow extension to proclaim compatibility with any Zend version */
87 if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
88 if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
89 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
90 "The Zend Engine API version %d which is installed, is outdated.\n\n",
91 new_extension->name,
92 extension_version_info->zend_extension_api_no,
94/* See http://support.microsoft.com/kb/190351 */
95#ifdef ZEND_WIN32
96 fflush(stderr);
97#endif
98 DL_UNLOAD(handle);
99 return FAILURE;
100 } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
101 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
102 "The Zend Engine API version %d which is installed, is newer.\n"
103 "Contact %s at %s for a later version of %s.\n\n",
104 new_extension->name,
105 extension_version_info->zend_extension_api_no,
107 new_extension->author,
108 new_extension->URL,
109 new_extension->name);
110/* See http://support.microsoft.com/kb/190351 */
111#ifdef ZEND_WIN32
112 fflush(stderr);
113#endif
114 DL_UNLOAD(handle);
115 return FAILURE;
116 }
117 } else if (strcmp(ZEND_EXTENSION_BUILD_ID, extension_version_info->build_id) &&
118 (!new_extension->build_id_check || new_extension->build_id_check(ZEND_EXTENSION_BUILD_ID) != SUCCESS)) {
119 fprintf(stderr, "Cannot load %s - it was built with configuration %s, whereas running engine is %s\n",
120 new_extension->name, extension_version_info->build_id, ZEND_EXTENSION_BUILD_ID);
121/* See http://support.microsoft.com/kb/190351 */
122#ifdef ZEND_WIN32
123 fflush(stderr);
124#endif
125 DL_UNLOAD(handle);
126 return FAILURE;
127 } else if (zend_get_extension(new_extension->name)) {
128 fprintf(stderr, "Cannot load %s - it was already loaded\n", new_extension->name);
129/* See http://support.microsoft.com/kb/190351 */
130#ifdef ZEND_WIN32
131 fflush(stderr);
132#endif
133 DL_UNLOAD(handle);
134 return FAILURE;
135 }
136
137 zend_register_extension(new_extension, handle);
138 return SUCCESS;
139#else
140 fprintf(stderr, "Extensions are not supported on this platform.\n");
141/* See http://support.microsoft.com/kb/190351 */
142#ifdef ZEND_WIN32
143 fflush(stderr);
144#endif
145 return FAILURE;
146#endif
147}
148
149
151{
152#if ZEND_EXTENSIONS_SUPPORT
153 zend_extension extension;
154
155 extension = *new_extension;
156 extension.handle = handle;
157
159
161
162 if (extension.op_array_ctor) {
164 }
165 if (extension.op_array_dtor) {
167 }
168 if (extension.op_array_handler) {
170 }
171 if (extension.op_array_persist_calc) {
173 }
174 if (extension.op_array_persist) {
176 }
177 /*fprintf(stderr, "Loaded %s, version %s\n", extension.name, extension.version);*/
178#endif
179}
180
181
182static void zend_extension_shutdown(zend_extension *extension)
183{
184#if ZEND_EXTENSIONS_SUPPORT
185 if (extension->shutdown) {
186 extension->shutdown(extension);
187 }
188#endif
189}
190
191/* int return due to zend linked list API */
192static int zend_extension_startup(zend_extension *extension)
193{
194#if ZEND_EXTENSIONS_SUPPORT
195 if (extension->startup) {
196 if (extension->startup(extension)!=SUCCESS) {
197 return 1;
198 }
199 zend_append_version_info(extension);
200 }
201#endif
202 return 0;
203}
204
205
207{
208 /* Startup extensions mechanism */
209 zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1);
212 last_resource_number = 0;
213}
214
215
217{
218 zend_llist_apply_with_del(&zend_extensions, (int (*)(void *)) zend_extension_startup);
219}
220
221
227
228
230{
231#if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG
232 if (extension->handle && !getenv("ZEND_DONT_UNLOAD_MODULES")) {
233 DL_UNLOAD(extension->handle);
234 }
235#endif
236}
237
238
239static void zend_extension_message_dispatcher(const zend_extension *extension, int num_args, va_list args)
240{
241 int message;
242 void *arg;
243
244 if (!extension->message_handler || num_args!=2) {
245 return;
246 }
247 message = va_arg(args, int);
248 arg = va_arg(args, void *);
249 extension->message_handler(message, arg);
250}
251
252
254{
255 zend_llist_apply_with_arguments(&zend_extensions, (llist_apply_with_args_func_t) zend_extension_message_dispatcher, 2, message, arg);
256}
257
258
259ZEND_API int zend_get_resource_handle(const char *module_name)
260{
261 if (last_resource_number<ZEND_MAX_RESERVED_RESOURCES) {
262 zend_add_system_entropy(module_name, "zend_get_resource_handle", &last_resource_number, sizeof(int));
263 return last_resource_number++;
264 } else {
265 return -1;
266 }
267}
268
291{
293 zend_add_system_entropy(module_name, "zend_get_op_array_extension_handle", &zend_op_array_extension_handles, sizeof(int));
294 return handle;
295}
296
298ZEND_API int zend_get_op_array_extension_handles(const char *module_name, int handles)
299{
302 zend_add_system_entropy(module_name, "zend_get_op_array_extension_handle", &zend_op_array_extension_handles, sizeof(int));
303 return handle;
304}
305
307{
309 zend_add_system_entropy(module_name, "zend_get_internal_function_extension_handle", &zend_internal_function_extension_handles, sizeof(int));
310 return handle;
311}
312
313ZEND_API int zend_get_internal_function_extension_handles(const char *module_name, int handles)
314{
317 zend_add_system_entropy(module_name, "zend_get_internal_function_extension_handle", &zend_internal_function_extension_handles, sizeof(int));
318 return handle;
319}
320
324
327 if (rt_size) {
328 size_t functions = zend_hash_num_elements(CG(function_table));
330 ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) {
331 functions += zend_hash_num_elements(&ce->function_table);
333
334 size_t alloc_size = functions * rt_size;
335 char *ptr = pemalloc(alloc_size, 1);
336
337 CG(internal_run_time_cache) = ptr;
338 CG(internal_run_time_cache_size) = alloc_size;
339
341 ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), zif) {
342 if (!ZEND_USER_CODE(zif->type) && ZEND_MAP_PTR_GET(zif->run_time_cache) == NULL) {
343 ZEND_MAP_PTR_SET(zif->run_time_cache, (void *)ptr);
344 ptr += rt_size;
345 }
347 ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) {
349 if (!ZEND_USER_CODE(zif->type) && ZEND_MAP_PTR_GET(zif->run_time_cache) == NULL) {
350 ZEND_MAP_PTR_SET(zif->run_time_cache, (void *)ptr);
351 ptr += rt_size;
352 }
355 }
356}
357
359 if (CG(internal_run_time_cache)) {
360 memset(CG(internal_run_time_cache), 0, CG(internal_run_time_cache_size));
361 }
362}
363
364ZEND_API zend_extension *zend_get_extension(const char *extension_name)
365{
366 zend_llist_element *element;
367
368 for (element = zend_extensions.head; element; element = element->next) {
369 zend_extension *extension = (zend_extension *) element->data;
370
371 if (!strcmp(extension->name, extension_name)) {
372 return extension;
373 }
374 }
375 return NULL;
376}
377
383
384static void zend_extension_op_array_persist_calc_handler(zend_extension *extension, zend_extension_persist_data *data)
385{
386 if (extension->op_array_persist_calc) {
387 data->size += extension->op_array_persist_calc(data->op_array);
388 }
389}
390
391static void zend_extension_op_array_persist_handler(zend_extension *extension, zend_extension_persist_data *data)
392{
393 if (extension->op_array_persist) {
394 size_t size = extension->op_array_persist(data->op_array, data->mem);
395 if (size) {
396 data->mem = (void*)((char*)data->mem + size);
397 data->size += size;
398 }
399 }
400}
401
403{
406
407 data.op_array = op_array;
408 data.size = 0;
409 data.mem = NULL;
410 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_persist_calc_handler, &data);
411 return data.size;
412 }
413 return 0;
414}
415
417{
420
421 data.op_array = op_array;
422 data.size = 0;
423 data.mem = mem;
424 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_persist_handler, &data);
425 return data.size;
426 }
427 return 0;
428}
fprintf($stream, string $format, mixed ... $values)
getenv(?string $name=null, bool $local_only=false)
fflush($stream)
DL_HANDLE handle
Definition ffi.c:3028
new_type size
Definition ffi.c:4365
void * ptr
Definition ffi.c:3814
char * err
Definition ffi.c:3029
zval * arg
Definition ffi.c:3975
memset(ptr, 0, type->size)
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
HashTable functions
zend_constant * data
HashTable function_table
Definition zend.h:163
message_handler_func_t message_handler
op_array_persist_calc_func_t op_array_persist_calc
op_array_persist_func_t op_array_persist
int(* build_id_check)(const char *build_id)
op_array_dtor_func_t op_array_dtor
shutdown_func_t shutdown
const char * URL
op_array_ctor_func_t op_array_ctor
op_array_handler_func_t op_array_handler
const char * name
const char * author
int(* api_no_check)(int api_no)
startup_func_t startup
struct _zend_llist_element * next
Definition zend_llist.h:26
PHP_WINUTIL_API BOOL php_win32_image_compatible(HMODULE handle, char **err)
Definition winutil.c:479
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
Definition zend.c:1666
ZEND_API void zend_append_version_info(const zend_extension *extension)
Definition zend.c:1284
#define pemalloc(size, persistent)
Definition zend_alloc.h:189
strcmp(string $string1, string $string2)
uint32_t num_args
zval * args
#define ZEND_USER_CODE(type)
struct _zend_op_array zend_op_array
struct _zend_internal_function zend_internal_function
#define ZEND_API
#define E_CORE_WARNING
Definition zend_errors.h:28
ZEND_API int zend_internal_function_extension_handles
ZEND_API int zend_get_internal_function_extension_handles(const char *module_name, int handles)
void zend_register_extension(zend_extension *new_extension, DL_HANDLE handle)
void zend_startup_extensions(void)
zend_result zend_load_extension(const char *path)
ZEND_API uint32_t zend_extension_flags
ZEND_API size_t zend_extensions_op_array_persist(zend_op_array *op_array, void *mem)
ZEND_API void zend_init_internal_run_time_cache(void)
ZEND_API int zend_get_resource_handle(const char *module_name)
ZEND_API size_t zend_extensions_op_array_persist_calc(zend_op_array *op_array)
ZEND_API zend_extension * zend_get_extension(const char *extension_name)
ZEND_API int zend_get_internal_function_extension_handle(const char *module_name)
void zend_shutdown_extensions(void)
ZEND_API int zend_get_op_array_extension_handles(const char *module_name, int handles)
ZEND_API void zend_reset_internal_run_time_cache(void)
ZEND_API zend_llist zend_extensions
zend_result zend_load_extension_handle(DL_HANDLE handle, const char *path)
struct _zend_extension_persist_data zend_extension_persist_data
ZEND_API void zend_extension_dispatch_message(int message, void *arg)
ZEND_API int zend_get_op_array_extension_handle(const char *module_name)
ZEND_API size_t zend_internal_run_time_cache_reserved_size(void)
ZEND_API int zend_op_array_extension_handles
void zend_startup_extensions_mechanism(void)
void zend_extension_dtor(zend_extension *extension)
struct _zend_extension_version_info zend_extension_version_info
#define ZEND_EXTENSION_BUILD_ID
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_CTOR
#define ZEND_EXTMSG_NEW_EXTENSION
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_HANDLER
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST_CALC
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_DTOR
struct _zend_extension zend_extension
#define ZEND_EXTENSION_API_NO
#define CG(v)
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
Definition zend_hash.h:1326
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
ZEND_API void zend_llist_destroy(zend_llist *l)
Definition zend_llist.c:102
ZEND_API void zend_llist_add_element(zend_llist *l, const void *element)
Definition zend_llist.c:34
ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
Definition zend_llist.c:24
ZEND_API void zend_llist_apply_with_del(zend_llist *l, int(*func)(void *data))
Definition zend_llist.c:164
ZEND_API void zend_llist_apply_with_arguments(zend_llist *l, llist_apply_with_args_func_t func, int num_args,...)
Definition zend_llist.c:241
ZEND_API void zend_llist_apply(zend_llist *l, llist_apply_func_t func)
Definition zend_llist.c:179
ZEND_API void zend_llist_apply_with_argument(zend_llist *l, llist_apply_with_arg_func_t func, void *arg)
Definition zend_llist.c:231
struct _zend_llist_element zend_llist_element
void(* llist_apply_with_args_func_t)(void *data, int num_args, va_list args)
Definition zend_llist.h:33
void(* llist_apply_with_arg_func_t)(void *data, void *arg)
Definition zend_llist.h:34
void(* llist_apply_func_t)(void *)
Definition zend_llist.h:35
struct _zend_llist zend_llist
#define ZEND_MAP_PTR_GET(ptr)
#define ZEND_MAP_PTR_SET(ptr, val)
#define DL_HANDLE
#define ZEND_MAX_RESERVED_RESOURCES
struct _zend_class_entry zend_class_entry
ZEND_API zend_result zend_add_system_entropy(const char *module_name, const char *hook_name, const void *data, size_t size)
@ FAILURE
Definition zend_types.h:61
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64