]> granicus.if.org Git - strace/commitdiff
bpf: add support for checking structures outside union bpf_attr
authorEugene Syromyatnikov <evgsyr@gmail.com>
Sun, 20 May 2018 23:24:08 +0000 (01:24 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 28 May 2018 17:34:50 +0000 (17:34 +0000)
struct bpf_prog_info and bpf_map_info need essentially the same handling
as union bpf_attr.

* gen_bpf_attr_check.sh: Derive type_name from $struct if it doesn't
start with "BPF_", derive TYPE_NAME from type_name, use them in code
generation.
* m4/gen_bpf_attr_m4.sh: Rewrite parsing/generation code into awk,
add support for structures outside union bpf_attr.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
gen_bpf_attr_check.sh
m4/gen_bpf_attr_m4.sh

index 1a52c2177745c513f74707ff4aeb9ea663b068d6..517e6212cbb5417ca3a951b26db72a210c35cde2 100755 (executable)
@@ -38,7 +38,13 @@ cat <<EOF
 # define SoM(type_, member_) (sizeof(((type_ *)0)->member_))
 EOF
 
-for struct in $(sed -n 's/^struct \(BPF_[^[:space:]]\+_struct\) .*/\1/p' < "$input"); do
+for struct in $(sed -n 's/^struct \([^[:space:]]\+_struct\) .*/\1/p' < "$input"); do
+       case "$struct" in
+               BPF_*) type_name='union bpf_attr' ;;
+               *) type_name="struct ${struct%_struct}" ;;
+       esac
+       TYPE_NAME="$(printf %s "$type_name" |tr '[:lower:] ' '[:upper:]_')"
+
        enum="$(sed -n 's/^struct '"$struct"' \/\* \([^[:space:]]\+\) \*\/ {.*/\1/p' < "$input")"
        ENUM="$(printf %s "$enum" |tr '[:lower:]' '[:upper:]')"
        enum="$enum${enum:+.}"
@@ -49,12 +55,12 @@ for struct in $(sed -n 's/^struct \(BPF_[^[:space:]]\+_struct\) .*/\1/p' < "$inp
                FIELD="$(printf %s "$field" |tr '[:lower:]' '[:upper:]')"
                cat <<EOF
 
-# ifdef HAVE_UNION_BPF_ATTR_$ENUM$FIELD
-       static_assert(SoM(struct $struct, $field) == SoM(union bpf_attr, $enum$field),
+# ifdef HAVE_${TYPE_NAME}_$ENUM$FIELD
+       static_assert(SoM(struct $struct, $field) == SoM($type_name, $enum$field),
                      "$struct.$field size mismatch");
-       static_assert(offsetof(struct $struct, $field) == offsetof(union bpf_attr, $enum$field),
+       static_assert(offsetof(struct $struct, $field) == offsetof($type_name, $enum$field),
                      "$struct.$field offset mismatch");
-# endif /* HAVE_UNION_BPF_ATTR_$ENUM$FIELD */
+# endif /* HAVE_${TYPE_NAME}_$ENUM$FIELD */
 EOF
        done
                cat <<EOF
index 188d66288cd1d75baf9270a7adb9b03053baa377..313b909386df7dc4bf9bdae2ed2f14cf58546856 100755 (executable)
@@ -34,37 +34,36 @@ AC_DEFUN([st_BPF_ATTR], [dnl
        AC_CHECK_MEMBERS(m4_normalize([
 EOF
 
-fetch_structs()
-{
-       local name="${1:-}"
-       local name_re=
-       [ -z "$name" ] ||
-               name_re='\/\* '"$name"' \*\/ '
+gawk -e '
+/^struct ([^[:space:]]+)_struct([[:space:]]+\/\* ([^[:space:]]+) \*\/)?[[:space:]]+{/ {
+       match($0, /^struct ([^[:space:]]+)_struct([[:space:]]+\/\* ([^[:space:]]+) \*\/)?[[:space:]]+{/, a)
 
-       sed -n '/^struct BPF_[^[:space:]]\+_struct '"$name_re"'{/,/^};/p' < "$input"
-}
+       struct_name = a[1]
+       subtype_name = a[3]
+
+       if (struct_name ~ /^BPF_/)
+               prefix = "union bpf_attr"
+       else
+               prefix = "struct " struct_name
+
+       if (subtype_name != "")
+               prefix = prefix "." subtype_name
 
-filter_entries()
-{
-       local name="${1:-}"
-       local subtype=
-       [ -z "$name" ] ||
-               subtype=".$name"
-       local search='^[[:space:]]\+[^][;]*[[:space:]]\([^][[:space:];]\+\)\(\[[^;]*\]\)\?;$'
-       local replacement='\t\tunion bpf_attr'"$subtype"'.\1,'
-       sed -n "s/$search/$replacement/p" |
-               sort -u
+       in_struct = 1
+       next
 }
 
-# nameless structures in union bpf_attr
-fetch_structs |
-       filter_entries
+/^}( ATTRIBUTE_ALIGNED\(.*\))?;/ {
+       in_struct = 0
+       next
+}
 
-# named structures in union bpf_attr
-for name in $(sed -n 's/^struct BPF_[^[:space:]]\+_struct \/\* \([^[:space:]]\+\) \*\/ {.*/\1/p' < "$input"); do
-       fetch_structs "$name" |
-               filter_entries "$name"
-done
+(in_struct == 1) {
+       if (match($0, /^[[:space:]]+[^;\[\]]+[[:space:]]+([^[:space:]\[\];]+)(\[[^;]*\])?;$/, a)) {
+               print "\t\t" prefix "." a[1] ","
+       }
+}
+' < "$input" | sort -u
 
 cat <<'EOF'
                union bpf_attr.dummy