OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [debug/] [dwarf/] [type.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 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
// DWARF type information structures.
6
// The format is heavily biased toward C, but for simplicity
7
// the String methods use a pseudo-Go syntax.
8
 
9
package dwarf
10
 
11
import "strconv"
12
 
13
// A Type conventionally represents a pointer to any of the
14
// specific Type structures (CharType, StructType, etc.).
15
type Type interface {
16
        Common() *CommonType
17
        String() string
18
        Size() int64
19
}
20
 
21
// A CommonType holds fields common to multiple types.
22
// If a field is not known or not applicable for a given type,
23
// the zero value is used.
24
type CommonType struct {
25
        ByteSize int64  // size of value of this type, in bytes
26
        Name     string // name that can be used to refer to type
27
}
28
 
29
func (c *CommonType) Common() *CommonType { return c }
30
 
31
func (c *CommonType) Size() int64 { return c.ByteSize }
32
 
33
// Basic types
34
 
35
// A BasicType holds fields common to all basic types.
36
type BasicType struct {
37
        CommonType
38
        BitSize   int64
39
        BitOffset int64
40
}
41
 
42
func (b *BasicType) Basic() *BasicType { return b }
43
 
44
func (t *BasicType) String() string {
45
        if t.Name != "" {
46
                return t.Name
47
        }
48
        return "?"
49
}
50
 
51
// A CharType represents a signed character type.
52
type CharType struct {
53
        BasicType
54
}
55
 
56
// A UcharType represents an unsigned character type.
57
type UcharType struct {
58
        BasicType
59
}
60
 
61
// An IntType represents a signed integer type.
62
type IntType struct {
63
        BasicType
64
}
65
 
66
// A UintType represents an unsigned integer type.
67
type UintType struct {
68
        BasicType
69
}
70
 
71
// A FloatType represents a floating point type.
72
type FloatType struct {
73
        BasicType
74
}
75
 
76
// A ComplexType represents a complex floating point type.
77
type ComplexType struct {
78
        BasicType
79
}
80
 
81
// A BoolType represents a boolean type.
82
type BoolType struct {
83
        BasicType
84
}
85
 
86
// An AddrType represents a machine address type.
87
type AddrType struct {
88
        BasicType
89
}
90
 
91
// qualifiers
92
 
93
// A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
94
type QualType struct {
95
        CommonType
96
        Qual string
97
        Type Type
98
}
99
 
100
func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
101
 
102
func (t *QualType) Size() int64 { return t.Type.Size() }
103
 
104
// An ArrayType represents a fixed size array type.
105
type ArrayType struct {
106
        CommonType
107
        Type          Type
108
        StrideBitSize int64 // if > 0, number of bits to hold each element
109
        Count         int64 // if == -1, an incomplete array, like char x[].
110
}
111
 
112
func (t *ArrayType) String() string {
113
        return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
114
}
115
 
116
func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() }
117
 
118
// A VoidType represents the C void type.
119
type VoidType struct {
120
        CommonType
121
}
122
 
123
func (t *VoidType) String() string { return "void" }
124
 
125
// A PtrType represents a pointer type.
126
type PtrType struct {
127
        CommonType
128
        Type Type
129
}
130
 
131
func (t *PtrType) String() string { return "*" + t.Type.String() }
132
 
133
// A StructType represents a struct, union, or C++ class type.
134
type StructType struct {
135
        CommonType
136
        StructName string
137
        Kind       string // "struct", "union", or "class".
138
        Field      []*StructField
139
        Incomplete bool // if true, struct, union, class is declared but not defined
140
}
141
 
142
// A StructField represents a field in a struct, union, or C++ class type.
143
type StructField struct {
144
        Name       string
145
        Type       Type
146
        ByteOffset int64
147
        ByteSize   int64
148
        BitOffset  int64 // within the ByteSize bytes at ByteOffset
149
        BitSize    int64 // zero if not a bit field
150
}
151
 
152
func (t *StructType) String() string {
153
        if t.StructName != "" {
154
                return t.Kind + " " + t.StructName
155
        }
156
        return t.Defn()
157
}
158
 
159
func (t *StructType) Defn() string {
160
        s := t.Kind
161
        if t.StructName != "" {
162
                s += " " + t.StructName
163
        }
164
        if t.Incomplete {
165
                s += " /*incomplete*/"
166
                return s
167
        }
168
        s += " {"
169
        for i, f := range t.Field {
170
                if i > 0 {
171
                        s += "; "
172
                }
173
                s += f.Name + " " + f.Type.String()
174
                s += "@" + strconv.FormatInt(f.ByteOffset, 10)
175
                if f.BitSize > 0 {
176
                        s += " : " + strconv.FormatInt(f.BitSize, 10)
177
                        s += "@" + strconv.FormatInt(f.BitOffset, 10)
178
                }
179
        }
180
        s += "}"
181
        return s
182
}
183
 
184
// An EnumType represents an enumerated type.
185
// The only indication of its native integer type is its ByteSize
186
// (inside CommonType).
187
type EnumType struct {
188
        CommonType
189
        EnumName string
190
        Val      []*EnumValue
191
}
192
 
193
// An EnumValue represents a single enumeration value.
194
type EnumValue struct {
195
        Name string
196
        Val  int64
197
}
198
 
199
func (t *EnumType) String() string {
200
        s := "enum"
201
        if t.EnumName != "" {
202
                s += " " + t.EnumName
203
        }
204
        s += " {"
205
        for i, v := range t.Val {
206
                if i > 0 {
207
                        s += "; "
208
                }
209
                s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
210
        }
211
        s += "}"
212
        return s
213
}
214
 
215
// A FuncType represents a function type.
216
type FuncType struct {
217
        CommonType
218
        ReturnType Type
219
        ParamType  []Type
220
}
221
 
222
func (t *FuncType) String() string {
223
        s := "func("
224
        for i, t := range t.ParamType {
225
                if i > 0 {
226
                        s += ", "
227
                }
228
                s += t.String()
229
        }
230
        s += ")"
231
        if t.ReturnType != nil {
232
                s += " " + t.ReturnType.String()
233
        }
234
        return s
235
}
236
 
237
// A DotDotDotType represents the variadic ... function parameter.
238
type DotDotDotType struct {
239
        CommonType
240
}
241
 
242
func (t *DotDotDotType) String() string { return "..." }
243
 
244
// A TypedefType represents a named type.
245
type TypedefType struct {
246
        CommonType
247
        Type Type
248
}
249
 
250
func (t *TypedefType) String() string { return t.Name }
251
 
252
func (t *TypedefType) Size() int64 { return t.Type.Size() }
253
 
254
func (d *Data) Type(off Offset) (Type, error) {
255
        if t, ok := d.typeCache[off]; ok {
256
                return t, nil
257
        }
258
 
259
        r := d.Reader()
260
        r.Seek(off)
261
        e, err := r.Next()
262
        if err != nil {
263
                return nil, err
264
        }
265
        if e == nil || e.Offset != off {
266
                return nil, DecodeError{"info", off, "no type at offset"}
267
        }
268
 
269
        // Parse type from Entry.
270
        // Must always set d.typeCache[off] before calling
271
        // d.Type recursively, to handle circular types correctly.
272
        var typ Type
273
 
274
        // Get next child; set err if error happens.
275
        next := func() *Entry {
276
                if !e.Children {
277
                        return nil
278
                }
279
                kid, err1 := r.Next()
280
                if err1 != nil {
281
                        err = err1
282
                        return nil
283
                }
284
                if kid == nil {
285
                        err = DecodeError{"info", r.b.off, "unexpected end of DWARF entries"}
286
                        return nil
287
                }
288
                if kid.Tag == 0 {
289
                        return nil
290
                }
291
                return kid
292
        }
293
 
294
        // Get Type referred to by Entry's AttrType field.
295
        // Set err if error happens.  Not having a type is an error.
296
        typeOf := func(e *Entry) Type {
297
                toff, ok := e.Val(AttrType).(Offset)
298
                if !ok {
299
                        // It appears that no Type means "void".
300
                        return new(VoidType)
301
                }
302
                var t Type
303
                if t, err = d.Type(toff); err != nil {
304
                        return nil
305
                }
306
                return t
307
        }
308
 
309
        switch e.Tag {
310
        case TagArrayType:
311
                // Multi-dimensional array.  (DWARF v2 §5.4)
312
                // Attributes:
313
                //      AttrType:subtype [required]
314
                //      AttrStrideSize: size in bits of each element of the array
315
                //      AttrByteSize: size of entire array
316
                // Children:
317
                //      TagSubrangeType or TagEnumerationType giving one dimension.
318
                //      dimensions are in left to right order.
319
                t := new(ArrayType)
320
                typ = t
321
                d.typeCache[off] = t
322
                if t.Type = typeOf(e); err != nil {
323
                        goto Error
324
                }
325
                t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
326
 
327
                // Accumulate dimensions,
328
                ndim := 0
329
                for kid := next(); kid != nil; kid = next() {
330
                        // TODO(rsc): Can also be TagEnumerationType
331
                        // but haven't seen that in the wild yet.
332
                        switch kid.Tag {
333
                        case TagSubrangeType:
334
                                max, ok := kid.Val(AttrUpperBound).(int64)
335
                                if !ok {
336
                                        max = -2 // Count == -1, as in x[].
337
                                }
338
                                if ndim == 0 {
339
                                        t.Count = max + 1
340
                                } else {
341
                                        // Multidimensional array.
342
                                        // Create new array type underneath this one.
343
                                        t.Type = &ArrayType{Type: t.Type, Count: max + 1}
344
                                }
345
                                ndim++
346
                        case TagEnumerationType:
347
                                err = DecodeError{"info", kid.Offset, "cannot handle enumeration type as array bound"}
348
                                goto Error
349
                        }
350
                }
351
                if ndim == 0 {
352
                        // LLVM generates this for x[].
353
                        t.Count = -1
354
                }
355
 
356
        case TagBaseType:
357
                // Basic type.  (DWARF v2 §5.1)
358
                // Attributes:
359
                //      AttrName: name of base type in programming language of the compilation unit [required]
360
                //      AttrEncoding: encoding value for type (encFloat etc) [required]
361
                //      AttrByteSize: size of type in bytes [required]
362
                //      AttrBitOffset: for sub-byte types, size in bits
363
                //      AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes
364
                name, _ := e.Val(AttrName).(string)
365
                enc, ok := e.Val(AttrEncoding).(int64)
366
                if !ok {
367
                        err = DecodeError{"info", e.Offset, "missing encoding attribute for " + name}
368
                        goto Error
369
                }
370
                switch enc {
371
                default:
372
                        err = DecodeError{"info", e.Offset, "unrecognized encoding attribute value"}
373
                        goto Error
374
 
375
                case encAddress:
376
                        typ = new(AddrType)
377
                case encBoolean:
378
                        typ = new(BoolType)
379
                case encComplexFloat:
380
                        typ = new(ComplexType)
381
                case encFloat:
382
                        typ = new(FloatType)
383
                case encSigned:
384
                        typ = new(IntType)
385
                case encUnsigned:
386
                        typ = new(UintType)
387
                case encSignedChar:
388
                        typ = new(CharType)
389
                case encUnsignedChar:
390
                        typ = new(UcharType)
391
                }
392
                d.typeCache[off] = typ
393
                t := typ.(interface {
394
                        Basic() *BasicType
395
                }).Basic()
396
                t.Name = name
397
                t.BitSize, _ = e.Val(AttrBitSize).(int64)
398
                t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
399
 
400
        case TagClassType, TagStructType, TagUnionType:
401
                // Structure, union, or class type.  (DWARF v2 §5.5)
402
                // Attributes:
403
                //      AttrName: name of struct, union, or class
404
                //      AttrByteSize: byte size [required]
405
                //      AttrDeclaration: if true, struct/union/class is incomplete
406
                // Children:
407
                //      TagMember to describe one member.
408
                //              AttrName: name of member [required]
409
                //              AttrType: type of member [required]
410
                //              AttrByteSize: size in bytes
411
                //              AttrBitOffset: bit offset within bytes for bit fields
412
                //              AttrBitSize: bit size for bit fields
413
                //              AttrDataMemberLoc: location within struct [required for struct, class]
414
                // There is much more to handle C++, all ignored for now.
415
                t := new(StructType)
416
                typ = t
417
                d.typeCache[off] = t
418
                switch e.Tag {
419
                case TagClassType:
420
                        t.Kind = "class"
421
                case TagStructType:
422
                        t.Kind = "struct"
423
                case TagUnionType:
424
                        t.Kind = "union"
425
                }
426
                t.StructName, _ = e.Val(AttrName).(string)
427
                t.Incomplete = e.Val(AttrDeclaration) != nil
428
                t.Field = make([]*StructField, 0, 8)
429
                for kid := next(); kid != nil; kid = next() {
430
                        if kid.Tag == TagMember {
431
                                f := new(StructField)
432
                                if f.Type = typeOf(kid); err != nil {
433
                                        goto Error
434
                                }
435
                                if loc, ok := kid.Val(AttrDataMemberLoc).([]byte); ok {
436
                                        b := makeBuf(d, "location", 0, loc, d.addrsize)
437
                                        if b.uint8() != opPlusUconst {
438
                                                err = DecodeError{"info", kid.Offset, "unexpected opcode"}
439
                                                goto Error
440
                                        }
441
                                        f.ByteOffset = int64(b.uint())
442
                                        if b.err != nil {
443
                                                err = b.err
444
                                                goto Error
445
                                        }
446
                                }
447
                                f.Name, _ = kid.Val(AttrName).(string)
448
                                f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
449
                                f.BitOffset, _ = kid.Val(AttrBitOffset).(int64)
450
                                f.BitSize, _ = kid.Val(AttrBitSize).(int64)
451
                                t.Field = append(t.Field, f)
452
                        }
453
                }
454
 
455
        case TagConstType, TagVolatileType, TagRestrictType:
456
                // Type modifier (DWARF v2 §5.2)
457
                // Attributes:
458
                //      AttrType: subtype
459
                t := new(QualType)
460
                typ = t
461
                d.typeCache[off] = t
462
                if t.Type = typeOf(e); err != nil {
463
                        goto Error
464
                }
465
                switch e.Tag {
466
                case TagConstType:
467
                        t.Qual = "const"
468
                case TagRestrictType:
469
                        t.Qual = "restrict"
470
                case TagVolatileType:
471
                        t.Qual = "volatile"
472
                }
473
 
474
        case TagEnumerationType:
475
                // Enumeration type (DWARF v2 §5.6)
476
                // Attributes:
477
                //      AttrName: enum name if any
478
                //      AttrByteSize: bytes required to represent largest value
479
                // Children:
480
                //      TagEnumerator:
481
                //              AttrName: name of constant
482
                //              AttrConstValue: value of constant
483
                t := new(EnumType)
484
                typ = t
485
                d.typeCache[off] = t
486
                t.EnumName, _ = e.Val(AttrName).(string)
487
                t.Val = make([]*EnumValue, 0, 8)
488
                for kid := next(); kid != nil; kid = next() {
489
                        if kid.Tag == TagEnumerator {
490
                                f := new(EnumValue)
491
                                f.Name, _ = kid.Val(AttrName).(string)
492
                                f.Val, _ = kid.Val(AttrConstValue).(int64)
493
                                n := len(t.Val)
494
                                if n >= cap(t.Val) {
495
                                        val := make([]*EnumValue, n, n*2)
496
                                        copy(val, t.Val)
497
                                        t.Val = val
498
                                }
499
                                t.Val = t.Val[0 : n+1]
500
                                t.Val[n] = f
501
                        }
502
                }
503
 
504
        case TagPointerType:
505
                // Type modifier (DWARF v2 §5.2)
506
                // Attributes:
507
                //      AttrType: subtype [not required!  void* has no AttrType]
508
                //      AttrAddrClass: address class [ignored]
509
                t := new(PtrType)
510
                typ = t
511
                d.typeCache[off] = t
512
                if e.Val(AttrType) == nil {
513
                        t.Type = &VoidType{}
514
                        break
515
                }
516
                t.Type = typeOf(e)
517
 
518
        case TagSubroutineType:
519
                // Subroutine type.  (DWARF v2 §5.7)
520
                // Attributes:
521
                //      AttrType: type of return value if any
522
                //      AttrName: possible name of type [ignored]
523
                //      AttrPrototyped: whether used ANSI C prototype [ignored]
524
                // Children:
525
                //      TagFormalParameter: typed parameter
526
                //              AttrType: type of parameter
527
                //      TagUnspecifiedParameter: final ...
528
                t := new(FuncType)
529
                typ = t
530
                d.typeCache[off] = t
531
                if t.ReturnType = typeOf(e); err != nil {
532
                        goto Error
533
                }
534
                t.ParamType = make([]Type, 0, 8)
535
                for kid := next(); kid != nil; kid = next() {
536
                        var tkid Type
537
                        switch kid.Tag {
538
                        default:
539
                                continue
540
                        case TagFormalParameter:
541
                                if tkid = typeOf(kid); err != nil {
542
                                        goto Error
543
                                }
544
                        case TagUnspecifiedParameters:
545
                                tkid = &DotDotDotType{}
546
                        }
547
                        t.ParamType = append(t.ParamType, tkid)
548
                }
549
 
550
        case TagTypedef:
551
                // Typedef (DWARF v2 §5.3)
552
                // Attributes:
553
                //      AttrName: name [required]
554
                //      AttrType: type definition [required]
555
                t := new(TypedefType)
556
                typ = t
557
                d.typeCache[off] = t
558
                t.Name, _ = e.Val(AttrName).(string)
559
                t.Type = typeOf(e)
560
        }
561
 
562
        if err != nil {
563
                goto Error
564
        }
565
 
566
        {
567
                b, ok := e.Val(AttrByteSize).(int64)
568
                if !ok {
569
                        b = -1
570
                }
571
                typ.Common().ByteSize = b
572
        }
573
        return typ, nil
574
 
575
Error:
576
        // If the parse fails, take the type out of the cache
577
        // so that the next call with this offset doesn't hit
578
        // the cache and return success.
579
        delete(d.typeCache, off)
580
        return nil, err
581
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.