# settings for validator code generator input-tag: "!filter" output-tag: "!ebpf" input-extension: ".c" output-extension: ".ebpf" compiler: clang-5.0 cflags: "-x c -ffreestanding -target bpf -O2 -c -o - -" common: prolog: |+ /* * filter method for ${NODE_NAME} * */ #include #include #ifndef NULL #define NULL 0 #endif /* never accessed directly but the pointers are valid keys */ struct node; struct property; struct ref; /* flags when getting */ #define EXISTS 1 #define BADTYPE 2 static int (*callback)(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) = (void *) 1; static int (*bpf_printf)(const char *fmt, ...) = (void *) 2; static int64_t (*get_int)(struct node *np, const char *name, uint64_t *flagsp) = (void *) 3; static bool (*get_bool)(struct node *np, const char *name, uint64_t *flagsp) = (void *) 4; static const char *(*get_str)(struct node *np, const char *name, uint64_t *flagsp) = (void *) 5; static const char **(*get_strseq)(struct node *np, const char *name, uint64_t *flagsp) = (void *) 6; static bool (*streq)(const char *str1, const char *str2) = (void *) 7; static bool (*anystreq)(const char **strv, const char *str2) = (void *) 8; static struct node *(*get_parent)(struct node *np) = (void *) 9; static const int64_t *(*get_intseq)(struct node *np, const char *name, int64_t *countp, uint64_t *flagsp) = (void *) 10; static const int64_t (*get_depth)(struct node *np) = (void *) 11; #define SELECT_BASE 100000 #define ERROR_BASE 4000 #define BADTYPE_BASE 3000 #define EXISTS_BASE 2000 #define PROPC_BASE 1000 #define NODEC_BASE 0 epilog: | /* ${NODE_NAME} ends */ node: select: # entry is select() entry: select prolog: |+ /* prolog for ${NODE_NAME} */ int select(struct node *np) { epilog: |+ /* comment here due to YAML formatting */ return 0; } check: entry: check prolog: |+ /* prolog for ${NODE_NAME} */ int check(struct node *np) { epilog: |+ /* comment here due to YAML formatting */ return 0; } property: check: prolog: |+ /* for ${PROPERTY_NAME} from ${RULE_NAME} rule */ if (!( epilog: |+ )) return -PROPC_BASE - ${PROPERTY_INDEX}; badtype-prolog: |+ if (badtype) return -BADTYPE_BASE - ${PROPERTY_INDEX}; badtype-epilog: |+ types: int: prolog: |+ { uint64_t flags; const int64_t v = get_int(np, "${PROPERTY_NAME}", &flags); const bool badtype = !!(flags & BADTYPE); const bool exists = !!(flags & EXISTS); epilog: |+ } uint: prolog: |+ { uint64_t flags; const unsigned int v = get_uint(np, "${PROPERTY_NAME}", &flags); const bool badtype = !!(flags & BADTYPE); const bool exists = !!(flags & EXISTS); epilog: + } str: prolog: |+ { uint64_t flags; const char *v = get_str(np, "${PROPERTY_NAME}", &flags); const bool badtype = !!(flags & BADTYPE); const bool exists = !!(flags & EXISTS); epilog: |+ } bool: prolog: |+ { uint64_t flags; const bool v = get_bool(np, "${PROPERTY_NAME}", &flags); const bool badtype = !!(flags & BADTYPE); const bool exists = !!(flags & EXISTS); epilog: |+ } strseq: prolog: |+ { uint64_t flags; const char **v = get_strseq(np, "${PROPERTY_NAME}", &flags); const bool badtype = !!(flags & BADTYPE); const bool exists = !!(flags & EXISTS); epilog: |+ } intseq: prolog: |+ { uint64_t flags; int64_t temp_count; const int64_t *v = get_intseq(np, "${PROPERTY_NAME}", &temp_count, &flags); const int64_t count = temp_count; const bool badtype = !!(flags & BADTYPE); const bool exists = !!(flags & EXISTS); epilog: |+ } categories: required: prolog: |+ if (!exists) return -EXISTS_BASE - ${PROPERTY_INDEX}; epilog: |+ optional: prolog: |+ if (!exists) goto skip_${PROPERTY_INDEX}; epilog: |+ skip_${PROPERTY_INDEX}: do { } while(0); /* fix goto that requires a statement */