mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 10:47:27 +08:00 
			
		
		
		
	 1e3ff49610
			
		
	
	1e3ff49610
	
	
	
		
			
			Splits out type parsing and go-specific Type hierarchy from x/debug/dwarf, replace x/debug/dwarf with debug/dwarf everywhere, remove x/debug/dwarf from vendoring.
		
			
				
	
	
		
			152 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			3.0 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.
 | |
| 
 | |
| // Buffered reading and decoding of DWARF data streams.
 | |
| 
 | |
| package util
 | |
| 
 | |
| import (
 | |
| 	"debug/dwarf"
 | |
| 	"fmt"
 | |
| )
 | |
| 
 | |
| // 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
 | |
| }
 | |
| 
 | |
| // Some parts of DWARF 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
 | |
| }
 | |
| 
 | |
| func MakeBuf(d *dwarf.Data, format dataFormat, name string, off dwarf.Offset, data []byte) buf {
 | |
| 	return buf{d, format, name, off, data, nil}
 | |
| }
 | |
| 
 | |
| func (b *buf) slice(length int) buf {
 | |
| 	n := *b
 | |
| 	data := b.data
 | |
| 	b.skip(length) // Will validate length.
 | |
| 	n.data = data[:length]
 | |
| 	return n
 | |
| }
 | |
| 
 | |
| 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
 | |
| }
 | |
| 
 | |
| func (b *buf) bytes(n int) []byte {
 | |
| 	if len(b.data) < n {
 | |
| 		b.error("underflow")
 | |
| 		return nil
 | |
| 	}
 | |
| 	data := b.data[0:n]
 | |
| 	b.data = b.data[n:]
 | |
| 	b.off += dwarf.Offset(n)
 | |
| 	return data
 | |
| }
 | |
| 
 | |
| func (b *buf) skip(n int) { b.bytes(n) }
 | |
| 
 | |
| // string returns the NUL-terminated (C-like) string at the start of the buffer.
 | |
| // The terminal NUL is discarded.
 | |
| func (b *buf) string() string {
 | |
| 	for i := 0; i < len(b.data); i++ {
 | |
| 		if b.data[i] == 0 {
 | |
| 			s := string(b.data[0:i])
 | |
| 			b.data = b.data[i+1:]
 | |
| 			b.off += dwarf.Offset(i + 1)
 | |
| 			return s
 | |
| 		}
 | |
| 	}
 | |
| 	b.error("underflow")
 | |
| 	return ""
 | |
| }
 | |
| 
 | |
| // Read 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
 | |
| }
 | |
| 
 | |
| // Unsigned int is just a varint.
 | |
| func (b *buf) Uint() uint64 {
 | |
| 	x, _ := b.Varint()
 | |
| 	return x
 | |
| }
 | |
| 
 | |
| // Signed 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{b.name, b.off, s}
 | |
| 	}
 | |
| }
 |