Skip to content

feat(nts): resolver shim + EMBEDDING.md in NTS tarballs, shared-embed variant - #44

Merged
luthermonson merged 2 commits into
mainfrom
feat/nts-embed-integration
Aug 12, 2026
Merged

feat(nts): resolver shim + EMBEDDING.md in NTS tarballs, shared-embed variant#44
luthermonson merged 2 commits into
mainfrom
feat/nts-embed-integration

Conversation

@luthermonson

Copy link
Copy Markdown
Contributor

Two integration gaps reported by PAM building against the NTS SDK.

1. Static link fails on glibc >= 2.34: undefined __dn_expand / __res_nsearch / __dn_skipname

lib/libphp.a is compiled against glibc 2.28, which still exported the unversioned resolver compat aliases that PHP's ext/standard/dns.c references. glibc 2.34 moved libresolv into libc and dropped them, so linking on Ubuntu 22.04+ / Debian 12+ / RHEL 9+ fails.

NTS tarballs (-gnu-nts and -gnu-nts-shared) now ship embed/resolver_shim.c (from ephpm, MIT, attribution in the header — maps the underscored names to the public resolver API) and an EMBEDDING.md documenting the link line via the relocatable bin/php-config.

Reproduced and verified in an ubuntu:22.04 (glibc 2.35) container against the v8.4.24 x86_64 NTS tarball:

  • control, no shim: undefined reference to '__dn_expand' (ext/standard/dns.c), link exit 1
  • with shim: link clean, binary runs: embed-ok 8.4.24 zts=0

2. Shared-embed NTS variant for consumers that only detect libphp.so

PAM's build detects libphp.so/.dylib, not .a. New platform entries linux-{x86_64,aarch64}-gnu-nts-shared set SPC_CMD_VAR_PHP_EMBED_TYPE=shared — env-driven in spc rc18 (src/Package/Target/php.php:274, php/unix.php:368), no fork patch — producing php-sdk-<ver>-linux-<arch>-gnu-nts-shared.tar.gz with lib/libphp.so (dependencies statically linked in; no dependency archives shipped). Staging, the x86_64 SHA-NI intrinsics guard, and the release body are adapted; the ZTS guard (php_config.h) applies unchanged. versions.json adds the shared platforms to platforms_nts so watch-php keeps them current for minors_nts.

Validation (test tag v8.4.24-shtest, x86_64, both runs green, tag deleted after)

  • static run 31554160428 / shared run 31554164872
  • static tarball contains embed/resolver_shim.c + EMBEDDING.md (tar listing)
  • shared tarball: lib/libphp.so + bundled libstdc++.a, embed/ + EMBEDDING.md, no .a dependency archives
  • on ubuntu:22.04, against the shtest artifacts:
    • nm -D: php_embed_init / php_embed_shutdown exported
    • no #define ZTS 1 in php_config.h (NTS)
    • readelf --dyn-syms: resolver refs are versioned (__dn_expand@GLIBC_2.2.5), so the shim is genuinely static-only
    • functional OPcache gate, both variants: sapi=embed zts=0 opcache_loaded=1 opcache_active=1 — OPcache activates under the embed SAPI, proving the rc18 SPC_OPCACHE_EXTRA_SAPIS allowlist injection end to end (opcache_active=0 is what an un-whitelisted SAPI produces on 8.4)
  • note: string-adjacency checks on ZendAccelerator literals are only valid on the unlinked object (.a member) — the linker's literal merging deduplicates embed/litespeed in the final .so, which is why the functional gate is the evidence here
  • production v8.4.24 assets byte-identical before/after (same IDs/sizes/timestamps)

What PAM should be told

  • Static (-gnu-nts): compile embed/resolver_shim.c from the tarball into the embed build; link line via bin/php-config --includes / --libs. Required on any glibc >= 2.34 host.
  • Shared: use php-sdk-<ver>-linux-<arch>-gnu-nts-shared.tar.gz; lib/libphp.so works with their existing shared-library detection, -lphp, no shim needed. The loading process needs libstdc++.so.6 at runtime.
  • Tarballs for 8.4.24/8.5.9 get built once this merges (aarch64 after x86_64 proves, per plan).

aarch64 shared is unvalidated so far — x86_64 first per plan; the aarch64 leg differs only in runner/arch, and its static NTS twin is proven on both arches.

… variant

Two integration gaps reported by PAM building against the NTS SDK:

1. Linking lib/libphp.a on glibc >= 2.34 (Ubuntu 22.04+) fails with
   undefined __dn_expand / __res_nsearch / __dn_skipname. libphp.a is
   compiled against glibc 2.28, which still exported those unversioned
   compat aliases; 2.34 moved libresolv into libc and dropped them. NTS
   tarballs now ship embed/resolver_shim.c (from ephpm, MIT, maps the
   underscored names to the public resolver API) plus EMBEDDING.md
   documenting the link line via the relocatable bin/php-config.

2. PAM's build detects only a shared libphp. New platform entries
   linux-{x86_64,aarch64}-gnu-nts-shared set
   SPC_CMD_VAR_PHP_EMBED_TYPE=shared (env-driven in spc rc18
   src/Package/Target/php/unix.php, no fork patch), producing
   php-sdk-<ver>-linux-<arch>-gnu-nts-shared.tar.gz with lib/libphp.so
   (dependencies statically linked in, versioned lib + symlink) instead
   of libphp.a. Staging, the x86_64 intrinsics guard, and the release
   body updated accordingly; ZTS guard unchanged (php_config.h).

versions.json: shared platforms added to platforms_nts so watch-php
keeps them current for minors_nts once assets exist.
- libphp.so in the shared tarball is a plain file, not a versioned
  symlink (rc18 only versions it when a -release is set, which this
  build does not).
- The shared library's resolver references are versioned
  (__dn_expand@GLIBC_2.2.5, confirmed via readelf on the shtest build),
  so the shim really is static-only; say how to check.
- Document the ~15 undefined C++ runtime refs in libphp.so: the loading
  process needs libstdc++.so.6.
@luthermonson
luthermonson merged commit 9af2206 into main Aug 12, 2026
@luthermonson
luthermonson deleted the feat/nts-embed-integration branch August 12, 2026 04:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant