summaryrefslogtreecommitdiff
path: root/internal/generate
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-21 13:59:39 +0200
committerPaul Buetow <paul@buetow.org>2026-02-21 13:59:39 +0200
commitb5792f8e23d1599dcce49bc83e5d128abee484f3 (patch)
treeef07039e4e05b23a6b41adf6b663abd0109a436b /internal/generate
parent114f0cb9e6e5487fccaafb7d7065b611c8c14402 (diff)
Enable name_to_handle_at and io_uring fd attribution
Amp-Thread-ID: https://ampcode.com/threads/T-019c7fec-eec9-706a-8338-3ce674802680 Co-authored-by: Amp <amp@ampcode.com>
Diffstat (limited to 'internal/generate')
-rw-r--r--internal/generate/classify.go10
-rw-r--r--internal/generate/classify_test.go25
-rw-r--r--internal/generate/codegen_test.go30
-rw-r--r--internal/generate/testdata.go101
4 files changed, 143 insertions, 23 deletions
diff --git a/internal/generate/classify.go b/internal/generate/classify.go
index 75a12fe..c55e46f 100644
--- a/internal/generate/classify.go
+++ b/internal/generate/classify.go
@@ -28,7 +28,7 @@ const (
type ClassificationResult struct {
Kind TracepointKind
- PathnameField string // for KindPathname: "pathname", "path", or "filename"
+ PathnameField string // for KindPathname: "pathname", "path", "filename", or "name"
}
// ClassifyFormat determines the tracepoint kind for a parsed format section.
@@ -103,6 +103,10 @@ func classifyNameOnly(name string) (ClassificationResult, bool) {
switch name {
case "sys_enter_open_by_handle_at":
return ClassificationResult{Kind: KindOpenByHandleAt}, true
+ case "sys_enter_io_uring_enter":
+ return ClassificationResult{Kind: KindFd}, true
+ case "sys_enter_io_uring_register":
+ return ClassificationResult{Kind: KindFd}, true
case "sys_enter_fcntl":
return ClassificationResult{Kind: KindFcntl}, true
case "sys_enter_syslog":
@@ -132,6 +136,10 @@ func classifyNameAndField(name, fieldType, fieldName string) (ClassificationResu
if fieldType == "unsigned int" && fieldName == "oldfd" {
return ClassificationResult{Kind: KindDup3}, true
}
+ case "sys_enter_name_to_handle_at":
+ if fieldType == "const char *" && fieldName == "name" {
+ return ClassificationResult{Kind: KindPathname, PathnameField: "name"}, true
+ }
}
if strings.HasPrefix(name, "sys_enter") &&
diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go
index c94e359..950e056 100644
--- a/internal/generate/classify_test.go
+++ b/internal/generate/classify_test.go
@@ -136,6 +136,16 @@ func TestClassifyOpenByHandleAt(t *testing.T) {
}
}
+func TestClassifyNameToHandleAt(t *testing.T) {
+ r := classifyFromData(t, FormatNameToHandleAt)
+ if r.Kind != KindPathname {
+ t.Errorf("name_to_handle_at: got kind %d, want KindPathname", r.Kind)
+ }
+ if r.PathnameField != "name" {
+ t.Errorf("name_to_handle_at: PathnameField = %q, want name", r.PathnameField)
+ }
+}
+
func TestClassifyNullSync(t *testing.T) {
r := classifyFromData(t, FormatSync)
if r.Kind != KindNull {
@@ -152,8 +162,15 @@ func TestClassifyNullSyslog(t *testing.T) {
func TestClassifyNullIoUring(t *testing.T) {
r := classifyFromData(t, FormatIoUringEnter)
- if r.Kind != KindNull {
- t.Errorf("io_uring_enter: got kind %d, want KindNull", r.Kind)
+ if r.Kind != KindFd {
+ t.Errorf("io_uring_enter: got kind %d, want KindFd", r.Kind)
+ }
+}
+
+func TestClassifyIoUringRegister(t *testing.T) {
+ r := classifyFromData(t, FormatIoUringRegister)
+ if r.Kind != KindFd {
+ t.Errorf("io_uring_register: got kind %d, want KindFd", r.Kind)
}
}
@@ -282,7 +299,9 @@ func TestClassifySyscallPairAccepted(t *testing.T) {
{"sync", FormatSync, FormatExitSync, KindNull},
{"syslog", FormatSyslog, FormatExitSyslog, KindNull},
{"open_by_handle_at", FormatOpenByHandleAt, FormatExitOpenByHandleAt, KindOpenByHandleAt},
- {"io_uring_enter", FormatIoUringEnter, FormatExitIoUringEnter, KindNull},
+ {"name_to_handle_at", FormatNameToHandleAt, FormatExitNameToHandleAt, KindPathname},
+ {"io_uring_enter", FormatIoUringEnter, FormatExitIoUringEnter, KindFd},
+ {"io_uring_register", FormatIoUringRegister, FormatExitIoUringRegister, KindFd},
{"pread64", FormatPread64, FormatExitPread64, KindFd},
{"symlink", FormatSymlink, FormatExitSymlink, KindName},
}
diff --git a/internal/generate/codegen_test.go b/internal/generate/codegen_test.go
index b19a824..23ab7c1 100644
--- a/internal/generate/codegen_test.go
+++ b/internal/generate/codegen_test.go
@@ -129,6 +129,26 @@ func TestGenerateNullHandler(t *testing.T) {
}
}
+func TestGenerateIoUringEnterHandler(t *testing.T) {
+ output := generateFromPair(t, FormatIoUringEnter, FormatExitIoUringEnter)
+
+ requireContains(t, output, `SEC("tracepoint/syscalls/sys_enter_io_uring_enter")`)
+ requireContains(t, output, "struct fd_event *ev")
+ requireContains(t, output, "ev->event_type = ENTER_FD_EVENT;")
+ requireContains(t, output, "ev->trace_id = SYS_ENTER_IO_URING_ENTER;")
+ requireContains(t, output, "ev->fd = (__s32)ctx->args[0];")
+}
+
+func TestGenerateIoUringRegisterHandler(t *testing.T) {
+ output := generateFromPair(t, FormatIoUringRegister, FormatExitIoUringRegister)
+
+ requireContains(t, output, `SEC("tracepoint/syscalls/sys_enter_io_uring_register")`)
+ requireContains(t, output, "struct fd_event *ev")
+ requireContains(t, output, "ev->event_type = ENTER_FD_EVENT;")
+ requireContains(t, output, "ev->trace_id = SYS_ENTER_IO_URING_REGISTER;")
+ requireContains(t, output, "ev->fd = (__s32)ctx->args[0];")
+}
+
func TestGenerateDup3Handler(t *testing.T) {
output := generateFromPair(t, FormatDup3, FormatExitDup3)
@@ -146,6 +166,16 @@ func TestGenerateOpenByHandleAtHandler(t *testing.T) {
requireContains(t, output, "ev->flags = (__s32)ctx->args[2];")
}
+func TestGenerateNameToHandleAtHandler(t *testing.T) {
+ output := generateFromPair(t, FormatNameToHandleAt, FormatExitNameToHandleAt)
+
+ requireContains(t, output, `SEC("tracepoint/syscalls/sys_enter_name_to_handle_at")`)
+ requireContains(t, output, "struct path_event *ev")
+ requireContains(t, output, "ev->event_type = ENTER_PATH_EVENT;")
+ requireContains(t, output, "ev->trace_id = SYS_ENTER_NAME_TO_HANDLE_AT;")
+ requireContains(t, output, "bpf_probe_read_user_str(ev->pathname, sizeof(ev->pathname), (void*)ctx->args[1]);")
+}
+
func TestGenerateIgnoredComment(t *testing.T) {
output := generateFromPair(t, FormatKill, FormatExitKill)
diff --git a/internal/generate/testdata.go b/internal/generate/testdata.go
index 7ca29cd..e36a6a1 100644
--- a/internal/generate/testdata.go
+++ b/internal/generate/testdata.go
@@ -362,10 +362,10 @@ print fmt: "0x%lx", REC->ret
const FormatOpenByHandleAt = `name: sys_enter_open_by_handle_at
ID: 1133
format:
- field:unsigned short common_type; offset:0; size:2; signed:0;
- field:unsigned char common_flags; offset:2; size:1; signed:0;
- field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
- field:int common_pid; offset:4; size:4; signed:1;
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
field:int __syscall_nr; offset:8; size:4; signed:1;
field:int mountdirfd; offset:16; size:8; signed:0;
@@ -375,13 +375,31 @@ format:
print fmt: "mountdirfd: 0x%08lx, handle: 0x%08lx, flags: 0x%08lx", ((unsigned long)(REC->mountdirfd)), ((unsigned long)(REC->handle)), ((unsigned long)(REC->flags))
`
+const FormatNameToHandleAt = `name: sys_enter_name_to_handle_at
+ID: 1135
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int __syscall_nr; offset:8; size:4; signed:1;
+ field:int dfd; offset:16; size:8; signed:0;
+ field:const char * name; offset:24; size:8; signed:0;
+ field:struct file_handle * handle; offset:32; size:8; signed:0;
+ field:void * mnt_id; offset:40; size:8; signed:0;
+ field:int flag; offset:48; size:8; signed:0;
+
+print fmt: "dfd: 0x%08lx, name: 0x%08lx, handle: 0x%08lx, mnt_id: 0x%08lx, flag: 0x%08lx", ((unsigned long)(REC->dfd)), ((unsigned long)(REC->name)), ((unsigned long)(REC->handle)), ((unsigned long)(REC->mnt_id)), ((unsigned long)(REC->flag))
+`
+
const FormatExitOpenByHandleAt = `name: sys_exit_open_by_handle_at
ID: 1132
format:
- field:unsigned short common_type; offset:0; size:2; signed:0;
- field:unsigned char common_flags; offset:2; size:1; signed:0;
- field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
- field:int common_pid; offset:4; size:4; signed:1;
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
field:int __syscall_nr; offset:8; size:4; signed:1;
field:long ret; offset:16; size:8; signed:1;
@@ -389,25 +407,70 @@ format:
print fmt: "0x%lx", REC->ret
`
+const FormatExitNameToHandleAt = `name: sys_exit_name_to_handle_at
+ID: 1134
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int __syscall_nr; offset:8; size:4; signed:1;
+ field:long ret; offset:16; size:8; signed:1;
+
+print fmt: "0x%lx", REC->ret
+`
+
const FormatIoUringEnter = `name: sys_enter_io_uring_enter
ID: 1496
format:
- field:unsigned short common_type; offset:0; size:2; signed:0;
- field:unsigned char common_flags; offset:2; size:1; signed:0;
- field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
- field:int common_pid; offset:4; size:4; signed:1;
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
- field:int __syscall_nr; offset:8; size:4; signed:1;
- field:unsigned int fd; offset:16; size:8; signed:0;
- field:u32 to_submit; offset:24; size:8; signed:0;
- field:u32 min_complete; offset:32; size:8; signed:0;
- field:u32 flags; offset:40; size:8; signed:0;
- field:const void * argp; offset:48; size:8; signed:0;
- field:size_t argsz; offset:56; size:8; signed:0;
+ field:int __syscall_nr; offset:8; size:4; signed:1;
+ field:unsigned int fd; offset:16; size:8; signed:0;
+ field:u32 to_submit; offset:24; size:8; signed:0;
+ field:u32 min_complete; offset:32; size:8; signed:0;
+ field:u32 flags; offset:40; size:8; signed:0;
+ field:const void * argp; offset:48; size:8; signed:0;
+ field:size_t argsz; offset:56; size:8; signed:0;
print fmt: "fd: 0x%08lx, to_submit: 0x%08lx, min_complete: 0x%08lx, flags: 0x%08lx, argp: 0x%08lx, argsz: 0x%08lx", ((unsigned long)(REC->fd)), ((unsigned long)(REC->to_submit)), ((unsigned long)(REC->min_complete)), ((unsigned long)(REC->flags)), ((unsigned long)(REC->argp)), ((unsigned long)(REC->argsz))
`
+const FormatIoUringRegister = `name: sys_enter_io_uring_register
+ID: 1515
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int __syscall_nr; offset:8; size:4; signed:1;
+ field:unsigned int fd; offset:16; size:8; signed:0;
+ field:unsigned int opcode; offset:24; size:8; signed:0;
+ field:void * arg; offset:32; size:8; signed:0;
+ field:unsigned int nr_args; offset:40; size:8; signed:0;
+
+print fmt: "fd: 0x%08lx, opcode: 0x%08lx, arg: 0x%08lx, nr_args: 0x%08lx", ((unsigned long)(REC->fd)), ((unsigned long)(REC->opcode)), ((unsigned long)(REC->arg)), ((unsigned long)(REC->nr_args))
+`
+
+const FormatExitIoUringRegister = `name: sys_exit_io_uring_register
+ID: 1514
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int __syscall_nr; offset:8; size:4; signed:1;
+ field:long ret; offset:16; size:8; signed:1;
+
+print fmt: "0x%lx", REC->ret
+`
+
const FormatExitIoUringEnter = `name: sys_exit_io_uring_enter
ID: 1495
format: