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 7package dwarf 8 9import ( 10 "encoding/binary" 11 "strconv" 12) 13 14// Data buffer being decoded. 15type buf struct { 16 dwarf *Data 17 order binary.ByteOrder 18 format dataFormat 19 name string 20 off Offset 21 data []byte 22 err error 23} 24 25// Data format, other than byte order. This affects the handling of 26// certain field formats. 27type dataFormat interface { 28 // DWARF version number. Zero means unknown. 29 version() int 30 31 // 64-bit DWARF format? 32 dwarf64() (dwarf64 bool, isKnown bool) 33 34 // Size of an address, in bytes. Zero means unknown. 35 addrsize() int 36} 37 38// Some parts of DWARF have no data format, e.g., abbrevs. 39type unknownFormat struct{} 40 41func (u unknownFormat) version() int { 42 return 0 43} 44 45func (u unknownFormat) dwarf64() (bool, bool) { 46 return false, false 47} 48 49func (u unknownFormat) addrsize() int { 50 return 0 51} 52 53func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf { 54 return buf{d, d.order, format, name, off, data, nil} 55} 56 57func (b *buf) uint8() uint8 { 58 if len(b.data) < 1 { 59 b.error("underflow") 60 return 0 61 } 62 val := b.data[0] 63 b.data = b.data[1:] 64 b.off++ 65 return val 66} 67 68func (b *buf) bytes(n int) []byte { 69 if len(b.data) < n { 70 b.error("underflow") 71 return nil 72 } 73 data := b.data[0:n] 74 b.data = b.data[n:] 75 b.off += Offset(n) 76 return data 77} 78 79func (b *buf) skip(n int) { b.bytes(n) } 80 81func (b *buf) string() string { 82 for i := 0; i < len(b.data); i++ { 83 if b.data[i] == 0 { 84 s := string(b.data[0:i]) 85 b.data = b.data[i+1:] 86 b.off += Offset(i + 1) 87 return s 88 } 89 } 90 b.error("underflow") 91 return "" 92} 93 94func (b *buf) uint16() uint16 { 95 a := b.bytes(2) 96 if a == nil { 97 return 0 98 } 99 return b.order.Uint16(a) 100} 101 102func (b *buf) uint32() uint32 { 103 a := b.bytes(4) 104 if a == nil { 105 return 0 106 } 107 return b.order.Uint32(a) 108} 109 110func (b *buf) uint64() uint64 { 111 a := b.bytes(8) 112 if a == nil { 113 return 0 114 } 115 return b.order.Uint64(a) 116} 117 118// Read a varint, which is 7 bits per byte, little endian. 119// the 0x80 bit means read another byte. 120func (b *buf) varint() (c uint64, bits uint) { 121 for i := 0; i < len(b.data); i++ { 122 byte := b.data[i] 123 c |= uint64(byte&0x7F) << bits 124 bits += 7 125 if byte&0x80 == 0 { 126 b.off += Offset(i + 1) 127 b.data = b.data[i+1:] 128 return c, bits 129 } 130 } 131 return 0, 0 132} 133 134// Unsigned int is just a varint. 135func (b *buf) uint() uint64 { 136 x, _ := b.varint() 137 return x 138} 139 140// Signed int is a sign-extended varint. 141func (b *buf) int() int64 { 142 ux, bits := b.varint() 143 x := int64(ux) 144 if x&(1<<(bits-1)) != 0 { 145 x |= -1 << bits 146 } 147 return x 148} 149 150// Address-sized uint. 151func (b *buf) addr() uint64 { 152 switch b.format.addrsize() { 153 case 1: 154 return uint64(b.uint8()) 155 case 2: 156 return uint64(b.uint16()) 157 case 4: 158 return uint64(b.uint32()) 159 case 8: 160 return uint64(b.uint64()) 161 } 162 b.error("unknown address size") 163 return 0 164} 165 166func (b *buf) unitLength() (length Offset, dwarf64 bool) { 167 length = Offset(b.uint32()) 168 if length == 0xffffffff { 169 dwarf64 = true 170 length = Offset(b.uint64()) 171 } else if length >= 0xfffffff0 { 172 b.error("unit length has reserved value") 173 } 174 return 175} 176 177func (b *buf) error(s string) { 178 if b.err == nil { 179 b.data = nil 180 b.err = DecodeError{b.name, b.off, s} 181 } 182} 183 184type DecodeError struct { 185 Name string 186 Offset Offset 187 Err string 188} 189 190func (e DecodeError) Error() string { 191 return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err 192} 193