podman

Форк
0
233 строки · 6.2 Кб
1
// Copyright 2019 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4

5
package goobj
6

7
import (
8
	"bytes"
9
	"github.com/twitchyliquid64/golang-asm/objabi"
10
	"encoding/binary"
11
)
12

13
// CUFileIndex is used to index the filenames that are stored in the
14
// per-package/per-CU FileList.
15
type CUFileIndex uint32
16

17
// FuncInfo is serialized as a symbol (aux symbol). The symbol data is
18
// the binary encoding of the struct below.
19
//
20
// TODO: make each pcdata a separate symbol?
21
type FuncInfo struct {
22
	Args   uint32
23
	Locals uint32
24
	FuncID objabi.FuncID
25

26
	Pcsp        uint32
27
	Pcfile      uint32
28
	Pcline      uint32
29
	Pcinline    uint32
30
	Pcdata      []uint32
31
	PcdataEnd   uint32
32
	Funcdataoff []uint32
33
	File        []CUFileIndex
34

35
	InlTree []InlTreeNode
36
}
37

38
func (a *FuncInfo) Write(w *bytes.Buffer) {
39
	var b [4]byte
40
	writeUint32 := func(x uint32) {
41
		binary.LittleEndian.PutUint32(b[:], x)
42
		w.Write(b[:])
43
	}
44

45
	writeUint32(a.Args)
46
	writeUint32(a.Locals)
47
	writeUint32(uint32(a.FuncID))
48

49
	writeUint32(a.Pcsp)
50
	writeUint32(a.Pcfile)
51
	writeUint32(a.Pcline)
52
	writeUint32(a.Pcinline)
53
	writeUint32(uint32(len(a.Pcdata)))
54
	for _, x := range a.Pcdata {
55
		writeUint32(x)
56
	}
57
	writeUint32(a.PcdataEnd)
58
	writeUint32(uint32(len(a.Funcdataoff)))
59
	for _, x := range a.Funcdataoff {
60
		writeUint32(x)
61
	}
62
	writeUint32(uint32(len(a.File)))
63
	for _, f := range a.File {
64
		writeUint32(uint32(f))
65
	}
66
	writeUint32(uint32(len(a.InlTree)))
67
	for i := range a.InlTree {
68
		a.InlTree[i].Write(w)
69
	}
70
}
71

72
func (a *FuncInfo) Read(b []byte) {
73
	readUint32 := func() uint32 {
74
		x := binary.LittleEndian.Uint32(b)
75
		b = b[4:]
76
		return x
77
	}
78

79
	a.Args = readUint32()
80
	a.Locals = readUint32()
81
	a.FuncID = objabi.FuncID(readUint32())
82

83
	a.Pcsp = readUint32()
84
	a.Pcfile = readUint32()
85
	a.Pcline = readUint32()
86
	a.Pcinline = readUint32()
87
	pcdatalen := readUint32()
88
	a.Pcdata = make([]uint32, pcdatalen)
89
	for i := range a.Pcdata {
90
		a.Pcdata[i] = readUint32()
91
	}
92
	a.PcdataEnd = readUint32()
93
	funcdataofflen := readUint32()
94
	a.Funcdataoff = make([]uint32, funcdataofflen)
95
	for i := range a.Funcdataoff {
96
		a.Funcdataoff[i] = readUint32()
97
	}
98
	filelen := readUint32()
99
	a.File = make([]CUFileIndex, filelen)
100
	for i := range a.File {
101
		a.File[i] = CUFileIndex(readUint32())
102
	}
103
	inltreelen := readUint32()
104
	a.InlTree = make([]InlTreeNode, inltreelen)
105
	for i := range a.InlTree {
106
		b = a.InlTree[i].Read(b)
107
	}
108
}
109

110
// FuncInfoLengths is a cache containing a roadmap of offsets and
111
// lengths for things within a serialized FuncInfo. Each length field
112
// stores the number of items (e.g. files, inltree nodes, etc), and the
113
// corresponding "off" field stores the byte offset of the start of
114
// the items in question.
115
type FuncInfoLengths struct {
116
	NumPcdata      uint32
117
	PcdataOff      uint32
118
	NumFuncdataoff uint32
119
	FuncdataoffOff uint32
120
	NumFile        uint32
121
	FileOff        uint32
122
	NumInlTree     uint32
123
	InlTreeOff     uint32
124
	Initialized    bool
125
}
126

127
func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths {
128
	var result FuncInfoLengths
129

130
	const numpcdataOff = 28
131
	result.NumPcdata = binary.LittleEndian.Uint32(b[numpcdataOff:])
132
	result.PcdataOff = numpcdataOff + 4
133

134
	numfuncdataoffOff := result.PcdataOff + 4*(result.NumPcdata+1)
135
	result.NumFuncdataoff = binary.LittleEndian.Uint32(b[numfuncdataoffOff:])
136
	result.FuncdataoffOff = numfuncdataoffOff + 4
137

138
	numfileOff := result.FuncdataoffOff + 4*result.NumFuncdataoff
139
	result.NumFile = binary.LittleEndian.Uint32(b[numfileOff:])
140
	result.FileOff = numfileOff + 4
141

142
	numinltreeOff := result.FileOff + 4*result.NumFile
143
	result.NumInlTree = binary.LittleEndian.Uint32(b[numinltreeOff:])
144
	result.InlTreeOff = numinltreeOff + 4
145

146
	result.Initialized = true
147

148
	return result
149
}
150

151
func (*FuncInfo) ReadArgs(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }
152

153
func (*FuncInfo) ReadLocals(b []byte) uint32 { return binary.LittleEndian.Uint32(b[4:]) }
154

155
func (*FuncInfo) ReadFuncID(b []byte) uint32 { return binary.LittleEndian.Uint32(b[8:]) }
156

157
// return start and end offsets.
158
func (*FuncInfo) ReadPcsp(b []byte) (uint32, uint32) {
159
	return binary.LittleEndian.Uint32(b[12:]), binary.LittleEndian.Uint32(b[16:])
160
}
161

162
// return start and end offsets.
163
func (*FuncInfo) ReadPcfile(b []byte) (uint32, uint32) {
164
	return binary.LittleEndian.Uint32(b[16:]), binary.LittleEndian.Uint32(b[20:])
165
}
166

167
// return start and end offsets.
168
func (*FuncInfo) ReadPcline(b []byte) (uint32, uint32) {
169
	return binary.LittleEndian.Uint32(b[20:]), binary.LittleEndian.Uint32(b[24:])
170
}
171

172
// return start and end offsets.
173
func (*FuncInfo) ReadPcinline(b []byte, pcdataoffset uint32) (uint32, uint32) {
174
	return binary.LittleEndian.Uint32(b[24:]), binary.LittleEndian.Uint32(b[pcdataoffset:])
175
}
176

177
// return start and end offsets.
178
func (*FuncInfo) ReadPcdata(b []byte, pcdataoffset uint32, k uint32) (uint32, uint32) {
179
	return binary.LittleEndian.Uint32(b[pcdataoffset+4*k:]), binary.LittleEndian.Uint32(b[pcdataoffset+4+4*k:])
180
}
181

182
func (*FuncInfo) ReadFuncdataoff(b []byte, funcdataofffoff uint32, k uint32) int64 {
183
	return int64(binary.LittleEndian.Uint32(b[funcdataofffoff+4*k:]))
184
}
185

186
func (*FuncInfo) ReadFile(b []byte, filesoff uint32, k uint32) CUFileIndex {
187
	return CUFileIndex(binary.LittleEndian.Uint32(b[filesoff+4*k:]))
188
}
189

190
func (*FuncInfo) ReadInlTree(b []byte, inltreeoff uint32, k uint32) InlTreeNode {
191
	const inlTreeNodeSize = 4 * 6
192
	var result InlTreeNode
193
	result.Read(b[inltreeoff+k*inlTreeNodeSize:])
194
	return result
195
}
196

197
// InlTreeNode is the serialized form of FileInfo.InlTree.
198
type InlTreeNode struct {
199
	Parent   int32
200
	File     CUFileIndex
201
	Line     int32
202
	Func     SymRef
203
	ParentPC int32
204
}
205

206
func (inl *InlTreeNode) Write(w *bytes.Buffer) {
207
	var b [4]byte
208
	writeUint32 := func(x uint32) {
209
		binary.LittleEndian.PutUint32(b[:], x)
210
		w.Write(b[:])
211
	}
212
	writeUint32(uint32(inl.Parent))
213
	writeUint32(uint32(inl.File))
214
	writeUint32(uint32(inl.Line))
215
	writeUint32(inl.Func.PkgIdx)
216
	writeUint32(inl.Func.SymIdx)
217
	writeUint32(uint32(inl.ParentPC))
218
}
219

220
// Read an InlTreeNode from b, return the remaining bytes.
221
func (inl *InlTreeNode) Read(b []byte) []byte {
222
	readUint32 := func() uint32 {
223
		x := binary.LittleEndian.Uint32(b)
224
		b = b[4:]
225
		return x
226
	}
227
	inl.Parent = int32(readUint32())
228
	inl.File = CUFileIndex(readUint32())
229
	inl.Line = int32(readUint32())
230
	inl.Func = SymRef{readUint32(), readUint32()}
231
	inl.ParentPC = int32(readUint32())
232
	return b
233
}
234

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.