summaryrefslogtreecommitdiff
path: root/internal/generate
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-21 11:39:18 +0300
committerPaul Buetow <paul@buetow.org>2026-05-21 11:39:18 +0300
commitc58aa139f5e7252aefb1bcacb5fa8b9ea8cdcdef (patch)
tree09ae5323e06a3a0b5ade451f1b8e4b9efccb4561 /internal/generate
parenta0d6f222864301c11afd9c1d3306e6bfe8446d5d (diff)
n7 classify pidfd and misc tail syscalls
Diffstat (limited to 'internal/generate')
-rw-r--r--internal/generate/bpfhandler.go6
-rw-r--r--internal/generate/classify.go26
-rw-r--r--internal/generate/classify_test.go44
-rw-r--r--internal/generate/codegen_test.go4
-rw-r--r--internal/generate/kindregistry.go1
-rw-r--r--internal/generate/retclassify_test.go2
-rw-r--r--internal/generate/tracepointsgo.go7
-rw-r--r--internal/generate/tracepointsgo_test.go2
8 files changed, 88 insertions, 4 deletions
diff --git a/internal/generate/bpfhandler.go b/internal/generate/bpfhandler.go
index ee56f17..85377f1 100644
--- a/internal/generate/bpfhandler.go
+++ b/internal/generate/bpfhandler.go
@@ -91,6 +91,8 @@ func generateExtra(tp GeneratedTracepoint, isEnter bool) string {
return generateExtraPipe(f, isEnter)
case KindEventfd:
return generateExtraEventfd(f, isEnter)
+ case KindPidfd:
+ return generateExtraEventfd(f, isEnter)
case KindEpollCtl:
return generateExtraEpollCtl()
case KindTwoFd:
@@ -272,6 +274,8 @@ func generateExtraEventfd(f *Format, isEnter bool) string {
flagsExpr = "(__s32)ctx->args[3]"
case "sys_enter_timerfd_create":
flagsExpr = "(__s32)ctx->args[1]"
+ case "sys_enter_pidfd_open":
+ flagsExpr = "(__s32)ctx->args[0]"
case "sys_enter_fsmount":
flagsExpr = "(__s32)ctx->args[1]"
case "sys_enter_fsopen":
@@ -290,6 +294,8 @@ func generateExtraTwoFd(name string) string {
switch name {
case "sys_enter_move_mount":
return " ev->fd_a = (__s32)ctx->args[0];\n ev->fd_b = (__s32)ctx->args[2];\n ev->extra = (__u64)ctx->args[4];\n"
+ case "sys_enter_kcmp":
+ return " ev->fd_a = (__s32)ctx->args[3];\n ev->fd_b = (__s32)ctx->args[4];\n ev->extra = (__u64)ctx->args[2];\n"
default:
return " ev->fd_a = (__s32)ctx->args[0];\n ev->fd_b = (__s32)ctx->args[1];\n ev->extra = (__u64)ctx->args[2];\n"
}
diff --git a/internal/generate/classify.go b/internal/generate/classify.go
index ad9d694..69ada90 100644
--- a/internal/generate/classify.go
+++ b/internal/generate/classify.go
@@ -22,6 +22,7 @@ const (
KindAccept
KindPipe
KindEventfd
+ KindPidfd
KindEpollCtl
KindTwoFd
KindPoll
@@ -66,6 +67,8 @@ func (k TracepointKind) MetadataName() string {
return "pipe"
case KindEventfd:
return "eventfd"
+ case KindPidfd:
+ return "pidfd"
case KindEpollCtl:
return "epoll-ctl"
case KindTwoFd:
@@ -203,6 +206,10 @@ func classifyNameOnly(name string) (ClassificationResult, bool) {
return ClassificationResult{Kind: KindEventfd}, true
case "sys_exit_timerfd_create":
return ClassificationResult{Kind: KindEventfd}, true
+ case "sys_enter_pidfd_open":
+ return ClassificationResult{Kind: KindPidfd}, true
+ case "sys_exit_pidfd_open":
+ return ClassificationResult{Kind: KindPidfd}, true
case "sys_enter_bind":
return ClassificationResult{Kind: KindFd}, true
case "sys_enter_connect":
@@ -265,6 +272,12 @@ func classifyNameOnly(name string) (ClassificationResult, bool) {
return ClassificationResult{Kind: KindPtrace}, true
case "sys_enter_perf_event_open":
return ClassificationResult{Kind: KindPerfOpen}, true
+ case "sys_enter_pidfd_send_signal":
+ return ClassificationResult{Kind: KindFd}, true
+ case "sys_enter_kexec_file_load":
+ return ClassificationResult{Kind: KindFd}, true
+ case "sys_enter_kcmp":
+ return ClassificationResult{Kind: KindTwoFd}, true
case "sys_enter_mq_timedsend":
return ClassificationResult{Kind: KindFd}, true
case "sys_enter_mq_timedreceive":
@@ -281,6 +294,18 @@ func classifyNameOnly(name string) (ClassificationResult, bool) {
return ClassificationResult{Kind: KindNull}, true
case "sys_enter_exit_group":
return ClassificationResult{Kind: KindNull}, true
+ case "sys_enter_membarrier":
+ return ClassificationResult{Kind: KindNull}, true
+ case "sys_enter_rseq":
+ return ClassificationResult{Kind: KindNull}, true
+ case "sys_enter_set_robust_list":
+ return ClassificationResult{Kind: KindNull}, true
+ case "sys_enter_get_robust_list":
+ return ClassificationResult{Kind: KindNull}, true
+ case "sys_enter_mmap2":
+ return ClassificationResult{Kind: KindNull}, true
+ case "sys_enter_kexec_load":
+ return ClassificationResult{Kind: KindNull}, true
}
if strings.HasPrefix(name, "sys_enter_io_") {
return ClassificationResult{Kind: KindNull}, true
@@ -409,6 +434,7 @@ var retClassifications = map[string]RetClassification{
"readv": ReadClassified,
"recvmsg": ReadClassified,
"recvfrom": ReadClassified,
+ "getrandom": ReadClassified,
"syslog": ReadClassified,
"mq_timedreceive": ReadClassified,
diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go
index 79e6240..4b156ff 100644
--- a/internal/generate/classify_test.go
+++ b/internal/generate/classify_test.go
@@ -620,6 +620,40 @@ func TestClassifyMqFdSyscallsByName(t *testing.T) {
}
}
+func TestClassifyN7NameOnlyKinds(t *testing.T) {
+ tests := []struct {
+ name string
+ want TracepointKind
+ }{
+ {"sys_enter_pidfd_open", KindPidfd},
+ {"sys_exit_pidfd_open", KindPidfd},
+ {"sys_enter_pidfd_send_signal", KindFd},
+ {"sys_enter_kexec_file_load", KindFd},
+ {"sys_enter_kcmp", KindTwoFd},
+ {"sys_enter_membarrier", KindNull},
+ {"sys_enter_rseq", KindNull},
+ {"sys_enter_set_robust_list", KindNull},
+ {"sys_enter_get_robust_list", KindNull},
+ {"sys_enter_mmap2", KindNull},
+ {"sys_enter_kexec_load", KindNull},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ r := ClassifyFormat(&Format{
+ Name: tt.name,
+ ExternalFields: []Field{
+ {Type: "long", Name: "__syscall_nr"},
+ {Type: "long", Name: "arg0"},
+ },
+ })
+ if r.Kind != tt.want {
+ t.Fatalf("%s: got kind %d, want %d", tt.name, r.Kind, tt.want)
+ }
+ })
+ }
+}
+
func TestClassifyMount(t *testing.T) {
r := classifyFromData(t, FormatMount)
if r.Kind != KindPathname {
@@ -785,6 +819,8 @@ func TestClassifySyscallPairAccepted(t *testing.T) {
{"pipe2", FormatPipe2, FormatExitPipe2, KindPipe},
{"eventfd", FormatEventfd, FormatExitEventfd, KindEventfd},
{"eventfd2", FormatEventfd2, FormatExitEventfd2, KindEventfd},
+ {"pidfd_open", syntheticEnter("pidfd_open", 9320), syntheticExit("pidfd_open", 9319), KindPidfd},
+ {"pidfd_send_signal", syntheticEnter("pidfd_send_signal", 9322), syntheticExit("pidfd_send_signal", 9321), KindFd},
{"epoll_ctl", FormatEpollCtl, FormatExitEpollCtl, KindEpollCtl},
{"epoll_wait", FormatEpollWait, FormatExitEpollWait, KindFd},
{"epoll_pwait", FormatEpollPwait, FormatExitEpollPwait, KindFd},
@@ -805,6 +841,14 @@ func TestClassifySyscallPairAccepted(t *testing.T) {
{"mount", FormatMount, FormatExitMount, KindPathname},
{"umount", FormatUmount, FormatExitUmount, KindPathname},
{"move_mount", FormatMoveMount, FormatExitMoveMount, KindTwoFd},
+ {"kcmp", syntheticEnter("kcmp", 9324), syntheticExit("kcmp", 9323), KindTwoFd},
+ {"kexec_file_load", syntheticEnter("kexec_file_load", 9326), syntheticExit("kexec_file_load", 9325), KindFd},
+ {"membarrier", syntheticEnter("membarrier", 9328), syntheticExit("membarrier", 9327), KindNull},
+ {"rseq", syntheticEnter("rseq", 9330), syntheticExit("rseq", 9329), KindNull},
+ {"set_robust_list", syntheticEnter("set_robust_list", 9332), syntheticExit("set_robust_list", 9331), KindNull},
+ {"get_robust_list", syntheticEnter("get_robust_list", 9334), syntheticExit("get_robust_list", 9333), KindNull},
+ {"mmap2", syntheticEnter("mmap2", 9336), syntheticExit("mmap2", 9335), KindNull},
+ {"kexec_load", syntheticEnter("kexec_load", 9338), syntheticExit("kexec_load", 9337), KindNull},
{"fsmount", FormatFsmount, FormatExitFsmount, KindEventfd},
{"pivot_root", FormatPivotRoot, FormatExitPivotRoot, KindPathname},
{"quotactl", FormatQuotactl, FormatExitQuotactl, KindPathname},
diff --git a/internal/generate/codegen_test.go b/internal/generate/codegen_test.go
index c653ad0..83d316f 100644
--- a/internal/generate/codegen_test.go
+++ b/internal/generate/codegen_test.go
@@ -550,6 +550,7 @@ func TestGenerateAllEventTypes(t *testing.T) {
{KindAccept, "ENTER_ACCEPT_EVENT", "EXIT_ACCEPT_EVENT"},
{KindPipe, "ENTER_PIPE_EVENT", "EXIT_PIPE_EVENT"},
{KindEventfd, "ENTER_EVENTFD_EVENT", "EXIT_EVENTFD_EVENT"},
+ {KindPidfd, "ENTER_EVENTFD_EVENT", "EXIT_EVENTFD_EVENT"},
{KindEpollCtl, "ENTER_EPOLL_CTL_EVENT", "EXIT_EPOLL_CTL_EVENT"},
{KindTwoFd, "ENTER_TWO_FD_EVENT", "EXIT_TWO_FD_EVENT"},
{KindPoll, "ENTER_POLL_EVENT", "EXIT_POLL_EVENT"},
@@ -591,6 +592,7 @@ func TestEventStructNames(t *testing.T) {
{KindAccept, "accept_event"},
{KindPipe, "pipe_event"},
{KindEventfd, "eventfd_event"},
+ {KindPidfd, "eventfd_event"},
{KindEpollCtl, "epoll_ctl_event"},
{KindTwoFd, "two_fd_event"},
{KindPoll, "poll_event"},
@@ -617,7 +619,7 @@ func TestEnterReject(t *testing.T) {
t.Error("KindNone should be enter-rejected")
}
- accepted := []TracepointKind{KindFd, KindOpen, KindMqOpen, KindExec, KindPathname, KindName, KindFcntl, KindNull, KindDup3, KindOpenByHandleAt, KindSocket, KindSocketpair, KindAccept, KindPipe, KindEventfd, KindEpollCtl, KindTwoFd, KindPoll, KindMem, KindSleep, KindKeyctl, KindPtrace, KindPerfOpen}
+ accepted := []TracepointKind{KindFd, KindOpen, KindMqOpen, KindExec, KindPathname, KindName, KindFcntl, KindNull, KindDup3, KindOpenByHandleAt, KindSocket, KindSocketpair, KindAccept, KindPipe, KindEventfd, KindPidfd, KindEpollCtl, KindTwoFd, KindPoll, KindMem, KindSleep, KindKeyctl, KindPtrace, KindPerfOpen}
for _, k := range accepted {
if isEnterRejected(k) {
t.Errorf("kind %d should NOT be enter-rejected", k)
diff --git a/internal/generate/kindregistry.go b/internal/generate/kindregistry.go
index a5f5795..9387e19 100644
--- a/internal/generate/kindregistry.go
+++ b/internal/generate/kindregistry.go
@@ -32,6 +32,7 @@ var kindRegistry = map[TracepointKind]kindMeta{
KindAccept: {structName: "accept_event", enterAccepted: true},
KindPipe: {structName: "pipe_event", enterAccepted: true},
KindEventfd: {structName: "eventfd_event", enterAccepted: true},
+ KindPidfd: {structName: "eventfd_event", enterAccepted: true},
KindEpollCtl: {structName: "epoll_ctl_event", enterAccepted: true},
KindTwoFd: {structName: "two_fd_event", enterAccepted: true},
KindPoll: {structName: "poll_event", enterAccepted: true},
diff --git a/internal/generate/retclassify_test.go b/internal/generate/retclassify_test.go
index f837957..4e9655b 100644
--- a/internal/generate/retclassify_test.go
+++ b/internal/generate/retclassify_test.go
@@ -7,7 +7,7 @@ func TestClassifyRetRead(t *testing.T) {
"fgetxattr", "flistxattr", "getdents", "getdents64", "getxattr",
"lgetxattr", "listxattr", "llistxattr", "pread64", "preadv",
"preadv2", "process_vm_readv", "read", "readlink", "readlinkat",
- "readv", "recvmsg", "recvfrom", "syslog", "mq_timedreceive",
+ "readv", "recvmsg", "recvfrom", "syslog", "mq_timedreceive", "getrandom",
}
for _, name := range reads {
if got := ClassifyRet("sys_exit_" + name); got != ReadClassified {
diff --git a/internal/generate/tracepointsgo.go b/internal/generate/tracepointsgo.go
index 47c2e8f..bc44b2f 100644
--- a/internal/generate/tracepointsgo.go
+++ b/internal/generate/tracepointsgo.go
@@ -10,7 +10,7 @@ import (
)
var secRe = regexp.MustCompile(`^SEC.*sys_((?:enter|exit)_[a-z_0-9]+)`)
-var kindLineRe = regexp.MustCompile(`^(sys_enter_[a-z0-9_]+)\s+is a struct\s+([a-z0-9_]+)(?:\s+.*)?$`)
+var kindLineRe = regexp.MustCompile(`^(sys_enter_[a-z0-9_]+)\s+is a struct\s+([a-z0-9_]+)(?:.*\(kind=([a-z0-9-]+)\))?\s*$`)
// ExtractTracepoints reads generated C code and extracts tracepoint names from
// SEC annotations, producing the generated_tracepoints.go content.
@@ -66,7 +66,10 @@ func extractSyscallKinds(r io.Reader) (map[string]string, error) {
continue
}
syscall := strings.TrimPrefix(m[1], "sys_enter_")
- kind := normalizeStructKind(m[2])
+ kind := strings.TrimSpace(m[3])
+ if kind == "" {
+ kind = normalizeStructKind(m[2])
+ }
if kind == "" {
continue
}
diff --git a/internal/generate/tracepointsgo_test.go b/internal/generate/tracepointsgo_test.go
index ebad63d..ee15b81 100644
--- a/internal/generate/tracepointsgo_test.go
+++ b/internal/generate/tracepointsgo_test.go
@@ -131,6 +131,7 @@ func TestExtractTracepointsWithKinds(t *testing.T) {
sys_enter_open_by_handle_at is a struct open_by_handle_at_event
sys_enter_mq_open is a struct mq_open_event
sys_enter_epoll_ctl is a struct epoll_ctl_event
+sys_enter_pidfd_open is a struct eventfd_event (kind=pidfd)
`
output, err := ExtractTracepointsWithKinds(strings.NewReader(sampleGeneratedC), strings.NewReader(kindData))
if err != nil {
@@ -140,4 +141,5 @@ sys_enter_epoll_ctl is a struct epoll_ctl_event
requireContains(t, output, `"open_by_handle_at": "open-by-handle-at",`)
requireContains(t, output, `"mq_open": "mq-open",`)
requireContains(t, output, `"epoll_ctl": "epoll-ctl",`)
+ requireContains(t, output, `"pidfd_open": "pidfd",`)
}