1
2
3
4
5
6
7
8
9 package dwarf
10
11 import (
12 "os"
13 "strconv"
14 )
15
16
17
18 type Type interface {
19 Common() *CommonType
20 String() string
21 Size() int64
22 }
23
24
25
26
27 type CommonType struct {
28 ByteSize int64
29 Name string
30 }
31
32 func (c *CommonType) Common() *CommonType { return c }
33
34 func (c *CommonType) Size() int64 { return c.ByteSize }
35
36
37
38
39 type BasicType struct {
40 CommonType
41 BitSize int64
42 BitOffset int64
43 }
44
45 func (b *BasicType) Basic() *BasicType { return b }
46
47 func (t *BasicType) String() string {
48 if t.Name != "" {
49 return t.Name
50 }
51 return "?"
52 }
53
54
55 type CharType struct {
56 BasicType
57 }
58
59
60 type UcharType struct {
61 BasicType
62 }
63
64
65 type IntType struct {
66 BasicType
67 }
68
69
70 type UintType struct {
71 BasicType
72 }
73
74
75 type FloatType struct {
76 BasicType
77 }
78
79
80 type ComplexType struct {
81 BasicType
82 }
83
84
85 type BoolType struct {
86 BasicType
87 }
88
89
90 type AddrType struct {
91 BasicType
92 }
93
94
95
96
97 type QualType struct {
98 CommonType
99 Qual string
100 Type Type
101 }
102
103 func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
104
105 func (t *QualType) Size() int64 { return t.Type.Size() }
106
107
108 type ArrayType struct {
109 CommonType
110 Type Type
111 StrideBitSize int64
112 Count int64
113 }
114
115 func (t *ArrayType) String() string {
116 return "[" + strconv.Itoa64(t.Count) + "]" + t.Type.String()
117 }
118
119 func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() }
120
121
122 type VoidType struct {
123 CommonType
124 }
125
126 func (t *VoidType) String() string { return "void" }
127
128
129 type PtrType struct {
130 CommonType
131 Type Type
132 }
133
134 func (t *PtrType) String() string { return "*" + t.Type.String() }
135
136
137 type StructType struct {
138 CommonType
139 StructName string
140 Kind string
141 Field []*StructField
142 Incomplete bool
143 }
144
145
146 type StructField struct {
147 Name string
148 Type Type
149 ByteOffset int64
150 ByteSize int64
151 BitOffset int64
152 BitSize int64
153 }
154
155 func (t *StructType) String() string {
156 if t.StructName != "" {
157 return t.Kind + " " + t.StructName
158 }
159 return t.Defn()
160 }
161
162 func (t *StructType) Defn() string {
163 s := t.Kind
164 if t.StructName != "" {
165 s += " " + t.StructName
166 }
167 if t.Incomplete {
168 s += " /*incomplete*/"
169 return s
170 }
171 s += " {"
172 for i, f := range t.Field {
173 if i > 0 {
174 s += "; "
175 }
176 s += f.Name + " " + f.Type.String()
177 s += "@" + strconv.Itoa64(f.ByteOffset)
178 if f.BitSize > 0 {
179 s += " : " + strconv.Itoa64(f.BitSize)
180 s += "@" + strconv.Itoa64(f.BitOffset)
181 }
182 }
183 s += "}"
184 return s
185 }
186
187
188
189
190 type EnumType struct {
191 CommonType
192 EnumName string
193 Val []*EnumValue
194 }
195
196
197 type EnumValue struct {
198 Name string
199 Val int64
200 }
201
202 func (t *EnumType) String() string {
203 s := "enum"
204 if t.EnumName != "" {
205 s += " " + t.EnumName
206 }
207 s += " {"
208 for i, v := range t.Val {
209 if i > 0 {
210 s += "; "
211 }
212 s += v.Name + "=" + strconv.Itoa64(v.Val)
213 }
214 s += "}"
215 return s
216 }
217
218
219 type FuncType struct {
220 CommonType
221 ReturnType Type
222 ParamType []Type
223 }
224
225 func (t *FuncType) String() string {
226 s := "func("
227 for i, t := range t.ParamType {
228 if i > 0 {
229 s += ", "
230 }
231 s += t.String()
232 }
233 s += ")"
234 if t.ReturnType != nil {
235 s += " " + t.ReturnType.String()
236 }
237 return s
238 }
239
240
241 type DotDotDotType struct {
242 CommonType
243 }
244
245 func (t *DotDotDotType) String() string { return "..." }
246
247
248 type TypedefType struct {
249 CommonType
250 Type Type
251 }
252
253 func (t *TypedefType) String() string { return t.Name }
254
255 func (t *TypedefType) Size() int64 { return t.Type.Size() }
256
257 func (d *Data) Type(off Offset) (Type, os.Error) {
258 if t, ok := d.typeCache[off]; ok {
259 return t, nil
260 }
261
262 r := d.Reader()
263 r.Seek(off)
264 e, err := r.Next()
265 if err != nil {
266 return nil, err
267 }
268 if e == nil || e.Offset != off {
269 return nil, DecodeError{"info", off, "no type at offset"}
270 }
271
272
273
274
275 var typ Type
276
277
278 next := func() *Entry {
279 if !e.Children {
280 return nil
281 }
282 kid, err1 := r.Next()
283 if err1 != nil {
284 err = err1
285 return nil
286 }
287 if kid == nil {
288 err = DecodeError{"info", r.b.off, "unexpected end of DWARF entries"}
289 return nil
290 }
291 if kid.Tag == 0 {
292 return nil
293 }
294 return kid
295 }
296
297
298
299 typeOf := func(e *Entry) Type {
300 toff, ok := e.Val(AttrType).(Offset)
301 if !ok {
302
303 return new(VoidType)
304 }
305 var t Type
306 if t, err = d.Type(toff); err != nil {
307 return nil
308 }
309 return t
310 }
311
312 switch e.Tag {
313 case TagArrayType:
314
315
316
317
318
319
320
321
322 t := new(ArrayType)
323 typ = t
324 d.typeCache[off] = t
325 if t.Type = typeOf(e); err != nil {
326 goto Error
327 }
328 t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
329
330
331 ndim := 0
332 for kid := next(); kid != nil; kid = next() {
333
334
335 switch kid.Tag {
336 case TagSubrangeType:
337 max, ok := kid.Val(AttrUpperBound).(int64)
338 if !ok {
339 max = -2
340 }
341 if ndim == 0 {
342 t.Count = max + 1
343 } else {
344
345
346 t.Type = &ArrayType{Type: t.Type, Count: max + 1}
347 }
348 ndim++
349 case TagEnumerationType:
350 err = DecodeError{"info", kid.Offset, "cannot handle enumeration type as array bound"}
351 goto Error
352 }
353 }
354 if ndim == 0 {
355
356 t.Count = -1
357 }
358
359 case TagBaseType:
360
361
362
363
364
365
366
367 name, _ := e.Val(AttrName).(string)
368 enc, ok := e.Val(AttrEncoding).(int64)
369 if !ok {
370 err = DecodeError{"info", e.Offset, "missing encoding attribute for " + name}
371 goto Error
372 }
373 switch enc {
374 default:
375 err = DecodeError{"info", e.Offset, "unrecognized encoding attribute value"}
376 goto Error
377
378 case encAddress:
379 typ = new(AddrType)
380 case encBoolean:
381 typ = new(BoolType)
382 case encComplexFloat:
383 typ = new(ComplexType)
384 case encFloat:
385 typ = new(FloatType)
386 case encSigned:
387 typ = new(IntType)
388 case encUnsigned:
389 typ = new(UintType)
390 case encSignedChar:
391 typ = new(CharType)
392 case encUnsignedChar:
393 typ = new(UcharType)
394 }
395 d.typeCache[off] = typ
396 t := typ.(interface {
397 Basic() *BasicType
398 }).Basic()
399 t.Name = name
400 t.BitSize, _ = e.Val(AttrBitSize).(int64)
401 t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
402
403 case TagClassType, TagStructType, TagUnionType:
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418 t := new(StructType)
419 typ = t
420 d.typeCache[off] = t
421 switch e.Tag {
422 case TagClassType:
423 t.Kind = "class"
424 case TagStructType:
425 t.Kind = "struct"
426 case TagUnionType:
427 t.Kind = "union"
428 }
429 t.StructName, _ = e.Val(AttrName).(string)
430 t.Incomplete = e.Val(AttrDeclaration) != nil
431 t.Field = make([]*StructField, 0, 8)
432 for kid := next(); kid != nil; kid = next() {
433 if kid.Tag == TagMember {
434 f := new(StructField)
435 if f.Type = typeOf(kid); err != nil {
436 goto Error
437 }
438 if loc, ok := kid.Val(AttrDataMemberLoc).([]byte); ok {
439 b := makeBuf(d, "location", 0, loc, d.addrsize)
440 if b.uint8() != opPlusUconst {
441 err = DecodeError{"info", kid.Offset, "unexpected opcode"}
442 goto Error
443 }
444 f.ByteOffset = int64(b.uint())
445 if b.err != nil {
446 err = b.err
447 goto Error
448 }
449 }
450 f.Name, _ = kid.Val(AttrName).(string)
451 f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
452 f.BitOffset, _ = kid.Val(AttrBitOffset).(int64)
453 f.BitSize, _ = kid.Val(AttrBitSize).(int64)
454 t.Field = append(t.Field, f)
455 }
456 }
457
458 case TagConstType, TagVolatileType, TagRestrictType:
459
460
461
462 t := new(QualType)
463 typ = t
464 d.typeCache[off] = t
465 if t.Type = typeOf(e); err != nil {
466 goto Error
467 }
468 switch e.Tag {
469 case TagConstType:
470 t.Qual = "const"
471 case TagRestrictType:
472 t.Qual = "restrict"
473 case TagVolatileType:
474 t.Qual = "volatile"
475 }
476
477 case TagEnumerationType:
478
479
480
481
482
483
484
485
486 t := new(EnumType)
487 typ = t
488 d.typeCache[off] = t
489 t.EnumName, _ = e.Val(AttrName).(string)
490 t.Val = make([]*EnumValue, 0, 8)
491 for kid := next(); kid != nil; kid = next() {
492 if kid.Tag == TagEnumerator {
493 f := new(EnumValue)
494 f.Name, _ = kid.Val(AttrName).(string)
495 f.Val, _ = kid.Val(AttrConstValue).(int64)
496 n := len(t.Val)
497 if n >= cap(t.Val) {
498 val := make([]*EnumValue, n, n*2)
499 copy(val, t.Val)
500 t.Val = val
501 }
502 t.Val = t.Val[0 : n+1]
503 t.Val[n] = f
504 }
505 }
506
507 case TagPointerType:
508
509
510
511
512 t := new(PtrType)
513 typ = t
514 d.typeCache[off] = t
515 if e.Val(AttrType) == nil {
516 t.Type = &VoidType{}
517 break
518 }
519 t.Type = typeOf(e)
520
521 case TagSubroutineType:
522
523
524
525
526
527
528
529
530
531 t := new(FuncType)
532 typ = t
533 d.typeCache[off] = t
534 if t.ReturnType = typeOf(e); err != nil {
535 goto Error
536 }
537 t.ParamType = make([]Type, 0, 8)
538 for kid := next(); kid != nil; kid = next() {
539 var tkid Type
540 switch kid.Tag {
541 default:
542 continue
543 case TagFormalParameter:
544 if tkid = typeOf(kid); err != nil {
545 goto Error
546 }
547 case TagUnspecifiedParameters:
548 tkid = &DotDotDotType{}
549 }
550 t.ParamType = append(t.ParamType, tkid)
551 }
552
553 case TagTypedef:
554
555
556
557
558 t := new(TypedefType)
559 typ = t
560 d.typeCache[off] = t
561 t.Name, _ = e.Val(AttrName).(string)
562 t.Type = typeOf(e)
563 }
564
565 if err != nil {
566 goto Error
567 }
568
569 {
570 b, ok := e.Val(AttrByteSize).(int64)
571 if !ok {
572 b = -1
573 }
574 typ.Common().ByteSize = b
575 }
576 return typ, nil
577
578 Error:
579
580
581
582 d.typeCache[off] = nil, false
583 return nil, err
584 }