github.com/cnboonhan/delve@v0.0.0-20230908061759-363f2388c2fb/pkg/dwarf/godwarf/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  //lint:file-ignore ST1021 imported file
     6  
     7  package godwarf
     8  
     9  import (
    10  	"debug/dwarf"
    11  	"fmt"
    12  )
    13  
    14  // buf is data buffer being decoded.
    15  type buf struct {
    16  	dwarf  *dwarf.Data
    17  	format dataFormat
    18  	name   string
    19  	off    dwarf.Offset
    20  	data   []byte
    21  	Err    error
    22  }
    23  
    24  // Data format, other than byte order. This affects the handling of
    25  // certain field formats.
    26  type dataFormat interface {
    27  	// DWARF version number.  Zero means unknown.
    28  	version() int
    29  
    30  	// 64-bit DWARF format?
    31  	dwarf64() (dwarf64 bool, isKnown bool)
    32  
    33  	// Size of an address, in bytes.  Zero means unknown.
    34  	addrsize() int
    35  }
    36  
    37  // unknownFormat is a struct for some parts of DWARF that have no data format, e.g., abbrevs.
    38  type unknownFormat struct{}
    39  
    40  func (u unknownFormat) version() int {
    41  	return 0
    42  }
    43  
    44  func (u unknownFormat) dwarf64() (bool, bool) {
    45  	return false, false
    46  }
    47  
    48  func (u unknownFormat) addrsize() int {
    49  	return 0
    50  }
    51  
    52  // makeBuf creates buf for reading and decoding of DWARF data streams.
    53  func makeBuf(d *dwarf.Data, format dataFormat, name string, off dwarf.Offset, data []byte) buf {
    54  	return buf{d, format, name, off, data, nil}
    55  }
    56  
    57  // Uint8 reads an uint8.
    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  // Varint reads 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  // Uint is just a varint.
    86  func (b *buf) Uint() uint64 {
    87  	x, _ := b.Varint()
    88  	return x
    89  }
    90  
    91  // 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  }