Source file src/pkg/debug/dwarf/buf.go
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.
4
5 // Buffered reading and decoding of DWARF data streams.
6
7 package dwarf
8
9 import (
10 "encoding/binary"
11 "strconv"
12 )
13
14 // Data buffer being decoded.
15 type buf struct {
16 dwarf *Data
17 order binary.ByteOrder
18 name string
19 off Offset
20 data []byte
21 addrsize int
22 err error
23 }
24
25 func makeBuf(d *Data, name string, off Offset, data []byte, addrsize int) buf {
26 return buf{d, d.order, name, off, data, addrsize, nil}
27 }
28
29 func (b *buf) uint8() uint8 {
30 if len(b.data) < 1 {
31 b.error("underflow")
32 return 0
33 }
34 val := b.data[0]
35 b.data = b.data[1:]
36 b.off++
37 return val
38 }
39
40 func (b *buf) bytes(n int) []byte {
41 if len(b.data) < n {
42 b.error("underflow")
43 return nil
44 }
45 data := b.data[0:n]
46 b.data = b.data[n:]
47 b.off += Offset(n)
48 return data
49 }
50
51 func (b *buf) skip(n int) { b.bytes(n) }
52
53 func (b *buf) string() string {
54 for i := 0; i < len(b.data); i++ {
55 if b.data[i] == 0 {
56 s := string(b.data[0:i])
57 b.data = b.data[i+1:]
58 b.off += Offset(i + 1)
59 return s
60 }
61 }
62 b.error("underflow")
63 return ""
64 }
65
66 func (b *buf) uint16() uint16 {
67 a := b.bytes(2)
68 if a == nil {
69 return 0
70 }
71 return b.order.Uint16(a)
72 }
73
74 func (b *buf) uint32() uint32 {
75 a := b.bytes(4)
76 if a == nil {
77 return 0
78 }
79 return b.order.Uint32(a)
80 }
81
82 func (b *buf) uint64() uint64 {
83 a := b.bytes(8)
84 if a == nil {
85 return 0
86 }
87 return b.order.Uint64(a)
88 }
89
90 // Read a varint, which is 7 bits per byte, little endian.
91 // the 0x80 bit means read another byte.
92 func (b *buf) varint() (c uint64, bits uint) {
93 for i := 0; i < len(b.data); i++ {
94 byte := b.data[i]
95 c |= uint64(byte&0x7F) << bits
96 bits += 7
97 if byte&0x80 == 0 {
98 b.off += Offset(i + 1)
99 b.data = b.data[i+1:]
100 return c, bits
101 }
102 }
103 return 0, 0
104 }
105
106 // Unsigned int is just a varint.
107 func (b *buf) uint() uint64 {
108 x, _ := b.varint()
109 return x
110 }
111
112 // Signed int is a sign-extended varint.
113 func (b *buf) int() int64 {
114 ux, bits := b.varint()
115 x := int64(ux)
116 if x&(1<<(bits-1)) != 0 {
117 x |= -1 << bits
118 }
119 return x
120 }
121
122 // Address-sized uint.
123 func (b *buf) addr() uint64 {
124 switch b.addrsize {
125 case 1:
126 return uint64(b.uint8())
127 case 2:
128 return uint64(b.uint16())
129 case 4:
130 return uint64(b.uint32())
131 case 8:
132 return uint64(b.uint64())
133 }
134 b.error("unknown address size")
135 return 0
136 }
137
138 func (b *buf) error(s string) {
139 if b.err == nil {
140 b.data = nil
141 b.err = DecodeError{b.name, b.off, s}
142 }
143 }
144
145 type DecodeError struct {
146 Name string
147 Offset Offset
148 Err string
149 }
150
151 func (e DecodeError) Error() string {
152 return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err
153 }