2018-01-29 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgo / go / debug / dwarf / buf.go
blob24d266db10738be0b2a6e9ae6277a381042ab9c2
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 // Buffered reading and decoding of DWARF data streams.
7 package dwarf
9 import (
10 "encoding/binary"
11 "strconv"
14 // Data buffer being decoded.
15 type buf struct {
16 dwarf *Data
17 order binary.ByteOrder
18 format dataFormat
19 name string
20 off Offset
21 data []byte
22 err error
25 // Data format, other than byte order. This affects the handling of
26 // certain field formats.
27 type dataFormat interface {
28 // DWARF version number. Zero means unknown.
29 version() int
31 // 64-bit DWARF format?
32 dwarf64() (dwarf64 bool, isKnown bool)
34 // Size of an address, in bytes. Zero means unknown.
35 addrsize() int
38 // Some parts of DWARF have no data format, e.g., abbrevs.
39 type unknownFormat struct{}
41 func (u unknownFormat) version() int {
42 return 0
45 func (u unknownFormat) dwarf64() (bool, bool) {
46 return false, false
49 func (u unknownFormat) addrsize() int {
50 return 0
53 func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf {
54 return buf{d, d.order, format, name, off, data, nil}
57 func (b *buf) uint8() uint8 {
58 if len(b.data) < 1 {
59 b.error("underflow")
60 return 0
62 val := b.data[0]
63 b.data = b.data[1:]
64 b.off++
65 return val
68 func (b *buf) bytes(n int) []byte {
69 if len(b.data) < n {
70 b.error("underflow")
71 return nil
73 data := b.data[0:n]
74 b.data = b.data[n:]
75 b.off += Offset(n)
76 return data
79 func (b *buf) skip(n int) { b.bytes(n) }
81 func (b *buf) string() string {
82 for i := 0; i < len(b.data); i++ {
83 if b.data[i] == 0 {
84 s := string(b.data[0:i])
85 b.data = b.data[i+1:]
86 b.off += Offset(i + 1)
87 return s
90 b.error("underflow")
91 return ""
94 func (b *buf) uint16() uint16 {
95 a := b.bytes(2)
96 if a == nil {
97 return 0
99 return b.order.Uint16(a)
102 func (b *buf) uint32() uint32 {
103 a := b.bytes(4)
104 if a == nil {
105 return 0
107 return b.order.Uint32(a)
110 func (b *buf) uint64() uint64 {
111 a := b.bytes(8)
112 if a == nil {
113 return 0
115 return b.order.Uint64(a)
118 // Read a varint, which is 7 bits per byte, little endian.
119 // the 0x80 bit means read another byte.
120 func (b *buf) varint() (c uint64, bits uint) {
121 for i := 0; i < len(b.data); i++ {
122 byte := b.data[i]
123 c |= uint64(byte&0x7F) << bits
124 bits += 7
125 if byte&0x80 == 0 {
126 b.off += Offset(i + 1)
127 b.data = b.data[i+1:]
128 return c, bits
131 return 0, 0
134 // Unsigned int is just a varint.
135 func (b *buf) uint() uint64 {
136 x, _ := b.varint()
137 return x
140 // Signed int is a sign-extended varint.
141 func (b *buf) int() int64 {
142 ux, bits := b.varint()
143 x := int64(ux)
144 if x&(1<<(bits-1)) != 0 {
145 x |= -1 << bits
147 return x
150 // Address-sized uint.
151 func (b *buf) addr() uint64 {
152 switch b.format.addrsize() {
153 case 1:
154 return uint64(b.uint8())
155 case 2:
156 return uint64(b.uint16())
157 case 4:
158 return uint64(b.uint32())
159 case 8:
160 return b.uint64()
162 b.error("unknown address size")
163 return 0
166 func (b *buf) unitLength() (length Offset, dwarf64 bool) {
167 length = Offset(b.uint32())
168 if length == 0xffffffff {
169 dwarf64 = true
170 length = Offset(b.uint64())
171 } else if length >= 0xfffffff0 {
172 b.error("unit length has reserved value")
174 return
177 func (b *buf) error(s string) {
178 if b.err == nil {
179 b.data = nil
180 b.err = DecodeError{b.name, b.off, s}
184 type DecodeError struct {
185 Name string
186 Offset Offset
187 Err string
190 func (e DecodeError) Error() string {
191 return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err