aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--prog/analysis.go4
-rw-r--r--prog/size_test.go4
-rw-r--r--sys/decl.go2
-rw-r--r--sys/test.txt11
-rw-r--r--sysgen/sysgen.go21
5 files changed, 37 insertions, 5 deletions
diff --git a/prog/analysis.go b/prog/analysis.go
index ad962f3f2..6348a48c6 100644
--- a/prog/analysis.go
+++ b/prog/analysis.go
@@ -160,8 +160,8 @@ func generateSize(arg *Arg, lenType *sys.LenType) *Arg {
case *sys.VmaType:
return pageSizeArg(lenType, arg.AddrPagesNum, 0)
case *sys.ArrayType:
- if lenType.ByteSize {
- return constArg(lenType, arg.Size())
+ if lenType.ByteSize != 0 {
+ return constArg(lenType, arg.Size() / lenType.ByteSize)
} else {
return constArg(lenType, uintptr(len(arg.Inner)))
}
diff --git a/prog/size_test.go b/prog/size_test.go
index 9faa27546..c257eae31 100644
--- a/prog/size_test.go
+++ b/prog/size_test.go
@@ -102,6 +102,10 @@ func TestAssignSize(t *testing.T) {
"syz_test$length15(0xff, 0x0)",
"syz_test$length15(0xff, 0x2)",
},
+ {
+ "syz_test$length16(&(0x7f0000000000)={[0x42, 0x42], 0xff, 0xff, 0xff, 0xff, 0xff})",
+ "syz_test$length16(&(0x7f0000000000)={[0x42, 0x42], 0x2, 0x10, 0x8, 0x4, 0x2})",
+ },
}
for i, test := range tests {
diff --git a/sys/decl.go b/sys/decl.go
index bb82cfa18..63fca61b7 100644
--- a/sys/decl.go
+++ b/sys/decl.go
@@ -157,7 +157,7 @@ type LenType struct {
TypeCommon
TypeSize uintptr
BigEndian bool
- ByteSize bool // want size in bytes instead of array size
+ ByteSize uintptr // want size in multiple of bytes instead of array size
Buf string
}
diff --git a/sys/test.txt b/sys/test.txt
index e6865b467..2c0c489a1 100644
--- a/sys/test.txt
+++ b/sys/test.txt
@@ -97,6 +97,8 @@ syz_test$length13(a0 ptr[inout, syz_length_large_struct], a1 ptr[inout, len[a0,
syz_test$length14(a0 ptr[inout, syz_length_large_struct], a1 ptr[inout, len[a0, int64], opt])
syz_test$length15(a0 int16, a1 len[a0])
+syz_test$length16(a0 ptr[in, syz_length_bytesize_struct])
+
syz_length_flags = 0, 1
syz_length_int_struct {
@@ -167,6 +169,15 @@ syz_length_large_struct {
f2 array[int32, 8]
}
+syz_length_bytesize_struct {
+ f0 array[int64, 2]
+ f1 len[f0, int8]
+ f2 bytesize[f0, int8]
+ f3 bytesize2[f0, int8]
+ f4 bytesize4[f0, int8]
+ f5 bytesize8[f0, int8]
+}
+
# Big endian.
syz_test$end0(a0 ptr[in, syz_end_int_struct])
diff --git a/sysgen/sysgen.go b/sysgen/sysgen.go
index 5bda2ed2b..92258150d 100644
--- a/sysgen/sysgen.go
+++ b/sysgen/sysgen.go
@@ -465,7 +465,7 @@ func generateArg(
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
}
fmt.Fprintf(out, "&VmaType{%v}", common())
- case "len", "bytesize":
+ case "len", "bytesize", "bytesize2", "bytesize4", "bytesize8":
canBeArg = true
size := uint64(ptrSize)
bigEndian := false
@@ -479,7 +479,11 @@ func generateArg(
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
}
}
- fmt.Fprintf(out, "&LenType{%v, Buf: \"%v\", TypeSize: %v, BigEndian: %v, ByteSize: %v}", common(), a[0], size, bigEndian, typ == "bytesize")
+ byteSize := uint8(0)
+ if typ != "len" {
+ byteSize = decodeByteSizeType(typ)
+ }
+ fmt.Fprintf(out, "&LenType{%v, Buf: \"%v\", TypeSize: %v, BigEndian: %v, ByteSize: %v}", common(), a[0], size, bigEndian, byteSize)
case "flags":
canBeArg = true
size := uint64(ptrSize)
@@ -683,6 +687,19 @@ func decodeIntType(typ string) (uint64, bool) {
return uint64(sz / 8), bigEndian
}
+func decodeByteSizeType(typ string) uint8 {
+ switch typ {
+ case "bytesize", "bytesize2", "bytesize4", "bytesize8":
+ default:
+ failf("unknown type %v", typ)
+ }
+ sz := int64(1)
+ if typ != "bytesize" {
+ sz, _ = strconv.ParseInt(typ[8:], 10, 8)
+ }
+ return uint8(sz)
+}
+
func isIdentifier(s string) bool {
for i, c := range s {
if c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || i > 0 && (c >= '0' && c <= '9') {