1
2
3
4
5
6
7
8
9
10
11 package dwarf
12
13 import "os"
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, os.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, "abbrev", 0, data, 0)
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
189
190 case formRefAddr:
191 val = Offset(b.addr())
192 case formRef1:
193 val = Offset(b.uint8()) + ubase
194 case formRef2:
195 val = Offset(b.uint16()) + ubase
196 case formRef4:
197 val = Offset(b.uint32()) + ubase
198 case formRef8:
199 val = Offset(b.uint64()) + ubase
200 case formRefUdata:
201 val = Offset(b.uint()) + ubase
202
203
204 case formString:
205 val = b.string()
206 case formStrp:
207 off := b.uint32()
208 if b.err != nil {
209 return nil
210 }
211 b1 := makeBuf(b.dwarf, "str", 0, b.dwarf.str, 0)
212 b1.skip(int(off))
213 val = b1.string()
214 if b1.err != nil {
215 b.err = b1.err
216 return nil
217 }
218 }
219 e.Field[i].Val = val
220 }
221 if b.err != nil {
222 return nil
223 }
224 return e
225 }
226
227
228
229
230
231
232 type Reader struct {
233 b buf
234 d *Data
235 err os.Error
236 unit int
237 lastChildren bool
238 lastSibling Offset
239 }
240
241
242
243 func (d *Data) Reader() *Reader {
244 r := &Reader{d: d}
245 r.Seek(0)
246 return r
247 }
248
249
250
251 func (r *Reader) Seek(off Offset) {
252 d := r.d
253 r.err = nil
254 r.lastChildren = false
255 if off == 0 {
256 if len(d.unit) == 0 {
257 return
258 }
259 u := &d.unit[0]
260 r.unit = 0
261 r.b = makeBuf(r.d, "info", u.off, u.data, u.addrsize)
262 return
263 }
264
265
266 var i int
267 var u *unit
268 for i = range d.unit {
269 u = &d.unit[i]
270 if u.off <= off && off < u.off+Offset(len(u.data)) {
271 r.unit = i
272 r.b = makeBuf(r.d, "info", off, u.data[off-u.off:], u.addrsize)
273 return
274 }
275 }
276 r.err = os.NewError("offset out of range")
277 }
278
279
280 func (r *Reader) maybeNextUnit() {
281 for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
282 r.unit++
283 u := &r.d.unit[r.unit]
284 r.b = makeBuf(r.d, "info", u.off, u.data, u.addrsize)
285 }
286 }
287
288
289
290
291
292 func (r *Reader) Next() (*Entry, os.Error) {
293 if r.err != nil {
294 return nil, r.err
295 }
296 r.maybeNextUnit()
297 if len(r.b.data) == 0 {
298 return nil, nil
299 }
300 u := &r.d.unit[r.unit]
301 e := r.b.entry(u.atable, u.base)
302 if r.b.err != nil {
303 r.err = r.b.err
304 return nil, r.err
305 }
306 if e != nil {
307 r.lastChildren = e.Children
308 if r.lastChildren {
309 r.lastSibling, _ = e.Val(AttrSibling).(Offset)
310 }
311 } else {
312 r.lastChildren = false
313 }
314 return e, nil
315 }
316
317
318
319
320 func (r *Reader) SkipChildren() {
321 if r.err != nil || !r.lastChildren {
322 return
323 }
324
325
326
327
328
329 if r.lastSibling >= r.b.off {
330 r.Seek(r.lastSibling)
331 return
332 }
333
334 for {
335 e, err := r.Next()
336 if err != nil || e == nil || e.Tag == 0 {
337 break
338 }
339 if e.Children {
340 r.SkipChildren()
341 }
342 }
343 }