1
2
3
4
5 package goobj
6
7 import (
8 "bytes"
9 "encoding/binary"
10 "internal/abi"
11 )
12
13
14
15 type CUFileIndex uint32
16
17
18
19 type FuncInfo struct {
20 Args uint32
21 Locals uint32
22 FuncID abi.FuncID
23 FuncFlag abi.FuncFlag
24 StartLine int32
25 File []CUFileIndex
26 InlTree []InlTreeNode
27 }
28
29 func (a *FuncInfo) Write(w *bytes.Buffer) {
30 writeUint8 := func(x uint8) {
31 w.WriteByte(x)
32 }
33 var b [4]byte
34 writeUint32 := func(x uint32) {
35 binary.LittleEndian.PutUint32(b[:], x)
36 w.Write(b[:])
37 }
38
39 writeUint32(a.Args)
40 writeUint32(a.Locals)
41 writeUint8(uint8(a.FuncID))
42 writeUint8(uint8(a.FuncFlag))
43 writeUint8(0)
44 writeUint8(0)
45 writeUint32(uint32(a.StartLine))
46
47 writeUint32(uint32(len(a.File)))
48 for _, f := range a.File {
49 writeUint32(uint32(f))
50 }
51 writeUint32(uint32(len(a.InlTree)))
52 for i := range a.InlTree {
53 a.InlTree[i].Write(w)
54 }
55 }
56
57
58
59
60
61
62 type FuncInfoLengths struct {
63 NumFile uint32
64 FileOff uint32
65 NumInlTree uint32
66 InlTreeOff uint32
67 Initialized bool
68 }
69
70 func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths {
71 var result FuncInfoLengths
72
73
74
75 const numfileOff = 16
76 result.NumFile = binary.LittleEndian.Uint32(b[numfileOff:])
77 result.FileOff = numfileOff + 4
78
79 numinltreeOff := result.FileOff + 4*result.NumFile
80 result.NumInlTree = binary.LittleEndian.Uint32(b[numinltreeOff:])
81 result.InlTreeOff = numinltreeOff + 4
82
83 result.Initialized = true
84
85 return result
86 }
87
88 func (*FuncInfo) ReadArgs(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }
89
90 func (*FuncInfo) ReadLocals(b []byte) uint32 { return binary.LittleEndian.Uint32(b[4:]) }
91
92 func (*FuncInfo) ReadFuncID(b []byte) abi.FuncID { return abi.FuncID(b[8]) }
93
94 func (*FuncInfo) ReadFuncFlag(b []byte) abi.FuncFlag { return abi.FuncFlag(b[9]) }
95
96 func (*FuncInfo) ReadStartLine(b []byte) int32 { return int32(binary.LittleEndian.Uint32(b[12:])) }
97
98 func (*FuncInfo) ReadFile(b []byte, filesoff uint32, k uint32) CUFileIndex {
99 return CUFileIndex(binary.LittleEndian.Uint32(b[filesoff+4*k:]))
100 }
101
102 func (*FuncInfo) ReadInlTree(b []byte, inltreeoff uint32, k uint32) InlTreeNode {
103 const inlTreeNodeSize = 4 * 6
104 var result InlTreeNode
105 result.Read(b[inltreeoff+k*inlTreeNodeSize:])
106 return result
107 }
108
109
110 type InlTreeNode struct {
111 Parent int32
112 File CUFileIndex
113 Line int32
114 Func SymRef
115 ParentPC int32
116 }
117
118 func (inl *InlTreeNode) Write(w *bytes.Buffer) {
119 var b [4]byte
120 writeUint32 := func(x uint32) {
121 binary.LittleEndian.PutUint32(b[:], x)
122 w.Write(b[:])
123 }
124 writeUint32(uint32(inl.Parent))
125 writeUint32(uint32(inl.File))
126 writeUint32(uint32(inl.Line))
127 writeUint32(inl.Func.PkgIdx)
128 writeUint32(inl.Func.SymIdx)
129 writeUint32(uint32(inl.ParentPC))
130 }
131
132
133 func (inl *InlTreeNode) Read(b []byte) []byte {
134 readUint32 := func() uint32 {
135 x := binary.LittleEndian.Uint32(b)
136 b = b[4:]
137 return x
138 }
139 inl.Parent = int32(readUint32())
140 inl.File = CUFileIndex(readUint32())
141 inl.Line = int32(readUint32())
142 inl.Func = SymRef{readUint32(), readUint32()}
143 inl.ParentPC = int32(readUint32())
144 return b
145 }
146
View as plain text