mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Fix linker failure when building Opcache statically
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
This commit is contained in:
parent
04feb452ba
commit
73b1ebfa20
17 changed files with 2402 additions and 171 deletions
|
@ -62,11 +62,90 @@ function main(int $argc, array $argv): void
|
|||
echo "DEBUG: " . ($environment->debug ? 'Yes' : 'No') . "\n";
|
||||
echo "=====================================================================\n";
|
||||
|
||||
echo "No tests in this branch yet.\n";
|
||||
try {
|
||||
output_group_start($environment, 'Running Opcache TLS tests');
|
||||
if (!run_opcache_tls_tests($environment)) {
|
||||
echo "Failed\n";
|
||||
exit(1);
|
||||
}
|
||||
} finally {
|
||||
output_group_end($environment);
|
||||
}
|
||||
|
||||
echo "All OK\n";
|
||||
}
|
||||
|
||||
function run_opcache_tls_tests(Environment $environment): bool
|
||||
{
|
||||
if (!$environment->zts) {
|
||||
echo "Skipping: NTS\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$environment->debug) {
|
||||
echo "Skipping: NDEBUG\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
$tlsc = '';
|
||||
$machine = '';
|
||||
$static_support = 'yes';
|
||||
|
||||
switch ($environment->cpuArch) {
|
||||
case 'x86':
|
||||
$machine = '-m32';
|
||||
break;
|
||||
case 'x86_64':
|
||||
case 'aarch64':
|
||||
break;
|
||||
default:
|
||||
echo "Skipping: {$environment->cpuArch}\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
switch ($environment->os) {
|
||||
case 'Linux':
|
||||
case 'FreeBSD':
|
||||
$tlsc = __DIR__ . "/ext/opcache/jit/tls/zend_jit_tls_{$environment->cpuArch}.c";
|
||||
break;
|
||||
case 'Darwin':
|
||||
if ($environment->cpuArch === 'aarch64') {
|
||||
echo "Skipping: JIT+TLS not supported on MacOS Apple Silicon\n";
|
||||
return true;
|
||||
}
|
||||
$tlsc = __DIR__ . "/ext/opcache/jit/tls/zend_jit_tls_darwin.c";
|
||||
$static_support = 'no';
|
||||
break;
|
||||
default:
|
||||
echo "Skipping: {$environment->os}\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
echo "TLSC=$tlsc MACHINE=$machine STATIC_SUPPORT=$static_support ext/opcache/jit/tls/testing/test.sh\n";
|
||||
|
||||
$proc = proc_open(
|
||||
__DIR__ . '/ext/opcache/jit/tls/testing/test.sh',
|
||||
[
|
||||
0 => ['pipe', 'r'],
|
||||
],
|
||||
$pipes,
|
||||
env_vars: array_merge(getenv(), [
|
||||
'TLSC' => $tlsc,
|
||||
'MACHINE' => $machine,
|
||||
'STATIC_SUPPORT' => $static_support,
|
||||
]),
|
||||
);
|
||||
|
||||
if (!$proc) {
|
||||
echo "proc_open() failed\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose($pipes[0]);
|
||||
|
||||
return proc_close($proc) === 0;
|
||||
}
|
||||
|
||||
function output_group_start(Environment $environment, string $name): void
|
||||
{
|
||||
if ($environment->githubAction) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue