diff options
| -rw-r--r-- | prog/any.go | 28 | ||||
| -rw-r--r-- | prog/any_test.go | 17 | ||||
| -rw-r--r-- | sys/test/exec.txt | 1 |
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 |
