boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

boot4.sh (6400B)


      1 #!/bin/sh
      2 ## boot4.sh — self-host tcc rebuild stages on top of boot3's tcc0.
      3 ##
      4 ## boot3 produced tcc0 (cc.scm-built bootstrap). boot4 runs the rest of
      5 ## the four-stage chain: tcc0 → tcc1 → tcc2 → tcc3. The bootstrap
      6 ## fixed-point check is `tcc2 == tcc3`: once tcc is compiling itself
      7 ## with no help from cc.scm, the chain reaches a byte-identical fixed
      8 ## point. (See docs/PLAN.md for the cc.scm vs tcc codegen-divergence
      9 ## reasoning behind needing four stages rather than two.)
     10 ##
     11 ##   tcc0 = tcc-source compiled by cc.scm        ← boot3
     12 ##   tcc1 = tcc-source compiled by tcc0          ← produced here
     13 ##   tcc2 = tcc-source compiled by tcc1          ← produced here
     14 ##   tcc3 = tcc-source compiled by tcc2          ← produced here
     15 ##
     16 ## ─── Inputs (sources, from canonical tree) ───────────────────────────
     17 ##   build/$ARCH/src/src/tcc-libc/$ARCH/{start.S, sys_stubs.S}
     18 ##   build/$ARCH/src/src/tcc-cc/mem.c
     19 ##   build/$ARCH/src/src/tcc/tcc-0.9.26-1147-gee75a10c/lib/<arch-specific>
     20 ##   build/$ARCH/src/src/tcc/tcc.flat.c
     21 ##   build/$ARCH/src/src/libc/libc.flat.c
     22 ##   build/$ARCH/src/src/test-fixtures/boot-hello.c
     23 ##
     24 ## ─── Inputs (binaries from prior stages) ──────────────────────────────
     25 ##   build/$ARCH/$DRIVER/boot3/tcc0
     26 ##   build/$ARCH/$DRIVER/boot2/{catm, scheme1}
     27 ##
     28 ## ─── Tools ────────────────────────────────────────────────────────────
     29 ##   scheme1 evaluates a host-generated run.scm (from boot4-gen-runscm.sh)
     30 ##   against the flat staging root. Every arch has CONFIG_TCC_ASM and
     31 ##   assembles .S inputs (start.S, sys_stubs.S) directly inside the
     32 ##   container; no host asm step. The aarch64 assembler is the phase-1
     33 ##   arm64-asm.c that flatten patches into tcc-0.9.26 (see
     34 ##   docs/TCC-ARM64-ASM.md).
     35 ##
     36 ## ─── Outputs ──────────────────────────────────────────────────────────
     37 ##   build/$ARCH/$DRIVER/boot4/{tcc1, tcc2, tcc3}
     38 ##                           tcc2 and tcc3 are byte-identical (asserted
     39 ##                           below) — that equality is the fixed-point.
     40 ##   build/$ARCH/$DRIVER/boot4/crt1.o
     41 ##                           tcc2-built startup object, kept outside
     42 ##                           libc.a because it must lead link lines.
     43 ##   build/$ARCH/$DRIVER/boot4/libc.a
     44 ##                           tcc2-built archive of sys_stubs.o + mem.o
     45 ##                           + libc.o
     46 ##   build/$ARCH/$DRIVER/boot4/libtcc1.a
     47 ##                           tcc2-built tcc compiler helper archive
     48 ##   build/$ARCH/$DRIVER/boot4/hello — mes-libc-linked smoke binary
     49 ##
     50 ## ─── Env knobs ────────────────────────────────────────────────────────
     51 ##   TCC_BOOTSTRAP_RELAX_FIXEDPOINT=1
     52 ##       After a codegen-altering tcc patch, the two-stage rule needs a
     53 ##       third bounce to converge. Set this to accept tcc3 even when
     54 ##       tcc2 != tcc3; the next boot4 run, started from this run's
     55 ##       tcc3, will reach tcc2 == tcc3 with no extra knob.
     56 ##
     57 ## Usage: scripts/boot4.sh <arch>
     58 ##   <arch> ∈ {aarch64, amd64, riscv64} for either DRIVER (default podman).
     59 
     60 set -eu
     61 
     62 . scripts/lib-arch.sh
     63 bootlib_init boot4 "${1:-}"
     64 driver_init empty
     65 require_src
     66 
     67 case "$ARCH" in
     68     aarch64) LIBTCC1_C_SRCS="lib-arm64.c";              LIBTCC1_ASM_SRCS="" ;;
     69     amd64)   LIBTCC1_C_SRCS="libtcc1.c va_list.c";      LIBTCC1_ASM_SRCS="alloca86_64.S alloca86_64-bt.S" ;;
     70     riscv64) LIBTCC1_C_SRCS="lib-arm64.c";              LIBTCC1_ASM_SRCS="" ;;
     71 esac
     72 
     73 BOOT2=build/$ARCH/$DRIVER/boot2
     74 BOOT3=build/$ARCH/$DRIVER/boot3
     75 SRC=build/$ARCH/src
     76 
     77 TCC_PKG=tcc-0.9.26-1147-gee75a10c
     78 TCC_LIB_REL=tcc/$TCC_PKG/lib
     79 
     80 # ── prerequisites ─────────────────────────────────────────────────────
     81 require_prev "$BOOT3" tcc0
     82 require_prev "$BOOT2" catm scheme1
     83 for f in $LIBTCC1_C_SRCS $LIBTCC1_ASM_SRCS; do
     84     require_file "$SRC/src/$TCC_LIB_REL/$f"
     85 done
     86 
     87 # ── stage inputs and run scheme1 + boot4 run.scm under $DRIVER ────────
     88 . scripts/lib-runscm.sh
     89 runscm_init "$STAGE" "$OUT"
     90 runscm_gen scripts/boot4-gen-runscm.sh "$ARCH"
     91 
     92 runscm_scheme1 "$BOOT2/scheme1"
     93 runscm_prelude "$SRC/src/scheme1/prelude.scm"
     94 
     95 runscm_input tcc0           "$BOOT3/tcc0"
     96 runscm_input catm           "$BOOT2/catm"
     97 
     98 runscm_input_from_src "tcc-libc/$ARCH/start.S"
     99 runscm_input_from_src "tcc-libc/$ARCH/sys_stubs.S"
    100 runscm_input_from_src tcc-cc/mem.c
    101 for f in $LIBTCC1_C_SRCS $LIBTCC1_ASM_SRCS; do
    102     runscm_input_from_src "$TCC_LIB_REL/$f"
    103 done
    104 
    105 runscm_input_from_src tcc/tcc.flat.c
    106 runscm_input_from_src libc/libc.flat.c
    107 runscm_input_from_src test-fixtures/boot-hello.c hello.c
    108 
    109 runscm_export tcc1 tcc2 tcc3 s3-crt1.o s3-libc.a s3-libtcc1.a hello
    110 runscm_run "${BOOT4_TIMEOUT:-5400}"
    111 
    112 # ── fixed-point check (host-side) ─────────────────────────────────────
    113 if ! cmp -s "$OUT/tcc2" "$OUT/tcc3"; then
    114     s2=$(wc -c <"$OUT/tcc2")
    115     s3=$(wc -c <"$OUT/tcc3")
    116     if [ "${TCC_BOOTSTRAP_RELAX_FIXEDPOINT:-0}" = 1 ]; then
    117         echo "[$BOOT_TAG] WARN: tcc2 ($s2) != tcc3 ($s3); TCC_BOOTSTRAP_RELAX_FIXEDPOINT=1, accepting tcc3" >&2
    118     else
    119         echo "[$BOOT_TAG] FIXED-POINT FAIL: tcc2 ($s2) != tcc3 ($s3)" >&2
    120         exit 1
    121     fi
    122 fi
    123 
    124 # ── normalize output names (drop s3- prefix) ──────────────────────────
    125 # tcc1 / tcc2 are kept on disk: the test path (tcc-cc / tcc-libc suites)
    126 # uses them as stage-2 / stage-3 self-built tcc binaries.
    127 mv "$OUT/s3-crt1.o"    "$OUT/crt1.o"
    128 mv "$OUT/s3-libc.a"    "$OUT/libc.a"
    129 mv "$OUT/s3-libtcc1.a" "$OUT/libtcc1.a"
    130 chmod 0700 "$OUT/tcc1" "$OUT/tcc2" "$OUT/tcc3" "$OUT/hello"
    131 
    132 echo "[$BOOT_TAG] sizes: libtcc1.a=$(wc -c <"$OUT/libtcc1.a") libc.a=$(wc -c <"$OUT/libc.a") hello=$(wc -c <"$OUT/hello")"
    133 echo "[$BOOT_TAG] OK -> $OUT/{tcc3, crt1.o, libc.a, libtcc1.a, hello} (fixed point: tcc2 == tcc3)"