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