commit 3c5314adf20422fa3616120e78e0d1d23ce95d46
parent 4cd7ae1656d42c902f4e371502ea984b539bd9cf
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 29 Apr 2026 20:21:22 -0700
rename: lispcc → boot2 across the tree
The repo is named boot2 (per Makefile + container image name); a
handful of stragglers — comments, doc text, test fixtures, and one
file (lispcc-syscall.c) — still carried the old project name. Bulk
sed pass: lispcc-syscall.c → boot2-syscall.c (file rename, content
otherwise identical), and lispcc → boot2 in comments. No
behavioural changes.
Diffstat:
17 files changed, 299 insertions(+), 299 deletions(-)
diff --git a/P1/entry-libc.P1pp b/P1/entry-libc.P1pp
@@ -1,8 +1,8 @@
# P1/entry-libc.P1pp — executable entry stub for links that include
-# our libc (vendor/mes-libc + lispcc-syscall.c).
+# our libc (vendor/mes-libc + boot2-syscall.c).
#
# Same shape as entry-plain.P1pp but threads __libc_init in front of
-# main. __libc_init (lispcc-syscall.c) reads argv's NULL terminator
+# main. __libc_init (boot2-syscall.c) reads argv's NULL terminator
# to populate `environ` so getenv()/etc don't dereference a NULL
# environment pointer on the first call. argc/argv arrive in a0/a1
# from the bootstrap _start; %call doesn't clobber them, so the
diff --git a/docs/CC.md b/docs/CC.md
@@ -1,4 +1,4 @@
-# Minimal C subset (lispcc)
+# Minimal C subset (boot2)
Working doc. Baseline is C99; everything here is a delta against it. The
target is **just enough C** to compile
@@ -450,10 +450,10 @@ Status legend: `[x]` done · `[~]` in progress · `[ ]` not started.
ELF.
3. [ ] Compile the mes libc unified-libc.c (the same file MesCC builds
into libc.a).
-4. [ ] Compile tcc.c (under the tcc-mes defines) → tcc-lispcc; verify
- `tcc-lispcc -version` runs.
-5. [ ] Use tcc-lispcc to build tcc-boot0; verify checksum matches the
+4. [ ] Compile tcc.c (under the tcc-mes defines) → tcc-boot2; verify
+ `tcc-boot2 -version` runs.
+5. [ ] Use tcc-boot2 to build tcc-boot0; verify checksum matches the
live-bootstrap reference.
-Hitting (5) is the bootstrap milestone — at that point lispcc has
+Hitting (5) is the bootstrap milestone — at that point boot2 has
fully replaced MesCC in the chain.
diff --git a/docs/LIBC.md b/docs/LIBC.md
@@ -1,4 +1,4 @@
-# lispcc libc
+# boot2 libc
Goal: a `tcc-boot2` that runs and produces working binaries. Three
phases:
@@ -18,7 +18,7 @@ link external archives — `-version`, parse-only smokes.
Strategy in one sentence: **vendor a curated subset of mes libc as
source, patch a handful of small things, replace mes's per-arch
inline-asm syscall wrappers with one hand-written file
-(`lispcc-syscall.c`) that calls our P1pp labelled `sys_*` entry
+(`boot2-syscall.c`) that calls our P1pp labelled `sys_*` entry
points, then build it three different ways: as P1pp linked into
tcc-boot2 (Phase A), as ELF object files via tcc-boot2 itself
(Phase B1), and tcc's own `lib/libtcc1.c` via tcc-boot2 (Phase B2).**
@@ -38,11 +38,11 @@ vendor/mes-libc/
│ └── *.c ../mes/lib/)
├── linux/
│ └── malloc.c (only file kept; the others are replaced
-│ by lispcc-syscall.c)
+│ by boot2-syscall.c)
├── include/ (verbatim copy of ../mes/include/, plus an
│ empty mes/config.h shim)
├── patches/ (literal-block .before/.after pairs)
-├── lispcc-syscall.c (our hand-written replacement for mes's
+├── boot2-syscall.c (our hand-written replacement for mes's
│ per-arch inline-asm syscall.c + glue)
├── unified-libc.c (#include's every .c above; host -E flattens)
└── LICENSE (mes's COPYING; libc subset is GPLv3+)
@@ -118,7 +118,7 @@ mes/ abtol.c __assert_fail.c __buffered_read.c cast.c dtoab.c
```
Linux syscall-touching files (`brk`, `close`, `lseek`, `_open3`,
-`_read`, `unlink`) are replaced by `lispcc-syscall.c` directly so we
+`_read`, `unlink`) are replaced by `boot2-syscall.c` directly so we
don't drag in mes's `_sys_callN` indirection. `linux/malloc.c` stays
— it's a free-list allocator on top of `brk()`, no syscall plumbing
of its own.
@@ -149,7 +149,7 @@ int globals (no TLS).
&& __x86_64__ && !SYSTEM_LIBC` blocks evaluate to zero under our
defines (no `__GNUC__`); confirm by grep on `libc.flat.c` if in doubt.
-### lispcc-syscall.c
+### boot2-syscall.c
The only file we author. Provides:
@@ -186,7 +186,7 @@ The only file we author. Provides:
`MES_ARCH` mapping is `aarch64→riscv64`, `amd64→x86_64`,
`riscv64→riscv64`. mes ships no aarch64 headers; the riscv64 set
suffices because nothing in our flatten ends up referencing arch-
-specific syscall numbers or struct stat layouts (lispcc-syscall.c
+specific syscall numbers or struct stat layouts (boot2-syscall.c
goes around them).
`-I` order is **`include` before `include/linux/$MES_ARCH`** —
@@ -225,7 +225,7 @@ arguments. Both the tcc-boot2 link rule (Makefile) and the cc-libc
test suite (boot-run-tests.sh) compose this way; the tcc-boot2
client uses prefix `tcc__`, every cc-libc fixture uses `app__`.
-`__libc_init` (`vendor/mes-libc/lispcc-syscall.c`) walks argv's
+`__libc_init` (`vendor/mes-libc/boot2-syscall.c`) walks argv's
NULL terminator to populate `environ`; it must run before any libc
function that reads the environment. That's why the entry fragment
calls it ahead of `main`.
@@ -451,5 +451,5 @@ flag, see §Linking). Remaining issues:
100 instead of 42 from `va_arg`. Symptom is cc-libc/05-printf-int;
not yet diagnosed.
- **Floating-point literals.** cc.scm rejects `0.0`. Use `(double) 0`
- or similar non-literal forms (one site in lispcc-syscall.c's
+ or similar non-literal forms (one site in boot2-syscall.c's
`strtod` stub).
diff --git a/docs/OS.md b/docs/OS.md
@@ -1,6 +1,6 @@
# Minimal OS contract
-The lispcc bootstrap depends on a small, well-bounded set of OS
+The boot2 bootstrap depends on a small, well-bounded set of OS
capabilities. This document specifies that contract so a minimal OS
kernel can be implemented (and verified) against it. The rest of the
chain — `M0`, `hex2`, `cc.scm`, `tcc-boot2`, libc — assumes nothing
@@ -79,7 +79,7 @@ sp + 8 argv[0] (pointer)
[argv/envp string bytes follow, anywhere in image]
```
-`__libc_init` (`vendor/mes-libc/lispcc-syscall.c`) walks past argv's
+`__libc_init` (`vendor/mes-libc/boot2-syscall.c`) walks past argv's
NULL to find `environ`. **auxv is not required** — nothing in the
chain reads it.
@@ -113,7 +113,7 @@ chain reads it.
No signal-handler installation is required. Default actions
(SIGSEGV → terminate, SIGPIPE → terminate, etc.) are sufficient. The
-chain installs zero handlers; `lispcc-syscall.c` stubs `raise` to
+chain installs zero handlers; `boot2-syscall.c` stubs `raise` to
ENOSYS.
## Filesystem
@@ -158,7 +158,7 @@ Eight calls. Wired in `P1/P1pp.P1pp:986-1055`.
Errors are returned as negative errno (`-EBADF`, `-ENOENT`, …) in the
result register, per the standard Linux convention. The libc errno
-layer (`vendor/mes-libc/lispcc-syscall.c`) negates and stores into a
+layer (`vendor/mes-libc/boot2-syscall.c`) negates and stores into a
single global `errno` int.
Everything in `docs/LIBC.txt`'s "syscall-using" column reduces to
@@ -242,5 +242,5 @@ A minimal-OS implementation is compliant when:
layer) can invoke `tcc-boot2` on a `.c` source, wait for it to
exit, and read the resulting ELF back from disk.
-Both acceptance suites run end-to-end in the lispcc tree; an OS
-reaching Tier 2 needs no lispcc-side changes.
+Both acceptance suites run end-to-end in the boot2 tree; an OS
+reaching Tier 2 needs no boot2-side changes.
diff --git a/docs/TCC-TODO.md b/docs/TCC-TODO.md
@@ -170,7 +170,7 @@ Done. `parse_number` declares `double d; d = 0;` which triggered the
`cg-cast` FP rejection. `%cg-fp-reject!` is now a named no-op so
fp ctypes flow through size-dispatched load/store and same-size casts
as raw bit patterns. Real FP arithmetic is still wrong (binops emit
-integer ALU ops on the underlying bits), but tcc-lispcc's runtime
+integer ALU ops on the underlying bits), but tcc-boot2's runtime
never executes its own float code paths when compiling float-free
programs, so producing valid-but-semantically-wrong P1pp here is
sufficient. Comment in cc.scm flags the call sites for any future
@@ -309,8 +309,8 @@ likely walls live in the assembly side and at runtime:
unmet — there is no libc in the link today. See §libc strategy below.
The end goal is milestone 4 in [CC.md §Validation milestones](CC.md)
-— "Compile tcc.c (under the tcc-mes defines) → tcc-lispcc; verify
-`tcc-lispcc -version` runs."
+— "Compile tcc.c (under the tcc-mes defines) → tcc-boot2; verify
+`tcc-boot2 -version` runs."
## libc — see [LIBC.md](LIBC.md)
diff --git a/tests/cc-libc/01-write-syscall.c b/tests/cc-libc/01-write-syscall.c
@@ -1,5 +1,5 @@
/* Confirms our P1pp sys_write -> _write path works end-to-end through
- * lispcc-syscall.c. No buffering, no FILE struct, no varargs. */
+ * boot2-syscall.c. No buffering, no FILE struct, no varargs. */
extern long sys_write (long fd, long buf, long len);
int
diff --git a/tests/cc-libc/02-write-libc.c b/tests/cc-libc/02-write-libc.c
@@ -1,4 +1,4 @@
-/* posix/write.c -> lispcc-syscall.c::_write -> P1pp sys_write.
+/* posix/write.c -> boot2-syscall.c::_write -> P1pp sys_write.
* Adds the public `write(int, const void *, size_t)` layer with errno
* handling on top of 01-write-syscall. cc.scm rejects #include
* (file inclusion is upstream of cc.scm via host -E pre-flatten); use
diff --git a/tests/cc-libc/03-fputs-stdout.c b/tests/cc-libc/03-fputs-stdout.c
@@ -1,6 +1,6 @@
/* fputs(s, stdout) — canonical libc usage. fputs casts stream to long
* (the fd) and forwards to write. stdout is a global (FILE*)1 that
- * lispcc-syscall.c provides as a real symbol (mes's #define is undef'd
+ * boot2-syscall.c provides as a real symbol (mes's #define is undef'd
* post-include). */
typedef long FILE;
extern FILE *stdout;
diff --git a/tests/cc-libc/07-malloc-roundtrip.c b/tests/cc-libc/07-malloc-roundtrip.c
@@ -1,4 +1,4 @@
-/* Allocator smoke: malloc -> brk syscall (via lispcc-syscall.c::brk).
+/* Allocator smoke: malloc -> brk syscall (via boot2-syscall.c::brk).
* Writes a sentinel through the returned pointer and reads it back so
* a successful malloc that returned a bad address is still caught. */
typedef unsigned long size_t;
diff --git a/tests/cc-libc/09-exit-code.c b/tests/cc-libc/09-exit-code.c
@@ -1,4 +1,4 @@
-/* exit(N) -> stdlib/exit.c -> stdlib/__exit.c -> lispcc-syscall.c::_exit
+/* exit(N) -> stdlib/exit.c -> stdlib/__exit.c -> boot2-syscall.c::_exit
* -> P1pp sys_exit. 00-exit covers the implicit return-from-main path;
* this fixture exercises the explicit terminator that abort() / errors
* out of main use. The literal `return 99;` after the exit call must
diff --git a/tests/cc-libc/10-file-roundtrip.c b/tests/cc-libc/10-file-roundtrip.c
@@ -24,7 +24,7 @@ extern ssize_t write (int fd, void const *buf, size_t n);
int
main (void)
{
- char const *path = "/tmp/lispcc-cclibc-10";
+ char const *path = "/tmp/boot2-cclibc-10";
FILE *w = fopen (path, "w");
if (!w)
diff --git a/tests/cc-libc/11-fseek.c b/tests/cc-libc/11-fseek.c
@@ -19,7 +19,7 @@ extern ssize_t write (int fd, void const *buf, size_t n);
int
main (void)
{
- char const *path = "/tmp/lispcc-cclibc-11";
+ char const *path = "/tmp/boot2-cclibc-11";
FILE *w = fopen (path, "w");
if (!w)
diff --git a/tests/cc-libc/12-unlink.c b/tests/cc-libc/12-unlink.c
@@ -1,4 +1,4 @@
-/* unlink -> lispcc-syscall.c::unlink -> P1pp sys_unlink (= unlinkat
+/* unlink -> boot2-syscall.c::unlink -> P1pp sys_unlink (= unlinkat
* with AT_FDCWD). Drives the syscall by creating a file, removing it,
* then re-opening it for read and asserting fopen now returns NULL.
* The first fopen("w") must succeed, the second fopen("r") after
@@ -17,7 +17,7 @@ extern ssize_t write (int fd, void const *buf, size_t n);
int
main (void)
{
- char const *path = "/tmp/lispcc-cclibc-12";
+ char const *path = "/tmp/boot2-cclibc-12";
FILE *w = fopen (path, "w");
if (!w)
diff --git a/vendor/mes-libc/boot2-syscall.c b/vendor/mes-libc/boot2-syscall.c
@@ -0,0 +1,260 @@
+/* boot2-syscall.c — replaces mes's per-arch inline-asm syscall wrappers
+ * with C wrappers that call P1pp's labelled syscall entry points.
+ *
+ * The P1pp labels (sys_read / sys_write / sys_open / sys_close /
+ * sys_lseek / sys_brk / sys_unlink / sys_exit) are defined in
+ * P1/P1pp.P1pp and resolved at the linker stage thanks to cc.scm's
+ * external-linkage rule (commit 6488cca).
+ *
+ * Layering:
+ * public libc (read, write, open, …) — comes from the posix layer
+ * └─ low-level _read, _write, _open3 — provided here
+ * └─ named sys_* labels — provided by P1pp.P1pp
+ *
+ * mes's linux/{brk,close,lseek,_open3,_read,unlink}.c are NOT vendored;
+ * the equivalents live here and bypass mes's _sys_callN indirection.
+ * mes's linux/<arch>-mes-{mescc,gcc}/{syscall,_exit,_write,…}.c are
+ * also unused — those are the inline-asm files we replace.
+ */
+
+#include <mes/lib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+/* mes's <stdio.h> defines stdin/stdout/stderr as macros expanding to
+ * (FILE*)0/1/2. That works for libc's own .c files, but client code
+ * (cc-libc tests, eventually tcc-boot2's compiled output) that uses
+ * `extern FILE *stdout;` needs a real linkage symbol. Drop the macros
+ * after libc's headers have set their guards, then define globals
+ * with the same initializer values. mes's libc bodies that already
+ * referenced `stdout` had the macro substitution happen on their
+ * #include path; subsequent .c files re-include <stdio.h> but hit
+ * the include guard and so see the now-undef'd identifiers, which
+ * resolve to our globals at link time (same numeric value, same fd). */
+#undef stdin
+#undef stdout
+#undef stderr
+FILE *stdin = (FILE *) 0;
+FILE *stdout = (FILE *) 1;
+FILE *stderr = (FILE *) 2;
+
+/* `__stdout` and friends (the int-typed fd globals oputs / fdputs read)
+ * are file-scope initialized in mes/mes_open.c — but that initializer
+ * is gated behind `#if SYSTEM_LIBC`, which we don't define. Without
+ * SYSTEM_LIBC we'd be left with only mes/globals.c's tentative
+ * `int __stdout;`, which zero-inits — meaning oputs("ok") writes to
+ * fd 0 (read-only stdin) and silently no-ops. unified-libc.c includes
+ * boot2-syscall.c before globals.c, so cc.scm's redecl-merge sees
+ * the proper definition first and absorbs the later tentative. */
+int __stdin = 0;
+int __stdout = 1;
+int __stderr = 2;
+
+extern long sys_read (long fd, long buf, long n);
+extern long sys_write (long fd, long buf, long n);
+extern long sys_open (long path, long flags, long mode);
+extern long sys_close (long fd);
+extern long sys_lseek (long fd, long off, long whence);
+extern long sys_brk (long addr);
+extern long sys_unlink (long path);
+extern long sys_exit (long code);
+
+/* mes/globals.c already provides `int errno;` and the FILE-helper
+ * indirections (__buffered_read_clear, __ungetc_clear, __ungetc_init).
+ * mes/__buffered_read.c and mes/fdgetc.c implement them. */
+
+ssize_t
+_read (int filedes, void *buffer, size_t size)
+{
+ return sys_read (filedes, (long) buffer, (long) size);
+}
+
+ssize_t
+_write (int filedes, void const *buffer, size_t size)
+{
+ return sys_write (filedes, (long) buffer, (long) size);
+}
+
+int
+_open3 (char const *file_name, int flags, int mask)
+{
+ int r = sys_open ((long) file_name, flags, mask);
+ __ungetc_init ();
+ if (r > 2)
+ {
+ if (r >= __FILEDES_MAX)
+ {
+ errno = EMFILE;
+ return -1;
+ }
+ __ungetc_clear (r);
+ __buffered_read_clear (r);
+ }
+ return r;
+}
+
+int
+close (int filedes)
+{
+ long r = sys_close (filedes);
+ if (r < 0)
+ {
+ errno = -r;
+ return -1;
+ }
+ errno = 0;
+ return (int) r;
+}
+
+off_t
+_lseek (int filedes, off_t offset, int whence)
+{
+ return sys_lseek (filedes, offset, whence);
+}
+
+off_t
+lseek (int filedes, off_t offset, int whence)
+{
+ /* mirrors mes's linux/lseek.c: drain the per-fd read buffer before
+ * letting the kernel see a positional move; SEEK_CUR offsets must
+ * back out the buffered-but-not-yet-consumed bytes. */
+ size_t skip = __buffered_read_clear (filedes);
+ if (whence == SEEK_CUR)
+ offset -= skip;
+ return sys_lseek (filedes, offset, whence);
+}
+
+long
+brk (void *addr)
+{
+ return sys_brk ((long) addr);
+}
+
+int
+unlink (char const *file_name)
+{
+ long r = sys_unlink ((long) file_name);
+ if (r < 0)
+ {
+ errno = -r;
+ return -1;
+ }
+ errno = 0;
+ return 0;
+}
+
+void
+_exit (int status)
+{
+ sys_exit (status);
+}
+
+/* Linux aarch64/amd64/riscv64 stack at exec entry:
+ * [sp] = argc
+ * [sp + 8 * (1)] = argv[0]
+ * ...
+ * [sp + 8 * (argc+1)] = NULL (terminates argv)
+ * [sp + 8 * (argc+2)] = envp[0]
+ * Our :_start passes (a0=argc, a1=argv) to :p1_main. envp follows
+ * argv's NULL terminator, so we compute it from argv. tcc's getenv
+ * walks the resulting environ; without initialization it dereferences
+ * NULL on the first call and segfaults during tcc_new(). */
+extern char **environ;
+
+void
+__libc_init (int argc, char **argv)
+{
+ (void) argc;
+ char **p = argv;
+ while (*p)
+ p++;
+ environ = p + 1;
+}
+
+/* ---- ENOSYS stubs for libc-internal references not exercised by ----
+ * tcc-boot2's golden path. The mes libc transitively pulls these in
+ * (posix/getcwd.c → _getcwd, posix/execvp.c → execve, stdlib/abort.c
+ * → raise, …). Providing -ENOSYS stubs keeps the link clean; if any
+ * of these surfaces in a real workload, replace the stub with a P1pp
+ * label and a thin wrapper above. */
+
+#define ENOSYS 38
+
+char *
+_getcwd (char *buffer, size_t size)
+{
+ (void) buffer; (void) size;
+ errno = ENOSYS;
+ return 0;
+}
+
+int
+access (char const *path, int mode)
+{
+ (void) path; (void) mode;
+ errno = ENOSYS;
+ return -1;
+}
+
+void
+assert_msg (int check, char *msg)
+{
+ if (!check)
+ {
+ sys_write (2, (long) msg, 0);
+ sys_exit (1);
+ }
+}
+
+int
+execve (char const *file, char *const argv[], char *const envp[])
+{
+ (void) file; (void) argv; (void) envp;
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+fsync (int filedes)
+{
+ (void) filedes;
+ return 0;
+}
+
+int
+raise (int sig)
+{
+ /* abort() calls raise(SIGABRT); take that as a hard exit. */
+ sys_exit (128 + sig);
+ return -1;
+}
+
+int
+rmdir (char const *file_name)
+{
+ (void) file_name;
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+stat (char const *file_name, struct stat *buf)
+{
+ (void) file_name; (void) buf;
+ errno = ENOSYS;
+ return -1;
+}
+
+double
+strtod (char const *string, char **tailptr)
+{
+ /* tcc.flat.c never reaches strtod under our defines (HAVE_FLOAT off),
+ * and stdlib/strtof.c only forwards. cc.scm rejects FP literals, so
+ * we cast a zero int — same numeric value, no `0.0` token. */
+ if (tailptr)
+ *tailptr = (char *) string;
+ return (double) 0;
+}
diff --git a/vendor/mes-libc/lispcc-syscall.c b/vendor/mes-libc/lispcc-syscall.c
@@ -1,260 +0,0 @@
-/* lispcc-syscall.c — replaces mes's per-arch inline-asm syscall wrappers
- * with C wrappers that call P1pp's labelled syscall entry points.
- *
- * The P1pp labels (sys_read / sys_write / sys_open / sys_close /
- * sys_lseek / sys_brk / sys_unlink / sys_exit) are defined in
- * P1/P1pp.P1pp and resolved at the linker stage thanks to cc.scm's
- * external-linkage rule (commit 6488cca).
- *
- * Layering:
- * public libc (read, write, open, …) — comes from the posix layer
- * └─ low-level _read, _write, _open3 — provided here
- * └─ named sys_* labels — provided by P1pp.P1pp
- *
- * mes's linux/{brk,close,lseek,_open3,_read,unlink}.c are NOT vendored;
- * the equivalents live here and bypass mes's _sys_callN indirection.
- * mes's linux/<arch>-mes-{mescc,gcc}/{syscall,_exit,_write,…}.c are
- * also unused — those are the inline-asm files we replace.
- */
-
-#include <mes/lib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-/* mes's <stdio.h> defines stdin/stdout/stderr as macros expanding to
- * (FILE*)0/1/2. That works for libc's own .c files, but client code
- * (cc-libc tests, eventually tcc-boot2's compiled output) that uses
- * `extern FILE *stdout;` needs a real linkage symbol. Drop the macros
- * after libc's headers have set their guards, then define globals
- * with the same initializer values. mes's libc bodies that already
- * referenced `stdout` had the macro substitution happen on their
- * #include path; subsequent .c files re-include <stdio.h> but hit
- * the include guard and so see the now-undef'd identifiers, which
- * resolve to our globals at link time (same numeric value, same fd). */
-#undef stdin
-#undef stdout
-#undef stderr
-FILE *stdin = (FILE *) 0;
-FILE *stdout = (FILE *) 1;
-FILE *stderr = (FILE *) 2;
-
-/* `__stdout` and friends (the int-typed fd globals oputs / fdputs read)
- * are file-scope initialized in mes/mes_open.c — but that initializer
- * is gated behind `#if SYSTEM_LIBC`, which we don't define. Without
- * SYSTEM_LIBC we'd be left with only mes/globals.c's tentative
- * `int __stdout;`, which zero-inits — meaning oputs("ok") writes to
- * fd 0 (read-only stdin) and silently no-ops. unified-libc.c includes
- * lispcc-syscall.c before globals.c, so cc.scm's redecl-merge sees
- * the proper definition first and absorbs the later tentative. */
-int __stdin = 0;
-int __stdout = 1;
-int __stderr = 2;
-
-extern long sys_read (long fd, long buf, long n);
-extern long sys_write (long fd, long buf, long n);
-extern long sys_open (long path, long flags, long mode);
-extern long sys_close (long fd);
-extern long sys_lseek (long fd, long off, long whence);
-extern long sys_brk (long addr);
-extern long sys_unlink (long path);
-extern long sys_exit (long code);
-
-/* mes/globals.c already provides `int errno;` and the FILE-helper
- * indirections (__buffered_read_clear, __ungetc_clear, __ungetc_init).
- * mes/__buffered_read.c and mes/fdgetc.c implement them. */
-
-ssize_t
-_read (int filedes, void *buffer, size_t size)
-{
- return sys_read (filedes, (long) buffer, (long) size);
-}
-
-ssize_t
-_write (int filedes, void const *buffer, size_t size)
-{
- return sys_write (filedes, (long) buffer, (long) size);
-}
-
-int
-_open3 (char const *file_name, int flags, int mask)
-{
- int r = sys_open ((long) file_name, flags, mask);
- __ungetc_init ();
- if (r > 2)
- {
- if (r >= __FILEDES_MAX)
- {
- errno = EMFILE;
- return -1;
- }
- __ungetc_clear (r);
- __buffered_read_clear (r);
- }
- return r;
-}
-
-int
-close (int filedes)
-{
- long r = sys_close (filedes);
- if (r < 0)
- {
- errno = -r;
- return -1;
- }
- errno = 0;
- return (int) r;
-}
-
-off_t
-_lseek (int filedes, off_t offset, int whence)
-{
- return sys_lseek (filedes, offset, whence);
-}
-
-off_t
-lseek (int filedes, off_t offset, int whence)
-{
- /* mirrors mes's linux/lseek.c: drain the per-fd read buffer before
- * letting the kernel see a positional move; SEEK_CUR offsets must
- * back out the buffered-but-not-yet-consumed bytes. */
- size_t skip = __buffered_read_clear (filedes);
- if (whence == SEEK_CUR)
- offset -= skip;
- return sys_lseek (filedes, offset, whence);
-}
-
-long
-brk (void *addr)
-{
- return sys_brk ((long) addr);
-}
-
-int
-unlink (char const *file_name)
-{
- long r = sys_unlink ((long) file_name);
- if (r < 0)
- {
- errno = -r;
- return -1;
- }
- errno = 0;
- return 0;
-}
-
-void
-_exit (int status)
-{
- sys_exit (status);
-}
-
-/* Linux aarch64/amd64/riscv64 stack at exec entry:
- * [sp] = argc
- * [sp + 8 * (1)] = argv[0]
- * ...
- * [sp + 8 * (argc+1)] = NULL (terminates argv)
- * [sp + 8 * (argc+2)] = envp[0]
- * Our :_start passes (a0=argc, a1=argv) to :p1_main. envp follows
- * argv's NULL terminator, so we compute it from argv. tcc's getenv
- * walks the resulting environ; without initialization it dereferences
- * NULL on the first call and segfaults during tcc_new(). */
-extern char **environ;
-
-void
-__libc_init (int argc, char **argv)
-{
- (void) argc;
- char **p = argv;
- while (*p)
- p++;
- environ = p + 1;
-}
-
-/* ---- ENOSYS stubs for libc-internal references not exercised by ----
- * tcc-boot2's golden path. The mes libc transitively pulls these in
- * (posix/getcwd.c → _getcwd, posix/execvp.c → execve, stdlib/abort.c
- * → raise, …). Providing -ENOSYS stubs keeps the link clean; if any
- * of these surfaces in a real workload, replace the stub with a P1pp
- * label and a thin wrapper above. */
-
-#define ENOSYS 38
-
-char *
-_getcwd (char *buffer, size_t size)
-{
- (void) buffer; (void) size;
- errno = ENOSYS;
- return 0;
-}
-
-int
-access (char const *path, int mode)
-{
- (void) path; (void) mode;
- errno = ENOSYS;
- return -1;
-}
-
-void
-assert_msg (int check, char *msg)
-{
- if (!check)
- {
- sys_write (2, (long) msg, 0);
- sys_exit (1);
- }
-}
-
-int
-execve (char const *file, char *const argv[], char *const envp[])
-{
- (void) file; (void) argv; (void) envp;
- errno = ENOSYS;
- return -1;
-}
-
-int
-fsync (int filedes)
-{
- (void) filedes;
- return 0;
-}
-
-int
-raise (int sig)
-{
- /* abort() calls raise(SIGABRT); take that as a hard exit. */
- sys_exit (128 + sig);
- return -1;
-}
-
-int
-rmdir (char const *file_name)
-{
- (void) file_name;
- errno = ENOSYS;
- return -1;
-}
-
-int
-stat (char const *file_name, struct stat *buf)
-{
- (void) file_name; (void) buf;
- errno = ENOSYS;
- return -1;
-}
-
-double
-strtod (char const *string, char **tailptr)
-{
- /* tcc.flat.c never reaches strtod under our defines (HAVE_FLOAT off),
- * and stdlib/strtof.c only forwards. cc.scm rejects FP literals, so
- * we cast a zero int — same numeric value, no `0.0` token. */
- if (tailptr)
- *tailptr = (char *) string;
- return (double) 0;
-}
diff --git a/vendor/mes-libc/patches/ntoab-inline-defined.after b/vendor/mes-libc/patches/ntoab-inline-defined.after
@@ -1,4 +1,4 @@
-/* lispcc: drop the helper macro — wrapping `defined()` in a #define body
+/* boot2: drop the helper macro — wrapping `defined()` in a #define body
* is UB per ISO C and triggers -Wexpansion-to-defined. The mes author's
* FIXME comment already had the inlined form; we just promote it. */
#if __M2__ || (!defined (__MESC__and__arm__) && !defined (__TINYC__and__arm__and__BOOTSTRAP))
diff --git a/vendor/mes-libc/unified-libc.c b/vendor/mes-libc/unified-libc.c
@@ -1,9 +1,9 @@
/* unified-libc.c — single translation unit gathering every vendored
- * mes-libc .c plus lispcc-syscall.c. The host preprocessor flattens
+ * mes-libc .c plus boot2-syscall.c. The host preprocessor flattens
* the whole thing to libc.flat.c, which cc.scm compiles to libc.P1pp.
*
* Order matters in a few specific places:
- * 1. lispcc-syscall.c declares the extern sys_* P1pp labels and
+ * 1. boot2-syscall.c declares the extern sys_* P1pp labels and
* defines _read / _write / _open3 / close / lseek / brk / unlink /
* _exit. It comes early so later layers see the prototypes.
* 2. mes/globals.c defines errno / __stdin etc. as tentative
@@ -20,7 +20,7 @@
#include <mes/lib.h>
/* ---- low-level: P1pp syscall wrappers + thin posix glue --------- */
-#include "lispcc-syscall.c"
+#include "boot2-syscall.c"
/* ---- ctype ------------------------------------------------------ */
#include "ctype/isalnum.c"
@@ -107,7 +107,7 @@
#include "stdlib/strtoul.c"
#include "stdlib/strtoull.c"
-/* ---- linux (allocator only; the rest replaced by lispcc-syscall.c) */
+/* ---- linux (allocator only; the rest replaced by boot2-syscall.c) */
#include "linux/malloc.c"
/* ---- posix ------------------------------------------------------ */