#!/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 } put_cmp() { line_cut_next val=$next line_cut_next label=$(find_label "$next") test "$label" || die "missing label $next" label=$(($label - 1 - $ip)) printf '\t%s(%s, %d),\n' "$1" "$val" "$label" } put_load() { line_cut_next printf '\tCHA_BPF_LOAD(%s),\n' "$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 '\tCHA_BPF_RET(%s),\n' "$val" } ip=0 while read -r line do line=${line%%#*} case $line in ': '*) 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 ;; ret) put_ret ;; ifeq) put_cmp CHA_BPF_JE;; ifne) put_cmp CHA_BPF_JNE;; ifle) put_cmp CHA_BPF_JLE;; load) put_load;; *) die "unexpected instruction $next" ;; esac ip=$(($ip + 1)) done < "$1" printf '#define EXPECTED_COUNT %d\n' "$ip"