⬢ DragonFlyBSD Kernel Audit
DF-5276 / extract.sh
← back to finding ↓ download raw
#!/bin/sh
# extract.sh -- pull the VPD parser VERBATIM out of the kernel source tree.
#
# Functions are located by content anchors (not fixed line numbers) so the
# extraction works on both the original and the fix.diff-patched tree.
#
# usage: extract.sh <pci.c-path> <pcivar.h-path> <out-header> [kmod]
#   user mode: also extract the pcivar.h VPD structs (vpd_structs.h) and
#              the readonly-lookup method.
#   kmod mode: parser only (kernel modules include the real pcivar.h).
set -eu
PCIC=${1:-/usr/src/sys/bus/pci/pci.c}
PCIVAR=${2:-/usr/src/sys/bus/pci/pcivar.h}
OUT=${3:-vpd_extracted.h}
MODE=${4:-user}

# block A: from "#define PCI_VPD_TIMEOUT" through the end of vpd_nextbyte
# (the line '}' that follows the vpd_nextbyte closing sequence)
awk '
/^#define[ \t]*PCI_VPD_TIMEOUT/ {ina=1}
ina {print}
ina && /^vpd_nextbyte/ {innb=1}
innb && /^}$/ {exit}
' "$PCIC" > /tmp/.vpd_blockA.$$

# block B: pci_read_vpd() -- from the "static void" preceding its
# signature through the "}" after "#undef WREG"
awk '
/^pci_read_vpd\(device_t pcib, pcicfgregs \*cfg\)$/ {inb=1; print "static void"; print}
inb && !/^pci_read_vpd\(device_t/ {if (!seen) {print; if (/^#undef WREG/) seen=1} else {print; if (/^}$/) exit}}
' "$PCIC" > /tmp/.vpd_blockB.$$

# block C (user mode): pci_get_vpd_readonly_method()
if [ "$MODE" = user ]; then
	awk '
	/^pci_get_vpd_readonly_method\(device_t dev, device_t child, const char \*kw,$/ {
		inc=1; print "int"; print
	}
	inc && !/^pci_get_vpd_readonly_method/ {print; if (/^}$/) exit}
	' "$PCIC" > /tmp/.vpd_blockC.$$
fi

{
	echo "/*"
	echo " * VERBATIM extraction from $PCIC / $PCIVAR -- do not edit."
	echo " * Generated by extract.sh (content-anchored)."
	echo " */"
	echo
	if [ "$MODE" = user ]; then
		echo "/* pcivar.h : VPD structures -> vpd_structs.h */"
	fi
	echo "/* pci.c : PCI_VPD_TIMEOUT, pci_read_vpd_reg, vpd_readstate, vpd_nextbyte */"
	cat /tmp/.vpd_blockA.$$
	echo
	echo "/* pci.c : pci_read_vpd (the VPD state machine) */"
	cat /tmp/.vpd_blockB.$$
	if [ "$MODE" = user ]; then
		echo
		echo "/* pci.c : pci_get_vpd_readonly_method */"
		cat /tmp/.vpd_blockC.$$
	fi
} > "$OUT"
rm -f /tmp/.vpd_blockA.$$ /tmp/.vpd_blockB.$$ /tmp/.vpd_blockC.$$

if [ "$MODE" = user ]; then
	awk '/^struct vpd_readonly \{/,/^\};/' "$PCIVAR" > /tmp/.vpd_s1.$$
	awk '/^struct vpd_write \{/,/^\};/' "$PCIVAR" > /tmp/.vpd_s2.$$
	awk '/^struct pcicfg_vpd \{/,/^\};/' "$PCIVAR" > /tmp/.vpd_s3.$$
	cat /tmp/.vpd_s1.$$ /tmp/.vpd_s2.$$ /tmp/.vpd_s3.$$ > vpd_structs.h
	rm -f /tmp/.vpd_s1.$$ /tmp/.vpd_s2.$$ /tmp/.vpd_s3.$$
fi

echo "extracted $OUT:" >&2
wc -l "$OUT" >&2
[ "$MODE" = user ] && wc -l vpd_structs.h >&2 || true