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 }