github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/debug/dwarf/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 package dwarf 8 9 import ( 10 "bytes" 11 "encoding/binary" 12 "strconv" 13 ) 14 15 // Data buffer being decoded. 16 type 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. 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 *Data, format dataFormat, name string, off Offset, data []byte) buf { 55 return buf{d, d.order, 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 func (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 80 func (b *buf) skip(n int) { b.bytes(n) } 81 82 func (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 95 func (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 103 func (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 115 func (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 123 func (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. 133 func (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. 148 func (b *buf) uint() uint64 { 149 x, _ := b.varint() 150 return x 151 } 152 153 // Signed int is a sign-extended varint. 154 func (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. 164 func (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 179 func (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 190 func (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 197 type DecodeError struct { 198 Name string 199 Offset Offset 200 Err string 201 } 202 203 func (e DecodeError) Error() string { 204 return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err 205 }