1
2
3
4
5
6
7 package dwarf
8
9 import (
10 "bytes"
11 "encoding/binary"
12 "strconv"
13 )
14
15
16 type buf struct {
17 dwarf *Data
18 order binary.ByteOrder
19 format dataFormat
20 name string
21 off Offset
22 data []byte
23 err error
24 }
25
26
27
28 type dataFormat interface {
29
30 version() int
31
32
33 dwarf64() (dwarf64 bool, isKnown bool)
34
35
36 addrsize() int
37 }
38
39
40 type unknownFormat struct{}
41
42 func (u unknownFormat) version() int {
43 return 0
44 }
45
46 func (u unknownFormat) dwarf64() (bool, bool) {
47 return false, false
48 }
49
50 func (u unknownFormat) addrsize() int {
51 return 0
52 }
53
54 func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf {
55 return buf{d, d.order, format, name, off, data, nil}
56 }
57
58 func (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
69 func (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
80 func (b *buf) skip(n int) { b.bytes(n) }
81
82 func (b *buf) string() string {
83 i := bytes.IndexByte(b.data, 0)
84 if i < 0 {
85 b.error("underflow")
86 return ""
87 }
88
89 s := string(b.data[0:i])
90 b.data = b.data[i+1:]
91 b.off += Offset(i + 1)
92 return s
93 }
94
95 func (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
103 func (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
115 func (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
123 func (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
132
133 func (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
148 func (b *buf) uint() uint64 {
149 x, _ := b.varint()
150 return x
151 }
152
153
154 func (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
164 func (b *buf) addr() uint64 {
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:
173 return b.uint64()
174 }
175 b.error("unknown address size")
176 return 0
177 }
178
179 func (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
190 func (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
197 type DecodeError struct {
198 Name string
199 Offset Offset
200 Err string
201 }
202
203 func (e DecodeError) Error() string {
204 return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err
205 }
206
View as plain text