diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-20 07:23:45 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-20 07:23:45 +0300 |
| commit | df1225efe494cc81513cf98e93891376e45f9615 (patch) | |
| tree | 8fe131ba9ae5737022f26fcd60e662c1660329c6 /internal/generate | |
| parent | 11a8642b7035ff558fb84d7761e93525c84e4908 (diff) | |
task 07: add KindMem and separate address-space byte accounting
Diffstat (limited to 'internal/generate')
| -rw-r--r-- | internal/generate/bpfhandler.go | 13 | ||||
| -rw-r--r-- | internal/generate/classify.go | 5 | ||||
| -rw-r--r-- | internal/generate/classify_test.go | 18 | ||||
| -rw-r--r-- | internal/generate/codegen_test.go | 16 | ||||
| -rw-r--r-- | internal/generate/kindregistry.go | 1 | ||||
| -rw-r--r-- | internal/generate/testdata.go | 61 |
6 files changed, 113 insertions, 1 deletions
diff --git a/internal/generate/bpfhandler.go b/internal/generate/bpfhandler.go index 20859ee..e3d0d67 100644 --- a/internal/generate/bpfhandler.go +++ b/internal/generate/bpfhandler.go @@ -87,6 +87,8 @@ func generateExtra(tp GeneratedTracepoint, isEnter bool) string { return generateExtraEpollCtl() case KindPoll: return generateExtraPoll(f.Name) + case KindMem: + return generateExtraMem(f.Name) case KindOpen: return generateExtraOpen(f) case KindPathname: @@ -222,6 +224,17 @@ func generateExtraPoll(name string) string { } } +func generateExtraMem(name string) string { + switch name { + case "sys_enter_munmap": + return " ev->addr = (__u64)ctx->args[0];\n ev->length = (__u64)ctx->args[1];\n ev->length2 = 0;\n ev->flags = 0;\n" + case "sys_enter_mremap": + return " ev->addr = (__u64)ctx->args[0];\n ev->length = (__u64)ctx->args[1];\n ev->length2 = (__u64)ctx->args[2];\n ev->flags = (__u64)ctx->args[3];\n" + default: + return " ev->addr = 0;\n ev->length = 0;\n ev->length2 = 0;\n ev->flags = 0;\n" + } +} + // eventStructName returns the C struct name for a TracepointKind. The mapping // is driven by kindRegistry so adding a new kind only requires a registry entry. func eventStructName(kind TracepointKind) string { diff --git a/internal/generate/classify.go b/internal/generate/classify.go index 7c391fb..a2da47d 100644 --- a/internal/generate/classify.go +++ b/internal/generate/classify.go @@ -22,6 +22,7 @@ const ( KindEventfd KindEpollCtl KindPoll + KindMem ) type RetClassification string @@ -148,6 +149,10 @@ func classifyNameOnly(name string) (ClassificationResult, bool) { return ClassificationResult{Kind: KindPoll}, true case "sys_enter_pselect6": return ClassificationResult{Kind: KindPoll}, true + case "sys_enter_munmap": + return ClassificationResult{Kind: KindMem}, true + case "sys_enter_mremap": + return ClassificationResult{Kind: KindMem}, true } if strings.HasPrefix(name, "sys_enter_io_") { return ClassificationResult{Kind: KindNull}, true diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go index 367d7c8..2bc0e88 100644 --- a/internal/generate/classify_test.go +++ b/internal/generate/classify_test.go @@ -425,6 +425,20 @@ func TestClassifyPselect6(t *testing.T) { } } +func TestClassifyMunmap(t *testing.T) { + r := classifyFromData(t, FormatMunmap) + if r.Kind != KindMem { + t.Errorf("munmap: got kind %d, want KindMem", r.Kind) + } +} + +func TestClassifyMremap(t *testing.T) { + r := classifyFromData(t, FormatMremap) + if r.Kind != KindMem { + t.Errorf("mremap: got kind %d, want KindMem", r.Kind) + } +} + func TestClassifyKillRequiresGenerationFallback(t *testing.T) { r := classifyFromData(t, FormatKill) if r.Kind != KindNone { @@ -477,6 +491,8 @@ func TestClassifySyscallPairAccepted(t *testing.T) { {"ppoll", FormatPpoll, FormatExitPpoll, KindPoll}, {"select", FormatSelect, FormatExitSelect, KindPoll}, {"pselect6", FormatPselect6, FormatExitPselect6, KindPoll}, + {"munmap", FormatMunmap, FormatExitMunmap, KindMem}, + {"mremap", FormatMremap, FormatExitMremap, KindMem}, {"kill", FormatKill, FormatExitKill, KindNull}, } @@ -514,6 +530,8 @@ func TestClassifySyscallPairEmitsAllFamilies(t *testing.T) { {"ppoll", FormatPpoll, FormatExitPpoll, FamilyPolling}, {"select", FormatSelect, FormatExitSelect, FamilyPolling}, {"pselect6", FormatPselect6, FormatExitPselect6, FamilyPolling}, + {"munmap", FormatMunmap, FormatExitMunmap, FamilyMemory}, + {"mremap", FormatMremap, FormatExitMremap, FamilyMemory}, {"kill", FormatKill, FormatExitKill, FamilySignals}, } diff --git a/internal/generate/codegen_test.go b/internal/generate/codegen_test.go index a3baed7..3ec8d72 100644 --- a/internal/generate/codegen_test.go +++ b/internal/generate/codegen_test.go @@ -168,6 +168,18 @@ func TestGenerateMmapHandlerUsesFdArgumentIndex(t *testing.T) { requireContains(t, output, "ev->fd = (__s32)ctx->args[4];") } +func TestGenerateMemHandler(t *testing.T) { + output := generateFromPair(t, FormatMremap, FormatExitMremap) + + requireContains(t, output, `SEC("tracepoint/syscalls/sys_enter_mremap")`) + requireContains(t, output, "struct mem_event *ev") + requireContains(t, output, "ev->event_type = ENTER_MEM_EVENT;") + requireContains(t, output, "ev->addr = (__u64)ctx->args[0];") + requireContains(t, output, "ev->length = (__u64)ctx->args[1];") + requireContains(t, output, "ev->length2 = (__u64)ctx->args[2];") + requireContains(t, output, "ev->flags = (__u64)ctx->args[3];") +} + func TestGenerateDup3Handler(t *testing.T) { output := generateFromPair(t, FormatDup3, FormatExitDup3) @@ -412,6 +424,7 @@ func TestGenerateAllEventTypes(t *testing.T) { {KindEventfd, "ENTER_EVENTFD_EVENT", "EXIT_EVENTFD_EVENT"}, {KindEpollCtl, "ENTER_EPOLL_CTL_EVENT", "EXIT_EPOLL_CTL_EVENT"}, {KindPoll, "ENTER_POLL_EVENT", "EXIT_POLL_EVENT"}, + {KindMem, "ENTER_MEM_EVENT", "EXIT_MEM_EVENT"}, } for _, tt := range tests { @@ -445,6 +458,7 @@ func TestEventStructNames(t *testing.T) { {KindEventfd, "eventfd_event"}, {KindEpollCtl, "epoll_ctl_event"}, {KindPoll, "poll_event"}, + {KindMem, "mem_event"}, } for _, tt := range tests { @@ -463,7 +477,7 @@ func TestEnterReject(t *testing.T) { t.Error("KindNone should be enter-rejected") } - accepted := []TracepointKind{KindFd, KindOpen, KindPathname, KindName, KindFcntl, KindNull, KindDup3, KindOpenByHandleAt, KindSocket, KindSocketpair, KindAccept, KindPipe, KindEventfd, KindEpollCtl, KindPoll} + accepted := []TracepointKind{KindFd, KindOpen, KindPathname, KindName, KindFcntl, KindNull, KindDup3, KindOpenByHandleAt, KindSocket, KindSocketpair, KindAccept, KindPipe, KindEventfd, KindEpollCtl, KindPoll, KindMem} 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 e8efe99..756ed17 100644 --- a/internal/generate/kindregistry.go +++ b/internal/generate/kindregistry.go @@ -32,6 +32,7 @@ var kindRegistry = map[TracepointKind]kindMeta{ KindEventfd: {structName: "eventfd_event", enterAccepted: true}, KindEpollCtl: {structName: "epoll_ctl_event", enterAccepted: true}, KindPoll: {structName: "poll_event", enterAccepted: true}, + KindMem: {structName: "mem_event", enterAccepted: true}, // KindNone is intentionally absent: it represents "unclassified" and is // never enter-accepted. lookupKind returns the zero kindMeta (enterAccepted=false) // for any unregistered kind, so KindNone is implicitly rejected. diff --git a/internal/generate/testdata.go b/internal/generate/testdata.go index e3e3036..6b08f98 100644 --- a/internal/generate/testdata.go +++ b/internal/generate/testdata.go @@ -201,6 +201,67 @@ format: print fmt: "0x%lx", REC->ret ` +const FormatMunmap = `name: sys_enter_munmap +ID: 696 +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 long addr; offset:16; size:8; signed:0; + field:size_t len; offset:24; size:8; signed:0; + +print fmt: "addr: 0x%08lx, len: 0x%08lx", ((unsigned long)(REC->addr)), ((unsigned long)(REC->len)) +` + +const FormatExitMunmap = `name: sys_exit_munmap +ID: 695 +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 FormatMremap = `name: sys_enter_mremap +ID: 710 +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 long addr; offset:16; size:8; signed:0; + field:unsigned long old_len; offset:24; size:8; signed:0; + field:unsigned long new_len; offset:32; size:8; signed:0; + field:unsigned long flags; offset:40; size:8; signed:0; + field:unsigned long new_addr; offset:48; size:8; signed:0; + +print fmt: "addr: 0x%08lx, old_len: 0x%08lx, new_len: 0x%08lx, flags: 0x%08lx, new_addr: 0x%08lx", ((unsigned long)(REC->addr)), ((unsigned long)(REC->old_len)), ((unsigned long)(REC->new_len)), ((unsigned long)(REC->flags)), ((unsigned long)(REC->new_addr)) +` + +const FormatExitMremap = `name: sys_exit_mremap +ID: 709 +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 FormatExitMsync = `name: sys_exit_msync ID: 1028 format: |
