summaryrefslogtreecommitdiff
path: root/internal/generate
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-20 07:23:45 +0300
committerPaul Buetow <paul@buetow.org>2026-05-20 07:23:45 +0300
commitdf1225efe494cc81513cf98e93891376e45f9615 (patch)
tree8fe131ba9ae5737022f26fcd60e662c1660329c6 /internal/generate
parent11a8642b7035ff558fb84d7761e93525c84e4908 (diff)
task 07: add KindMem and separate address-space byte accounting
Diffstat (limited to 'internal/generate')
-rw-r--r--internal/generate/bpfhandler.go13
-rw-r--r--internal/generate/classify.go5
-rw-r--r--internal/generate/classify_test.go18
-rw-r--r--internal/generate/codegen_test.go16
-rw-r--r--internal/generate/kindregistry.go1
-rw-r--r--internal/generate/testdata.go61
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: