Skip to content
Merged
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
19 changes: 1 addition & 18 deletions lib/JIT/Builtin/GcCollectCyclesRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -929,24 +929,7 @@ private static function ensureExternals(Context $context): void

private static function ensureExternal(Context $context, string $name, $ft): void
{
try {
$context->lookupFunction($name);

return;
} catch (\Throwable $e) {
}
// The symbol may already exist in the MODULE while being absent from the context registry —
// LibcExtern adds `memset` and gives it a body via implementMemsetBody() without every
// caller having registered it. addFunction() on an existing name does not fail; LLVM
// silently renames the second one to `memset.1`, which carries no body, so the link ends
// with `undefined reference to memset.1` from phpc_gc_collect_cycles_impl and EVERY AOT
// binary fails to link (aot-smoke 0/8). Reuse the existing declaration instead, matching
// the getNamedFunction()-first pattern LibcExtern already uses.
$fn = $context->module->getNamedFunction($name);
if (null === $fn) {
$fn = $context->module->addFunction($name, $ft);
}
$context->registerFunction($name, $fn);
\PHPCompiler\JIT\LibcExtern::ensureExternalDecl($context, $name, $ft);
}

private static function registerLinkedRuntime(Context $context): void
Expand Down
10 changes: 3 additions & 7 deletions lib/JIT/Builtin/ObStorageLlvm.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PHPCompiler\ext\standard\ob_end_clean;
use PHPCompiler\ext\standard\ob_end_flush;
use PHPCompiler\JIT\Context;
use PHPCompiler\JIT\LibcExtern;
use PHPCompiler\VM\ObStackLimits;
use PHPLLVM\Builder;
use PHPLLVM\Value;
Expand Down Expand Up @@ -1130,7 +1131,7 @@ private static function ensureLibc(Context $context): void
self::ensureExternal($context, 'strlen', $context->context->functionType($sizeT, false, $i8p));
self::ensureExternal($context, 'write', $context->context->functionType($i64, false, $i32, $i8p, $i64));
self::ensureExternal($context, 'fflush', $context->context->functionType($i32, false, $i8p));
self::ensureExternal($context, 'memcpy', $context->context->functionType($i8p, false, $i8p, $i8p, $sizeT));
LibcExtern::ensureMemcpyDecl($context);
self::ensureExternal($context, 'malloc', $context->context->functionType($i8p, false, $sizeT));
self::ensureExternal(
$context,
Expand Down Expand Up @@ -1185,12 +1186,7 @@ private static function fn(Context $context, string $name, $ret, bool $vararg, .

private static function ensureExternal(Context $context, string $name, $ft): void
{
try {
$context->lookupFunction($name);
} catch (\Throwable) {
$fn = $context->module->addFunction($name, $ft);
$context->registerFunction($name, $fn);
}
LibcExtern::ensureExternalDecl($context, $name, $ft);
}

private static function registerLinkedRuntime(Context $context, bool $requireAll = true): void
Expand Down
11 changes: 3 additions & 8 deletions lib/JIT/Builtin/OutputRewriteVarsStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ public static function ensureLibc(Context $context): void
{
$i8p = $context->getTypeFromString('int8*');
$sizeT = $context->getTypeFromString('size_t');
self::ensureExternal($context, 'memcpy', $context->context->functionType($i8p, false, $i8p, $i8p, $sizeT));
self::ensureExternal($context, 'malloc', $context->context->functionType($i8p, false, $sizeT));
\PHPCompiler\JIT\LibcExtern::ensureMemcpyDecl($context);
\PHPCompiler\JIT\LibcExtern::ensureExternalDecl($context, 'malloc', $context->context->functionType($i8p, false, $sizeT));
}

/** Append name\\x1Evalue (with \\x1D separator when blob non-empty). */
Expand Down Expand Up @@ -391,11 +391,6 @@ private static function lenPtr(Context $context, string $name): Value

private static function ensureExternal(Context $context, string $name, $ft): void
{
try {
$context->lookupFunction($name);
} catch (\Throwable) {
$fn = $context->module->addFunction($name, $ft);
$context->registerFunction($name, $fn);
}
\PHPCompiler\JIT\LibcExtern::ensureExternalDecl($context, $name, $ft);
}
}
13 changes: 1 addition & 12 deletions lib/JIT/Builtin/StringSscanfByRef.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,19 +155,8 @@ private static function ensureJitHelperCompiled(Context $context): void

private static function ensureRuntimeHelpers(Context $context): void
{
// Match LibcExtern i8* memcpy — void* decls make NestedJIT emit mistyped calls (#27663).
\PHPCompiler\JIT\LibcExtern::register($context);
try {
$context->lookupFunction('memcpy');
} catch (\Throwable) {
$i8p = $context->getTypeFromString('int8*');
$sizeT = $context->getTypeFromString('size_t');
$fn = $context->module->addFunction(
'memcpy',
$context->context->functionType($i8p, false, $i8p, $i8p, $sizeT)
);
$context->registerFunction('memcpy', $fn);
}
\PHPCompiler\JIT\LibcExtern::ensureMemcpyDecl($context);
}

private static function registerLinkedRuntime(Context $context): void
Expand Down
7 changes: 1 addition & 6 deletions lib/JIT/Builtin/StringZlibJit.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,7 @@ private static function ensureRuntimeHelpers(Context $context): void

private static function ensureExternal(Context $context, string $name, $ft): void
{
try {
$context->lookupFunction($name);
} catch (\Throwable) {
$fn = $context->module->addFunction($name, $ft);
$context->registerFunction($name, $fn);
}
\PHPCompiler\JIT\LibcExtern::ensureExternalDecl($context, $name, $ft);
}

private static function emitDeflateBytes(Context $context): void
Expand Down
9 changes: 2 additions & 7 deletions lib/JIT/Builtin/UrlRewriterApplyRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,9 @@ private static function ensureStringInit(Context $context): void
foreach ([
'__string__init' => $context->context->functionType($strPtr, false, $i64, $i8p),
'malloc' => $context->context->functionType($i8p, false, $sizeT),
'memcpy' => $context->context->functionType($i8p, false, $i8p, $i8p, $sizeT),
] as $name => $ft) {
try {
$context->lookupFunction($name);
} catch (\Throwable) {
$fn = $context->module->addFunction($name, $ft);
$context->registerFunction($name, $fn);
}
\PHPCompiler\JIT\LibcExtern::ensureExternalDecl($context, $name, $ft);
}
\PHPCompiler\JIT\LibcExtern::ensureMemcpyDecl($context);
}
}
22 changes: 17 additions & 5 deletions lib/JIT/LibcExtern.php
Original file line number Diff line number Diff line change
Expand Up @@ -654,18 +654,30 @@ private static function implementStrcmpBody(Context $context): void
$context->registerFunction('strcmp', $fn);
}

private static function ensure(Context $context, string $name, $fnType): void
/**
* Declare an external libc/helper symbol without versioning duplicates (#31894).
*
* lookupFunction() may throw while the symbol already exists in the MODULE (LibcExtern
* implement*Body adds bodies without always registering). addFunction() on an existing name
* silently versions to name.N with no body → link failure for every AOT binary.
*/
public static function ensureExternalDecl(Context $context, string $name, $fnType): void
{
if (null !== $context->module->getNamedFunction($name)) {
return;
}
try {
$context->lookupFunction($name);

return;
} catch (\Throwable) {
}
$fn = $context->module->addFunction($name, $fnType);
$fn = $context->module->getNamedFunction($name);
if (null === $fn) {
$fn = $context->module->addFunction($name, $fnType);
}
$context->registerFunction($name, $fn);
}

private static function ensure(Context $context, string $name, $fnType): void
{
self::ensureExternalDecl($context, $name, $fnType);
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading