boot2

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

boot4.sh (5854B)


      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 three-binary chain: tcc0 → tcc1 → tcc2. The bootstrap fixed-point
      6 ## check is `tcc1 == tcc2`: tcc0 ≠ tcc1 because cc.scm and tcc emit
      7 ## different — but both correct — code from the same source, but once tcc
      8 ## is compiling itself the output is byte-identical. Stages C and D use
      9 ## the same archive-based link line, so tcc0(tcc.c) and tcc1(tcc.c)
     10 ## differ only where tcc0's runtime behavior differs from tcc1's — so the
     11 ## check doubles as a proof that cc.scm compiled tcc.c faithfully.
     12 ##
     13 ##   tcc0 = tcc-source compiled by cc.scm        ← boot3
     14 ##   tcc1 = tcc-source compiled by tcc0          ← produced here
     15 ##   tcc2 = tcc-source compiled by tcc1          ← produced here
     16 ##
     17 ## ─── Inputs (sources, from canonical tree) ───────────────────────────
     18 ##   build/$ARCH/src/src/tcc/libc/$ARCH/{start.S, sys_stubs.S}
     19 ##   build/$ARCH/src/src/tcc/cc/mem.c
     20 ##   build/$ARCH/src/src/tcc/tcc-0.9.26-1147-gee75a10c/lib/<arch-specific>
     21 ##   build/$ARCH/src/src/tcc/tcc.flat.c
     22 ##   build/$ARCH/src/src/libc/libc.flat.c
     23 ##   build/$ARCH/src/src/test-fixtures/boot-hello.c
     24 ##
     25 ## ─── Inputs (binaries from prior stages) ──────────────────────────────
     26 ##   build/$ARCH/$DRIVER/boot3/tcc0
     27 ##   build/$ARCH/$DRIVER/boot2/{catm, scheme1}
     28 ##
     29 ## ─── Tools ────────────────────────────────────────────────────────────
     30 ##   scheme1 evaluates the prep-time run.scm at
     31 ##   build/$ARCH/src/run/boot4.scm (generated by
     32 ##   bootprep/boot4-gen-runscm.sh) against the flat staging root. Every arch has CONFIG_TCC_ASM and
     33 ##   assembles .S inputs (start.S, sys_stubs.S) directly inside the
     34 ##   container; no host asm step. The aarch64 assembler is the phase-1
     35 ##   arm64-asm.c that flatten patches into tcc-0.9.26 (see
     36 ##   bootprep/stage1-flatten.sh, around the arm64-asm patch block).
     37 ##
     38 ## ─── Outputs ──────────────────────────────────────────────────────────
     39 ##   build/$ARCH/$DRIVER/boot4/{tcc1, tcc2}
     40 ##                           tcc1 and tcc2 are byte-identical (asserted
     41 ##                           below) — that equality is the fixed-point.
     42 ##   build/$ARCH/$DRIVER/boot4/crt1.o
     43 ##                           tcc1-built startup object, kept outside
     44 ##                           libc.a because it must lead link lines.
     45 ##   build/$ARCH/$DRIVER/boot4/libc.a
     46 ##                           tcc1-built archive of sys_stubs.o + mem.o
     47 ##                           + libc.o
     48 ##   build/$ARCH/$DRIVER/boot4/libtcc1.a
     49 ##                           tcc1-built tcc compiler helper archive
     50 ##   build/$ARCH/$DRIVER/boot4/hello — mes-libc-linked smoke binary
     51 ##
     52 ## Usage: boot/boot4.sh <arch>
     53 ##   <arch> ∈ {aarch64, amd64, riscv64} for either DRIVER (default podman).
     54 
     55 set -eu
     56 
     57 . boot/lib-arch.sh
     58 bootlib_init boot4 "${1:-}"
     59 driver_init empty
     60 require_src
     61 
     62 case "$ARCH" in
     63     aarch64) LIBTCC1_C_SRCS="lib-arm64.c";              LIBTCC1_ASM_SRCS="" ;;
     64     amd64)   LIBTCC1_C_SRCS="libtcc1.c va_list.c";      LIBTCC1_ASM_SRCS="alloca86_64.S alloca86_64-bt.S" ;;
     65     riscv64) LIBTCC1_C_SRCS="lib-arm64.c";              LIBTCC1_ASM_SRCS="" ;;
     66 esac
     67 
     68 BOOT2=build/$ARCH/$DRIVER/boot2
     69 BOOT3=build/$ARCH/$DRIVER/boot3
     70 SRC=build/$ARCH/src
     71 
     72 TCC_PKG=tcc-0.9.26-1147-gee75a10c
     73 TCC_LIB_REL=tcc/$TCC_PKG/lib
     74 
     75 # ── prerequisites ─────────────────────────────────────────────────────
     76 require_prev "$BOOT3" tcc0
     77 require_prev "$BOOT2" catm scheme1
     78 for f in $LIBTCC1_C_SRCS $LIBTCC1_ASM_SRCS; do
     79     require_file "$SRC/src/$TCC_LIB_REL/$f"
     80 done
     81 
     82 # ── stage inputs and run scheme1 + boot4 run.scm under $DRIVER ────────
     83 . boot/lib-runscm.sh
     84 runscm_init "$STAGE" "$OUT"
     85 runscm_runscm "$SRC/run/boot4.scm"
     86 
     87 runscm_scheme1 "$BOOT2/scheme1"
     88 runscm_prelude "$SRC/src/scheme1/prelude.scm"
     89 
     90 runscm_input tcc0           "$BOOT3/tcc0"
     91 runscm_input catm           "$BOOT2/catm"
     92 
     93 runscm_input_from_src "tcc/libc/$ARCH/start.S"
     94 runscm_input_from_src "tcc/libc/$ARCH/sys_stubs.S"
     95 runscm_input_from_src tcc/cc/mem.c
     96 for f in $LIBTCC1_C_SRCS $LIBTCC1_ASM_SRCS; do
     97     runscm_input_from_src "$TCC_LIB_REL/$f"
     98 done
     99 
    100 runscm_input_from_src tcc/tcc.flat.c
    101 runscm_input_from_src libc/libc.flat.c
    102 runscm_input_from_src test-fixtures/boot-hello.c hello.c
    103 
    104 runscm_export tcc1 tcc2 s2-crt1.o s2-libc.a s2-libtcc1.a hello
    105 runscm_run "${BOOT4_TIMEOUT:-5400}"
    106 
    107 # ── fixed-point check (host-side) ─────────────────────────────────────
    108 if ! cmp -s "$OUT/tcc1" "$OUT/tcc2"; then
    109     s1=$(wc -c <"$OUT/tcc1")
    110     s2=$(wc -c <"$OUT/tcc2")
    111     echo "[$BOOT_TAG] FIXED-POINT FAIL: tcc1 ($s1) != tcc2 ($s2)" >&2
    112     exit 1
    113 fi
    114 
    115 # ── normalize output names (drop s2- prefix) ──────────────────────────
    116 # tcc1 / tcc2 are kept on disk: the test path (tcc-cc / tcc-libc suites)
    117 # uses them as stage-2 / stage-3 self-built tcc binaries.
    118 mv "$OUT/s2-crt1.o"    "$OUT/crt1.o"
    119 mv "$OUT/s2-libc.a"    "$OUT/libc.a"
    120 mv "$OUT/s2-libtcc1.a" "$OUT/libtcc1.a"
    121 chmod 0700 "$OUT/tcc1" "$OUT/tcc2" "$OUT/hello"
    122 
    123 echo "[$BOOT_TAG] sizes: libtcc1.a=$(wc -c <"$OUT/libtcc1.a") libc.a=$(wc -c <"$OUT/libc.a") hello=$(wc -c <"$OUT/hello")"
    124 echo "[$BOOT_TAG] OK -> $OUT/{tcc2, crt1.o, libc.a, libtcc1.a, hello} (fixed point: tcc1 == tcc2)"