github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/declextract/serialization.go (about)

     1  // Copyright 2024 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.
     3  
     4  package declextract
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"strings"
    10  )
    11  
    12  func (ctx *context) serialize() {
    13  	ctx.descriptions = new(bytes.Buffer)
    14  	ctx.fmt(header)
    15  	ctx.serializeIncludes()
    16  	ctx.serializeEnums()
    17  	ctx.serializeSyscalls()
    18  	ctx.serializeFileOps()
    19  	ctx.serializeNetlink()
    20  	ctx.serializeStructs()
    21  	ctx.serializeDefines()
    22  }
    23  
    24  const header = `# Code generated by syz-declextract. DO NOT EDIT.
    25  
    26  meta automatic
    27  
    28  type auto_todo int8
    29  
    30  type auto_union[INFERRED, RAW] [
    31  	inferred	INFERRED
    32  	raw		RAW
    33  ]
    34  
    35  type auto_aligner[N] {
    36  	void	void
    37  } [align[N]]
    38  
    39  `
    40  
    41  func (ctx *context) fmt(msg string, args ...any) {
    42  	fmt.Fprintf(ctx.descriptions, msg, args...)
    43  }
    44  
    45  func (ctx *context) serializeIncludes() {
    46  	for _, inc := range ctx.includes {
    47  		ctx.fmt("include <%s>\n", inc)
    48  	}
    49  	ctx.fmt("\n")
    50  }
    51  
    52  func (ctx *context) serializeDefines() {
    53  	for _, def := range ctx.defines {
    54  		ctx.fmt("define %v %v\n", def.Name, def.Value)
    55  	}
    56  	ctx.fmt("\n")
    57  }
    58  
    59  func (ctx *context) serializeSyscalls() {
    60  	for _, call := range ctx.Syscalls {
    61  		ctx.fmt("%v(", call.Func)
    62  		for i, arg := range call.Args {
    63  			ctx.fmt("%v%v %v", comma(i), arg.Name, arg.syzType)
    64  		}
    65  		ctx.fmt(") %v\n", call.returnType)
    66  	}
    67  	ctx.fmt("\n")
    68  }
    69  
    70  func (ctx *context) serializeEnums() {
    71  	for _, enum := range ctx.Enums {
    72  		ctx.fmt("%v = ", enum.Name)
    73  		for i, val := range enum.Values {
    74  			ctx.fmt("%v %v", comma(i), val)
    75  		}
    76  		ctx.fmt("\n")
    77  	}
    78  	ctx.fmt("\n")
    79  }
    80  
    81  func (ctx *context) serializeStructs() {
    82  	for _, str := range ctx.Structs {
    83  		// Empty structs are not supported, but we also shouldn't emit references to them.
    84  		if str.ByteSize == 0 {
    85  			continue
    86  		}
    87  		delims := "{}"
    88  		if str.IsUnion {
    89  			delims = "[]"
    90  		}
    91  		ctx.fmt("%v %c\n", str.Name, delims[0])
    92  		for _, f := range str.Fields {
    93  			ctx.fmt("%v %v\n", f.Name, f.syzType)
    94  		}
    95  		ctx.fmt("%c", delims[1])
    96  		var attrs []string
    97  		if str.IsPacked {
    98  			attrs = append(attrs, "packed")
    99  		}
   100  		if str.AlignAttr != 0 {
   101  			attrs = append(attrs, fmt.Sprintf("align[%v]", str.AlignAttr))
   102  		}
   103  		if len(attrs) != 0 {
   104  			ctx.fmt(" [%v]", strings.Join(attrs, ", "))
   105  		}
   106  		ctx.fmt("\n\n")
   107  	}
   108  }