Best Syzkaller code snippet using compiler.isVarlen
types.go
Source:types.go
1// Copyright 2015/2016 syzkaller project authors. All rights reserved.2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.3package prog4import (5 "fmt"6 "strings"7 "unicode"8)9type Syscall struct {10 ID int11 NR uint64 // kernel syscall number12 Name string13 CallName string14 MissingArgs int // number of trailing args that should be zero-filled15 Args []Field16 Ret Type17 Attrs SyscallAttrs18 inputResources []*ResourceDesc19 outputResources []*ResourceDesc20}21// SyscallAttrs represents call attributes in syzlang.22//23// This structure is the source of truth for the all other parts of the system.24// pkg/compiler uses this structure to parse descriptions.25// syz-sysgen uses this structure to generate code for executor.26//27// Only bool's and uint64's are currently supported.28//29// See docs/syscall_descriptions_syntax.md for description of individual attributes.30type SyscallAttrs struct {31 Disabled bool32 Timeout uint6433 ProgTimeout uint6434 IgnoreReturn bool35 BreaksReturns bool36}37// MaxArgs is maximum number of syscall arguments.38// Executor also knows about this value.39const MaxArgs = 940type Dir uint841const (42 DirIn Dir = iota43 DirOut44 DirInOut45)46func (dir Dir) String() string {47 switch dir {48 case DirIn:49 return "in"50 case DirOut:51 return "out"52 case DirInOut:53 return "inout"54 default:55 panic("unknown dir")56 }57}58type Field struct {59 Name string60 Type61}62type BinaryFormat int63const (64 FormatNative BinaryFormat = iota65 FormatBigEndian66 FormatStrDec67 FormatStrHex68 FormatStrOct69)70type Type interface {71 String() string72 Name() string73 TemplateName() string // for template structs name without arguments74 Optional() bool75 Varlen() bool76 Size() uint6477 TypeBitSize() uint6478 Format() BinaryFormat79 BitfieldOffset() uint6480 BitfieldLength() uint6481 IsBitfield() bool82 // For most of the types UnitSize is equal to Size.83 // These are different only for all but last bitfield in the group,84 // where Size == 0 and UnitSize equals to the underlying bitfield type size.85 UnitSize() uint6486 UnitOffset() uint6487 DefaultArg(dir Dir) Arg88 isDefaultArg(arg Arg) bool89 generate(r *randGen, s *state, dir Dir) (arg Arg, calls []*Call)90 mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Call, retry, preserve bool)91 getMutationPrio(target *Target, arg Arg, ignoreSpecial bool) (prio float64, stopRecursion bool)92 minimize(ctx *minimizeArgsCtx, arg Arg, path string) bool93 ref() Ref94 setRef(ref Ref)95}96type Ref uint3297func (ti Ref) String() string { panic("prog.Ref method called") }98func (ti Ref) Name() string { panic("prog.Ref method called") }99func (ti Ref) TemplateName() string { panic("prog.Ref method called") }100func (ti Ref) Optional() bool { panic("prog.Ref method called") }101func (ti Ref) Varlen() bool { panic("prog.Ref method called") }102func (ti Ref) Size() uint64 { panic("prog.Ref method called") }103func (ti Ref) TypeBitSize() uint64 { panic("prog.Ref method called") }104func (ti Ref) Format() BinaryFormat { panic("prog.Ref method called") }105func (ti Ref) BitfieldOffset() uint64 { panic("prog.Ref method called") }106func (ti Ref) BitfieldLength() uint64 { panic("prog.Ref method called") }107func (ti Ref) IsBitfield() bool { panic("prog.Ref method called") }108func (ti Ref) UnitSize() uint64 { panic("prog.Ref method called") }109func (ti Ref) UnitOffset() uint64 { panic("prog.Ref method called") }110func (ti Ref) DefaultArg(dir Dir) Arg { panic("prog.Ref method called") }111func (ti Ref) Clone() Type { panic("prog.Ref method called") }112func (ti Ref) isDefaultArg(arg Arg) bool { panic("prog.Ref method called") }113func (ti Ref) generate(r *randGen, s *state, dir Dir) (Arg, []*Call) { panic("prog.Ref method called") }114func (ti Ref) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) ([]*Call, bool, bool) {115 panic("prog.Ref method called")116}117func (ti Ref) getMutationPrio(target *Target, arg Arg, ignoreSpecial bool) (float64, bool) {118 panic("prog.Ref method called")119}120func (ti Ref) minimize(ctx *minimizeArgsCtx, arg Arg, path string) bool {121 panic("prog.Ref method called")122}123func (ti Ref) ref() Ref { panic("prog.Ref method called") }124func (ti Ref) setRef(ref Ref) { panic("prog.Ref method called") }125func IsPad(t Type) bool {126 if ct, ok := t.(*ConstType); ok && ct.IsPad {127 return true128 }129 return false130}131type TypeCommon struct {132 TypeName string133 // Static size of the type, or 0 for variable size types and all but last bitfields in the group.134 TypeSize uint64135 IsOptional bool136 IsVarlen bool137 self Ref138}139func (t *TypeCommon) Name() string {140 return t.TypeName141}142func (t *TypeCommon) TemplateName() string {143 name := t.TypeName144 if pos := strings.IndexByte(name, '['); pos != -1 {145 name = name[:pos]146 }147 return name148}149func (t *TypeCommon) Optional() bool {150 return t.IsOptional151}152func (t *TypeCommon) Size() uint64 {153 if t.IsVarlen {154 panic(fmt.Sprintf("static type size is not known: %#v", t))155 }156 return t.TypeSize157}158func (t *TypeCommon) TypeBitSize() uint64 {159 panic("cannot get the bitsize for a non-integer type")160}161func (t *TypeCommon) Varlen() bool {162 return t.IsVarlen163}164func (t *TypeCommon) Format() BinaryFormat {165 return FormatNative166}167func (t *TypeCommon) BitfieldOffset() uint64 {168 return 0169}170func (t *TypeCommon) BitfieldLength() uint64 {171 return 0172}173func (t *TypeCommon) UnitSize() uint64 {174 return t.Size()175}176func (t *TypeCommon) UnitOffset() uint64 {177 return 0178}179func (t *TypeCommon) IsBitfield() bool {180 return false181}182func (t *TypeCommon) ref() Ref {183 if t.self == 0 {184 panic("ref is not assigned yet")185 }186 return t.self187}188func (t *TypeCommon) setRef(ref Ref) {189 t.self = ref190}191type ResourceDesc struct {192 Name string193 Kind []string194 Values []uint64195 Ctors []ResourceCtor196}197type ResourceCtor struct {198 Call int // Index in Target.Syscalls199 Precise bool200}201type ResourceType struct {202 TypeCommon203 ArgFormat BinaryFormat204 Desc *ResourceDesc205}206func (t *ResourceType) String() string {207 return t.Name()208}209func (t *ResourceType) DefaultArg(dir Dir) Arg {210 return MakeResultArg(t, dir, nil, t.Default())211}212func (t *ResourceType) isDefaultArg(arg Arg) bool {213 a := arg.(*ResultArg)214 return a.Res == nil && a.OpDiv == 0 && a.OpAdd == 0 &&215 len(a.uses) == 0 && a.Val == t.Default()216}217func (t *ResourceType) Default() uint64 {218 return t.Desc.Values[0]219}220func (t *ResourceType) SpecialValues() []uint64 {221 return t.Desc.Values222}223func (t *ResourceType) Format() BinaryFormat {224 return t.ArgFormat225}226type IntTypeCommon struct {227 TypeCommon228 ArgFormat BinaryFormat229 BitfieldOff uint64230 BitfieldLen uint64231 BitfieldUnit uint64232 BitfieldUnitOff uint64233}234func (t *IntTypeCommon) String() string {235 return t.Name()236}237func (t *IntTypeCommon) Format() BinaryFormat {238 return t.ArgFormat239}240// Returns the size in bits for integers in binary format or 64 for string-formatted integers. The return241// value is used in computing limits and truncating other values.242func (t *IntTypeCommon) TypeBitSize() uint64 {243 if t.ArgFormat != FormatNative && t.ArgFormat != FormatBigEndian {244 // TODO: add special cases for mutation and generation of string-formatted integers.245 return 64246 }247 if t.BitfieldLen != 0 {248 return t.BitfieldLen249 }250 return t.TypeSize * 8251}252func (t *IntTypeCommon) BitfieldOffset() uint64 {253 return t.BitfieldOff254}255func (t *IntTypeCommon) BitfieldLength() uint64 {256 return t.BitfieldLen257}258func (t *IntTypeCommon) UnitSize() uint64 {259 if t.BitfieldLen != 0 {260 return t.BitfieldUnit261 }262 return t.Size()263}264func (t *IntTypeCommon) UnitOffset() uint64 {265 return t.BitfieldUnitOff266}267func (t *IntTypeCommon) IsBitfield() bool {268 return t.BitfieldLen != 0269}270type ConstType struct {271 IntTypeCommon272 Val uint64273 IsPad bool274}275func (t *ConstType) DefaultArg(dir Dir) Arg {276 return MakeConstArg(t, dir, t.Val)277}278func (t *ConstType) isDefaultArg(arg Arg) bool {279 return arg.(*ConstArg).Val == t.Val280}281func (t *ConstType) String() string {282 if t.IsPad {283 return fmt.Sprintf("pad[%v]", t.Size())284 }285 return fmt.Sprintf("const[%v, %v]", t.Val, t.IntTypeCommon.String())286}287type IntKind int288const (289 IntPlain IntKind = iota290 IntRange291)292type IntType struct {293 IntTypeCommon294 Kind IntKind295 RangeBegin uint64296 RangeEnd uint64297 Align uint64298}299func (t *IntType) DefaultArg(dir Dir) Arg {300 return MakeConstArg(t, dir, 0)301}302func (t *IntType) isDefaultArg(arg Arg) bool {303 return arg.(*ConstArg).Val == 0304}305type FlagsType struct {306 IntTypeCommon307 Vals []uint64 // compiler ensures that it's not empty308 BitMask bool309}310func (t *FlagsType) DefaultArg(dir Dir) Arg {311 return MakeConstArg(t, dir, 0)312}313func (t *FlagsType) isDefaultArg(arg Arg) bool {314 return arg.(*ConstArg).Val == 0315}316type LenType struct {317 IntTypeCommon318 BitSize uint64 // want size in multiple of bits instead of array size319 Offset bool // offset from the beginning of the parent struct or base object320 Path []string321}322func (t *LenType) DefaultArg(dir Dir) Arg {323 return MakeConstArg(t, dir, 0)324}325func (t *LenType) isDefaultArg(arg Arg) bool {326 return arg.(*ConstArg).Val == 0327}328type ProcType struct {329 IntTypeCommon330 ValuesStart uint64331 ValuesPerProc uint64332}333const (334 MaxPids = 32335 procDefaultValue = 0xffffffffffffffff // special value denoting 0 for all procs336)337func (t *ProcType) DefaultArg(dir Dir) Arg {338 return MakeConstArg(t, dir, procDefaultValue)339}340func (t *ProcType) isDefaultArg(arg Arg) bool {341 return arg.(*ConstArg).Val == procDefaultValue342}343type CsumKind int344const (345 CsumInet CsumKind = iota346 CsumPseudo347)348type CsumType struct {349 IntTypeCommon350 Kind CsumKind351 Buf string352 Protocol uint64 // for CsumPseudo353}354func (t *CsumType) String() string {355 return "csum"356}357func (t *CsumType) DefaultArg(dir Dir) Arg {358 return MakeConstArg(t, dir, 0)359}360func (t *CsumType) isDefaultArg(arg Arg) bool {361 return arg.(*ConstArg).Val == 0362}363type VmaType struct {364 TypeCommon365 RangeBegin uint64 // in pages366 RangeEnd uint64367}368func (t *VmaType) String() string {369 return "vma"370}371func (t *VmaType) DefaultArg(dir Dir) Arg {372 return MakeSpecialPointerArg(t, dir, 0)373}374func (t *VmaType) isDefaultArg(arg Arg) bool {375 a := arg.(*PointerArg)376 return a.IsSpecial() && a.Address == 0377}378type BufferKind int379const (380 BufferBlobRand BufferKind = iota381 BufferBlobRange382 BufferString383 BufferFilename384 BufferText385)386type TextKind int387const (388 TextTarget TextKind = iota389 TextX86Real390 TextX86bit16391 TextX86bit32392 TextX86bit64393 TextArm64394)395type BufferType struct {396 TypeCommon397 Kind BufferKind398 RangeBegin uint64 // for BufferBlobRange kind399 RangeEnd uint64 // for BufferBlobRange kind400 Text TextKind // for BufferText401 SubKind string402 Values []string // possible values for BufferString kind403 NoZ bool // non-zero terminated BufferString/BufferFilename404}405func (t *BufferType) String() string {406 return "buffer"407}408func (t *BufferType) DefaultArg(dir Dir) Arg {409 if dir == DirOut {410 var sz uint64411 if !t.Varlen() {412 sz = t.Size()413 }414 return MakeOutDataArg(t, dir, sz)415 }416 var data []byte417 if !t.Varlen() {418 data = make([]byte, t.Size())419 }420 return MakeDataArg(t, dir, data)421}422func (t *BufferType) isDefaultArg(arg Arg) bool {423 a := arg.(*DataArg)424 if a.Size() == 0 {425 return true426 }427 if a.Type().Varlen() {428 return false429 }430 if a.Dir() == DirOut {431 return true432 }433 for _, v := range a.Data() {434 if v != 0 {435 return false436 }437 }438 return true439}440type ArrayKind int441const (442 ArrayRandLen ArrayKind = iota443 ArrayRangeLen444)445type ArrayType struct {446 TypeCommon447 Elem Type448 Kind ArrayKind449 RangeBegin uint64450 RangeEnd uint64451}452func (t *ArrayType) String() string {453 return fmt.Sprintf("array[%v]", t.Elem.String())454}455func (t *ArrayType) DefaultArg(dir Dir) Arg {456 var elems []Arg457 if t.Kind == ArrayRangeLen && t.RangeBegin == t.RangeEnd {458 for i := uint64(0); i < t.RangeBegin; i++ {459 elems = append(elems, t.Elem.DefaultArg(dir))460 }461 }462 return MakeGroupArg(t, dir, elems)463}464func (t *ArrayType) isDefaultArg(arg Arg) bool {465 a := arg.(*GroupArg)466 if !a.fixedInnerSize() && len(a.Inner) != 0 {467 return false468 }469 for _, elem := range a.Inner {470 if !isDefault(elem) {471 return false472 }473 }474 return true475}476type PtrType struct {477 TypeCommon478 Elem Type479 ElemDir Dir480}481func (t *PtrType) String() string {482 return fmt.Sprintf("ptr[%v, %v]", t.ElemDir, t.Elem.String())483}484func (t *PtrType) DefaultArg(dir Dir) Arg {485 if t.Optional() {486 return MakeSpecialPointerArg(t, dir, 0)487 }488 return MakePointerArg(t, dir, 0, t.Elem.DefaultArg(t.ElemDir))489}490func (t *PtrType) isDefaultArg(arg Arg) bool {491 a := arg.(*PointerArg)492 if t.Optional() {493 return a.IsSpecial() && a.Address == 0494 }495 return a.Address == 0 && a.Res != nil && isDefault(a.Res)496}497type StructType struct {498 TypeCommon499 Fields []Field500 AlignAttr uint64501}502func (t *StructType) String() string {503 return t.Name()504}505func (t *StructType) DefaultArg(dir Dir) Arg {506 inner := make([]Arg, len(t.Fields))507 for i, field := range t.Fields {508 inner[i] = field.DefaultArg(dir)509 }510 return MakeGroupArg(t, dir, inner)511}512func (t *StructType) isDefaultArg(arg Arg) bool {513 a := arg.(*GroupArg)514 for _, elem := range a.Inner {515 if !isDefault(elem) {516 return false517 }518 }519 return true520}521type UnionType struct {522 TypeCommon523 Fields []Field524}525func (t *UnionType) String() string {526 return t.Name()527}528func (t *UnionType) DefaultArg(dir Dir) Arg {529 return MakeUnionArg(t, dir, t.Fields[0].DefaultArg(dir), 0)530}531func (t *UnionType) isDefaultArg(arg Arg) bool {532 a := arg.(*UnionArg)533 return a.Index == 0 && isDefault(a.Option)534}535type ConstValue struct {536 Name string537 Value uint64538}539type TypeCtx struct {540 Meta *Syscall541 Dir Dir542 Ptr *Type543}544func ForeachType(syscalls []*Syscall, f func(t Type, ctx TypeCtx)) {545 for _, meta := range syscalls {546 foreachTypeImpl(meta, true, f)547 }548}549func ForeachTypePost(syscalls []*Syscall, f func(t Type, ctx TypeCtx)) {550 for _, meta := range syscalls {551 foreachTypeImpl(meta, false, f)552 }553}554func ForeachCallType(meta *Syscall, f func(t Type, ctx TypeCtx)) {555 foreachTypeImpl(meta, true, f)556}557func foreachTypeImpl(meta *Syscall, preorder bool, f func(t Type, ctx TypeCtx)) {558 // Note: we specifically don't create seen in ForeachType.559 // It would prune recursion more (across syscalls), but lots of users need to560 // visit each struct per-syscall (e.g. prio, used resources).561 seen := make(map[Type]bool)562 var rec func(*Type, Dir)563 rec = func(ptr *Type, dir Dir) {564 if preorder {565 f(*ptr, TypeCtx{Meta: meta, Dir: dir, Ptr: ptr})566 }567 switch a := (*ptr).(type) {568 case *PtrType:569 rec(&a.Elem, a.ElemDir)570 case *ArrayType:571 rec(&a.Elem, dir)572 case *StructType:573 if seen[a] {574 break // prune recursion via pointers to structs/unions575 }576 seen[a] = true577 for i := range a.Fields {578 rec(&a.Fields[i].Type, dir)579 }580 case *UnionType:581 if seen[a] {582 break // prune recursion via pointers to structs/unions583 }584 seen[a] = true585 for i := range a.Fields {586 rec(&a.Fields[i].Type, dir)587 }588 case *ResourceType, *BufferType, *VmaType, *LenType, *FlagsType,589 *ConstType, *IntType, *ProcType, *CsumType:590 case Ref:591 // This is only needed for pkg/compiler.592 default:593 panic("unknown type")594 }595 if !preorder {596 f(*ptr, TypeCtx{Meta: meta, Dir: dir, Ptr: ptr})597 }598 }599 for i := range meta.Args {600 rec(&meta.Args[i].Type, DirIn)601 }602 if meta.Ret != nil {603 rec(&meta.Ret, DirOut)604 }605}606// CppName transforms PascalStyleNames to cpp_style_names.607func CppName(name string) string {608 var res []byte609 for i := range name {610 c := rune(name[i])611 if unicode.IsUpper(c) && i != 0 && !unicode.IsUpper(rune(name[i-1])) {612 res = append(res, '_')613 }614 res = append(res, byte(unicode.ToLower(c)))615 }616 return string(res)617}...
gen.go
Source:gen.go
1// Copyright 2017 syzkaller project authors. All rights reserved.2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.3package compiler4import (5 "fmt"6 "sort"7 "github.com/google/syzkaller/pkg/ast"8 "github.com/google/syzkaller/prog"9)10const sizeUnassigned = ^uint64(0)11func (comp *compiler) genResources() []*prog.ResourceDesc {12 var resources []*prog.ResourceDesc13 for name, n := range comp.resources {14 if !comp.used[name] {15 continue16 }17 resources = append(resources, comp.genResource(n))18 }19 sort.Slice(resources, func(i, j int) bool {20 return resources[i].Name < resources[j].Name21 })22 return resources23}24func (comp *compiler) genResource(n *ast.Resource) *prog.ResourceDesc {25 res := &prog.ResourceDesc{26 Name: n.Name.Name,27 }28 var base *ast.Type29 for n != nil {30 res.Values = append(genIntArray(n.Values), res.Values...)31 res.Kind = append([]string{n.Name.Name}, res.Kind...)32 base = n.Base33 n = comp.resources[n.Base.Ident]34 }35 if len(res.Values) == 0 {36 res.Values = []uint64{0}37 }38 res.Type = comp.genType(base, "", prog.DirIn, false)39 return res40}41func (comp *compiler) genSyscalls() []*prog.Syscall {42 var calls []*prog.Syscall43 for _, decl := range comp.desc.Nodes {44 if n, ok := decl.(*ast.Call); ok && n.NR != ^uint64(0) {45 calls = append(calls, comp.genSyscall(n))46 }47 }48 sort.Slice(calls, func(i, j int) bool {49 return calls[i].Name < calls[j].Name50 })51 return calls52}53func (comp *compiler) genSyscall(n *ast.Call) *prog.Syscall {54 var ret prog.Type55 if n.Ret != nil {56 ret = comp.genType(n.Ret, "ret", prog.DirOut, true)57 }58 return &prog.Syscall{59 Name: n.Name.Name,60 CallName: n.CallName,61 NR: n.NR,62 Args: comp.genFieldArray(n.Args, prog.DirIn, true),63 Ret: ret,64 }65}66func (comp *compiler) genStructDescs(syscalls []*prog.Syscall) []*prog.KeyedStruct {67 // Calculate struct/union/array sizes, add padding to structs and detach68 // StructDesc's from StructType's. StructType's can be recursive so it's69 // not possible to write them out inline as other types. To break the70 // recursion detach them, and write StructDesc's out as separate array71 // of KeyedStruct's. prog package will reattach them during init.72 padded := make(map[interface{}]bool)73 detach := make(map[**prog.StructDesc]bool)74 var structs []*prog.KeyedStruct75 var rec func(t prog.Type)76 checkStruct := func(key prog.StructKey, descp **prog.StructDesc) bool {77 detach[descp] = true78 desc := *descp79 if padded[desc] {80 return false81 }82 padded[desc] = true83 for _, f := range desc.Fields {84 rec(f)85 if !f.Varlen() && f.Size() == sizeUnassigned {86 // An inner struct is not padded yet.87 // Leave this struct for next iteration.88 delete(padded, desc)89 return false90 }91 }92 if comp.used[key.Name] {93 structs = append(structs, &prog.KeyedStruct{94 Key: key,95 Desc: desc,96 })97 }98 return true99 }100 rec = func(t0 prog.Type) {101 switch t := t0.(type) {102 case *prog.PtrType:103 rec(t.Type)104 case *prog.ArrayType:105 if padded[t] {106 return107 }108 rec(t.Type)109 if !t.Type.Varlen() && t.Type.Size() == sizeUnassigned {110 // An inner struct is not padded yet.111 // Leave this array for next iteration.112 return113 }114 padded[t] = true115 t.TypeSize = 0116 if t.Kind == prog.ArrayRangeLen && t.RangeBegin == t.RangeEnd && !t.Type.Varlen() {117 t.TypeSize = t.RangeBegin * t.Type.Size()118 }119 case *prog.StructType:120 if !checkStruct(t.Key, &t.StructDesc) {121 return122 }123 structNode := comp.structNodes[t.StructDesc]124 // Add paddings, calculate size, mark bitfields.125 varlen := false126 for _, f := range t.Fields {127 if f.Varlen() {128 varlen = true129 }130 }131 comp.markBitfields(t.Fields)132 packed, sizeAttr, alignAttr := comp.parseStructAttrs(structNode)133 t.Fields = comp.addAlignment(t.Fields, varlen, packed, alignAttr)134 t.AlignAttr = alignAttr135 t.TypeSize = 0136 if !varlen {137 for _, f := range t.Fields {138 if !f.BitfieldMiddle() {139 t.TypeSize += f.Size()140 }141 }142 if sizeAttr != sizeUnassigned {143 if t.TypeSize > sizeAttr {144 comp.error(structNode.Pos, "struct %v has size attribute %v"+145 " which is less than struct size %v",146 structNode.Name.Name, sizeAttr, t.TypeSize)147 }148 if pad := sizeAttr - t.TypeSize; pad != 0 {149 t.Fields = append(t.Fields, genPad(pad))150 }151 t.TypeSize = sizeAttr152 }153 }154 case *prog.UnionType:155 if !checkStruct(t.Key, &t.StructDesc) {156 return157 }158 structNode := comp.structNodes[t.StructDesc]159 varlen, sizeAttr := comp.parseUnionAttrs(structNode)160 t.TypeSize = 0161 if !varlen {162 for _, fld := range t.Fields {163 sz := fld.Size()164 if sizeAttr != sizeUnassigned && sz > sizeAttr {165 comp.error(structNode.Pos, "union %v has size attribute %v"+166 " which is less than field %v size %v",167 structNode.Name.Name, sizeAttr, fld.Name(), sz)168 }169 if t.TypeSize < sz {170 t.TypeSize = sz171 }172 }173 if sizeAttr != sizeUnassigned {174 t.TypeSize = sizeAttr175 }176 }177 }178 }179 // We have to do this in the loop until we pad nothing new180 // due to recursive structs.181 for {182 start := len(padded)183 for _, c := range syscalls {184 for _, a := range c.Args {185 rec(a)186 }187 if c.Ret != nil {188 rec(c.Ret)189 }190 }191 if start == len(padded) {192 break193 }194 }195 // Detach StructDesc's from StructType's. prog will reattach them again.196 for descp := range detach {197 *descp = nil198 }199 sort.Slice(structs, func(i, j int) bool {200 si, sj := structs[i], structs[j]201 if si.Key.Name != sj.Key.Name {202 return si.Key.Name < sj.Key.Name203 }204 return si.Key.Dir < sj.Key.Dir205 })206 return structs207}208func (comp *compiler) genStructDesc(res *prog.StructDesc, n *ast.Struct, dir prog.Dir, varlen bool) {209 // Leave node for genStructDescs to calculate size/padding.210 comp.structNodes[res] = n211 common := genCommon(n.Name.Name, "", sizeUnassigned, dir, false)212 common.IsVarlen = varlen213 *res = prog.StructDesc{214 TypeCommon: common,215 Fields: comp.genFieldArray(n.Fields, dir, false),216 }217}218func (comp *compiler) markBitfields(fields []prog.Type) {219 var bfOffset uint64220 for i, f := range fields {221 if f.BitfieldLength() == 0 {222 continue223 }224 off, middle := bfOffset, true225 bfOffset += f.BitfieldLength()226 if i == len(fields)-1 || // Last bitfield in a group, if last field of the struct...227 fields[i+1].BitfieldLength() == 0 || // or next field is not a bitfield...228 f.Size() != fields[i+1].Size() || // or next field is of different size...229 bfOffset+fields[i+1].BitfieldLength() > f.Size()*8 { // or next field does not fit into the current group.230 middle, bfOffset = false, 0231 }232 setBitfieldOffset(f, off, middle)233 }234}235func setBitfieldOffset(t0 prog.Type, offset uint64, middle bool) {236 switch t := t0.(type) {237 case *prog.IntType:238 t.BitfieldOff, t.BitfieldMdl = offset, middle239 case *prog.ConstType:240 t.BitfieldOff, t.BitfieldMdl = offset, middle241 case *prog.LenType:242 t.BitfieldOff, t.BitfieldMdl = offset, middle243 case *prog.FlagsType:244 t.BitfieldOff, t.BitfieldMdl = offset, middle245 case *prog.ProcType:246 t.BitfieldOff, t.BitfieldMdl = offset, middle247 default:248 panic(fmt.Sprintf("type %#v can't be a bitfield", t))249 }250}251func (comp *compiler) addAlignment(fields []prog.Type, varlen, packed bool, alignAttr uint64) []prog.Type {252 var newFields []prog.Type253 if packed {254 // If a struct is packed, statically sized and has explicitly set alignment,255 // add a padding at the end.256 newFields = fields257 if !varlen && alignAttr != 0 {258 size := uint64(0)259 for _, f := range fields {260 if !f.BitfieldMiddle() {261 size += f.Size()262 }263 }264 if tail := size % alignAttr; tail != 0 {265 newFields = append(newFields, genPad(alignAttr-tail))266 }267 }268 return newFields269 }270 var align, off uint64271 for i, f := range fields {272 if i == 0 || !fields[i-1].BitfieldMiddle() {273 a := comp.typeAlign(f)274 if align < a {275 align = a276 }277 // Append padding if the last field is not a bitfield or it's the last bitfield in a set.278 if off%a != 0 {279 pad := a - off%a280 off += pad281 newFields = append(newFields, genPad(pad))282 }283 }284 newFields = append(newFields, f)285 if !f.BitfieldMiddle() && (i != len(fields)-1 || !f.Varlen()) {286 // Increase offset if the current field is not a bitfield287 // or it's the last bitfield in a set, except when it's288 // the last field in a struct and has variable length.289 off += f.Size()290 }291 }292 if alignAttr != 0 {293 align = alignAttr294 }295 if align != 0 && off%align != 0 && !varlen {296 pad := align - off%align297 off += pad298 newFields = append(newFields, genPad(pad))299 }300 return newFields301}302func (comp *compiler) typeAlign(t0 prog.Type) uint64 {303 switch t0.(type) {304 case *prog.IntType, *prog.ConstType, *prog.LenType, *prog.FlagsType, *prog.ProcType,305 *prog.CsumType, *prog.PtrType, *prog.VmaType, *prog.ResourceType:306 return t0.Size()307 case *prog.BufferType:308 return 1309 }310 switch t := t0.(type) {311 case *prog.ArrayType:312 return comp.typeAlign(t.Type)313 case *prog.StructType:314 packed, _, alignAttr := comp.parseStructAttrs(comp.structNodes[t.StructDesc])315 if alignAttr != 0 {316 return alignAttr // overrided by user attribute317 }318 if packed {319 return 1320 }321 align := uint64(0)322 for _, f := range t.Fields {323 if a := comp.typeAlign(f); align < a {324 align = a325 }326 }327 return align328 case *prog.UnionType:329 align := uint64(0)330 for _, f := range t.Fields {331 if a := comp.typeAlign(f); align < a {332 align = a333 }334 }335 return align336 default:337 panic(fmt.Sprintf("unknown type: %#v", t))338 }339}340func genPad(size uint64) prog.Type {341 return &prog.ConstType{342 IntTypeCommon: genIntCommon(genCommon("pad", "", size, prog.DirIn, false), 0, false),343 IsPad: true,344 }345}346func (comp *compiler) genField(f *ast.Field, dir prog.Dir, isArg bool) prog.Type {347 return comp.genType(f.Type, f.Name.Name, dir, isArg)348}349func (comp *compiler) genFieldArray(fields []*ast.Field, dir prog.Dir, isArg bool) []prog.Type {350 var res []prog.Type351 for _, f := range fields {352 res = append(res, comp.genField(f, dir, isArg))353 }354 return res355}356func (comp *compiler) genType(t *ast.Type, field string, dir prog.Dir, isArg bool) prog.Type {357 desc, args, base := comp.getArgsBase(t, field, dir, isArg)358 if desc.Gen == nil {359 panic(fmt.Sprintf("no gen for %v %#v", field, t))360 }361 base.IsVarlen = desc.Varlen != nil && desc.Varlen(comp, t, args)362 return desc.Gen(comp, t, args, base)363}364func genCommon(name, field string, size uint64, dir prog.Dir, opt bool) prog.TypeCommon {365 return prog.TypeCommon{366 TypeName: name,367 TypeSize: size,368 FldName: field,369 ArgDir: dir,370 IsOptional: opt,371 }372}373func genIntCommon(com prog.TypeCommon, bitLen uint64, bigEndian bool) prog.IntTypeCommon {374 return prog.IntTypeCommon{375 TypeCommon: com,376 BigEndian: bigEndian,377 BitfieldLen: bitLen,378 }379}380func genIntArray(a []*ast.Int) []uint64 {381 r := make([]uint64, len(a))382 for i, v := range a {383 r[i] = v.Value384 }385 return r386}387func genStrArray(a []*ast.String) []string {388 r := make([]string, len(a))389 for i, v := range a {390 r[i] = v.Value391 }392 return r393}...
isVarlen
Using AI Code Generation
1import (2func main() {3 f, err := parser.ParseFile(fset, "2.go", nil, parser.ParseComments)4 if err != nil {5 panic(err)6 }7 for _, s := range f.Imports {8 fmt.Println(s.Path.Value)9 }10}11I have a question regarding the use of the method isVarlen() of the compiler class. I have a function that takes a variable number of arguments. I want to know the number of arguments passed to the function. I am using the method isVarlen() to check if the function takes variable number of arguments. If it does, I want to get the number of arguments passed to the function. I am not sure how to use the method isVarlen() to get the number of arguments passed to the function. Can someone please help me with this?12I have a question regarding the use of the method isVarlen() of the compiler class. I have a function that takes a variable number of arguments. I want to know the number of arguments passed to the function. I am using the method isVarlen() to check if the function takes variable number of arguments. If it does, I want to get the number of arguments passed to the function. I am not sure how to use the method isVarlen() to get the number of arguments passed to the function. Can someone please help me with this?
isVarlen
Using AI Code Generation
1import (2func main() {3 fset := token.NewFileSet()4 f, err := parser.ParseFile(fset, "2.go", nil, parser.ImportsOnly)5 if err != nil {6 log.Fatal(err)7 }8 for _, s := range f.Imports {9 fmt.Println(s.Path.Value)10 }11}12import (13func main() {14 fset := token.NewFileSet()15 f, err := parser.ParseFile(fset, "3.go", nil, parser.ImportsOnly)16 if err != nil {17 log.Fatal(err)18 }19 for _, s := range f.Imports {20 fmt.Println(s.Path.Value)21 }22}23import (24func main() {25 fset := token.NewFileSet()26 f, err := parser.ParseFile(fset, "4.go", nil, parser.ImportsOnly)27 if err != nil {28 log.Fatal(err)29 }30 for _, s := range f.Imports {31 fmt.Println(s.Path.Value)32 }33}34import (35func main() {36 fset := token.NewFileSet()37 f, err := parser.ParseFile(fset, "5.go", nil, parser.ImportsOnly)38 if err != nil {39 log.Fatal(err)40 }41 for _, s := range f.Imports {42 fmt.Println(s.Path.Value)
isVarlen
Using AI Code Generation
1func (c *Compiler) isVarlen() bool {2}3func (c *Compiler) isVarlen() bool {4}5func (c *Compiler) isVarlen() bool {6}7func (c *Compiler) isVarlen() bool {8}9func (c *Compiler) isVarlen() bool {10}11func (c *Compiler) isVarlen() bool {12}13func (c *Compiler) isVarlen() bool {
isVarlen
Using AI Code Generation
1import (2type Foo struct {3}4func main() {5 f := Foo{"Hello"}6 fmt.Println(reflect.TypeOf(f.Bar).Kind() == reflect.String)7}8import (9type Foo struct {10}11func main() {12 f := Foo{"Hello"}13 fmt.Println(reflect.TypeOf(f.Bar).Kind() == reflect.Int)14}15import (16type Foo struct {17}18func main() {19 f := Foo{"Hello"}20 fmt.Println(reflect.TypeOf(f.Bar).Kind() == reflect.Bool)21}22import (23type Foo struct {24}25func main() {26 f := Foo{"Hello"}27 fmt.Println(reflect.TypeOf(f.Bar).Kind() == reflect.Float32)28}29import (30type Foo struct {31}32func main() {33 f := Foo{"Hello"}34 fmt.Println(reflect.TypeOf(f.Bar).Kind() == reflect.Uint16)35}36import (37type Foo struct {38}39func main() {40 f := Foo{"Hello"}41 fmt.Println(reflect.TypeOf(f.Bar).Kind() == reflect.Uint8)42}
isVarlen
Using AI Code Generation
1import (2func main() {3import "fmt"4func main() {5 fmt.Println("Hello World!")6}7 fset := token.NewFileSet()8 f, err := parser.ParseFile(fset, "", src, 0)9 if err != nil {10 log.Fatal(err)11 }12 ast.Inspect(f, func(n ast.Node) bool {13 switch x := n.(type) {14 fmt.Println(x.Type, "size:", fset.File(x.Type.Pos()).Size(x.Type.Pos(), x.Type.End()))15 }16 })17}18[]interface {} size: 019type interface{} interface{}20The type assertion operator.(type) is used to get the type of an interface variable. It is useful when you want to know the type of a value. It is also useful when you want to access the value of an
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!