do not edit — generated by btf.
git.druid.rocksindexdruid520kaboommk/bu.sh

mk/bu.sh


#!/bin/sh
# builds every userspace program under src/user/ into a trimmed,
# ready-to-place-in-kfs elf binary at $out/user/<name> -- disk-image
# building is now a separate step, mk/bd.sh (`mk . bd`), so a fresh
# binary sitting in $out/user can be inspected/tested standalone before
# it's baked onto a disk image. every program links against user.ld
# (0x400000) -- now that each process gets its own real address space
# (vmm.nsc), there's no reason for sh to need a different address from
# anything it runs. src/user/lib.nsc, mem.nsc, string.nsc, ctype.nsc, malloc.nsc,
# stdio.nsc, and crt.s are shared support (the userspace libc), not
# programs of their own, and are compiled once below rather than in
# the program loop -- nsc has no #include-and-compile-together model,
# but nothing stops sharing compiled objects across multiple final
# links. lib.o is linked into every program unconditionally (always
# has been); the newer modules (mem/string/ctype/malloc/stdio) are
# opt-in PER PROGRAM based on which of their own ".nsh" headers a
# program actually includes -- linking all of them into everything
# unconditionally was tried first and measured to add ~19kb of dead
# code to every single binary, which pushed ed over disk.pl's binary
# size cap for zero benefit to programs that never call any of it.
. ./mk.conf
set -e
 
userdir="$src/user"
outdir="$out/user"
mkdir -p "$outdir"
 
libmods="lib mem string ctype malloc stdio"
optmods="mem string ctype malloc stdio"
for mod in $libmods; do
	"$nscc" "$userdir/$mod.nsc" -o "$outdir/$mod.s"
	"$as" $asflgs "$outdir/$mod.s" -o "$outdir/$mod.o"
done
"$as" $asflgs "$userdir/crt.s" -o "$outdir/crt.o"
 
for prog in "$userdir"/*.nsc; do
	name=$(basename "$prog" .nsc)
	skip=0
	for mod in $libmods; do
		[ "$name" = "$mod" ] && skip=1
	done
	[ "$skip" = 1 ] && continue
 
	"$nscc" "$prog" -o "$outdir/$name.s"
	"$as" $asflgs "$outdir/$name.s" -o "$outdir/$name.o"
 
	# which optional libc modules does this program actually pull in
	# (by its own "X.nsh" includes), plus each module's own one-level
	# object dependency -- string.nsc and stdio.nsc both call mem.nsc's
	# functions, so their object needs mem.o on the link line too even
	# for a program that never includes mem.nsh itself directly.
	wanted=""
	for mod in $optmods; do
		if grep -q "\"$mod\.nsh\"" "$prog"; then
			wanted="$wanted $mod"
		fi
	done
	case " $wanted " in
		*" string "*|*" stdio "*)
			case " $wanted " in
				*" mem "*) ;;
				*) wanted="$wanted mem" ;;
			esac
			;;
	esac
 
	libobjs="$outdir/lib.o"
	for mod in $optmods; do
		case " $wanted " in
			*" $mod "*) libobjs="$libobjs $outdir/$mod.o" ;;
		esac
	done
 
	ldscript="$userdir/user.ld"
 
	# plain flags here, not $ldflgs (the kernel's strict set). NOT -n
	# any more: user.ld now defines two explicit
	# PT_LOAD segments (R+X, R+W) via PHDRS instead of relying on -n's
	# single-combined-segment behavior, which is what was triggering
	# ld's "RWX permissions" warning on every single userspace binary
	# (a real one, not cosmetic -- an actual OS with paging enforces
	# exactly what that warning is about; this kernel doesn't yet, but
	# there's no reason to keep shipping executable+writable segments
	# once splitting them costs nothing). -z max-page-size/
	# common-page-size are set far below the real 4096 specifically
	# because splitting into two segments would otherwise cost up to
	# ~4095 padding bytes per boundary to satisfy real page alignment
	# that this loader (src/kernel/elf.nsc) has no actual use for --
	# see user.ld's own comment for the full reasoning.
	"$ld" --build-id=none -z max-page-size=16 -z common-page-size=16 -T "$ldscript" -o "$outdir/$name.elf.full" \
		"$outdir/$name.o" $libobjs "$outdir/crt.o"
	strip -s "$outdir/$name.elf.full" -o "$outdir/$name.elf.stripped"
	perl mk/trim-elf.pl "$outdir/$name.elf.stripped" "$outdir/$name.elf"
	rm -f "$outdir/$name.elf.full" "$outdir/$name.elf.stripped"
done
 
echo "built userspace programs in $outdir"
powered by btf.