Skip to content

Enable 64bit integer support on 32bit arch --enable-zend-int64 #19079

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/actions/configure-x32/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ runs:

export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/i386-linux-gnu/pkgconfig"
./buildconf --force
export CFLAGS="-m32 -msse2"
export CXXFLAGS="-m32 -msse2"
export CFLAGS="-m32 -msse2 -mfpmath=sse -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES=1"
export CXXFLAGS="-m32 -msse2 -mfpmath=sse -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES=1"
export LDFLAGS=-L/usr/lib/i386-linux-gnu
./configure ${{ inputs.configurationParameters }} \
--enable-option-checking=fatal \
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,66 @@ jobs:
runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1
LINUX_X32_INT64:
if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
name: LINUX_X32_INT64_DEBUG_ZTS
runs-on: ubuntu-latest
timeout-minutes: 50
container:
image: ubuntu:24.04
env:
MYSQL_TEST_HOST: mysql
PDO_MYSQL_TEST_DSN: mysql:host=mysql;dbname=test
PDO_MYSQL_TEST_HOST: mysql
PDO_FIREBIRD_TEST_DSN: firebird:dbname=firebird:test.fdb
services:
mysql:
image: mysql:8.3
ports:
- 3306:3306
env:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: root
firebird:
image: jacobalberty/firebird
ports:
- 3050:3050
env:
ISC_PASSWORD: test
FIREBIRD_DATABASE: test.fdb
FIREBIRD_USER: test
FIREBIRD_PASSWORD: test
steps:
- name: git checkout
uses: actions/checkout@v4
- name: apt
uses: ./.github/actions/apt-x32
- name: ccache
uses: hendrikmuhs/[email protected]
with:
key: "${{github.job}}-${{hashFiles('main/php_version.h')}}"
append-timestamp: false
- name: ./configure
uses: ./.github/actions/configure-x32
with:
configurationParameters: >-
--enable-debug
--enable-zts
--enable-zend-int64
- name: make
run: make -j$(/usr/bin/nproc) >/dev/null
- name: make install
uses: ./.github/actions/install-linux-x32
- name: Test
if: matrix.asan == false
uses: ./.github/actions/test-linux
- name: Test Tracing JIT
uses: ./.github/actions/test-linux
with:
jitType: tracing
runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1
MACOS_DEBUG_NTS:
if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
strategy:
Expand Down
38 changes: 38 additions & 0 deletions Zend/Zend.m4
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ AX_CHECK_COMPILE_FLAG([-fno-common],
[-Werror])

ZEND_CHECK_ALIGNMENT
ZEND_CHECK_INT64
ZEND_CHECK_SIGNALS
ZEND_CHECK_MAX_EXECUTION_TIMERS
])
Expand Down Expand Up @@ -419,6 +420,43 @@ AS_VAR_IF([php_cv_align_mm], [failed],
])
])

dnl
dnl ZEND_CHECK_INT64
dnl
dnl Check whether to enable 64 bit integer if supported by the system.
dnl
AC_DEFUN([ZEND_CHECK_INT64], [dnl
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[]],
[[
#if !(defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64))
#error "Not a 64-bit platform"
#endif
]]
)],
[ZEND_INT64=yes],
[ZEND_INT64=no])

AC_ARG_ENABLE([zend-int64],
[AS_HELP_STRING([--enable-zend-int64], [Enable 64bit integer support (enabled by default on 64bit arch)])],
[ZEND_INT64=$enableval],
[ZEND_INT64=$ZEND_INT64])

AS_VAR_IF([ZEND_INT64], [yes],
AC_CHECK_TYPE([int64_t],,
[AC_MSG_ERROR([int64_t not found])],
[#include <stdint.h>]))

AS_VAR_IF([ZEND_INT64], [yes],
[AC_DEFINE([ZEND_INT64], [1],
[Define to 1 if zend_long as int64 is supported and enabled.])
AS_VAR_APPEND([CFLAGS], [" -DZEND_INT64"])])

AC_MSG_CHECKING([whether to enable 64 bit integer support])
AC_MSG_RESULT([$ZEND_INT64])
])

dnl
dnl ZEND_CHECK_SIGNALS
dnl
Expand Down
12 changes: 6 additions & 6 deletions Zend/zend_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static size_t _real_page_size = ZEND_MM_PAGE_SIZE;
#endif

typedef uint32_t zend_mm_page_info; /* 4-byte integer */
typedef zend_ulong zend_mm_bitset; /* 4-byte or 8-byte integer */
typedef size_t zend_mm_bitset; /* 4-byte or 8-byte integer */

#define ZEND_MM_ALIGNED_OFFSET(size, alignment) \
(((size_t)(size)) & ((alignment) - 1))
Expand Down Expand Up @@ -587,7 +587,7 @@ static void *zend_mm_mmap(size_t size)
/* number of trailing set (1) bits */
ZEND_ATTRIBUTE_CONST static zend_always_inline int zend_mm_bitset_nts(zend_mm_bitset bitset)
{
#if (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) && SIZEOF_ZEND_LONG == SIZEOF_LONG && defined(PHP_HAVE_BUILTIN_CTZL)
#if (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) && SIZEOF_SIZE_T == SIZEOF_LONG && defined(PHP_HAVE_BUILTIN_CTZL)
return __builtin_ctzl(~bitset);
#elif (defined(__GNUC__) || __has_builtin(__builtin_ctzll)) && defined(PHP_HAVE_BUILTIN_CTZLL)
return __builtin_ctzll(~bitset);
Expand All @@ -610,7 +610,7 @@ ZEND_ATTRIBUTE_CONST static zend_always_inline int zend_mm_bitset_nts(zend_mm_bi
if (bitset == (zend_mm_bitset)-1) return ZEND_MM_BITSET_LEN;

n = 0;
#if SIZEOF_ZEND_LONG == 8
#if SIZEOF_SIZE_T == 8
if (sizeof(zend_mm_bitset) == 8) {
if ((bitset & 0xffffffff) == 0xffffffff) {n += 32; bitset = bitset >> Z_UL(32);}
}
Expand Down Expand Up @@ -2065,7 +2065,7 @@ static zend_mm_heap *zend_mm_init(void)
#endif
zend_mm_init_key(heap);
#if ZEND_MM_LIMIT
heap->limit = (size_t)Z_L(-1) >> 1;
heap->limit = (size_t)-1 >> 1;
heap->overflow = 0;
#endif
#if ZEND_MM_CUSTOM
Expand Down Expand Up @@ -3262,7 +3262,7 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
zend_mm_heap *mm_heap = alloc_globals->mm_heap = malloc(sizeof(zend_mm_heap));
memset(mm_heap, 0, sizeof(zend_mm_heap));
mm_heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD;
mm_heap->limit = (size_t)Z_L(-1) >> 1;
mm_heap->limit = (size_t)-1 >> 1;
mm_heap->overflow = 0;

if (!tracked) {
Expand Down Expand Up @@ -3483,7 +3483,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
#endif
zend_mm_init_key(heap);
#if ZEND_MM_LIMIT
heap->limit = (size_t)Z_L(-1) >> 1;
heap->limit = (size_t)-1 >> 1;
heap->overflow = 0;
#endif
#if ZEND_MM_CUSTOM
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -12134,7 +12134,7 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
} else if (Z_TYPE_P(dim) != IS_STRING || is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, 1) != IS_LONG) {
return;
}
if (offset < 0 || (size_t)offset >= Z_STRLEN_P(container)) {
if (offset < 0 || ZEND_SIZE_T_LTE_ZEND_LONG(Z_STRLEN_P(container), offset)) {
return;
}
c = (uint8_t) Z_STRVAL_P(container)[offset];
Expand Down
12 changes: 6 additions & 6 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -2132,11 +2132,11 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
}
}

if ((size_t)offset >= ZSTR_LEN(s)) {
if (ZEND_SIZE_T_LTE_ZEND_LONG(ZSTR_LEN(s), offset)) {
/* Extend string if needed */
zend_long old_len = ZSTR_LEN(s);
size_t old_len = ZSTR_LEN(s);
ZVAL_NEW_STR(str, zend_string_extend(s, (size_t)offset + 1, 0));
memset(Z_STRVAL_P(str) + old_len, ' ', offset - old_len);
memset(Z_STRVAL_P(str) + old_len, ' ', (size_t)offset - old_len);
Z_STRVAL_P(str)[offset+1] = 0;
} else {
zend_string_forget_hash_val(Z_STR_P(str));
Expand Down Expand Up @@ -3094,7 +3094,7 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
}
out:

if (UNEXPECTED(ZSTR_LEN(str) < ((offset < 0) ? -(size_t)offset : ((size_t)offset + 1)))) {
if (UNEXPECTED(ZEND_SIZE_T_LT_ZEND_ULONG(ZSTR_LEN(str), ((offset < 0) ? -(zend_ulong)offset : ((zend_ulong)offset + 1))))) {
if (type != BP_VAR_IS) {
zend_error(E_WARNING, "Uninitialized string offset " ZEND_LONG_FMT, offset);
ZVAL_EMPTY_STRING(result);
Expand Down Expand Up @@ -3227,7 +3227,7 @@ static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(zval *container,
if (UNEXPECTED(lval < 0)) { /* Handle negative offset */
lval += (zend_long)Z_STRLEN_P(container);
}
if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
if (EXPECTED(lval >= 0) && ZEND_SIZE_T_GT_ZEND_LONG(Z_STRLEN_P(container), lval)) {
return 1;
} else {
return 0;
Expand Down Expand Up @@ -3266,7 +3266,7 @@ static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(zval *containe
if (UNEXPECTED(lval < 0)) { /* Handle negative offset */
lval += (zend_long)Z_STRLEN_P(container);
}
if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
if (EXPECTED(lval >= 0) && ZEND_SIZE_T_GT_ZEND_LONG(Z_STRLEN_P(container), lval)) {
return (Z_STRVAL_P(container)[lval] == '0');
} else {
return 1;
Expand Down
6 changes: 3 additions & 3 deletions Zend/zend_generators.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ static void zend_generator_remove_child(zend_generator_node *node, zend_generato
node->child.single = NULL;
} else {
HashTable *ht = node->child.ht;
zend_hash_index_del(ht, (zend_ulong) child);
zend_hash_index_del(ht, (zend_ulong)(uintptr_t)child);
if (node->children == 2) {
zend_generator *other_child;
ZEND_HASH_FOREACH_PTR(ht, other_child) {
Expand Down Expand Up @@ -533,11 +533,11 @@ static void zend_generator_add_child(zend_generator *generator, zend_generator *
HashTable *ht = emalloc(sizeof(HashTable));
zend_hash_init(ht, 0, NULL, NULL, 0);
zend_hash_index_add_new_ptr(ht,
(zend_ulong) node->child.single, node->child.single);
(zend_ulong)(uintptr_t)node->child.single, node->child.single);
node->child.ht = ht;
}

zend_hash_index_add_new_ptr(node->child.ht, (zend_ulong) child, child);
zend_hash_index_add_new_ptr(node->child.ht, (zend_ulong)(uintptr_t)child, child);
}

++node->children;
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_long.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include <stdint.h>

/* This is the heart of the whole int64 enablement in zval. */
#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)
#ifdef ZEND_INT64
# define ZEND_ENABLE_ZVAL_LONG64 1
#endif

Expand Down Expand Up @@ -97,7 +97,7 @@ typedef int32_t zend_off_t;
do { \
int st = snprintf((s), (len), ZEND_LONG_FMT, (i)); \
(s)[st] = '\0'; \
} while (0)
} while (0)
# define ZEND_ATOL(s) atol((s))
# endif
# define ZEND_STRTOL_PTR strtol
Expand Down
8 changes: 4 additions & 4 deletions Zend/zend_operators.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,11 +519,11 @@ ZEND_API void zend_reset_lc_ctype_locale(void);
#define ZVAL_OFFSETOF_TYPE \
(offsetof(zval, u1.type_info) - offsetof(zval, value))

#if defined(HAVE_ASM_GOTO) && !__has_feature(memory_sanitizer)
# define ZEND_USE_ASM_ARITHMETIC 1
#else
//#if defined(HAVE_ASM_GOTO) && !__has_feature(memory_sanitizer)
//# define ZEND_USE_ASM_ARITHMETIC 1
//#else
# define ZEND_USE_ASM_ARITHMETIC 0
#endif
//#endif

static zend_always_inline void fast_long_increment_function(zval *op1)
{
Expand Down
23 changes: 19 additions & 4 deletions Zend/zend_range_check.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,24 @@
#endif

/* Comparison zend_long vs size_t */
#define ZEND_SIZE_T_GT_ZEND_LONG(size, zlong) ((zlong) < 0 || (size) > (size_t)(zlong))
#define ZEND_SIZE_T_GTE_ZEND_LONG(size, zlong) ((zlong) < 0 || (size) >= (size_t)(zlong))
#define ZEND_SIZE_T_LT_ZEND_LONG(size, zlong) ((zlong) >= 0 && (size) < (size_t)(zlong))
#define ZEND_SIZE_T_LTE_ZEND_LONG(size, zlong) ((zlong) >= 0 && (size) <= (size_t)(zlong))
#if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
# define ZEND_SIZE_T_GT_ZEND_LONG(size, zlong) ((zlong) < 0 || ((zlong) < SIZE_MAX && (size) > (size_t)(zlong)))
# define ZEND_SIZE_T_GT_ZEND_ULONG(size, zulong) (zulong < SIZE_MAX && (size) > (size_t)(zulong))
# define ZEND_SIZE_T_GTE_ZEND_LONG(size, zlong) ((zlong) < 0 || ((zlong) <= SIZE_MAX && (size) >= (size_t)(zlong)))
# define ZEND_SIZE_T_GTE_ZEND_ULONG(size, zulong) ((zulong) <= SIZE_MAX && (size) >= (size_t)(zulong))
# define ZEND_SIZE_T_LT_ZEND_LONG(size, zlong) ((zlong) >= SIZE_MAX || ((zlong) > 0 && (size) < (size_t)(zlong)))
# define ZEND_SIZE_T_LT_ZEND_ULONG(size, zulong) ((zulong) >= SIZE_MAX || (size) < (size_t)(zulong))
# define ZEND_SIZE_T_LTE_ZEND_LONG(size, zlong) ((zlong) > SIZE_MAX || ((zlong) >= 0 && (size) <= (size_t)(zlong)))
# define ZEND_SIZE_T_LTE_ZEND_ULONG(size, zulong) ((zulong) > SIZE_MAX || (size) <= (size_t)(zlong))
#else
# define ZEND_SIZE_T_GT_ZEND_LONG(size, zlong) ((zlong) < 0 || (size) > (size_t)(zlong))
# define ZEND_SIZE_T_GT_ZEND_ULONG(size, zulong) ((size) > (size_t)(zulong))
# define ZEND_SIZE_T_GTE_ZEND_LONG(size, zlong) ((zlong) < 0 || (size) >= (size_t)(zlong))
# define ZEND_SIZE_T_GTE_ZEND_ULONG(size, zulong) ((size) >= (size_t)(zulong))
# define ZEND_SIZE_T_LT_ZEND_LONG(size, zlong) ((zlong) > 0 && (size) < (size_t)(zlong))
# define ZEND_SIZE_T_LT_ZEND_ULONG(size, zulong) ((size) < (size_t)(zulong))
# define ZEND_SIZE_T_LTE_ZEND_LONG(size, zlong) ((zlong) >= 0 && (size) <= (size_t)(zlong))
# define ZEND_SIZE_T_LTE_ZEND_ULONG(size, zulong) ((size) <= (size_t)(zulong))
#endif

#endif /* ZEND_RANGE_CHECK_H */
5 changes: 2 additions & 3 deletions Zend/zend_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ ZEND_API bool ZEND_FASTCALL I_REPLACE_SONAME_FNNAME_ZU(NONE,zend_string_equal_va
}
#endif

#if defined(__GNUC__) && defined(__i386__)
#if SIZEOF_SIZE_T == SIZEOF_ZEND_LONG && defined(__GNUC__) && defined(__i386__)
ZEND_API zend_never_inline NOIPA bool ZEND_FASTCALL zend_string_equal_val(const zend_string *s1, const zend_string *s2)
{
const char *ptr = ZSTR_VAL(s1);
Expand Down Expand Up @@ -430,8 +430,7 @@ ZEND_API zend_never_inline NOIPA bool ZEND_FASTCALL zend_string_equal_val(const
: "cc");
return ret;
}

#elif defined(__GNUC__) && defined(__x86_64__) && !defined(__ILP32__)
#elif SIZEOF_SIZE_T == SIZEOF_ZEND_LONG && defined(__GNUC__) && defined(__x86_64__) && !defined(__ILP32__)
ZEND_API zend_never_inline NOIPA bool ZEND_FASTCALL zend_string_equal_val(const zend_string *s1, const zend_string *s2)
{
const char *ptr = ZSTR_VAL(s1);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ static zend_always_inline bool zend_string_equals_cstr(const zend_string *s1, co
return ZSTR_LEN(s1) == s2_length && !memcmp(ZSTR_VAL(s1), s2, s2_length);
}

#if defined(__GNUC__) && (defined(__i386__) || (defined(__x86_64__) && !defined(__ILP32__)))
#if SIZEOF_SIZE_T == SIZEOF_ZEND_LONG && defined(__GNUC__) && (defined(__i386__) || (defined(__x86_64__) && !defined(__ILP32__)))
BEGIN_EXTERN_C()
ZEND_API bool ZEND_FASTCALL zend_string_equal_val(const zend_string *s1, const zend_string *s2);
END_EXTERN_C()
Expand Down
26 changes: 13 additions & 13 deletions Zend/zend_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@ typedef enum {

typedef ZEND_RESULT_CODE zend_result;

#ifdef ZEND_ENABLE_ZVAL_LONG64
# ifdef ZEND_WIN32
# define ZEND_SIZE_MAX _UI64_MAX
# else
# define ZEND_SIZE_MAX SIZE_MAX
# endif
#else
# if defined(ZEND_WIN32)
# define ZEND_SIZE_MAX _UI32_MAX
# else
# define ZEND_SIZE_MAX SIZE_MAX
# endif
#endif
// #ifdef ZEND_ENABLE_ZVAL_LONG64
// # ifdef ZEND_WIN32
// # define ZEND_SIZE_MAX _UI64_MAX
// # else
// # define ZEND_SIZE_MAX SIZE_MAX
// # endif
// #else
// # if defined(ZEND_WIN32)
// # define ZEND_SIZE_MAX _UI32_MAX
// # else
// # define ZEND_SIZE_MAX SIZE_MAX
// # endif
// #endif

#ifdef ZTS
#define ZEND_TLS static TSRM_TLS
Expand Down
Loading
Loading