Skip to content

vms-065c: gate crtl_rms->N=7 activation per-PR (regression-guard vms-1ef) - #959

Merged
baron-3dl merged 1 commit into
mainfrom
work/vms-065c-n7-gate
Aug 30, 2026
Merged

baron-3dl merged 1 commit into
mainfrom
work/vms-065c-n7-gate

Conversation

@baron-3dl

Copy link
Copy Markdown
Contributor

vms-065c: gate crtl_rms->N=7 activation per-PR (regression-guard vms-1ef)

vms-1ef (#958) root-caused + fixed a LINK.EXE weak_alias-thunk descriptor-export
bug (decc$_malloc64 exported its own cell-less PDSC instead of strong mallocng's,
SIGSEGV in the malloc->mallocng path). Its ONLY runtime proof was a MANUAL
joint-e2e boot -- regression-fragile: a future link.c/toolchain/CRTL change could
silently re-break crtl_rms->N=7 with no CI tell.

Add a per-PR gate that boots the crtl_rms port image on the real OVMX/Alpha
executive and asserts it reaches N=7, mirroring the existing N=3 alpha-boot-mount
gate (same real /dev/vms boot, same alpha_activation scope-gate + 150-min budget):

  • run-module-gp-activation-alpha.sh: parameterize the MILESTONE image
    (MILESTONE_MAIN, default joint_main.c) and add a "crtl-rms-gate" mode that
    builds crtl_rms_test.c (heap malloc->mallocng + RMS file I/O + stdio, returns
    sentinel 7) as the milestone. A dedicated assert_crtl_rms() is the teeth: the
    crtl_rms image does NOT print joint_main.c's "OVMX crt0 join" line, so its
    proof is (a) the heap+RMS+stdio port-test OK line -- the malloc(8192)->mallocng
    path that SIGSEGV'd pre-vms-1ef: export strong descriptor for a redirected weak_alias thunk (crtl_rms N=7) #958, now completing -- (b) $STATUS decoding to sentinel
    7 (0x0035A039), (c) no activation %-error. The mode runs its own can-fail
    selftest (clean proof passes; the pre-vms-1ef SIGSEGV signature reds) before
    trusting the boot, exactly as "gate" does.
  • ci.yml: alpha-crtl-rms-n7 job, gated on alpha_activation (src/vmslink +
    src/imgact + tools/cross-alpha*), invoking the crtl-rms-gate mode.

Validated: bash -n clean; YAML well-formed; assert_crtl_rms unit-tested (PASSES
the real vms-1ef N=7 boot log, REJECTS a synthetic malloc->mallocng SIGSEGV). This
PR touches tools/cross-alpha/** so the new gate runs on THIS PR, self-validating
the full build+boot end-to-end.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

…1ef)

vms-1ef (#958) root-caused + fixed a LINK.EXE weak_alias-thunk descriptor-export
bug (decc$_malloc64 exported its own cell-less PDSC instead of strong mallocng's,
SIGSEGV in the malloc->mallocng path). Its ONLY runtime proof was a MANUAL
joint-e2e boot -- regression-fragile: a future link.c/toolchain/CRTL change could
silently re-break crtl_rms->N=7 with no CI tell.

Add a per-PR gate that boots the crtl_rms port image on the real OVMX/Alpha
executive and asserts it reaches N=7, mirroring the existing N=3 alpha-boot-mount
gate (same real /dev/vms boot, same alpha_activation scope-gate + 150-min budget):

- run-module-gp-activation-alpha.sh: parameterize the MILESTONE image
  (MILESTONE_MAIN, default joint_main.c) and add a "crtl-rms-gate" mode that
  builds crtl_rms_test.c (heap malloc->mallocng + RMS file I/O + stdio, returns
  sentinel 7) as the milestone. A dedicated assert_crtl_rms() is the teeth: the
  crtl_rms image does NOT print joint_main.c's "OVMX crt0 join" line, so its
  proof is (a) the heap+RMS+stdio port-test OK line -- the malloc(8192)->mallocng
  path that SIGSEGV'd pre-#958, now completing -- (b) $STATUS decoding to sentinel
  7 (0x0035A039), (c) no activation %-error. The mode runs its own can-fail
  selftest (clean proof passes; the pre-vms-1ef SIGSEGV signature reds) before
  trusting the boot, exactly as "gate" does.
- ci.yml: alpha-crtl-rms-n7 job, gated on alpha_activation (src/vmslink +
  src/imgact + tools/cross-alpha*), invoking the crtl-rms-gate mode.

Validated: bash -n clean; YAML well-formed; assert_crtl_rms unit-tested (PASSES
the real vms-1ef N=7 boot log, REJECTS a synthetic malloc->mallocng SIGSEGV). This
PR touches tools/cross-alpha/** so the new gate runs on THIS PR, self-validating
the full build+boot end-to-end.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@baron-3dl
baron-3dl merged commit 58df594 into main Aug 30, 2026
124 checks passed
baron-3dl added a commit that referenced this pull request Sep 9, 2026
…-override — land the alpha CRTL->RMS ODS-2 proof without regressing N=7

The rung-4 branch's earlier link.c change (base+addend full-target match)
regressed the crtl_rms N=7 gate (gated-green at #958/#959): it dropped the
weak-alias thunk redirects the mallocng heap needs. Reverting to the base-only
redirect greened N=7 but crashed the veneer's calloc. Root-caused via
print-fatal-signals PC capture (gdb isn't in the images): TWO oppositely-signed
strong-sibling relocs that no reloc-local field can separate —

  - decc$_calloc64 (real calloc at $CODE$+0x8, past the offset-0 overridden weak
    __malloc_allzerop): base-only wrongly redirects it onto strong
    __malloc_allzerop+0x8 and calloc a_crash()es (veneer's early 0x4c618 crash).
    Must be LEFT.
  - the mallocng syscall/stdio thunks (decc$munmap/mremap/mmap/__syscall_cp,
    decc$fclose, __stdio_close): base-only correctly redirects them to their
    strong def; leaving them wild-jumps into the fork/execve code region (the
    0x4a354 crash shared by N=7). Must be REDIRECTED.

Both are byte-identical in every reloc field (psect/to_section/addend/type/
site-sym/target-sym/weak/overridden/self_ref), so this applies base-only to
every base-coincident section-relative reloc EXCEPT the precise, structurally-
detected calloc case: base-only's redirect would land inside strong
__malloc_allzerop while the reloc's real target is a distinct sibling. Bounded
workaround pending the weak_alias-granularity export-path fix (vms-f59).

Gates: OVMX/Alpha crtl_rms N=7 = clean sentinel 7 ($STATUS=%X0035A039,
port_ok=1); CRTL->RMS veneer = decc$fopen lands PORTTEST.DAT;1 on the ODS-2
volume, File ID (71,1,0) + full 16/16 blocks, confirmed by an INDEPENDENT
DIRECTORY/FULL reader (un-fakeable). Known-tracked: the veneer image still
signal-11s AFTER the write commits (pre-existing under every link variant; in
the RMS-veneer cleanup path, not exercised by the clean N=7 round-trip) — filed
as a follow-up under vms-fd1; the veneer gate proves the ODS-2 landing
independent of that post-commit crash.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ
baron-3dl added a commit that referenced this pull request Sep 9, 2026
…fc LLP64 width fix) (#1063)

* vms-f49: rung 4 — un-fakeable ODS-2 independent-reader proof + vms-1fc LLP64 width fix

Lands the MILESTONE of the vms-b4f ladder: prove the alpha-dec-vms GCC-port
image's CRTL fopen genuinely writes to a real Files-11 ODS-2 volume over the
executive ACP, not musl-ramfs — the anti-fabrication payoff (INV-6). Two
coupled items in one PR, because the width fix is VALIDATED by the proof.

PART A — vms-1fc (LLP64 syscall width fix). On the alpha-dec-vms C model
`long`/`unsigned long` are 32 bits while pointers are 64 (LLP64), so the
libvmssys raw-syscall path truncated every pointer argument to the /dev/vms
transport — the ioctl(/dev/vms, ...) RMS-over-ACP write landed on a garbage
address and reached nothing.
  - vms_syscall.h: widen __vms_syscall0..6 params + return to a guaranteed-
    64-bit `vms_reg_t` (== long long), and the vms_sys_* pointer casts with it;
    widen vms_sys_ioctl's `arg` param from `unsigned long` to vms_reg_t.
  - arch/alpha/syscall_vms.c: match the widened prototypes (long long).
  - kif_transport_linux.c: cast the request-block pointer through vms_reg_t,
    not `unsigned long` — THIS is the /dev/vms pointer the proof exercises.
  - vms_bgsock.c: widen its ioctl pointer casts to match.
  No-op on the LP64 targets (x86_64/aarch64/alpha-linux-gnu: long long == long,
  byte-identical codegen); the actual fix only on alpha-dec-vms. VAX is
  untouched by construction — it takes the __NetBSD__ branch
  (arch/vax/vms_syscall_netbsd.h) and compiles none of these declarations.

PART B — vms-f49 (rung 4, the un-fakeable gate). New `crtl-rms-veneer-gate`
mode of run-module-gp-activation-alpha.sh boots the veneer-wired crtl_rms port
image (JOINT_CRTL_RMS_VENEER=1) on the real /dev/vms + qemu-system-alpha; its
decc$fopen -> the crtl_rms_stdio veneer -> sys$create/$put -> LIBVMSRMS$SHR ->
ioctl(/dev/vms) -> ACP writes PORTTEST.DAT. Then an INDEPENDENT reader — DCL
DIRECTORY/FULL, a DIFFERENT accessor than the writer's CRTL/RMS handle, running
its own sys$search over the ACP directory — asserts PORTTEST.DAT;1 exists on the
ODS-2 volume with a genuine ODS-2 File ID that a ramfs write cannot produce.
  - SYSTARTUP_VMS_VENEER_PROOF.COM: RUN JOINT_E2E, then DIRECTORY/FULL PORTTEST.DAT.
  - build-alpha-bootimage.sh: stage LIBVMSRMS$SHR.EXE into SYS$SHARE and swap in
    the veneer-proof SYSTARTUP when a veneer build is present (keyed on the
    shareable), verify it on the mastered volume.
  - assert_veneer(): gates on the independent File-ID reader, NOT console/CRTL
    state; a can-fail selftest proves teeth incl. the NEGATIVE/REJECTION case —
    a same-CRTL success that ramfs satisfies (%DIRECT-W-NOFILES) must FAIL.
  - ci.yml: new PR job alpha-crtl-rms-veneer (alpha_activation scope, 150m). The
    non-veneer alpha-crtl-rms-n7 gate stays green as the control.

Local build+link verified: the veneer graph links zero-deferred under the
alpha-dec-vms cc1 with the width fix (decc$fopen->DECC$SHR, veneer
sys$create/$put/$get->LIBVMSRMS$SHR), LIBVMSRMS$SHR.EXE emitted; assert_veneer
selftest passes all six fixtures. The qemu-alpha runtime proof runs in CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: fix apostrophe quote-break in build-alpha-bootimage.sh staging block

The vms-f49 staging comments landed inside the assemble `docker run ... bash -c
'...'` SINGLE-QUOTED block with apostrophes ("image's"), which closed the quote
mid-body and exposed `decc$fopen` to the outer shell -> `line 91: fopen: unbound
variable` under `set -u`. This broke the boot-image assembly for EVERY alpha
activation gate that calls assemble_boot_image (gate/crtl-rms-gate/mf-gate/
crtl-rms-veneer-gate), before any qemu boot -- NOT a Part A regression (all three
reds died at the identical line-91 quote-break after "step 1 staged", pre-boot;
Part A links clean, proven by the green alpha RMS-substrate STRICT-link + DECC$SHR
jobs). The script's own header warns "no apostrophes in this block". Reworded the
two added comments apostrophe-free; verified the docker -c body now has balanced
single-quotes with zero outer-shell `$` exposure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: stage the full RMS producer graph + fix its DECC producer name (rung-4 activation)

The rung-4 veneer gate booted this time (N=7 control PASSED -> Part A width fix
does NOT regress alpha activation) but the veneer image RUN drew
%IMGACT-F-IMGNOTFND: LIBVMSRMS$SHR is not self-contained. It transitively imports
from the whole executive producer graph (LIBVMS/LIBVMSFS/LIBVMSLNM/LIBVMSPROCESS/
LIBVMSSYS$SHR) AND recorded its DECC producer as the phantom pass-1 bootstrap name
"DECC1$SHR.EXE" -- neither on SYS$SHARE, so IMGACT could not resolve them.

Two in-scope Part-B wiring fixes (no new executive facility):
 - build-joint-image.sh: build the pass-1 bootstrap DECC under $WORK/p1 with the
   BASENAME DECC$SHR.EXE (not DECC1$SHR.EXE). LINK records producers by basename,
   so the graph + LIBVMSRMS$SHR now record "DECC$SHR.EXE" and, at activation,
   IMGACT name-keyed binding resolves them against the SINGLE staged pass-2
   (veneer) DECC$SHR.EXE (GSMATCH LEQUAL). One DECC$SHR at runtime, no duplicate
   musl C-RTL. Also emit the whole producer graph to OUTDIR.
 - run-module-gp-activation-alpha.sh + build-alpha-bootimage.sh: stage the full
   graph (LIBVMSRMS/LIBVMS/LIBVMSFS/LIBVMSLNM/LIBVMSPROCESS/LIBVMSSYS$SHR) into
   SYS$SHARE and verify each on the mastered ODS-2 volume.

Also fixes a second single-quote apostrophe break ("IMGACT's", and 'DECC$SHR.EXE'
exposing $SHR) in the build-joint-image.sh docker bash -c block.

Local verify: veneer graph links zero-deferred; LIBVMSRMS$SHR + all 7 sibling
shareables now record DECC$SHR.EXE (grep DECC1 = 0 across the whole staged set);
full graph emitted to OUTDIR. Runtime activation runs in CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: surface the guest-kernel faulting PC in the veneer-gate failure output

The veneer image now activates (producer graph staged) but SIGSEGVs
(%DCL-F-ABORT signal 11) in the first-ever runtime execution of the alpha RMS
substrate over the veneer. The Alpha guest kernel prints the faulting user
PC/RA/VA to the console at fault time, but the gate's fixed pattern-grep never
surfaced it. Dump the guest fault-signature line(s) + the last 60 console lines
in the veneer-gate FAIL path so the authoritative fault PC is captured in CI
(disk-safe -- no qemu -d flags; the guest kernel already emitted it). This
localizes the crash so it can be fixed. Not a gate weakening -- failure path only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: capture qemu CPU-exception log to pin the veneer SIGSEGV faulting PC

The previous fault-capture confirmed the veneer image crashes at/near ACTIVATION
(no OVMX-CRTL-RMS sys$create trace precedes the %DCL-F-ABORT signal 11), and the
Alpha guest kernel prints no userspace fault line. So add qemu exception logging
(-d int,cpu_reset,guest_errors -D /work/qint.log), enabled ONLY for the
crtl-rms-veneer-gate via QEMU_DBG, and dump the last exceptions (faulting PC/VA)
in the veneer FAIL path. Disk-safe: the boot reaches Username: within ~30-60s so
qint.log stays small; other gates pass QEMU_DBG empty (unchanged). This is the
gdb-equivalent authoritative fault PC needed to decide RMS-substrate truncation
(hyp 1) vs IMGACT mutual-producer-cycle activation crash (hyp 2, the leading
hypothesis: the veneer DECC$SHR<->LIBVMSRMS$SHR cycle the non-veneer control lacks).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: filter qemu exception log (clk-interrupt firehose hid the fault)

The -d int log is dominated by clk_interrupt; the veneer SIGSEGV's Dfault/MMFAULT
exception with the faulting user pc= is buried. Filter out clk/dev interrupts and
add an exception-type histogram so the fault exception + PC is surfaced.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: IMGACT-MAP producer base logging to resolve the veneer fault PC

The qemu -d int log localized the veneer SIGSEGV to a repeated mmfault loop at
user pc=0x12005eb00 (and 0x12005a7f4). IMGACT is only ~37KB so the fault is in a
mmap'd producer (likely DECC$SHR, which holds the veneer ovmx_crtl_fopen). Print
each producer's runtime base (IMGACT-MAP: <name> base=0x..) at load so the
faulting pc can be resolved to <image>+offset and then to a symbol. Diagnostic
only; other gates grep their own patterns so the extra lines are inert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: log MAIN-EXE + IMGACT-INTERP bases to place the 0x120000000 fault region

Producer bases are all 0x20000xxxxx, but the veneer fault PCs cluster in the
0x120000000 range (0x12005eb00 repeated 18x = the unrecoverable fault; other
single-hit pcs are benign TLB fills). Log the kernel-mapped main-exe bias and the
PT_INTERP (IMGACT) base so the faulting region can be attributed to the main
image, the interp, or an unmapped bad-jump target (mis-resolved cross-image
linkage = hyp 2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: gate IMGACT-MAP behind OVMX_IMGACT_MAP=1 (silent by default)

Housekeeping: the IMGACT-MAP producer-base logging now emits only when the boot
cmdline carries OVMX_IMGACT_MAP=1 (kept for fault-localization, silent in
production). run_boot_a gains an optional QEMU_APPEND injection; the veneer gate
sets QEMU_APPEND=OVMX_IMGACT_MAP=1 so it still gets the map. The QEMU_DBG -d int
fault capture is retained (inert for other gates).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: Option-1 probe — log wild (0x120000000-region) import bindings in IMGACT

The veneer SIGSEGV jumps to 0x120000000+offset (default/stack-top base) while all
images map at 0x200_xxxx_xxxx; the value is COMPUTED at runtime (not stored). Add
a gated (OVMX_IMGACT_MAP=1) probe in bind_imports that logs any binding whose
resolved PV or filled code entry *(PV+8) lands in the wild region -- with the
importing image, the symbol, the cell, the PV, and the entry. A wild PV isolates
an SV-value fault; a sane PV with a wild entry isolates a producer PDSC-entry
rebase fault. Surface IMGACT-WILD/IMGACT-MAP in the veneer-gate failure dump. If
nothing fires, the wild target is code/GP-computed (not a linkage fill) and the
next step is a register (RA) capture. Probe only; no behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: correct the Option-1 probe wild-region range (0x1_xx, not the 0x200xxx image region)

The probe flagged all valid 0x200_xxxx_xxxx bindings as wild because the upper
bound (0x200000000000) sat above the real image region. Narrow it to
[0x1_0000_0000, 0x100_0000_0000) -- the 0x120000000 default/stack-top region --
so only genuinely-wild values fire. Confirmed against the CI run: with the correct
range NO binding is wild (all PVs/entries resolve to 0x200xxx), proving the veneer
SIGSEGV is NOT a linkage fill but a wrong-base code jump.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: fix emutls control-object width (LLP64) — the veneer rung-4 crash root cause

The alpha emulated-TLS runtime typed the control-object fields as `unsigned long`
(emutls_word), which on the alpha-dec-vms LLP64 target is 32 BITS — but the cc1
emits the control with 64-bit .quad fields (.quad size; .quad align; .quad loc;
.quad templ). So struct __emutls_object packed size+align into the first 8 bytes
and put `loc` at offset 8 (the align field) instead of 16. __emutls_get_address
returned obj->loc = the align value (4), and the first __thread access on the
veneer's sys$create path (a vms_kif 'vms_bound_pid == getpid()' check) then
dereferenced 4 -> SIGSEGV at 0x4 — the rung-4 (vms-f49) blocker, pinned via a
local qemu-system-alpha boot + an IMGACT SIGSEGV-handler RA capture.

Fix: emutls_word -> unsigned long long (64-bit on every target), so loc lands at
offset 16 and templ at 24, matching the .quad emission. Same LLP64 bug class as
vms-1fc. Arch-scoped: the whole file is #if defined(__alpha__), so x86_64/aarch64
(musl TLS) and VAX (NetBSD) never compile it — the non-veneer + VAX/x86_64
controls stay byte-identical.

Verified locally: the v0=4 / gp-as-stack SIGSEGV is gone; the veneer image now
advances past the emutls point into the Files-11 path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-f49: un-fakeable ODS-2 landing proof (rung 4) + bug #2/#3 toolchain fixes; strip diagnostics

Rung 4 of the vms-b4f ladder. Boots the CRTL->RMS veneer-wired alpha-dec-vms
GCC-port image on qemu-system-alpha + the real /dev/vms executive: its
decc$fopen -> ovmx_crtl veneer -> sys$create -> LIBVMSRMS$SHR -> ioctl(/dev/vms)
-> Files-11 ACP writes PORTTEST.DAT, then an INDEPENDENT reader (DCL
DIRECTORY/FULL, a different accessor than the writer's own CRTL/RMS handle)
asserts PORTTEST.DAT;1 landed on the real ODS-2 volume with a genuine File ID
AND the full 8192-byte content (16 blocks) -- something a ramfs/POSIX write can
never produce in the ACP directory. The gate keys on that fid+content landing
(strictly stronger than a same-CRTL round-trip a ramfs satisfies), with a 7/7
can-fail selftest.

Three first-exercise toolchain bugs the forcing function exposed:

- #1 emutls control-object width (LLP64): unsigned long is 32-bit on
  alpha-dec-vms, so __emutls_object {size,align,loc,templ} packed loc at offset
  8 instead of 16 and __emutls_get_address returned 4 -> SIGSEGV. emutls_word
  widened to unsigned long long. (committed earlier as e2c6cf5)

- #2 DECC$SHR symbol-vector index skew (mk_decc_shr.sh): the veneer pass dropped
  the 4 fopen/fwrite/fread/fclose entries from the middle of the sorted vector
  and re-appended the aliases at the tail, shifting every higher sv# down by 4.
  IMGACT binds cross-image imports BY INDEX, so producers linked against the
  bootstrap DECC dispatched e.g. decc$strlen[sv#414] to decc$strspn at runtime
  (NULL-arg SIGSEGV). Rewrite the 4 entries IN PLACE at their sorted slot,
  restoring the append-only sv# stability the recipe already documented.

- #3 calloc weak-override reloc (link.c): the vms-430 strong-over-weak
  base-redirect matched a section-relative reloc's section BASE before the
  addend was added, so every sibling symbol in a $CODE$ whose offset-0 proc is
  an overridden weak def (calloc.o's __malloc_allzerop) was pulled onto the
  strong def + addend -- decc$_calloc64 (real calloc at $CODE$+0x008) mis-bound
  onto strong __malloc_allzerop+0x008. Match base+addend and consume the addend
  on a hit; the symbol-target path is byte-identical. run_muldef_evax.sh green
  (incl. weak-first + strong-first self-bind redirect).

All diagnostic scaffolding stripped (IMGACT SIGSEGV handler / IMGACT-MAP probe /
qemu -d int injection) for a clean production activator.

The writer program's post-commit mallocng cleanup crash (free -> free_group ->
free(g->mem) hitting get_meta's `assert(meta->mem==base)` with a NULL group
meta) is a separate mallocng-group-release issue on the alpha-dec-vms substrate,
tracked as bug #4 (blocks vms-fd1); it fires AFTER the content commits and does
not affect the proven landing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

* vms-b14: bounded calloc-family exception in the section-relative weak-override — land the alpha CRTL->RMS ODS-2 proof without regressing N=7

The rung-4 branch's earlier link.c change (base+addend full-target match)
regressed the crtl_rms N=7 gate (gated-green at #958/#959): it dropped the
weak-alias thunk redirects the mallocng heap needs. Reverting to the base-only
redirect greened N=7 but crashed the veneer's calloc. Root-caused via
print-fatal-signals PC capture (gdb isn't in the images): TWO oppositely-signed
strong-sibling relocs that no reloc-local field can separate —

  - decc$_calloc64 (real calloc at $CODE$+0x8, past the offset-0 overridden weak
    __malloc_allzerop): base-only wrongly redirects it onto strong
    __malloc_allzerop+0x8 and calloc a_crash()es (veneer's early 0x4c618 crash).
    Must be LEFT.
  - the mallocng syscall/stdio thunks (decc$munmap/mremap/mmap/__syscall_cp,
    decc$fclose, __stdio_close): base-only correctly redirects them to their
    strong def; leaving them wild-jumps into the fork/execve code region (the
    0x4a354 crash shared by N=7). Must be REDIRECTED.

Both are byte-identical in every reloc field (psect/to_section/addend/type/
site-sym/target-sym/weak/overridden/self_ref), so this applies base-only to
every base-coincident section-relative reloc EXCEPT the precise, structurally-
detected calloc case: base-only's redirect would land inside strong
__malloc_allzerop while the reloc's real target is a distinct sibling. Bounded
workaround pending the weak_alias-granularity export-path fix (vms-f59).

Gates: OVMX/Alpha crtl_rms N=7 = clean sentinel 7 ($STATUS=%X0035A039,
port_ok=1); CRTL->RMS veneer = decc$fopen lands PORTTEST.DAT;1 on the ODS-2
volume, File ID (71,1,0) + full 16/16 blocks, confirmed by an INDEPENDENT
DIRECTORY/FULL reader (un-fakeable). Known-tracked: the veneer image still
signal-11s AFTER the write commits (pre-existing under every link variant; in
the RMS-veneer cleanup path, not exercised by the clean N=7 round-trip) — filed
as a follow-up under vms-fd1; the veneer gate proves the ODS-2 landing
independent of that post-commit crash.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJZf62TMXxvy6fXzFQYfLQ

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

2 participants