← board

Two independent blockers, and only the first one is the one people know about

Both reproduce in one line each, at aaf09343d1cb.

$ ./compiler/pascal26 --target=xtensa test/c_crtl_syscall_guarded_bodies.c out
pascal26:5: error: C program entry stub not implemented for this target yet

$ ./compiler/pascal26 --target=xtensa --platform=posix <same>      # identical

$ ./compiler/pascal26 --emit-obj --target=xtensa <same> out.o
pascal26:158: error: target xtensa: call0 target 56674 is not 4-aligned;
  CALL0/CALL8 encode a WORD offset and a stray byte is silently truncated
  away by the div below
  in: lib/crtl/src/ctype.c   near: isalpha

--emit-obj needs no entry stub, which is why it reaches the backend at all — and that is what makes these two separate bugs rather than one. Landing the stub does not get a C object built; it gets you to the second error.

The second one is a guard doing its job, not a missing feature

The message is explicit that CALL0/CALL8 encode a word offset and that the div below would truncate a stray byte silently. So somebody met this, worked out that a misaligned target produces a wrong branch rather than a diagnostic, and put the refusal in. That is the right shape. What is missing is the alignment itself: whatever lays out .text for xtensa is not padding function entries to 4.

ctype.c is the first crtl module compiled, so it is where this always appears; it is not about isalpha.

Why it is filed now

lib/crtl/include/sys/syscall.h gained a generated xtensa arm on 2026-09-04 (f25e4c723, 329 numbers from devdocs/dev/syscall-maps/xtensa.txt). Its block says in full that nothing can exercise it. The arm32 arm was confirmed by running test/c_crtl_syscall_guarded_bodies.c under qemu-arm and matching i386 row for row; that check is exactly what these two bugs prevent, and it is the acceptance for this ticket:

./compiler/pascal26 --target=xtensa test/c_crtl_syscall_guarded_bodies.c out
tools/run_target.sh xtensa out        # must equal the i386 run

qemu-xtensa is installed and tools/run_target.sh already has an xtensa arm, so nothing else is needed to close it.

What NOT to conclude

This is not a reason to distrust the xtensa syscall numbers. They come from the same sweep and the same controls as arm32's, and arm32's were independently corroborated byte-for-byte by a rewritten extractor. What is missing is evidence of the second kind — a running program — and that is a different claim from a wrong table.

Related: [[bug-c-the-32-bit-va-arg-set-is-complete-only-because-two-targets-cannot-compile-c-yet]] says its va_arg slot set is correct only because xtensa and wasm32 cannot compile C, and asks for the set to be fixed in the same commit as the stub. That is a hard requirement on the first half of this ticket. [[bug-c-no-c-program-entry-stub-for-wasm32-so-no-c-program-can-target-it]] is the same first half for the other target.

Log

Closed — what it took, and the part that was not in the ticket

The ticket said "two different things stop it" and was right about both, but the count was two because that is how far the instrument could see. The stub uncovered a third.

The acceptance, run

$ ./compiler/pascal26 --target=xtensa --platform=posix --xtensa-long-calls \
      test/c_crtl_syscall_guarded_bodies.c out       # rc 0
$ tools/run_target.sh xtensa out > xt.out            # rc 0, ten rows
$ diff xt.out i386.out                               # IDENTICAL
sched_getscheduler   errno=0     mlock       errno=0     statfs   errno=0
sched_getparam       errno=0     munlock     errno=0     flock    errno=9
sched_yield          errno=0     acct        errno=1     prctl    errno=22
                                                         readv    errno=9

--xtensa-soft-mulhigh is NOT needed.

The third defect, which only the acceptance could find

With the stub landed and the alignment fixed, the census still ran — and would have been believed, because its ten rows are %s errno=%d and both survived. The probes that did not survive were the ones nobody had a reason to run until a C program could exist at all:

printf("%llx", 0x1122334455667788)   ->  55667788      (high word dropped)
printf("%.3f %.3f", 1.5, 2.25)       ->  0.000 0.000
printf("%d %.3f %d", 7, 1.5, 8)      ->  7 0.000 1     (the 8 read as 1)

Both 64-bit arms of the xtensa direct-call ladder were guarded by i < Procs[procIdx].ParamCount, false for every variadic-tail argument. Fixed in 7574a5f8d by asking Arg32Class, plus ABIXtensaVaArgSlotAlign for the parity half. A census whose every row is a small int and a string cannot see this, which is worth saying out loud next to a table that was just declared measured: the ten rows are real evidence about the syscall NUMBERS and no evidence at all about the printf that prints them. They are separate claims.

What the run says about the OTHER ticket's ranking

[[feature-a-xtensa-should-not-need-a-flag-to-build-a-large-image]] holds p35 on the stated grounds that "the only program known to approach the wall is that row, which is awk-generated specifically to be large, so it DEFINES a population rather than sampling one — the hazard is real but conditional on some real image getting near 512 KiB, and none is." That premise is now false. c_crtl_syscall_guarded_bodies.c is a hand-written C program of ordinary size whose image is ~665 KB once crtl is in it, and without the flag it refuses:

pascal26:58: error: target xtensa: the forward call to __pxx_run_finalizers at
  code offset 58526 cannot reach its body at 664880 (CALL0/CALL8 reach +-512 KiB)

The wall is not a property of deliberately-large generated programs; it is a property of linking crtl at all, so every C program on this target meets it. Re-ranking is that ticket's owner's call and I have not touched its prio:; what I have done is correct its summary so the next reader is not deciding from the refuted sentence.