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 "bytes" 11 "encoding/binary" 12 "strconv" 13) 14 15// Data buffer being decoded. 16type 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// Data format, other than byte order. This affects the handling of 27// certain field formats. 28type dataFormat interface { 29 // DWARF version number. Zero means unknown. 30 version() int 31 32 // 64-bit DWARF format? 33 dwarf64() (dwarf64 bool, isKnown bool) 34 35 // Size of an address, in bytes. Zero means unknown. 36 addrsize() int 37} 38 39// Some parts of DWARF have no data format, e.g., abbrevs. 40type unknownFormat struct{} 41 42func (u unknownFormat) version() int { 43 return 0 44} 45 46func (u unknownFormat) dwarf64() (bool, bool) { 47 return false, false 48} 49 50func (u unknownFormat) addrsize() int { 51 return 0 52} 53 54func 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 58func (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 69func (b *buf) bytes(n int) []byte { 70 if n < 0 || 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 80func (b *buf) skip(n int) { b.bytes(n) } 81 82func (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 95func (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 103func (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 115func (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 123func (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// Read a varint, which is 7 bits per byte, little endian. 132// the 0x80 bit means read another byte. 133func (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// Unsigned int is just a varint. 148func (b *buf) uint() uint64 { 149 x, _ := b.varint() 150 return x 151} 152 153// Signed int is a sign-extended varint. 154func (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// Address-sized uint. 164func (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 179func (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 190func (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 197type DecodeError struct { 198 Name string 199 Offset Offset 200 Err string 201} 202 203func (e DecodeError) Error() string { 204 return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err 205} 206