about summary refs log tree commit diff stats
path: root/lib/chaseccomp/gen_syscalls
blob: a4d7d5b55b1cae352502195cd9d1f659f71a85c0 (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
#!/bin/sh

die() {
	echo "$*" >&2
	exit 1
}

test "$1" || die "usage: gen_syscalls [file]"

find_label() {
	printf '%s\n' "$labels" | while read -r line
	do	case $line in
		"$1 "*)	printf '%d\n' "${line#* }"
			break
			;;
		esac
	done
}

line_cut_next() {
	next=${line%% *}
	oline=$line
	line=${line#* }
	if test "$line" = "$oline"; then line= ; fi
}

cut_label() {
	line_cut_next
	label=$(find_label "$next")
	test "$label" || die "missing label $next"
	label=$(($label - 1 - $ip))
}

put_cmp() {
	line_cut_next
	val=$next
	cut_label
	printf '\t%s(%s, %d),\n' "$inst" "$val" "$label"
}

put_load() {
	line_cut_next
	printf '\t%s(%s),\n' "$inst" "$next"
}

put_ret() {
	line_cut_next
	case $next in
	allow)	val=SECCOMP_RET_ALLOW ;;
	trap)	val=SECCOMP_RET_TRAP ;;
	kill)	val=SECCOMP_RET_KILL_PROCESS ;;
	errno)	val="SECCOMP_RET_ERRNO | ($line & SECCOMP_RET_DATA)" ;;
	*)	die "wrong retval $line" ;;
	esac
	printf '\t%s(%s),\n' "$inst" "$val"
}

ip=0
while read -r line
do	line=${line%%#*}
	case $line in
	''|define' '*) ;;
	': '*)	line_cut_next
		if test -n "$labels"
		then	labels="$labels
$line $ip"
		else	labels="$line $ip"
		fi
		;;
	*)	ip=$((ip + 1)) ;;
	esac
done < "$1"

ip=0
while read -r line
do	line_cut_next
	case $next in
	:)	continue ;;
	define)	printf '#%s %s\n' "$next $line" ; continue ;;
	ret)	inst=CHA_BPF_RET put_ret ;;
	ifeq)	inst=CHA_BPF_JE put_cmp ;;
	ifne)	inst=CHA_BPF_JNE put_cmp ;;
	ifle)	inst=CHA_BPF_JLE put_cmp ;;
	load)	inst=CHA_BPF_LOAD put_load ;;
	*)	die "unexpected instruction $inst" ;;
	esac
	ip=$(($ip + 1))
done < "$1"