DF-2318 / extract2.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | #!/bin/sh # extract2.sh -- machine-extract the PRODUCTION pccard.c lifecycle code # (attach/detach card, function init/free/enable/disable, pnpinfo) plus the # PRODUCTION resource_list_* core from kern/subr_bus.c, byte-identical, from # the guest's own /usr/src kernel tree, into include-able .inc files for the # userland verification rig2 (DF-2318 / DF-5355 / DF-5356). # # sha256-gated like DF-2319's extract.sh: # PRISTINE -> sed fixed line-ranges (byte-identical by construction), # cross-checked against the awk function-extractor. # PATCHED -> awk anchor-based function extraction (fixes shift lines), # requires --allow-patched. # # Usage: sh extract2.sh <outdir> [srctree] [--allow-patched] # srctree default /usr/src/sys (use a patched COPY for fix variants) set -eu OUT="${1:-.}" TREE="${2:-/usr/src/sys}" ALLOW="${3:-}" SRC="$TREE/bus/pccard" KBUS=/usr/src/sys/kern/subr_bus.c # never patched in this run; always pristine # Pristine sha256 of the audit tree. P_PCCARD_C=5b61066925991ec0776510142c6280cffca5c94e317a06f480744da3736b8d5e P_CIS_C=acdd2484925fd5f09ab7266fcbb575134ae73e72c20f3e844c236ef0c2c2304c P_VAR_H=3e73a8771c78e6aa9e52c764f1431571b835674ec87aecb4d32575c6dcdb4141 P_CISH=9ed5d42411f363810ead8c9a6fd7e67abda1700504342325bb03fc281c8e0959 P_REG_H=55e55e8a7be4784ed1400c9de2c7dd72455e08b053dda985cb43e2fe2eb80309 P_SUBR_BUS=949f75de6c72fbbd3af7f23caf87aec6d2ed179744a738c6dd73149c1d091824 P_SYSBUS_H=4d01db59f8fe410b299041a33ccbbe08f230e008555f8af4a11fdc9291eea7e0 P_QUEUE=6072482fad8732b5ea0f315ed0fc0acd7abd02c3f8180c0733ea1b8c671d0745 h() { sha256 -r "$1" | awk '{print $1}'; } mkdir -p "$OUT" MAN="$OUT/extract2_manifest.txt" { echo "=== verbatim extraction manifest (rig2: pccard.c lifecycle) ===" date uname -a echo "srctree=$TREE" } > "$MAN" STATE=PRISTINE check() { # name file pristhash got=$(h "$2") if [ "$got" = "$3" ]; then echo "VERBATIM_CHECK $1 PRISTINE $got" | tee -a "$MAN" else echo "VERBATIM_CHECK $1 PATCHED $got (pristine=$3)" | tee -a "$MAN" STATE=PATCHED fi } check pccard.c "$SRC/pccard.c" "$P_PCCARD_C" check pccard_cis.c "$SRC/pccard_cis.c" "$P_CIS_C" check pccardvar.h "$SRC/pccardvar.h" "$P_VAR_H" check pccard_cis.h "$SRC/pccard_cis.h" "$P_CISH" check pccardreg.h "$SRC/pccardreg.h" "$P_REG_H" check subr_bus.c "$KBUS" "$P_SUBR_BUS" check sys/bus.h /usr/src/sys/sys/bus.h "$P_SYSBUS_H" check queue.h /usr/src/sys/sys/queue.h "$P_QUEUE" check queue.h.usrinc /usr/include/sys/queue.h "$P_QUEUE" if [ "$STATE" = PATCHED ] && [ "$ALLOW" != "--allow-patched" ]; then echo "REFUSING: source tree is PATCHED and --allow-patched not given" | tee -a "$MAN" exit 3 fi echo "SOURCE_STATE=$STATE" | tee -a "$MAN" # ---- function extractor: from the type line above '^name(' to the first # ---- '^}' (BSD kernel style: no column-0 braces inside function bodies). ef() { # file name -- emits function text (type line .. closing brace) n=$(grep -nE "^$2\(" "$1" | head -1 | cut -d: -f1) if [ -z "$n" ]; then echo "EXTRACT_FAIL:$2" >&2; exit 4; fi s=$((n - 1)) tl=$(sed -n "${s}p" "$1") case "$tl" in *\;*) echo "EXTRACT_FAIL:$2 type-line is a prototype: $tl" >&2; exit 4 ;; esac awk -v s=$s 'NR>=s { print; if ($0 ~ /^}/) exit }' "$1" echo "$s:$n" >> "$OUT/func_lines.txt" } : > "$OUT/func_lines.txt" # ---- pccard.c functions (verbatim) ------------------------------------- { sed -n '83,90p' "$SRC/pccard.c" # production forward decls ef "$SRC/pccard.c" pccard_ccr_read ef "$SRC/pccard.c" pccard_ccr_write ef "$SRC/pccard.c" pccard_set_default_descr ef "$SRC/pccard.c" pccard_attach_card ef "$SRC/pccard.c" pccard_detach_card ef "$SRC/pccard.c" pccard_function_init ef "$SRC/pccard.c" pccard_function_free ef "$SRC/pccard.c" pccard_mfc_adjust_iobase ef "$SRC/pccard.c" pccard_function_enable ef "$SRC/pccard.c" pccard_function_disable ef "$SRC/pccard.c" pccard_safe_quote ef "$SRC/pccard.c" pccard_child_pnpinfo_str ef "$SRC/pccard.c" pccard_read_ivar } > "$OUT/pccard_core.inc" # debug macros + PCCARDDEBUG define (not functions): if [ "$STATE" = PRISTINE ]; then sed -n '55p;71,81p' "$SRC/pccard.c" > "$OUT/pccard_macros.inc" else awk '/^#define PCCARDDEBUG$/ {print; exit}' "$SRC/pccard.c" > "$OUT/pccard_macros.inc" awk 'f{print; if($0 ~ /^#endif/) exit} /^#ifdef PCCARDDEBUG$/{f=1; print}' \ "$SRC/pccard.c" >> "$OUT/pccard_macros.inc" fi # ---- pccard_cis.c parser (verbatim; same ranges as DF-2319) ------------- if [ "$STATE" = PRISTINE ]; then sed -n '51,444p;612,1294p' "$SRC/pccard_cis.c" > "$OUT/pccard_cis_core.inc" else awk 'f && NR>=b1 && NR<=b2 {print} ' /dev/null 2>/dev/null || true A1=$(grep -n '^extern int pccard_cis_debug;' "$SRC/pccard_cis.c" | cut -d: -f1) A2=$(grep -n '^/\* XXX this is incredibly verbose' "$SRC/pccard_cis.c" | cut -d: -f1) B1=$(grep -n '^pccard_parse_cis_tuple(const struct pccard_tuple \*tuple, void \*arg)$' \ "$SRC/pccard_cis.c" | cut -d: -f1) B1=$((B1 - 1)) B2=$(wc -l < "$SRC/pccard_cis.c") sed -n "${A1},$((A2 - 2))p;${B1},${B2}p" "$SRC/pccard_cis.c" > "$OUT/pccard_cis_core.inc" echo "anchor ranges: ${A1},$((A2-2)) and ${B1},${B2} (patched layout)" >> "$MAN" fi # ---- pccardvar.h struct/macro ranges (verbatim; superset of DF-2319) ---- sed -n '62,70p;74,126p;128,160p;165,203p;213,222p;250,252p;161,163p;255,292p;322,335p;336,367p' \ "$SRC/pccardvar.h" > "$OUT/pccardvar2.inc" # ---- constant headers (whole-file copies) ------------------------------ cp "$SRC/pccard_cis.h" "$OUT/pccard_cis.h" cp "$SRC/pccardreg.h" "$OUT/pccardreg.h" # ---- kern/subr_bus.c resource_list core (verbatim; always pristine) ---- { sed -n '164,186p' /usr/src/sys/sys/bus.h # production prototypes ef "$KBUS" resource_list_init ef "$KBUS" resource_list_free ef "$KBUS" resource_list_add ef "$KBUS" resource_list_find ef "$KBUS" resource_list_delete ef "$KBUS" bus_child_pnpinfo_str } > "$OUT/subrbus_rl.inc" # ---- sys/sys/bus.h resource_list_entry struct (verbatim) ---------------- sed -n '136,146p' /usr/src/sys/sys/bus.h > "$OUT/sysbus_rl.inc" # ---- pristine byte-identity cross-check (sed fixed ranges vs awk) ------ # ranges verified against the pristine audit tree: # pccard.c: 55; 71-81; 150-175; 177-289; 291-326; 407-503; 512-538; # 540-574; 577-698; 701-755; 992-1009; 1011-1026; 1028-1072 # subr_bus.c: 2594-2598; 2600-2611; 2613-2644; 2646-2656; 258-2670 typo-guard; # 2658-2670; 3433-3444 if [ "$STATE" = PRISTINE ]; then sed -n '55p;71,81p;83,90p;134,139p;141,148p;150,175p;177,289p;291,326p;407,503p;512,538p;540,574p;577,698p;701,755p;992,1009p;1011,1026p;1028,1072p' \ "$SRC/pccard.c" > "$OUT/.pc_sedref" sed -n '2594,2598p;2600,2611p;2613,2644p;2646,2656p;2658,2670p;3433,3444p' \ "$KBUS" > "$OUT/.sb_sedref" echo "pccard.c sed-vs-awk byte diff (empty=identical):" >> "$MAN" cat "$OUT/pccard_core.inc" "$OUT/pccard_macros.inc" > "$OUT/.pc_concat" # awk emits functions in listed order; compare sorted content (the sha256 # gate on the pristine source is the primary byte-identity guarantee). sort "$OUT/.pc_concat" > "$OUT/.pc_a" sort "$OUT/.pc_sedref" > "$OUT/.pc_b" if cmp -s "$OUT/.pc_a" "$OUT/.pc_b"; then echo "PCCARD_BYTE_IDENTICAL=yes" | tee -a "$MAN" else echo "PCCARD_BYTE_IDENTICAL=NO (see below)" | tee -a "$MAN" diff "$OUT/.pc_a" "$OUT/.pc_b" | head -20 >> "$MAN" || true fi tail -n +24 "$OUT/subrbus_rl.inc" | sort > "$OUT/.sb_a" # skip proto block sort "$OUT/.sb_sedref" > "$OUT/.sb_b" if cmp -s "$OUT/.sb_a" "$OUT/.sb_b"; then echo "SUBR_BUS_BYTE_IDENTICAL=yes" | tee -a "$MAN" else echo "SUBR_BUS_BYTE_IDENTICAL=NO" | tee -a "$MAN" diff "$OUT/.sb_a" "$OUT/.sb_b" | head -20 >> "$MAN" || true fi rm -f "$OUT/.pc_sedref" "$OUT/.sb_sedref" \ "$OUT/.pc_concat" "$OUT/.pc_a" "$OUT/.pc_b" "$OUT/.sb_a" "$OUT/.sb_b" fi { echo "--- artifacts ---" cat "$OUT/func_lines.txt" | sed 's/^/func_lines /' sha256 -r "$OUT/pccard_core.inc" "$OUT/pccard_macros.inc" \ "$OUT/pccard_cis_core.inc" "$OUT/pccardvar2.inc" \ "$OUT/subrbus_rl.inc" "$OUT/sysbus_rl.inc" \ "$OUT/pccard_cis.h" "$OUT/pccardreg.h" echo "bytes core=$(wc -c < "$OUT/pccard_core.inc") cis=$(wc -c < "$OUT/pccard_cis_core.inc") rl=$(wc -c < "$OUT/subrbus_rl.inc")" } >> "$MAN" echo "EXTRACT2_OK state=$STATE" |