Skip to content

alpha-crtl: 3 rungs so REAL zlib 1.3.1 links zero-deferred out-of-box - #869

Merged
baron-3dl merged 1 commit into
mainfrom
work/vms-zlib-crtl-rungs
Aug 28, 2026
Merged

baron-3dl merged 1 commit into
mainfrom
work/vms-zlib-crtl-rungs

Conversation

@baron-3dl

Copy link
Copy Markdown
Contributor

The 3 CRTL rungs

A prior probe measured that all 15 zlib 1.3.1 TUs already compile clean on the alpha-dec-vms port (0 EVAX cc1 defect at harness flags). These three fixes close the remaining LINK / header-surface residuals so REAL zlib compiles and links zero-deferred out-of-box — no labelled probes, no manual symbol adds.

# Rung Fix (file:line)
1 zconf.h fires #ifdef VMS #include <unixio.h> (port predefines VMS — correct, it IS a VMS toolchain) but the musl-alpha CRTL header surface had no <unixio.h> NEW tools/cross-alpha-vms/musl-arch/arch/alpha-dec-vms/unixio.h — faithful DECLARE-ONLY DEC C UNIX-I/O header (open/close/read/write/lseek/dup/dup2/isatty/unlink/access/ftruncate/fsync/chdir/getcwd), every entry already implemented by the port musl; VMS-target-scoped in the arch overlay
2 errno accessor UNDEF at LINK — musl's errno = (*__errno_location()), an undecorated musl-internal name the alpha cc1 does not map to decc$*, so the linker-view decc$ enumeration misses it src/vmslink/mk_decc_shr.sh — add ___errno_location=PROCEDURE to the alpha-branch symbol vector (LINK.EXE's EVAX reader represents the external C symbol __errno_location with one leading underscore prepended, uniformly for def + ref → ___errno_location, three underscores, the exact name gzread.obj deferred). Brings alpha to parity with the generic branch, which already exports the errno accessor
3 OTS$DIV_UL/OTS$REM_UI UNDEF — the port lowers integer divide/rem to OTS$ calls; those live in the SEPARATE LIBOTS$ shareable, which DECC$SHR imports but does not re-export tools/cross-alpha-vms/joint-e2e/build-joint-image.sh — add --use LIBOTS$SHR.EXE alongside --use DECC$SHR.EXE in the canonical consumer link recipe. LINK binds only referenced imports → inert for OTS-free programs

errno-mechanism note

The C symbol is __errno_location (two underscores; how GNU nm reports it in libc.a). LINK.EXE's EVAX symbol reader prepends one leading underscore to external C symbols — uniformly for the musl definition and every consumer reference — so at the link/vector level the name is ___errno_location (three underscores). This is why the two-underscore C-form export did NOT resolve gzread.obj's reference (%LINK-F-UNDEF, EVAX: undefined symbol '___errno_location' referenced by gzread.obj); exporting the three-underscore name closes it. The DEC-C-decorated decc$get_errno_addr is a different (DEC C) errno ABI and is unrelated to what musl-compiled consumer code references.

Zlib zero-deferred out-of-box — proof

Containerized (ovmx-cross-alpha-vms), build-to-/tmp, Rule-9-clean. Not run under qemu-user (BOOT-A/B is the runtime test).

  • REAL zlib 1.3.1, pinned sha256 9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23.
  • All 15 TUs + a compress/uncompress round-trip main cross-compiled at harness flags (-mpointer-size=64 -g0) + -DZ_HAVE_UNISTD_H → compile clean.
  • Linked against the FIXED DECC$SHR + LIBOTS$ via the FIXED recipe (--transfer __main --use DECC$SHR.EXE --use LIBOTS_SHR.EXE):
    • zlib link rc=0 ; LINK-F-UNDEF count=0ZERO-DEFERRED OUT-OF-BOX (no manual adds)
    • image is Machine: Alpha, Type: DYN
  • Rung 1 proven live: unixio.h present at .../arch/alpha-dec-vms/unixio.h; all 15 TUs (incl. gzread, which pulls <unixio.h> via zconf.h) compile.

No regression

  • joint_e2e default (crt0 + joint_main, --use DECC$SHR.EXE only) rebuilt live → links clean (rung-3's LIBOTS is inert for OTS-free programs).
  • crtl_rms (aarch64 run_vmsrms_native.sh, which already exports __errno_location): depends solely on the generic branch of mk_decc_shr.sh; the errno edit is inside the alpha branch (if [ "$OVMX_DECC_ARCH" = alpha ]), so that branch is byte-unchanged → structurally cannot regress. unixio.h is alpha-arch-scoped; the LIBOTS edit is joint-only.

zlib build recipe (for the PR record)

# harness flags == build-joint-image.sh cc1 flags; -DZ_HAVE_UNISTD_H is what
# zlib's own ./configure sets (makes zconf.h include <unistd.h> then, under the
# port-predefined VMS, <unixio.h>). Include path = the alpha musl surface.
ALPHA_MUSL_INC="-I$MUSL_SRC/arch/alpha-dec-vms -I$MUSL_SRC/arch/generic \
  -I$MUSL_SRC/obj/src/internal -I$MUSL_SRC/src/include -I$MUSL_SRC/src/internal \
  -I$MUSL_SRC/obj/include -I$MUSL_SRC/include"
ZCF="-mpointer-size=64 -g0 -DZ_HAVE_UNISTD_H $ALPHA_MUSL_INC -I<zlib-src>"
for c in adler32 compress crc32 deflate gzclose gzlib gzread gzwrite \
         infback inffast inflate inftrees trees uncompr zutil; do
    alpha-dec-vms-gcc $ZCF -c $c.c -o $c.obj
done
LINK.EXE --transfer __main --use DECC\$SHR.EXE --use LIBOTS_SHR.EXE -o zlib_e2e.exe *.obj

Out-of-scope observation (separate, not a CRTL rung)

Compiling zlib at -O2 (not harness flags) surfaces an EVAX cc1/as codegen defect: deflate.c at -O2 produces .s the alpha-dec-vms as rejects (Error: syntax error). Independent of these three rungs (they are all LINK / header-surface); tracked separately.

🤖 Generated with Claude Code

Close the three CRTL residuals a prior probe measured on the alpha-dec-vms
port (all 15 zlib TUs already compile clean at harness flags; these were the
LINK/header-surface gaps that kept it from linking without manual symbol
adds or labelled probes):

1. unixio.h on the port CRTL include surface. zconf.h does
   `#ifdef VMS #include <unixio.h>` -- the alpha-dec-vms port predefines VMS
   (correctly; it IS a VMS toolchain), but the musl-alpha CRTL header surface
   had no <unixio.h>. Add a faithful, DECLARE-ONLY <unixio.h> to the
   alpha-dec-vms arch overlay (open/close/read/write/lseek/dup/dup2/isatty/
   unlink/access/ftruncate/fsync/chdir/getcwd) -- every one already IMPLEMENTED
   by the port musl; signatures track musl's own unistd.h/fcntl.h so a TU that
   includes both sees identical prototypes. VMS-target-scoped (arch overlay),
   never surfaced for a non-VMS target.

2. Export the errno accessor from the alpha DECC$SHR. musl's <errno.h> defines
   `errno` as `(*__errno_location())`; that plain, musl-internal name is not a
   DEC C RTL surface name, so the alpha cc1 does NOT decorate it to decc$* and
   the linker-view decc$ enumeration misses it. LINK.EXE's EVAX reader names
   the external C symbol with one leading underscore prepended (uniformly for
   the musl definition and every consumer reference), so at the vector level it
   is `___errno_location` (three underscores) -- the exact name gzread.obj
   deferred. Add `___errno_location=PROCEDURE` to the alpha-branch symbol
   vector, bringing alpha to parity with the generic (x86_64/aarch64) branch,
   which already exports the errno accessor. Alpha-branch only; the generic
   branch is untouched.

3. --use LIBOTS$SHR.EXE on the canonical consumer link. The port lowers every
   integer divide/remainder to OTS$DIV_*/OTS$REM_* (Alpha has no integer-divide
   instruction); those universals live in the SEPARATE LIBOTS$ shareable.
   DECC$SHR imports OTS$ for its own use but does not transitively re-export it,
   so a consumer that divides (zlib, and most real C) defers OTS$DIV_UL/
   OTS$REM_UI against DECC$SHR alone. Add `--use LIBOTS$SHR.EXE` alongside
   `--use DECC$SHR.EXE` in build-joint-image.sh's link recipe. LINK binds only
   REFERENCED imports, so this is inert for programs (like the default
   joint_main) that emit no OTS$ call.

VERIFIED (containerized, build-to-/tmp, Rule-9-clean; NOT run under qemu-user):
REAL zlib 1.3.1 (pinned sha256 9a93b2b7...df23) -- all 15 TUs + a compress/
uncompress round-trip main cross-compiled at harness flags (-mpointer-size=64
-g0) + -DZ_HAVE_UNISTD_H, linked against the FIXED DECC$SHR/LIBOTS$ via the
FIXED recipe -> 0 %LINK-F-UNDEF OUT-OF-BOX (no manual adds), EM_ALPHA ET_DYN.
No regression: default joint_e2e (crt0 + joint_main, DECC$SHR only) still links
clean; the errno edit is inside the alpha branch of mk_decc_shr.sh so the
aarch64 crtl_rms / generic branch is byte-unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@baron-3dl
baron-3dl merged commit 3c3d409 into main Aug 28, 2026
5 checks passed
@baron-3dl
baron-3dl deleted the work/vms-zlib-crtl-rungs branch August 28, 2026 20:41
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