OSDN Git Service

Add Go frontend, libgo library, and Go testsuite.
[pf3gnuchains/gcc-fork.git] / libgo / go / 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         "os"
12         "strconv"
13 )
14
15 // Data buffer being decoded.
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 // Read a varint, which is 7 bits per byte, little endian.
92 // the 0x80 bit means read another byte.
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 // Unsigned int is just a varint.
108 func (b *buf) uint() uint64 {
109         x, _ := b.varint()
110         return x
111 }
112
113 // Signed int is a sign-extended varint.
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 // Address-sized uint.
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 }