boot2

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

build-p1pp.sh (5151B)


      1 #!/bin/sh
      2 ## tests/build-p1pp.sh — in-container .P1pp -> ELF via the new chain.
      3 ##
      4 ## Pure transformation. Caller (the Makefile) ensures every fixed-path
      5 ## input below already exists, including the per-arch self-hosted M1pp
      6 ## ELF binary (build/$ARCH/podman/boot1/M1pp) and hex2pp ELF binary
      7 ## (build/$ARCH/podman/boot1/hex2pp). Both of those are built once via
      8 ## the seed M0+hex2 chain inside the bootN pipeline; after that point
      9 ## the seed tools no longer participate in any user/test pipeline.
     10 ##
     11 ## Pipeline (new chain — no M0/hex2 anywhere):
     12 ##   cat <P1-$ARCH.M1pp> <P1.M1pp> <P1pp.P1pp> <srcs...> -> /tmp/combined.M1pp
     13 ##   M1pp   /tmp/combined.M1pp                            -> /tmp/expanded.hex2pp
     14 ##   cat $ELF_HDR /tmp/expanded.hex2pp                    -> /tmp/linked.hex2pp
     15 ##   hex2pp /tmp/linked.hex2pp $OUT
     16 ##
     17 ## $ELF_HDR is vendor/seed/$ARCH/ELF.hex2, which supplies the
     18 ## :ELF_base / :_start / :ELF_end framing. hex2pp accepts the hex2
     19 ## `LABEL>OTHER` subtraction syntax as a synonym for its own
     20 ## `LABEL-OTHER`, so the vendor headers assemble unchanged.
     21 ##
     22 ## libp1pp (P1/P1pp.P1pp) is concatenated unconditionally so portable
     23 ## sources can use %fn, the control-flow macros, and libp1pp routines
     24 ## (sys_*, print*, parse_*, fmt_*, memcpy/memcmp, bump allocator, panic,
     25 ## %assert_*) without per-program plumbing. hex2pp has no link-time DCE,
     26 ## so programs that don't reference any libp1pp routine still pay a
     27 ## fixed code-size tax (~a few KB).
     28 ##
     29 ## Multiple <srcs> are concatenated in the order given. This is how
     30 ## libc-using executables compose: a typical chain is
     31 ##   P1/entry-libc.P1pp  build/$ARCH/podman/boot3/libc.P1pp  client.P1pp  P1/elf-end.P1pp
     32 ## with libc.P1pp / client.P1pp produced by cc.scm --lib=PFX so they
     33 ## omit the entry stub and trailing :ELF_end (those come from the
     34 ## fixed fragments instead). For a single-TU exec, pass exactly one
     35 ## source built without --lib= and the fragments are unnecessary.
     36 ##
     37 ## Per-call intermediates land at build/$ARCH/.work/<work-subpath>/.
     38 ## <work-subpath> defaults to the first src's path with extension
     39 ## stripped — fine for single-source builds (scheme1, p1 tests). For
     40 ## catm chains where the first src is a wrapper (e.g. P1/entry-libc.P1pp
     41 ## or a generated build/.../*.P1pp), the caller MUST set WORK_SUBPATH
     42 ## explicitly so the work dir mirrors the logical primary source path
     43 ## (e.g. tests/cc-libc/000-exit). A one-line sidecar at <out>.workdir
     44 ## records the resolved work dir so tooling (tools/disasm-elf.sh) can
     45 ## locate the artifacts from the binary alone.
     46 ##
     47 ## Env: ARCH=aarch64|amd64|riscv64
     48 ##      WORK_SUBPATH=<repo-relative-path-without-ext> — overrides the
     49 ##                    work-dir name; required when the first src isn't
     50 ##                    the logical primary source.
     51 ## Usage: tests/build-p1pp.sh <out> <srcs...>
     52 
     53 set -eu
     54 
     55 # Per-stage tracing is always on. M1pp / hex2pp print little on success
     56 # and bail fast on error, so we narrate which step is running, snapshot
     57 # intermediates to $WORK before exiting, and print a clear FAIL banner
     58 # on error so the user knows where it died.
     59 ARCH_LBL=${ARCH:-?}
     60 CURRENT_STEP=
     61 trap 'rc=$?
     62 if [ "$rc" -ne 0 ] && [ -n "$CURRENT_STEP" ]; then
     63     echo "[p1pp $ARCH_LBL] FAIL at: $CURRENT_STEP (exit $rc)" >&2
     64     if [ -n "${WORK:-}" ]; then
     65         echo "[p1pp $ARCH_LBL] partial intermediates in $WORK" >&2
     66     fi
     67 fi' EXIT
     68 
     69 trace() {
     70     label=$1; path=$2
     71     sz=$(wc -c < "$path" 2>/dev/null || echo "?")
     72     printf '[p1pp %s] %s (%s bytes) %s\n' "$ARCH_LBL" "$label" "$sz" "$path" >&2
     73 }
     74 
     75 step() {
     76     CURRENT_STEP=$1
     77     printf '[p1pp %s] >> %s\n' "$ARCH_LBL" "$CURRENT_STEP" >&2
     78 }
     79 
     80 : "${ARCH:?ARCH must be set}"
     81 [ "$#" -ge 2 ] || { echo "usage: ARCH=<arch> $0 <out> <srcs...>" >&2; exit 2; }
     82 
     83 OUT=$1
     84 shift
     85 
     86 BACKEND=P1/P1-$ARCH.M1pp
     87 FRONTEND=P1/P1.M1pp
     88 LIBP1PP=P1/P1pp.P1pp
     89 ELF_HDR=vendor/seed/$ARCH/ELF.hex2
     90 M1PP_BIN=build/$ARCH/podman/boot1/M1pp
     91 HEX2PP_BIN=build/$ARCH/podman/boot1/hex2pp
     92 if [ -n "${WORK_SUBPATH:-}" ]; then
     93     NAME=$WORK_SUBPATH
     94 else
     95     NAME=${1%.*}
     96 fi
     97 WORK=build/$ARCH/.work/$NAME
     98 mkdir -p "$WORK" "$(dirname "$OUT")"
     99 
    100 # Snapshot each intermediate to $WORK as soon as it's produced, so a
    101 # failure leaves the most-recent good artifact on disk for triage. With
    102 # the trap above, the user sees both the failing stage and where to
    103 # look.
    104 step "cat: combined.M1pp <- backend + frontend + libp1pp + $#"
    105 cat "$BACKEND" "$FRONTEND" "$LIBP1PP" "$@" > /tmp/combined.M1pp
    106 cp /tmp/combined.M1pp "$WORK/combined.M1pp"
    107 trace "combined.M1pp" /tmp/combined.M1pp
    108 
    109 step "M1pp: combined.M1pp -> expanded.hex2pp"
    110 "$M1PP_BIN" /tmp/combined.M1pp /tmp/expanded.hex2pp
    111 cp /tmp/expanded.hex2pp "$WORK/expanded.hex2pp"
    112 trace "expanded.hex2pp" /tmp/expanded.hex2pp
    113 
    114 step "cat: linked.hex2pp <- ELF header + expanded.hex2pp"
    115 cat "$ELF_HDR" /tmp/expanded.hex2pp > /tmp/linked.hex2pp
    116 cp /tmp/linked.hex2pp "$WORK/linked.hex2pp"
    117 trace "linked.hex2pp" /tmp/linked.hex2pp
    118 
    119 step "hex2pp: linked.hex2pp -> $OUT"
    120 "$HEX2PP_BIN" -B 0x600000 /tmp/linked.hex2pp /tmp/prog.bin
    121 cp /tmp/prog.bin "$OUT"
    122 chmod 0700 "$OUT"
    123 trace "$OUT" "$OUT"
    124 
    125 printf '%s\n' "$WORK" > "$OUT.workdir"
    126 CURRENT_STEP=