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