summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/bpf/gen_bpf_skel.sh
blob: 60942f24b094cb86e85902381c06e6367ef86c43 (plain) (blame)
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
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Link BPF object file(s) with "bpftool gen object" and generate a
# skeleton (or light skeleton) header from the result.
#
# Usage:
#   BPFTOOL=<bpftool> gen_bpf_skel.sh --name NAME --skel OUT
#                      [options] OBJ...
#
#   --name NAME       skeleton object name ("name NAME" for bpftool)
#   --skel OUT        output header ("foo.skel.h" or "foo.lskel.h")
#   --subskel OUT     also generate a subskeleton header into OUT
#   --lskel           generate a light skeleton (bpftool gen skeleton -L)
#   --sign            sign the (light) skeleton, with the key and
#                     certificate taken from $PRIVATE_KEY and
#                     $VERIFICATION_CERT
#
# The inputs are linked three times and the 2nd and 3rd results compared,
# as a regression test for the determinism of "bpftool gen object".
#
# Intermediate files are named after the output header with a "linked"
# infix - "llinked" for light or signed skeletons, so that generating a
# .skel.h and a .lskel.h from the same .bpf.o in parallel never races on
# the intermediates.
#
# The bpftool binary is taken from $BPFTOOL (default: bpftool from PATH).
# On failure all outputs and intermediates are removed and the script exits
# non-zero; permissive-mode skipping is the caller's business (see
# skip_on_fail in the Makefile).

set -u

bpftool=${BPFTOOL:-bpftool}
name='' skel='' subskel=''
lskel=0 sign=0

while [ $# -gt 0 ]; do
	case "$1" in
	--name)		name=$2; shift 2 ;;
	--skel)		skel=$2; shift 2 ;;
	--subskel)	subskel=$2; shift 2 ;;
	--lskel)	lskel=1; shift ;;
	--sign)		sign=1; shift ;;
	--)		shift; break ;;
	-*)		echo "$0: unknown option: $1" >&2; exit 1 ;;
	*)		break ;;
	esac
done

if [ -z "$name" ] || [ -z "$skel" ] || [ $# -eq 0 ]; then
	echo "usage: $0 --name NAME --skel OUT [options] OBJ..." >&2
	exit 1
fi

infix=linked
if [ "$lskel" -eq 1 ] || [ "$sign" -eq 1 ]; then
	infix=llinked
fi

if [ "$sign" -eq 1 ] && { [ -z "${PRIVATE_KEY-}" ] || [ -z "${VERIFICATION_CERT-}" ]; }; then
	echo "$0: --sign requires PRIVATE_KEY and VERIFICATION_CERT in the environment" >&2
	exit 1
fi

base=${skel%.skel.h}
base=${base%.lskel.h}
t1=$base.${infix}1.o
t2=$base.${infix}2.o
t3=$base.${infix}3.o

fail() {
	rm -f "$skel" ${subskel:+"$subskel"} "$t1" "$t2" "$t3"
	exit 1
}

"$bpftool" gen object "$t1" "$@" || fail
"$bpftool" gen object "$t2" "$t1" || fail
"$bpftool" gen object "$t3" "$t2" || fail
if ! cmp -s "$t2" "$t3"; then
	echo "$0: bpftool gen object is not deterministic for $skel" >&2
	fail
fi

args=()
if [ "$sign" -eq 1 ]; then
	args+=(-S -k "$PRIVATE_KEY" -i "$VERIFICATION_CERT")
fi
if [ "$lskel" -eq 1 ]; then
	args+=(-L)
fi
"$bpftool" gen skeleton ${args[@]+"${args[@]}"} "$t3" name "$name" > "$skel" || fail

if [ -n "$subskel" ]; then
	"$bpftool" gen subskeleton "$t3" name "$name" > "$subskel" || fail
fi

rm -f "$t1" "$t2" "$t3"
exit 0