aboutsummaryrefslogtreecommitdiffstats
path: root/prog/any.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2022-06-03 13:13:18 +0200
committerDmitry Vyukov <dvyukov@google.com>2022-06-03 17:26:50 +0200
commit438e961a3d21d171d2a07c566f0c512b1481e18c (patch)
tree72c4e790e381a9a6f92e2e62e6a0095073dea0f2 /prog/any.go
parent56250633ec0a1d1a77a9f35dd6fe7175142d43d9 (diff)
prog: fix panic in squash of out_overlay structs
We are seeing crashes like: panic: call overlay_uses: result arg overlayres64 references out-of-tree result This is caused by fact that we completely discard out_overlay part during squashing. So if it contains any resources used later, we will get out-of-tree references. Prohibit squashing structs with out_overlay attribute. Alternatives would be either to produce out_overlay struct after squashing as well, or remove all resources in out part from the program. But it does not seem to be worth the complexity (we have few complex structs with out_overlay, if any).
Diffstat (limited to 'prog/any.go')
-rw-r--r--prog/any.go28
1 files changed, 15 insertions, 13 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() {