aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-02-26 18:21:51 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-02-26 18:21:51 +0100
commit6284466bc9b948ccf0bfbdb4c80475712d1883c0 (patch)
tree0362f921e431f15a3b8b8cee3da5dec5bf6ac823
parentd1322dff4c35c033147ce97845e394576d42d7e9 (diff)
prog: properly squash bitfields
-rw-r--r--executor/syscalls_test.h4
-rw-r--r--prog/any.go34
-rw-r--r--prog/any_test.go4
-rw-r--r--sys/test/32.go14
-rw-r--r--sys/test/64.go14
-rw-r--r--sys/test/any.txt12
6 files changed, 68 insertions, 14 deletions
diff --git a/executor/syscalls_test.h b/executor/syscalls_test.h
index db1591e1f..aa35c1fef 100644
--- a/executor/syscalls_test.h
+++ b/executor/syscalls_test.h
@@ -2,7 +2,7 @@
#if 0
#define GOARCH "32"
-#define SYZ_REVISION "0d78e9b1f441c9ae33361f9778195af0a245ffdd"
+#define SYZ_REVISION "10a1935b1f3ef8f206e29a3b6863de4cac10bd9e"
#define SYZ_PAGE_SIZE 8192
#define SYZ_NUM_PAGES 2048
#define SYZ_DATA_OFFSET 536870912
@@ -104,7 +104,7 @@ call_t syscalls[] = {
#if 0
#define GOARCH "64"
-#define SYZ_REVISION "e361957ea430829459298bc20840e4edbd324930"
+#define SYZ_REVISION "7c718fa299ed570a4acbd25a1fcf2448c4e2a2d4"
#define SYZ_PAGE_SIZE 4096
#define SYZ_NUM_PAGES 4096
#define SYZ_DATA_OFFSET 536870912
diff --git a/prog/any.go b/prog/any.go
index 32c2fdaa6..76e9723b5 100644
--- a/prog/any.go
+++ b/prog/any.go
@@ -209,7 +209,7 @@ func (target *Target) squashPtr(arg *PointerArg, preserveField bool) {
}
func (target *Target) squashPtrImpl(a Arg, elems *[]Arg) {
- if a.Type().BitfieldMiddle() {
+ if a.Type().BitfieldLength() != 0 {
panic("bitfield in squash")
}
var pad uint64
@@ -218,8 +218,7 @@ func (target *Target) squashPtrImpl(a Arg, elems *[]Arg) {
if IsPad(arg.Type()) {
pad = arg.Size()
} else {
- // Note: we need a constant value, but it depends on pid for proc.
- v := arg.ValueForProc(0)
+ v := target.squashConst(arg)
elem := target.ensureDataElem(elems)
for i := uint64(0); i < arg.Size(); i++ {
elem.data = append(elem.Data(), byte(v))
@@ -272,9 +271,23 @@ func (target *Target) squashPtrImpl(a Arg, elems *[]Arg) {
pad = typ.AlignAttr - fieldsSize%typ.AlignAttr
}
}
+ var bitfield uint64
for _, fld := range arg.Inner {
- if fld.Type().BitfieldMiddle() {
- // TODO(dvyukov): handle bitfields
+ // Squash bitfields separately.
+ if bfLen := fld.Type().BitfieldLength(); bfLen != 0 {
+ bfOff := fld.Type().BitfieldOffset()
+ // Note: we can have a ResultArg here as well,
+ // but it is unsupported at the moment.
+ v := target.squashConst(fld.(*ConstArg))
+ bitfield |= (v & ((1 << bfLen) - 1)) << bfOff
+ if !fld.Type().BitfieldMiddle() {
+ elem := target.ensureDataElem(elems)
+ for i := uint64(0); i < fld.Size(); i++ {
+ elem.data = append(elem.Data(), byte(bitfield))
+ bitfield >>= 8
+ }
+ bitfield = 0
+ }
continue
}
target.squashPtrImpl(fld, elems)
@@ -288,6 +301,17 @@ func (target *Target) squashPtrImpl(a Arg, elems *[]Arg) {
}
}
+func (target *Target) squashConst(arg *ConstArg) uint64 {
+ // Note: we need a constant value, but it depends on pid for proc.
+ v := arg.ValueForProc(0)
+ if _, ok := arg.Type().(*CsumType); ok {
+ // We can't compute value for the checksum here,
+ // but at least leave something recognizable by hints code.
+ v = 0xabcdef1234567890
+ }
+ return v
+}
+
func (target *Target) ensureDataElem(elems *[]Arg) *DataArg {
if len(*elems) == 0 {
res := MakeDataArg(target.anyBlob, nil)
diff --git a/prog/any_test.go b/prog/any_test.go
index 104f77f9d..dee9246ea 100644
--- a/prog/any_test.go
+++ b/prog/any_test.go
@@ -39,8 +39,8 @@ func TestSquash(t *testing.T) {
squashed string
}{
{
- `foo$any0(&(0x7f0000000000)={0x11, 0x11223344, 0x2233, 0x1122334455667788, [{0x0, @res32=0x0, 0x0, @i8=0x44, "aabb"}, {0x0, @res64=0x1, 0x0, @i32=0x11223344, "1122334455667788"}]})`,
- `foo$any0(&(0x7f0000000000)=ANY=[@ANYBLOB="1100000044332211223300000000000088776655443322110000000000000000", @ANYRES32=0x0, @ANYBLOB="00000000000000000000000044aabb000000000000000000", @ANYRES64=0x1, @ANYBLOB="0000000000000000443322111122334455667788"])`,
+ `foo$any0(&(0x7f0000000000)={0x11, 0x11223344, 0x2233, 0x1122334455667788, {0x1, 0x7, 0x1, 0x1, 0x1bc, 0x4}, [{0x0, @res32=0x0, 0x0, @i8=0x44, "aabb"}, {0x0, @res64=0x1, 0x0, @i32=0x11223344, "1122334455667788"}]})`,
+ `foo$any0(&(0x7f0000000000)=ANY=[@ANYBLOB="1100000044332211223300000000000088776655443322113d0079230000000000000000", @ANYRES32=0x0, @ANYBLOB="00000000000000000000000044aabb000000000000000000", @ANYRES64=0x1, @ANYBLOB="000000000000000044332211112233445566778800000000"])`,
},
}
for i, test := range tests {
diff --git a/sys/test/32.go b/sys/test/32.go
index ca7c3715e..8b3dc2892 100644
--- a/sys/test/32.go
+++ b/sys/test/32.go
@@ -23,7 +23,8 @@ var structDescs_32 = []*KeyedStruct{
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16be", FldName: "f3", TypeSize: 2}, BigEndian: true}},
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 6}}, IsPad: true},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "f4", TypeSize: 8}}},
- &ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f5", IsVarlen: true}, Type: &StructType{Key: StructKey{Name: "any1"}}},
+ &StructType{Key: StructKey{Name: "anybitfields"}, FldName: "f5"},
+ &ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f6", IsVarlen: true}, Type: &StructType{Key: StructKey{Name: "any1"}}},
}, AlignAttr: 8}},
{Key: StructKey{Name: "any1"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "any1", IsVarlen: true}, Fields: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "f1", TypeSize: 4, IsOptional: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", TypeSize: 1}}}},
@@ -32,6 +33,15 @@ var structDescs_32 = []*KeyedStruct{
&UnionType{Key: StructKey{Name: "anyunion1"}, FldName: "f4"},
&BufferType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f5", IsVarlen: true}},
}, AlignAttr: 2}},
+ {Key: StructKey{Name: "anybitfields"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "anybitfields", TypeSize: 4}, Fields: []Type{
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "f1", TypeSize: 1}, BitfieldLen: 2, BitfieldMdl: true}},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "f2", TypeSize: 1}, BitfieldOff: 2, BitfieldLen: 3, BitfieldMdl: true}},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "f3", TypeSize: 1}, BitfieldOff: 5, BitfieldLen: 1}},
+ &ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 1}}, IsPad: true},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "f4", TypeSize: 2}, BitfieldLen: 1, BitfieldMdl: true}},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "f5", TypeSize: 2}, BitfieldOff: 1, BitfieldLen: 10, BitfieldMdl: true}},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "f6", TypeSize: 2}, BitfieldOff: 11, BitfieldLen: 3}},
+ }}},
{Key: StructKey{Name: "anyunion0"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "anyunion0", TypeSize: 8}, Fields: []Type{
&ResourceType{TypeCommon: TypeCommon{TypeName: "anyres32", FldName: "res32", TypeSize: 4}},
&ResourceType{TypeCommon: TypeCommon{TypeName: "anyres64", FldName: "res64", TypeSize: 8}},
@@ -772,4 +782,4 @@ var consts_32 = []ConstValue{
{Name: "ONLY_32BITS_CONST", Value: 1},
}
-const revision_32 = "0d78e9b1f441c9ae33361f9778195af0a245ffdd"
+const revision_32 = "10a1935b1f3ef8f206e29a3b6863de4cac10bd9e"
diff --git a/sys/test/64.go b/sys/test/64.go
index 9407c1873..ed996452d 100644
--- a/sys/test/64.go
+++ b/sys/test/64.go
@@ -23,7 +23,8 @@ var structDescs_64 = []*KeyedStruct{
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16be", FldName: "f3", TypeSize: 2}, BigEndian: true}},
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 6}}, IsPad: true},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "f4", TypeSize: 8}}},
- &ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f5", IsVarlen: true}, Type: &StructType{Key: StructKey{Name: "any1"}}},
+ &StructType{Key: StructKey{Name: "anybitfields"}, FldName: "f5"},
+ &ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f6", IsVarlen: true}, Type: &StructType{Key: StructKey{Name: "any1"}}},
}, AlignAttr: 8}},
{Key: StructKey{Name: "any1"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "any1", IsVarlen: true}, Fields: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "f1", TypeSize: 8, IsOptional: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", TypeSize: 1}}}},
@@ -32,6 +33,15 @@ var structDescs_64 = []*KeyedStruct{
&UnionType{Key: StructKey{Name: "anyunion1"}, FldName: "f4"},
&BufferType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f5", IsVarlen: true}},
}, AlignAttr: 2}},
+ {Key: StructKey{Name: "anybitfields"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "anybitfields", TypeSize: 4}, Fields: []Type{
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "f1", TypeSize: 1}, BitfieldLen: 2, BitfieldMdl: true}},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "f2", TypeSize: 1}, BitfieldOff: 2, BitfieldLen: 3, BitfieldMdl: true}},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "f3", TypeSize: 1}, BitfieldOff: 5, BitfieldLen: 1}},
+ &ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 1}}, IsPad: true},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "f4", TypeSize: 2}, BitfieldLen: 1, BitfieldMdl: true}},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "f5", TypeSize: 2}, BitfieldOff: 1, BitfieldLen: 10, BitfieldMdl: true}},
+ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "f6", TypeSize: 2}, BitfieldOff: 11, BitfieldLen: 3}},
+ }}},
{Key: StructKey{Name: "anyunion0"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "anyunion0", TypeSize: 8}, Fields: []Type{
&ResourceType{TypeCommon: TypeCommon{TypeName: "anyres32", FldName: "res32", TypeSize: 4}},
&ResourceType{TypeCommon: TypeCommon{TypeName: "anyres64", FldName: "res64", TypeSize: 8}},
@@ -770,4 +780,4 @@ var consts_64 = []ConstValue{
{Name: "IPPROTO_UDP", Value: 17},
}
-const revision_64 = "e361957ea430829459298bc20840e4edbd324930"
+const revision_64 = "7c718fa299ed570a4acbd25a1fcf2448c4e2a2d4"
diff --git a/sys/test/any.txt b/sys/test/any.txt
index 6a4e285ac..b0a0d0162 100644
--- a/sys/test/any.txt
+++ b/sys/test/any.txt
@@ -13,7 +13,8 @@ any0 {
f2 int32
f3 int16be
f4 int64
- f5 array[any1]
+ f5 anybitfields
+ f6 array[any1]
} [align_8]
any1 {
@@ -33,3 +34,12 @@ anyunion1 [
i8 int8
i32 int32
] [varlen]
+
+anybitfields {
+ f1 int8:2
+ f2 int8:3
+ f3 int8:1
+ f4 int16:1
+ f5 int16:10
+ f6 int16:3
+}