Skip to content

Incompatibility in Inline TLS Assembly on Alpine 3.22 with zend_jit_ir.c #18743

Closed
@thecaliskan

Description

@thecaliskan

Description

When building PHP on Alpine Linux 3.22 with musl and targeting 32-bit or 64-bit x86 platforms, a regression is observed related to inline assembly in ext/opcache/jit/zend_jit_ir.c, specifically:

This error does not occur on Alpine 3.21 using the same compilation toolchain. The issue stems from the @TLSGD usage which implicitly expects %rdi on x86_64 or %eax on i386, depending on the TLS model.

ext/opcache/jit/zend_jit_ir.c:3459: Error: @TLSGD operator requires %rdi' as dest register`

Environment

  • Alpine Linux 3.22
  • GCC (via build-base)
  • musl libc
  • Target: x86_64 or i386
  • Affected file: ext/opcache/jit/zend_jit_ir.c

Related PR / Reference

PHP Version

8.4.7-zts
8.3.21-zts
8.2.28-zts
8.1.32-zts

Operating System

Alpine 3.22

Activity

arnaud-lb

arnaud-lb commented on Jun 3, 2025

@arnaud-lb
Member

Thank you for reporting this. This is the same root cause as #15074 (see #15074 (comment)), and will be fixed by #18660 (specifically ba04798).

nielsdos

nielsdos commented on Jun 3, 2025

@nielsdos
Member

@arnaud-lb But this can be fixed on lower branches, and I think we should.
For this particular issue the following suffices (on PHP-8.3) (but would need to generalise to other platforms too ofc as we would need to change other code paths with the same assembly too):

diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 1f1abb59a1c..6ea8521ba6d 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -2910,7 +2910,7 @@ static int zend_jit_setup(void)
 
 		__asm__(
 			"leaq _tsrm_ls_cache@tlsgd(%%rip), %0\n"
-			: "=a" (ti));
+			: "=D" (ti));
 		tsrm_tls_offset = ti[1];
 		tsrm_tls_index = ti[0] * 8;
 #elif defined(__FreeBSD__)
arnaud-lb

arnaud-lb commented on Jun 5, 2025

@arnaud-lb
Member

@nielsdos I agree, and it's great that there is a simpler fix, as ba04798 felt a bit risky for release branches.

The change you propose looks good to me. We don't need to use the entire code sequence as in ba04798, because gas is only checking a single instruction, and ld will only check the entire sequence when building opcache statically, which is not allowed in release branches.

Glibc seems unaffected as we use @gottpoff, for which gas doesn't check the destination register: https://github.com/bminor/binutils-gdb/blob/ec181e1710e37007a8d95c284609bfaa5868d086/gas/config/tc-i386.c#L6869

Do you want to take care of this or shall I?

nielsdos

nielsdos commented on Jun 5, 2025

@nielsdos
Member

Thanks for the link, I'm on it.

added a commit that references this issue on Jun 5, 2025

Fix phpGH-18743: Incompatibility in Inline TLS Assembly on Alpine 3.22

cda883b
added 2 commits that reference this issue on Jun 9, 2025

Fix GH-18743: Incompatibility in Inline TLS Assembly on Alpine 3.22

b3c8afe
7a0beb4

3 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Incompatibility in Inline TLS Assembly on Alpine 3.22 with `zend_jit_ir.c` · Issue #18743 · php/php-src