github.com/undoio/delve@v1.9.0/pkg/dwarf/util/buf.go (about) 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 //lint:file-ignore ST1021 imported file 8 9 package util 10 11 import ( 12 "debug/dwarf" 13 "fmt" 14 ) 15 16 // Data buffer being decoded. 17 type buf struct { 18 dwarf *dwarf.Data 19 format dataFormat 20 name string 21 off dwarf.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. 28 type 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. 40 type UnknownFormat struct{} 41 42 func (u UnknownFormat) version() int { 43 return 0 44 } 45 46 func (u UnknownFormat) dwarf64() (bool, bool) { 47 return false, false 48 } 49 50 func (u UnknownFormat) addrsize() int { 51 return 0 52 } 53 54 func MakeBuf(d *dwarf.Data, format dataFormat, name string, off dwarf.Offset, data []byte) buf { 55 return buf{d, format, name, off, data, nil} 56 } 57 58 func (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 69 // Read a varint, which is 7 bits per byte, little endian. 70 // the 0x80 bit means read another byte. 71 func (b *buf) Varint() (c uint64, bits uint) { 72 for i := 0; i < len(b.data); i++ { 73 byte := b.data[i] 74 c |= uint64(byte&0x7F) << bits 75 bits += 7 76 if byte&0x80 == 0 { 77 b.off += dwarf.Offset(i + 1) 78 b.data = b.data[i+1:] 79 return c, bits 80 } 81 } 82 return 0, 0 83 } 84 85 // Unsigned int is just a varint. 86 func (b *buf) Uint() uint64 { 87 x, _ := b.Varint() 88 return x 89 } 90 91 // Signed int is a sign-extended varint. 92 func (b *buf) Int() int64 { 93 ux, bits := b.Varint() 94 x := int64(ux) 95 if x&(1<<(bits-1)) != 0 { 96 x |= -1 << bits 97 } 98 return x 99 } 100 101 // AssertEmpty checks that everything has been read from b. 102 func (b *buf) AssertEmpty() { 103 if len(b.data) == 0 { 104 return 105 } 106 if len(b.data) > 5 { 107 b.error(fmt.Sprintf("unexpected extra data: %x...", b.data[0:5])) 108 } 109 b.error(fmt.Sprintf("unexpected extra data: %x", b.data)) 110 } 111 112 func (b *buf) error(s string) { 113 if b.Err == nil { 114 b.data = nil 115 b.Err = dwarf.DecodeError{Name: b.name, Offset: b.off, Err: s} 116 } 117 }