summaryrefslogtreecommitdiff
path: root/internal/generate
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-18 14:30:26 +0300
committerPaul Buetow <paul@buetow.org>2026-05-18 14:30:26 +0300
commit7fb497c435596a36c0fb0bd0ecae2a84793bcc70 (patch)
treecc12d16c0e34b034b1fc383a86ec6ffec997381b /internal/generate
parent519cd996b5a7fede23b8b23f3c101d10b26111de (diff)
j6: account bytes for ret-classified syscalls
Diffstat (limited to 'internal/generate')
-rw-r--r--internal/generate/classify_test.go61
-rw-r--r--internal/generate/retclassify_test.go25
2 files changed, 86 insertions, 0 deletions
diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go
index f02f7de..4dd216e 100644
--- a/internal/generate/classify_test.go
+++ b/internal/generate/classify_test.go
@@ -338,6 +338,67 @@ func TestClassifySyscallPairEmitsAllFamilies(t *testing.T) {
}
}
+func TestClassifyPhaseAByteSyscallPairsAccepted(t *testing.T) {
+ tests := []struct {
+ name string
+ enterKindText string
+ retText string
+ }{
+ {"recvfrom", "struct fd_event", "READ_CLASSIFIED"},
+ {"recvmsg", "struct fd_event", "READ_CLASSIFIED"},
+ {"sendto", "struct fd_event", "WRITE_CLASSIFIED"},
+ {"sendmsg", "struct fd_event", "WRITE_CLASSIFIED"},
+ {"sendfile64", "struct null_event", "TRANSFER_CLASSIFIED"},
+ {"splice", "struct null_event", "TRANSFER_CLASSIFIED"},
+ {"tee", "struct null_event", "TRANSFER_CLASSIFIED"},
+ {"process_vm_readv", "struct null_event", "READ_CLASSIFIED"},
+ {"process_vm_writev", "struct null_event", "WRITE_CLASSIFIED"},
+ }
+
+ for i, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ formats := phaseAFormats(tt.name, 9000+i*2)
+ output := GenerateTracepointsC(formats)
+ if strings.Contains(output, "Ignoring") || strings.Contains(output, "Skipping") {
+ t.Fatalf("syscall %s was not accepted:\n%s", tt.name, output)
+ }
+ if !strings.Contains(output, "/// sys_enter_"+tt.name+" is a "+tt.enterKindText) {
+ t.Fatalf("sys_enter_%s did not use %s:\n%s", tt.name, tt.enterKindText, output)
+ }
+ if !strings.Contains(output, "/// sys_exit_"+tt.name+" is a struct ret_event ("+tt.retText+")") {
+ t.Fatalf("sys_exit_%s did not use %s:\n%s", tt.name, tt.retText, output)
+ }
+ })
+ }
+}
+
+func phaseAFormats(name string, enterID int) []Format {
+ enterFields := []Field{
+ {Type: "long", Name: "__syscall_nr"},
+ }
+ if name == "sendto" || name == "recvfrom" || name == "sendmsg" || name == "recvmsg" {
+ enterFields = append(enterFields, Field{Type: "int", Name: "fd"})
+ }
+
+ return []Format{
+ {
+ Name: "sys_enter_" + name,
+ ID: enterID,
+ Family: ClassifySyscallFamily("sys_enter_" + name),
+ ExternalFields: enterFields,
+ },
+ {
+ Name: "sys_exit_" + name,
+ ID: enterID - 1,
+ Family: ClassifySyscallFamily("sys_exit_" + name),
+ ExternalFields: []Field{
+ {Type: "long", Name: "__syscall_nr"},
+ {Type: "long", Name: "ret"},
+ },
+ },
+ }
+}
+
func TestClassifyFormatNoExternalFields(t *testing.T) {
f := &Format{
Name: "sys_enter_test",
diff --git a/internal/generate/retclassify_test.go b/internal/generate/retclassify_test.go
index 3152005..9a75a15 100644
--- a/internal/generate/retclassify_test.go
+++ b/internal/generate/retclassify_test.go
@@ -57,3 +57,28 @@ func TestClassifyRetCaseInsensitive(t *testing.T) {
t.Errorf("ClassifyRet(sys_exit_READ) = %q, want READ_CLASSIFIED", got)
}
}
+
+func TestPhaseAByteClassifiedSyscallsUseExistingRetClassifications(t *testing.T) {
+ tests := []struct {
+ name string
+ want RetClassification
+ }{
+ {"recvfrom", ReadClassified},
+ {"recvmsg", ReadClassified},
+ {"sendto", WriteClassified},
+ {"sendmsg", WriteClassified},
+ {"sendfile64", TransferClassified},
+ {"splice", TransferClassified},
+ {"tee", TransferClassified},
+ {"process_vm_readv", ReadClassified},
+ {"process_vm_writev", WriteClassified},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := ClassifyRet("sys_exit_" + tt.name); got != tt.want {
+ t.Fatalf("ClassifyRet(sys_exit_%s) = %q, want %q", tt.name, got, tt.want)
+ }
+ })
+ }
+}