diff --git a/observation/src/ttysnoop/ttysnoop.c b/observation/src/ttysnoop/ttysnoop.c index fe87d5f7b9dc1b28b578419aef6070de3a8940fc..2945e9f7ec77a3650fe952ac4561abd9588497b3 100644 --- a/observation/src/ttysnoop/ttysnoop.c +++ b/observation/src/ttysnoop/ttysnoop.c @@ -99,6 +99,43 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) return 0; } +static bool tty_write_is_newly(void) +{ + const struct btf_type *type; + __s32 id; + struct btf *btf; + + btf = btf__load_vmlinux_btf(); + if (!btf) { + warning("No BTF, cannot determine type info: %s", strerror(errno)); + goto failed; + } + + id = btf__find_by_name_kind(btf, "tty_write", BTF_KIND_FUNC); + if (id <= 0) { + warning("Can't find function tty_write in BTF: %s\n", + strerror(-id)); + goto failed; + } + + type = btf__type_by_id(btf, id); + if (!type || BTF_INFO_KIND(type->info) != BTF_KIND_FUNC) + goto failed; + + type = btf__type_by_id(btf, type->type); + if (!type || BTF_INFO_KIND(type->info) != BTF_KIND_FUNC_PROTO) + goto failed; + + btf__free(btf); + /* the newly tty_write has 2 params, old have 4 params */ + if (btf_vlen(type) != 2) + return false; + return true; + +failed: + return fallback_to_compare_kernel_version(); +} + int main(int argc, char *argv[]) { LIBBPF_OPTS(bpf_object_open_opts, open_opts); @@ -122,5 +159,7 @@ int main(int argc, char *argv[]) return 1; } + new_tty_write = tty_write_is_newly(); + return err != 0; }