c-family: char8_t and aliasing in C vs C++ [PR111884]
[official-gcc.git] / libgo / go / debug / dwarf / unit.go
blob9b3d6e902d9993274e16dcbf0129a02a82497658
1 // 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.
5 package dwarf
7 import (
8 "sort"
9 "strconv"
12 // DWARF debug info is split into a sequence of compilation units.
13 // Each unit has its own abbreviation table and address size.
15 type unit struct {
16 base Offset // byte offset of header within the aggregate info
17 off Offset // byte offset of data within the aggregate info
18 data []byte
19 atable abbrevTable
20 asize int
21 vers int
22 utype uint8 // DWARF 5 unit type
23 is64 bool // True for 64-bit DWARF format
26 // Implement the dataFormat interface.
28 func (u *unit) version() int {
29 return u.vers
32 func (u *unit) dwarf64() (bool, bool) {
33 return u.is64, true
36 func (u *unit) addrsize() int {
37 return u.asize
40 func (d *Data) parseUnits() ([]unit, error) {
41 // Count units.
42 nunit := 0
43 b := makeBuf(d, unknownFormat{}, "info", 0, d.info)
44 for len(b.data) > 0 {
45 len, _ := b.unitLength()
46 if len != Offset(uint32(len)) {
47 b.error("unit length overflow")
48 break
50 b.skip(int(len))
51 if len > 0 {
52 nunit++
55 if b.err != nil {
56 return nil, b.err
59 // Again, this time writing them down.
60 b = makeBuf(d, unknownFormat{}, "info", 0, d.info)
61 units := make([]unit, nunit)
62 for i := range units {
63 u := &units[i]
64 u.base = b.off
65 var n Offset
66 for n == 0 {
67 n, u.is64 = b.unitLength()
69 dataOff := b.off
70 vers := b.uint16()
71 if vers < 2 || vers > 5 {
72 b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
73 break
75 u.vers = int(vers)
76 if vers >= 5 {
77 u.utype = b.uint8()
78 u.asize = int(b.uint8())
80 var abbrevOff uint64
81 if u.is64 {
82 abbrevOff = b.uint64()
83 } else {
84 abbrevOff = uint64(b.uint32())
86 atable, err := d.parseAbbrev(abbrevOff, u.vers)
87 if err != nil {
88 if b.err == nil {
89 b.err = err
91 break
93 u.atable = atable
94 if vers < 5 {
95 u.asize = int(b.uint8())
98 switch u.utype {
99 case utSkeleton, utSplitCompile:
100 b.uint64() // unit ID
101 case utType, utSplitType:
102 b.uint64() // type signature
103 if u.is64 { // type offset
104 b.uint64()
105 } else {
106 b.uint32()
110 u.off = b.off
111 u.data = b.bytes(int(n - (b.off - dataOff)))
113 if b.err != nil {
114 return nil, b.err
116 return units, nil
119 // offsetToUnit returns the index of the unit containing offset off.
120 // It returns -1 if no unit contains this offset.
121 func (d *Data) offsetToUnit(off Offset) int {
122 // Find the unit after off
123 next := sort.Search(len(d.unit), func(i int) bool {
124 return d.unit[i].off > off
126 if next == 0 {
127 return -1
129 u := &d.unit[next-1]
130 if u.off <= off && off < u.off+Offset(len(u.data)) {
131 return next - 1
133 return -1