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  }