mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-28 05:40:26 +00:00
959ec07095
Currently we store most types by value in sys.Type. This is somewhat counter-intuitive for C++ programmers, because one can't easily update the type object. Store pointers to type objects for all types. It also makes it easier to update types, e.g. adding paddings.
81 lines
1.6 KiB
Go
81 lines
1.6 KiB
Go
// Copyright 2015 syzkaller project authors. All rights reserved.
|
|
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
|
|
|
package sys
|
|
|
|
func initAlign() {
|
|
var rec func(t Type)
|
|
rec = func(t Type) {
|
|
switch t1 := t.(type) {
|
|
case *PtrType:
|
|
rec(t1.Type)
|
|
case *ArrayType:
|
|
rec(t1.Type)
|
|
case *StructType:
|
|
if !t1.padded {
|
|
t1.padded = true
|
|
for _, f := range t1.Fields {
|
|
rec(f)
|
|
}
|
|
addAlignment(t1)
|
|
}
|
|
case *UnionType:
|
|
for _, opt := range t1.Options {
|
|
rec(opt)
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, s := range Structs {
|
|
rec(s)
|
|
}
|
|
}
|
|
|
|
func addAlignment(t *StructType) {
|
|
if t.packed {
|
|
return
|
|
}
|
|
var fields []Type
|
|
var off, align uintptr
|
|
varLen := false
|
|
for i, f := range t.Fields {
|
|
a := f.Align()
|
|
if align < a {
|
|
align = a
|
|
}
|
|
if off%a != 0 {
|
|
pad := a - off%a
|
|
off += pad
|
|
fields = append(fields, makePad(pad))
|
|
}
|
|
fields = append(fields, f)
|
|
if at, ok := f.(*ArrayType); ok && (at.Kind == ArrayRandLen || (at.Kind == ArrayRangeLen && at.RangeBegin != at.RangeEnd)) {
|
|
varLen = true
|
|
}
|
|
if at, ok := f.(*BufferType); ok && (at.Kind == BufferBlobRand || (at.Kind == BufferBlobRange && at.RangeBegin != at.RangeEnd)) {
|
|
varLen = true
|
|
}
|
|
if varLen && i != len(t.Fields)-1 {
|
|
panic("embed array in middle of a struct")
|
|
}
|
|
if !varLen {
|
|
off += f.Size()
|
|
}
|
|
}
|
|
if align != 0 && off%align != 0 && !varLen {
|
|
pad := align - off%align
|
|
off += pad
|
|
fields = append(fields, makePad(pad))
|
|
}
|
|
t.Fields = fields
|
|
}
|
|
|
|
func makePad(sz uintptr) Type {
|
|
return &ConstType{
|
|
TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false},
|
|
TypeSize: sz,
|
|
Val: 0,
|
|
IsPad: true,
|
|
}
|
|
}
|