github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/tools/syz-trace2syz/parser/intermediate_types.go (about) 1 // Copyright 2018 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 parser 5 6 import ( 7 "bytes" 8 "fmt" 9 ) 10 11 // TraceTree struct contains intermediate representation of trace. 12 // If a trace is multiprocess it constructs a trace for each type. 13 type TraceTree struct { 14 TraceMap map[int64]*Trace 15 Ptree map[int64][]int64 16 RootPid int64 17 } 18 19 // NewTraceTree initializes a TraceTree. 20 func NewTraceTree() *TraceTree { 21 return &TraceTree{ 22 TraceMap: make(map[int64]*Trace), 23 Ptree: make(map[int64][]int64), 24 } 25 } 26 27 func (tree *TraceTree) add(call *Syscall) { 28 if tree.RootPid == 0 { 29 tree.RootPid = call.Pid 30 } 31 if tree.TraceMap[call.Pid] == nil { 32 tree.TraceMap[call.Pid] = new(Trace) 33 } 34 c := tree.TraceMap[call.Pid].add(call) 35 if c.CallName == "clone" && !c.Paused { 36 tree.Ptree[c.Pid] = append(tree.Ptree[c.Pid], c.Ret) 37 } 38 } 39 40 // Trace is just a list of system calls 41 type Trace struct { 42 Calls []*Syscall 43 } 44 45 func (trace *Trace) add(call *Syscall) *Syscall { 46 if !call.Resumed { 47 trace.Calls = append(trace.Calls, call) 48 return call 49 } 50 lastCall := trace.Calls[len(trace.Calls)-1] 51 lastCall.Args = append(lastCall.Args, call.Args...) 52 lastCall.Paused = false 53 lastCall.Ret = call.Ret 54 return lastCall 55 } 56 57 // IrType is the intermediate representation of the strace output 58 // Every argument of a system call should be represented in an intermediate type 59 type IrType interface { 60 String() string 61 } 62 63 // Syscall struct is the IR type for any system call 64 type Syscall struct { 65 CallName string 66 Args []IrType 67 Pid int64 68 Ret int64 69 Paused bool 70 Resumed bool 71 } 72 73 // NewSyscall - constructor 74 func NewSyscall(pid int64, name string, args []IrType, ret int64, paused, resumed bool) (sys *Syscall) { 75 return &Syscall{ 76 CallName: name, 77 Args: args, 78 Pid: pid, 79 Ret: ret, 80 Paused: paused, 81 Resumed: resumed, 82 } 83 } 84 85 func (s *Syscall) String() string { 86 buf := new(bytes.Buffer) 87 fmt.Fprintf(buf, "Pid: -%v-Name: -%v-", s.Pid, s.CallName) 88 for _, typ := range s.Args { 89 fmt.Fprintf(buf, "-%v-", typ) 90 } 91 fmt.Fprintf(buf, "-Ret: %d\n", s.Ret) 92 return buf.String() 93 } 94 95 // GroupType contains arrays and structs 96 type GroupType struct { 97 Elems []IrType 98 } 99 100 func newGroupType(elems []IrType) (typ *GroupType) { 101 return &GroupType{Elems: elems} 102 } 103 104 // String implements IrType String() 105 func (a *GroupType) String() string { 106 var buf bytes.Buffer 107 108 buf.WriteString("[") 109 for _, elem := range a.Elems { 110 buf.WriteString(elem.String()) 111 buf.WriteString(",") 112 } 113 buf.WriteString("]") 114 return buf.String() 115 } 116 117 // Constant represents all evaluated expressions produced by strace 118 // Constant types are evaluated at parse time 119 type Constant uint64 120 121 func (c Constant) String() string { 122 return fmt.Sprintf("%#v", c) 123 } 124 125 func (c Constant) Val() uint64 { 126 return uint64(c) 127 } 128 129 // BufferType contains strings 130 type BufferType struct { 131 Val string 132 } 133 134 func newBufferType(val string) *BufferType { 135 return &BufferType{Val: val} 136 } 137 138 // String implements IrType String() 139 func (b *BufferType) String() string { 140 return fmt.Sprintf("Buffer: %v with length: %v\n", b.Val, len(b.Val)) 141 }