]> granicus.if.org Git - php/commitdiff
Fixed bug #46074 (Bus error during running PHP CLI under IRIX 6.5.30)
authorDmitry Stogov <dmitry@php.net>
Thu, 3 Sep 2009 14:33:11 +0000 (14:33 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 3 Sep 2009 14:33:11 +0000 (14:33 +0000)
Zend/zend_alloc.c
Zend/zend_alloc.h
Zend/zend_compile.c
Zend/zend_execute.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_execute.skl

index f7b6ffd8fbe54c248353fdab6f686c722ca72189..057fdf1a4139050d6594eeef4494a7bb3215c426 100644 (file)
@@ -532,20 +532,7 @@ static unsigned int _zend_mm_cookie = 0;
 /* optimized access */
 #define ZEND_MM_FREE_BLOCK_SIZE(b)             (b)->info._size
 
-#ifndef ZEND_MM_ALIGNMENT
-# define ZEND_MM_ALIGNMENT 8
-# define ZEND_MM_ALIGNMENT_LOG2 3
-#elif ZEND_MM_ALIGNMENT < 4
-# undef ZEND_MM_ALIGNMENT
-# undef ZEND_MM_ALIGNMENT_LOG2
-# define ZEND_MM_ALIGNMENT 4
-# define ZEND_MM_ALIGNMENT_LOG2 2
-#endif
-
-#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)
-
 /* Aligned header size */
-#define ZEND_MM_ALIGNED_SIZE(size)                     ((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
 #define ZEND_MM_ALIGNED_HEADER_SIZE                    ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block))
 #define ZEND_MM_ALIGNED_FREE_HEADER_SIZE       ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block))
 #define ZEND_MM_MIN_ALLOC_BLOCK_SIZE           ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE)
index dc258ad9343f94439646ff2dd78e5aeb98bf845f..4689ca1c779bb2c7c86bbc7538108f5313e1e622 100644 (file)
 #include <unicode/utypes.h>
 #include "zend.h"
 
+#ifndef ZEND_MM_ALIGNMENT
+# define ZEND_MM_ALIGNMENT 8
+# define ZEND_MM_ALIGNMENT_LOG2 3
+#elif ZEND_MM_ALIGNMENT < 4
+# undef ZEND_MM_ALIGNMENT
+# undef ZEND_MM_ALIGNMENT_LOG2
+# define ZEND_MM_ALIGNMENT 4
+# define ZEND_MM_ALIGNMENT_LOG2 2
+#endif
+
+#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)
+
+#define ZEND_MM_ALIGNED_SIZE(size)     (((size) + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
+
 typedef struct _zend_leak_info {
        void *addr;
        size_t size;
index a081979b2513eca2e66d5445c760fd8e05ea1eed..b18b9e8a8c2c08784753e6c8fb8e3883b0716732 100644 (file)
@@ -279,7 +279,7 @@ ZEND_API char *zend_get_compiled_script_encoding(TSRMLS_D) /* {{{ */
 
 static zend_uint get_temporary_variable(zend_op_array *op_array) /* {{{ */
 {
-       return (op_array->T)++ * sizeof(temp_variable);
+       return (op_array->T)++ * ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable));
 }
 /* }}} */
 
index 09f0590c79dc02617de93c6da9e6e60c09c712d5..5465890c09dfd2c3b1a71ee19b354744d76bbdc7 100644 (file)
@@ -162,9 +162,11 @@ struct _zend_vm_stack {
        void **top;
        void **end;
        zend_vm_stack prev;
-       void *elements[1];
 };
 
+#define ZEND_VM_STACK_ELEMETS(stack) \
+       ((void**)(((char*)(stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack))))
+
 #define ZEND_VM_STACK_GROW_IF_NEEDED(count)                                                    \
        do {                                                                                                                    \
                if (UNEXPECTED((count) >                                                                        \
@@ -174,10 +176,10 @@ struct _zend_vm_stack {
        } while (0)
 
 static inline zend_vm_stack zend_vm_stack_new_page(int count) {
-       zend_vm_stack page = (zend_vm_stack)emalloc(sizeof(*page)+sizeof(page->elements[0])*(count-1));
+       zend_vm_stack page = (zend_vm_stack)emalloc(ZEND_MM_ALIGNED_SIZE(sizeof(*page)) + sizeof(void*) * count);
 
-       page->top = page->elements;
-       page->end = page->elements + count;
+       page->top = ZEND_VM_STACK_ELEMETS(page);
+       page->end = page->top + count;
        page->prev = NULL;
        return page;
 }
@@ -225,7 +227,7 @@ static inline void *zend_vm_stack_pop(TSRMLS_D)
 {
        void *el = *(--EG(argument_stack)->top);
 
-       if (UNEXPECTED(EG(argument_stack)->top == EG(argument_stack)->elements)) {
+       if (UNEXPECTED(EG(argument_stack)->top == ZEND_VM_STACK_ELEMETS(EG(argument_stack)))) {
                zend_vm_stack p = EG(argument_stack);
                EG(argument_stack) = p->prev;
                efree(p);
@@ -239,15 +241,32 @@ static inline void *zend_vm_stack_alloc(size_t size TSRMLS_DC)
 
        size = (size + (sizeof(void*) - 1)) / sizeof(void*);
 
-       ZEND_VM_STACK_GROW_IF_NEEDED((int)size);
+       /* the following comparison must be optimized out at compile time */
+       if (ZEND_MM_ALIGNMENT > sizeof(void*)) {
+               int extra = (ZEND_MM_ALIGNMENT - ((zend_uintptr_t)EG(argument_stack)->top & (ZEND_MM_ALIGNMENT - 1))) / sizeof(void*);
+
+               if (UNEXPECTED(size + extra + ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*) >
+                   EG(argument_stack)->end - EG(argument_stack)->top)) {
+                       zend_vm_stack_extend(size TSRMLS_CC);
+               } else {
+                       void **old_top = EG(argument_stack)->top;
+
+                       EG(argument_stack)->top += extra;
+                       /* store old top on the stack */
+                       *EG(argument_stack)->top = (void*)old_top;
+                       EG(argument_stack)->top += ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*);
+               }
+       } else {
+               ZEND_VM_STACK_GROW_IF_NEEDED((int)size);
+       }
        ret = (void*)EG(argument_stack)->top;
        EG(argument_stack)->top += size;
        return ret;
 }
 
-static inline void zend_vm_stack_free(void *ptr TSRMLS_DC)
+static inline void zend_vm_stack_free_int(void *ptr TSRMLS_DC)
 {      
-       if (UNEXPECTED(EG(argument_stack)->elements == (void**)ptr)) {
+       if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) {
                zend_vm_stack p = EG(argument_stack);
 
                EG(argument_stack) = p->prev;
@@ -257,10 +276,28 @@ static inline void zend_vm_stack_free(void *ptr TSRMLS_DC)
        }
 }
 
+static inline void zend_vm_stack_free(void *ptr TSRMLS_DC)
+{      
+       if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) {
+               zend_vm_stack p = EG(argument_stack);
+
+               EG(argument_stack) = p->prev;
+               efree(p);
+       } else {
+               /* the following comparison must be optimized out at compile time */
+               if (ZEND_MM_ALIGNMENT > sizeof(void*)) {
+                       ptr = (void*)(((char*)ptr) - ZEND_MM_ALIGNED_SIZE(sizeof(void*)));
+                       EG(argument_stack)->top = *(void***)ptr;
+               } else {
+                       EG(argument_stack)->top = (void**)ptr;
+               }
+       }
+}
+
 static inline void** zend_vm_stack_push_args(int count TSRMLS_DC)
 {
 
-       if (UNEXPECTED(EG(argument_stack)->top - EG(argument_stack)->elements < count)  || 
+       if (UNEXPECTED(EG(argument_stack)->top - ZEND_VM_STACK_ELEMETS(EG(argument_stack)) < count)  || 
                UNEXPECTED(EG(argument_stack)->top == EG(argument_stack)->end)) {
                zend_vm_stack p = EG(argument_stack);
 
@@ -271,14 +308,14 @@ static inline void** zend_vm_stack_push_args(int count TSRMLS_DC)
                while (count-- > 0) {
                        void *data = *(--p->top);
 
-                       if (UNEXPECTED(p->top == p->elements)) {
+                       if (UNEXPECTED(p->top == ZEND_VM_STACK_ELEMETS(p))) {
                                zend_vm_stack r = p;
 
                                EG(argument_stack)->prev = p->prev;
                                p = p->prev;
                                efree(r);
                        }
-                       *(EG(argument_stack)->elements + count) = data;
+                       *(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + count) = data;
                }
                return EG(argument_stack)->top++;
        }
@@ -296,7 +333,7 @@ static inline void zend_vm_stack_clear_multiple(TSRMLS_D)
                *p = NULL;
                zval_ptr_dtor(&q);
        }
-       zend_vm_stack_free(p TSRMLS_CC);
+       zend_vm_stack_free_int(p TSRMLS_CC);
 }
 
 static inline zval** zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
index da5ae97935ee32acf94d7089fecf0fc203c6d64a..72167214ed54cfe224cd1104e85b868e7971b1c1 100644 (file)
@@ -4469,8 +4469,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
        int catched = 0;
        zval restored_error_reporting;
  
-       void **stack_frame = (void**)EX(Ts) +
-               (sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*);
+       void **stack_frame = (void**)(((char*)EX(Ts)) +
+               (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));
 
        while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
                zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
index ee032d1ec68e18c79ce6b3a96b31a5a7abbfd6f3..4b86568c4f7423c2ad064a3e1b60392c21df5d38 100644 (file)
@@ -52,13 +52,13 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
 zend_vm_enter:
        /* Initialize execute_data */
        execute_data = (zend_execute_data *)zend_vm_stack_alloc(
-               sizeof(zend_execute_data) +
-               sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2) +
-               sizeof(temp_variable) * op_array->T TSRMLS_CC);
+               ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) +
+               ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) +
+               ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC);
 
-       EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data));
+       EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
        memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
-       EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var * (EG(active_symbol_table) ? 1 : 2));
+       EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)));
        EX(fbc) = NULL;
        EX(called_scope) = NULL;
        EX(object) = NULL;
@@ -606,8 +606,8 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
        int catched = 0;
        zval restored_error_reporting;
 
-       void **stack_frame = (void**)EX(Ts) +
-               (sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*);
+       void **stack_frame = (void**)(((char*)EX(Ts)) +
+               (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));
 
        while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
                zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
index fbb5b074e2e22cb503f637cb8698ed04c1a7e2e3..2df20720d05736efccf790718fa31e796ae2ba5a 100644 (file)
@@ -18,13 +18,13 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
 zend_vm_enter:
        /* Initialize execute_data */
        execute_data = (zend_execute_data *)zend_vm_stack_alloc(
-               sizeof(zend_execute_data) +
-               sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2) +
-               sizeof(temp_variable) * op_array->T TSRMLS_CC);
+               ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) +
+               ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) +
+               ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC);
 
-       EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data));
+       EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
        memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
-       EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var * (EG(active_symbol_table) ? 1 : 2));
+       EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)));
        EX(fbc) = NULL;
        EX(called_scope) = NULL;
        EX(object) = NULL;