18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
28c2ecf20Sopenharmony_ci/* Copyright (c) 2020 Facebook */
38c2ecf20Sopenharmony_ci#include <vmlinux.h>
48c2ecf20Sopenharmony_ci#include <bpf/bpf_helpers.h>
58c2ecf20Sopenharmony_ci#include <bpf/bpf_core_read.h>
68c2ecf20Sopenharmony_ci#include <bpf/bpf_tracing.h>
78c2ecf20Sopenharmony_ci#include "pid_iter.h"
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci/* keep in sync with the definition in main.h */
108c2ecf20Sopenharmony_cienum bpf_obj_type {
118c2ecf20Sopenharmony_ci	BPF_OBJ_UNKNOWN,
128c2ecf20Sopenharmony_ci	BPF_OBJ_PROG,
138c2ecf20Sopenharmony_ci	BPF_OBJ_MAP,
148c2ecf20Sopenharmony_ci	BPF_OBJ_LINK,
158c2ecf20Sopenharmony_ci	BPF_OBJ_BTF,
168c2ecf20Sopenharmony_ci};
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ciextern const void bpf_link_fops __ksym;
198c2ecf20Sopenharmony_ciextern const void bpf_map_fops __ksym;
208c2ecf20Sopenharmony_ciextern const void bpf_prog_fops __ksym;
218c2ecf20Sopenharmony_ciextern const void btf_fops __ksym;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciconst volatile enum bpf_obj_type obj_type = BPF_OBJ_UNKNOWN;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistatic __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type)
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci	switch (type) {
288c2ecf20Sopenharmony_ci	case BPF_OBJ_PROG:
298c2ecf20Sopenharmony_ci		return BPF_CORE_READ((struct bpf_prog *)ent, aux, id);
308c2ecf20Sopenharmony_ci	case BPF_OBJ_MAP:
318c2ecf20Sopenharmony_ci		return BPF_CORE_READ((struct bpf_map *)ent, id);
328c2ecf20Sopenharmony_ci	case BPF_OBJ_BTF:
338c2ecf20Sopenharmony_ci		return BPF_CORE_READ((struct btf *)ent, id);
348c2ecf20Sopenharmony_ci	case BPF_OBJ_LINK:
358c2ecf20Sopenharmony_ci		return BPF_CORE_READ((struct bpf_link *)ent, id);
368c2ecf20Sopenharmony_ci	default:
378c2ecf20Sopenharmony_ci		return 0;
388c2ecf20Sopenharmony_ci	}
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciSEC("iter/task_file")
428c2ecf20Sopenharmony_ciint iter(struct bpf_iter__task_file *ctx)
438c2ecf20Sopenharmony_ci{
448c2ecf20Sopenharmony_ci	struct file *file = ctx->file;
458c2ecf20Sopenharmony_ci	struct task_struct *task = ctx->task;
468c2ecf20Sopenharmony_ci	struct pid_iter_entry e;
478c2ecf20Sopenharmony_ci	const void *fops;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	if (!file || !task)
508c2ecf20Sopenharmony_ci		return 0;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	switch (obj_type) {
538c2ecf20Sopenharmony_ci	case BPF_OBJ_PROG:
548c2ecf20Sopenharmony_ci		fops = &bpf_prog_fops;
558c2ecf20Sopenharmony_ci		break;
568c2ecf20Sopenharmony_ci	case BPF_OBJ_MAP:
578c2ecf20Sopenharmony_ci		fops = &bpf_map_fops;
588c2ecf20Sopenharmony_ci		break;
598c2ecf20Sopenharmony_ci	case BPF_OBJ_BTF:
608c2ecf20Sopenharmony_ci		fops = &btf_fops;
618c2ecf20Sopenharmony_ci		break;
628c2ecf20Sopenharmony_ci	case BPF_OBJ_LINK:
638c2ecf20Sopenharmony_ci		fops = &bpf_link_fops;
648c2ecf20Sopenharmony_ci		break;
658c2ecf20Sopenharmony_ci	default:
668c2ecf20Sopenharmony_ci		return 0;
678c2ecf20Sopenharmony_ci	}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	if (file->f_op != fops)
708c2ecf20Sopenharmony_ci		return 0;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	e.pid = task->tgid;
738c2ecf20Sopenharmony_ci	e.id = get_obj_id(file->private_data, obj_type);
748c2ecf20Sopenharmony_ci	bpf_probe_read_kernel(&e.comm, sizeof(e.comm),
758c2ecf20Sopenharmony_ci			      task->group_leader->comm);
768c2ecf20Sopenharmony_ci	bpf_seq_write(ctx->meta->seq, &e, sizeof(e));
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	return 0;
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cichar LICENSE[] SEC("license") = "Dual BSD/GPL";
82