mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
We use linker relocations to fetch the TLS index and offset of _tsrm_ls_cache.
When building Opcache statically, linkers may attempt to optimize that into a
more efficient code sequence (relaxing from "General Dynamic" to "Local Exec"
model [1]). Unfortunately, linkers will fail, rather than ignore our
relocations, when they don't recognize the exact code sequence they are
expecting.
This results in errors as reported by GH-15074:
TLS transition from R_X86_64_TLSGD to R_X86_64_GOTTPOFF against
`_tsrm_ls_cache' at 0x12fc3 in section `.text' failed"
Here I take a different approach:
* Emit the exact full code sequence expected by linkers
* Extract the TLS index/offset by inspecting the linked ASM code, rather than
executing it (execution would give us the thread-local address).
* We detect when the code was relaxed, in which case we can extract the TCB
offset instead.
* This is done in a conservative way so that if the linker did something we
didn't expect, we fallback to a safer (but slower) mechanism.
One additional benefit of that is we are now able to use the Local Exec model in
more cases, in JIT'ed code. This makes non-glibc builds faster in these cases.
Closes GH-18939.
Related RFC: https://wiki.php.net/rfc/make_opcache_required.
[1] https://www.akkadia.org/drepper/tls.pdf
35 lines
800 B
PHP
35 lines
800 B
PHP
--TEST--
|
|
Test basic logging for the Opcache
|
|
--DESCRIPTION--
|
|
This test runs a simple PHP script and ensures the Opcache
|
|
outputs the correct logging at the highest log_verbosity_level
|
|
--INI--
|
|
opcache.enable=1
|
|
opcache.enable_cli=1
|
|
opcache.file_cache=
|
|
opcache.file_cache_only=0
|
|
opcache.error_log=
|
|
opcache.log_verbosity_level=4
|
|
opcache.huge_code_pages=0
|
|
opcache.preload=
|
|
opcache.interned_strings_buffer=8
|
|
--EXTENSIONS--
|
|
opcache
|
|
--SKIPIF--
|
|
<?php
|
|
// Prints "Debug Restarting!" message on next request.
|
|
if (getenv('SKIP_REPEAT')) die("skip Not repeatable");
|
|
if (PHP_ZTS) die("skip ZTS prints extra messages");
|
|
?>
|
|
--FILE--
|
|
<?php
|
|
echo "Foo Bar\n";
|
|
opcache_reset();
|
|
echo "Opcache reset";
|
|
?>
|
|
--EXPECTF--
|
|
%s Message Cached script '%sbasic_logging%s'
|
|
Foo Bar
|
|
%s Debug Restart Scheduled! Reason: user
|
|
Opcache reset
|