mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 02:36:18 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			118 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2009 The Go Authors.  All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| //lint:file-ignore ST1021 imported file
 | |
| 
 | |
| package godwarf
 | |
| 
 | |
| import (
 | |
| 	"debug/dwarf"
 | |
| 	"fmt"
 | |
| )
 | |
| 
 | |
| // buf is data buffer being decoded.
 | |
| type buf struct {
 | |
| 	dwarf  *dwarf.Data
 | |
| 	format dataFormat
 | |
| 	name   string
 | |
| 	off    dwarf.Offset
 | |
| 	data   []byte
 | |
| 	Err    error
 | |
| }
 | |
| 
 | |
| // Data format, other than byte order. This affects the handling of
 | |
| // certain field formats.
 | |
| type dataFormat interface {
 | |
| 	// DWARF version number.  Zero means unknown.
 | |
| 	version() int
 | |
| 
 | |
| 	// 64-bit DWARF format?
 | |
| 	dwarf64() (dwarf64 bool, isKnown bool)
 | |
| 
 | |
| 	// Size of an address, in bytes.  Zero means unknown.
 | |
| 	addrsize() int
 | |
| }
 | |
| 
 | |
| // unknownFormat is a struct for some parts of DWARF that have no data format, e.g., abbrevs.
 | |
| type unknownFormat struct{}
 | |
| 
 | |
| func (u unknownFormat) version() int {
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| func (u unknownFormat) dwarf64() (bool, bool) {
 | |
| 	return false, false
 | |
| }
 | |
| 
 | |
| func (u unknownFormat) addrsize() int {
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| // makeBuf creates buf for reading and decoding of DWARF data streams.
 | |
| func makeBuf(d *dwarf.Data, format dataFormat, name string, off dwarf.Offset, data []byte) buf {
 | |
| 	return buf{d, format, name, off, data, nil}
 | |
| }
 | |
| 
 | |
| // Uint8 reads an uint8.
 | |
| func (b *buf) Uint8() uint8 {
 | |
| 	if len(b.data) < 1 {
 | |
| 		b.error("underflow")
 | |
| 		return 0
 | |
| 	}
 | |
| 	val := b.data[0]
 | |
| 	b.data = b.data[1:]
 | |
| 	b.off++
 | |
| 	return val
 | |
| }
 | |
| 
 | |
| // Varint reads a varint, which is 7 bits per byte, little endian.
 | |
| // the 0x80 bit means read another byte.
 | |
| func (b *buf) Varint() (c uint64, bits uint) {
 | |
| 	for i := 0; i < len(b.data); i++ {
 | |
| 		byte := b.data[i]
 | |
| 		c |= uint64(byte&0x7F) << bits
 | |
| 		bits += 7
 | |
| 		if byte&0x80 == 0 {
 | |
| 			b.off += dwarf.Offset(i + 1)
 | |
| 			b.data = b.data[i+1:]
 | |
| 			return c, bits
 | |
| 		}
 | |
| 	}
 | |
| 	return 0, 0
 | |
| }
 | |
| 
 | |
| // Uint is just a varint.
 | |
| func (b *buf) Uint() uint64 {
 | |
| 	x, _ := b.Varint()
 | |
| 	return x
 | |
| }
 | |
| 
 | |
| // Int is a sign-extended varint.
 | |
| func (b *buf) Int() int64 {
 | |
| 	ux, bits := b.Varint()
 | |
| 	x := int64(ux)
 | |
| 	if x&(1<<(bits-1)) != 0 {
 | |
| 		x |= -1 << bits
 | |
| 	}
 | |
| 	return x
 | |
| }
 | |
| 
 | |
| // AssertEmpty checks that everything has been read from b.
 | |
| func (b *buf) AssertEmpty() {
 | |
| 	if len(b.data) == 0 {
 | |
| 		return
 | |
| 	}
 | |
| 	if len(b.data) > 5 {
 | |
| 		b.error(fmt.Sprintf("unexpected extra data: %x...", b.data[0:5]))
 | |
| 	}
 | |
| 	b.error(fmt.Sprintf("unexpected extra data: %x", b.data))
 | |
| }
 | |
| 
 | |
| func (b *buf) error(s string) {
 | |
| 	if b.Err == nil {
 | |
| 		b.data = nil
 | |
| 		b.Err = dwarf.DecodeError{Name: b.name, Offset: b.off, Err: s}
 | |
| 	}
 | |
| }
 | 
