File: buf.go

package info (click to toggle)
delve 1.6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 9,892 kB
  • sloc: ansic: 2,289; sh: 111; asm: 92; makefile: 27; python: 9
file content (115 lines) | stat: -rw-r--r-- 2,360 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// 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) 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
}

// 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{Name: b.name, Offset: b.off, Err: s}
	}
}