aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--prog/any.go28
-rw-r--r--prog/any_test.go17
-rw-r--r--sys/test/exec.txt1
3 files changed, 32 insertions, 14 deletions
diff --git a/prog/any.go b/prog/any.go
index 16a309c90..a5106683d 100644
--- a/prog/any.go
+++ b/prog/any.go
@@ -79,10 +79,17 @@ func (target *Target) isComplexPtr(arg *PointerArg) bool {
if target.isAnyPtr(arg.Type()) {
return true
}
- complex, hasPtr := false, false
+ complex, unsupported := false, false
ForeachSubArg(arg.Res, func(a1 Arg, ctx *ArgCtx) {
switch typ := a1.Type().(type) {
case *StructType:
+ if typ.OverlayField != 0 {
+ // Squashing of structs with out_overlay is not supported.
+ // If we do it, we need to be careful to either squash out part as well,
+ // or remove any resources in the out part from the prog.
+ unsupported = true
+ ctx.Stop = true
+ }
if typ.Varlen() {
complex = true
}
@@ -91,11 +98,13 @@ func (target *Target) isComplexPtr(arg *PointerArg) bool {
complex = true
}
case *PtrType:
- hasPtr = true
+ // Squashing of pointers is not supported b/c if we do it
+ // we will pass random garbage as pointers.
+ unsupported = true
ctx.Stop = true
}
})
- return complex && !hasPtr
+ return complex && !unsupported
}
func (target *Target) isAnyRes(name string) bool {
@@ -236,18 +245,11 @@ func (target *Target) squashResult(arg *ResultArg, elems *[]Arg) {
}
func (target *Target) squashGroup(arg *GroupArg, elems *[]Arg) {
- overlayField := 0
- if typ, ok := arg.Type().(*StructType); ok {
- overlayField = typ.OverlayField
+ if typ, ok := arg.Type().(*StructType); ok && typ.OverlayField != 0 {
+ panic("squashing out_overlay")
}
var bitfield, fieldsSize uint64
- for i, fld := range arg.Inner {
- if i != 0 && i == overlayField {
- // We don't squash overlay fields.
- // Theoretically we could produce a squashed struct with overlay as well,
- // but it's quite complex to do.
- break
- }
+ for _, fld := range arg.Inner {
fieldsSize += fld.Size()
// Squash bitfields separately.
if fld.Type().IsBitfield() {
diff --git a/prog/any_test.go b/prog/any_test.go
index f021eeda7..2d08d92fb 100644
--- a/prog/any_test.go
+++ b/prog/any_test.go
@@ -45,12 +45,21 @@ func TestSquash(t *testing.T) {
// nolint: lll
tests := []struct {
prog string
- squashed string
+ squashed string // leave empty if the arg must not be squashed
}{
{
`foo$any0(&(0x7f0000000000)={0x11, 0x11223344, 0x2233, 0x1122334455667788, {0x1, 0x7, 0x1, 0x1, 0x1bc, 0x4}, [{@res32=0x0, @i8=0x44, "aabb"}, {@res64=0x1, @i32=0x11223344, "1122334455667788"}]})`,
`foo$any0(&(0x7f0000000000)=ANY=[@ANYBLOB="1100000044332211223300000000000088776655443322117d00bc11", @ANYRES32=0x0, @ANYBLOB="0000000044aabb00", @ANYRES64=0x1, @ANYBLOB="44332211112233445566778800000000"])`,
},
+ {
+ // Squashing of structs with out_overlay is not supported yet
+ // (used to panic, see isComplexPtr).
+ `
+overlay_any(&(0x7f0000000000)=@overlay2={0x0, 0x0, <r0=>0x0, 0x0})
+overlay_uses(0x0, 0x0, 0x0, r0)
+`,
+ ``,
+ },
}
for i, test := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
@@ -59,6 +68,12 @@ func TestSquash(t *testing.T) {
t.Fatalf("failed to deserialize prog: %v", err)
}
ptrArg := p.Calls[0].Args[0].(*PointerArg)
+ if test.squashed == "" {
+ if target.isComplexPtr(ptrArg) {
+ t.Fatalf("arg is complex and can be squashed")
+ }
+ return
+ }
if !target.isComplexPtr(ptrArg) {
t.Fatalf("arg is not complex")
}
diff --git a/sys/test/exec.txt b/sys/test/exec.txt
index 0de8e2989..5847afe7f 100644
--- a/sys/test/exec.txt
+++ b/sys/test/exec.txt
@@ -253,6 +253,7 @@ resource overlayres64[int64]
overlay_ctor(a ptr[out, overlayres8], b ptr[out, overlayres16], c ptr[out, overlayres32], d ptr[out, overlayres64])
overlay_uses(a overlayres8, b overlayres16, c overlayres32, d overlayres64)
+overlay_any(a ptr[in, compare_data])
overlayres [
res8 overlayres8