]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgo/go/debug/dwarf/buf.go
libgo: update to Go1.14beta1
[thirdparty/gcc.git] / libgo / go / debug / dwarf / buf.go
CommitLineData
22b955cc 1// Copyright 2009 The Go Authors. All rights reserved.
7a938933
ILT
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Buffered reading and decoding of DWARF data streams.
6
7package dwarf
8
9import (
5a8ea165 10 "bytes"
7a938933 11 "encoding/binary"
7a938933
ILT
12 "strconv"
13)
14
15// Data buffer being decoded.
16type buf struct {
be47d6ec
ILT
17 dwarf *Data
18 order binary.ByteOrder
19 format dataFormat
20 name string
21 off Offset
22 data []byte
23 err error
7a938933
ILT
24}
25
22b955cc 26// Data format, other than byte order. This affects the handling of
be47d6ec
ILT
27// certain field formats.
28type dataFormat interface {
22b955cc 29 // DWARF version number. Zero means unknown.
be47d6ec
ILT
30 version() int
31
32 // 64-bit DWARF format?
33 dwarf64() (dwarf64 bool, isKnown bool)
34
22b955cc 35 // Size of an address, in bytes. Zero means unknown.
be47d6ec
ILT
36 addrsize() int
37}
38
39// Some parts of DWARF have no data format, e.g., abbrevs.
40type unknownFormat struct{}
41
42func (u unknownFormat) version() int {
43 return 0
44}
45
46func (u unknownFormat) dwarf64() (bool, bool) {
47 return false, false
48}
49
50func (u unknownFormat) addrsize() int {
51 return 0
52}
53
54func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf {
55 return buf{d, d.order, format, name, off, data, nil}
7a938933
ILT
56}
57
58func (b *buf) uint8() uint8 {
59 if len(b.data) < 1 {
60 b.error("underflow")
61 return 0
62 }
63 val := b.data[0]
64 b.data = b.data[1:]
65 b.off++
66 return val
67}
68
69func (b *buf) bytes(n int) []byte {
70 if len(b.data) < n {
71 b.error("underflow")
72 return nil
73 }
74 data := b.data[0:n]
75 b.data = b.data[n:]
76 b.off += Offset(n)
77 return data
78}
79
80func (b *buf) skip(n int) { b.bytes(n) }
81
82func (b *buf) string() string {
5a8ea165
ILT
83 i := bytes.IndexByte(b.data, 0)
84 if i < 0 {
85 b.error("underflow")
86 return ""
7a938933 87 }
5a8ea165
ILT
88
89 s := string(b.data[0:i])
90 b.data = b.data[i+1:]
91 b.off += Offset(i + 1)
92 return s
7a938933
ILT
93}
94
95func (b *buf) uint16() uint16 {
96 a := b.bytes(2)
97 if a == nil {
98 return 0
99 }
100 return b.order.Uint16(a)
101}
102
5a8ea165
ILT
103func (b *buf) uint24() uint32 {
104 a := b.bytes(3)
105 if a == nil {
106 return 0
107 }
108 if b.dwarf.bigEndian {
109 return uint32(a[2]) | uint32(a[1])<<8 | uint32(a[0])<<16
110 } else {
111 return uint32(a[0]) | uint32(a[1])<<8 | uint32(a[2])<<16
112 }
113}
114
7a938933
ILT
115func (b *buf) uint32() uint32 {
116 a := b.bytes(4)
117 if a == nil {
118 return 0
119 }
120 return b.order.Uint32(a)
121}
122
123func (b *buf) uint64() uint64 {
124 a := b.bytes(8)
125 if a == nil {
126 return 0
127 }
128 return b.order.Uint64(a)
129}
130
131// Read a varint, which is 7 bits per byte, little endian.
132// the 0x80 bit means read another byte.
133func (b *buf) varint() (c uint64, bits uint) {
134 for i := 0; i < len(b.data); i++ {
135 byte := b.data[i]
136 c |= uint64(byte&0x7F) << bits
137 bits += 7
138 if byte&0x80 == 0 {
139 b.off += Offset(i + 1)
140 b.data = b.data[i+1:]
141 return c, bits
142 }
143 }
144 return 0, 0
145}
146
147// Unsigned int is just a varint.
148func (b *buf) uint() uint64 {
149 x, _ := b.varint()
150 return x
151}
152
153// Signed int is a sign-extended varint.
154func (b *buf) int() int64 {
155 ux, bits := b.varint()
156 x := int64(ux)
157 if x&(1<<(bits-1)) != 0 {
158 x |= -1 << bits
159 }
160 return x
161}
162
163// Address-sized uint.
164func (b *buf) addr() uint64 {
be47d6ec
ILT
165 switch b.format.addrsize() {
166 case 1:
167 return uint64(b.uint8())
168 case 2:
169 return uint64(b.uint16())
170 case 4:
171 return uint64(b.uint32())
172 case 8:
22b955cc 173 return b.uint64()
7a938933
ILT
174 }
175 b.error("unknown address size")
176 return 0
177}
178
af146490
ILT
179func (b *buf) unitLength() (length Offset, dwarf64 bool) {
180 length = Offset(b.uint32())
181 if length == 0xffffffff {
182 dwarf64 = true
183 length = Offset(b.uint64())
184 } else if length >= 0xfffffff0 {
185 b.error("unit length has reserved value")
186 }
187 return
188}
189
7a938933
ILT
190func (b *buf) error(s string) {
191 if b.err == nil {
192 b.data = nil
193 b.err = DecodeError{b.name, b.off, s}
194 }
195}
196
197type DecodeError struct {
198 Name string
199 Offset Offset
2fd401c8 200 Err string
7a938933
ILT
201}
202
2fd401c8 203func (e DecodeError) Error() string {
d5363590 204 return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err
7a938933 205}