Source file src/pkg/debug/dwarf/entry.go
1
2
3
4
5
6
7
8
9
10
11 package dwarf
12
13 import "errors"
14
15
16 type abbrev struct {
17 tag Tag
18 children bool
19 field []afield
20 }
21
22 type afield struct {
23 attr Attr
24 fmt format
25 }
26
27
28 type abbrevTable map[uint32]abbrev
29
30
31
32 func (d *Data) parseAbbrev(off uint32) (abbrevTable, error) {
33 if m, ok := d.abbrevCache[off]; ok {
34 return m, nil
35 }
36
37 data := d.abbrev
38 if off > uint32(len(data)) {
39 data = nil
40 } else {
41 data = data[off:]
42 }
43 b := makeBuf(d, unknownFormat{}, "abbrev", 0, data)
44
45
46
47 m := make(abbrevTable)
48 for {
49
50 id := uint32(b.uint())
51 if id == 0 {
52 break
53 }
54
55
56 n := 0
57 b1 := b
58 b1.uint()
59 b1.uint8()
60 for {
61 tag := b1.uint()
62 fmt := b1.uint()
63 if tag == 0 && fmt == 0 {
64 break
65 }
66 n++
67 }
68 if b1.err != nil {
69 return nil, b1.err
70 }
71
72
73 var a abbrev
74 a.tag = Tag(b.uint())
75 a.children = b.uint8() != 0
76 a.field = make([]afield, n)
77 for i := range a.field {
78 a.field[i].attr = Attr(b.uint())
79 a.field[i].fmt = format(b.uint())
80 }
81 b.uint()
82 b.uint()
83
84 m[id] = a
85 }
86 if b.err != nil {
87 return nil, b.err
88 }
89 d.abbrevCache[off] = m
90 return m, nil
91 }
92
93
94 type Entry struct {
95 Offset Offset
96 Tag Tag
97 Children bool
98 Field []Field
99 }
100
101
102 type Field struct {
103 Attr Attr
104 Val interface{}
105 }
106
107
108
109
110
111
112
113
114 func (e *Entry) Val(a Attr) interface{} {
115 for _, f := range e.Field {
116 if f.Attr == a {
117 return f.Val
118 }
119 }
120 return nil
121 }
122
123
124
125 type Offset uint32
126
127
128
129 func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry {
130 off := b.off
131 id := uint32(b.uint())
132 if id == 0 {
133 return &Entry{}
134 }
135 a, ok := atab[id]
136 if !ok {
137 b.error("unknown abbreviation table index")
138 return nil
139 }
140 e := &Entry{
141 Offset: off,
142 Tag: a.tag,
143 Children: a.children,
144 Field: make([]Field, len(a.field)),
145 }
146 for i := range e.Field {
147 e.Field[i].Attr = a.field[i].attr
148 fmt := a.field[i].fmt
149 if fmt == formIndirect {
150 fmt = format(b.uint())
151 }
152 var val interface{}
153 switch fmt {
154 default:
155 b.error("unknown entry attr format")
156
157
158 case formAddr:
159 val = b.addr()
160
161
162 case formDwarfBlock1:
163 val = b.bytes(int(b.uint8()))
164 case formDwarfBlock2:
165 val = b.bytes(int(b.uint16()))
166 case formDwarfBlock4:
167 val = b.bytes(int(b.uint32()))
168 case formDwarfBlock:
169 val = b.bytes(int(b.uint()))
170
171
172 case formData1:
173 val = int64(b.uint8())
174 case formData2:
175 val = int64(b.uint16())
176 case formData4:
177 val = int64(b.uint32())
178 case formData8:
179 val = int64(b.uint64())
180 case formSdata:
181 val = int64(b.int())
182 case formUdata:
183 val = int64(b.uint())
184
185
186 case formFlag:
187 val = b.uint8() == 1
188 case formFlagPresent:
189
190
191 val = true
192
193
194 case formRefAddr:
195 vers := b.format.version()
196 if vers == 0 {
197 b.error("unknown version for DW_FORM_ref_addr")
198 } else if vers == 2 {
199 val = Offset(b.addr())
200 } else {
201 is64, known := b.format.dwarf64()
202 if !known {
203 b.error("unknown size for DW_FORM_ref_addr")
204 } else if is64 {
205 val = Offset(b.uint64())
206 } else {
207 val = Offset(b.uint32())
208 }
209 }
210 case formRef1:
211 val = Offset(b.uint8()) + ubase
212 case formRef2:
213 val = Offset(b.uint16()) + ubase
214 case formRef4:
215 val = Offset(b.uint32()) + ubase
216 case formRef8:
217 val = Offset(b.uint64()) + ubase
218 case formRefUdata:
219 val = Offset(b.uint()) + ubase
220
221
222 case formString:
223 val = b.string()
224 case formStrp:
225 off := b.uint32()
226 if b.err != nil {
227 return nil
228 }
229 b1 := makeBuf(b.dwarf, unknownFormat{}, "str", 0, b.dwarf.str)
230 b1.skip(int(off))
231 val = b1.string()
232 if b1.err != nil {
233 b.err = b1.err
234 return nil
235 }
236 }
237 e.Field[i].Val = val
238 }
239 if b.err != nil {
240 return nil
241 }
242 return e
243 }
244
245
246
247
248
249
250 type Reader struct {
251 b buf
252 d *Data
253 err error
254 unit int
255 lastChildren bool
256 lastSibling Offset
257 }
258
259
260
261 func (d *Data) Reader() *Reader {
262 r := &Reader{d: d}
263 r.Seek(0)
264 return r
265 }
266
267
268
269 func (r *Reader) Seek(off Offset) {
270 d := r.d
271 r.err = nil
272 r.lastChildren = false
273 if off == 0 {
274 if len(d.unit) == 0 {
275 return
276 }
277 u := &d.unit[0]
278 r.unit = 0
279 r.b = makeBuf(r.d, u, "info", u.off, u.data)
280 return
281 }
282
283
284 var i int
285 var u *unit
286 for i = range d.unit {
287 u = &d.unit[i]
288 if u.off <= off && off < u.off+Offset(len(u.data)) {
289 r.unit = i
290 r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
291 return
292 }
293 }
294 r.err = errors.New("offset out of range")
295 }
296
297
298 func (r *Reader) maybeNextUnit() {
299 for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
300 r.unit++
301 u := &r.d.unit[r.unit]
302 r.b = makeBuf(r.d, u, "info", u.off, u.data)
303 }
304 }
305
306
307
308
309
310 func (r *Reader) Next() (*Entry, error) {
311 if r.err != nil {
312 return nil, r.err
313 }
314 r.maybeNextUnit()
315 if len(r.b.data) == 0 {
316 return nil, nil
317 }
318 u := &r.d.unit[r.unit]
319 e := r.b.entry(u.atable, u.base)
320 if r.b.err != nil {
321 r.err = r.b.err
322 return nil, r.err
323 }
324 if e != nil {
325 r.lastChildren = e.Children
326 if r.lastChildren {
327 r.lastSibling, _ = e.Val(AttrSibling).(Offset)
328 }
329 } else {
330 r.lastChildren = false
331 }
332 return e, nil
333 }
334
335
336
337
338 func (r *Reader) SkipChildren() {
339 if r.err != nil || !r.lastChildren {
340 return
341 }
342
343
344
345
346
347 if r.lastSibling >= r.b.off {
348 r.Seek(r.lastSibling)
349 return
350 }
351
352 for {
353 e, err := r.Next()
354 if err != nil || e == nil || e.Tag == 0 {
355 break
356 }
357 if e.Children {
358 r.SkipChildren()
359 }
360 }
361 }
View as plain text