proc/dwarf: Move util functions to dwarf package (#3252)

This commit is contained in:
Oleksandr Redko
2023-01-16 19:20:20 +02:00
committed by GitHub
parent 13143680f7
commit 58fc3931e8
13 changed files with 60 additions and 103 deletions

View File

@ -9,8 +9,8 @@ import (
"fmt"
"io"
"github.com/go-delve/delve/pkg/dwarf"
"github.com/go-delve/delve/pkg/dwarf/leb128"
"github.com/go-delve/delve/pkg/dwarf/util"
)
type parsefunc func(*parseContext) parsefunc
@ -154,7 +154,7 @@ func parseCIE(ctx *parseContext) parsefunc {
ctx.common.Version, _ = buf.ReadByte()
// parse augmentation
ctx.common.Augmentation, _ = util.ParseString(buf)
ctx.common.Augmentation, _ = dwarf.ReadString(buf)
if ctx.parsingEHFrame() {
if ctx.common.Augmentation == "eh" {
@ -241,21 +241,21 @@ func (ctx *parseContext) readEncodedPtr(addr uint64, buf leb128.Reader, ptrEnc p
switch ptrEnc & 0xf {
case ptrEncAbs, ptrEncSigned:
ptr, _ = util.ReadUintRaw(buf, binary.LittleEndian, ctx.ptrSize)
ptr, _ = dwarf.ReadUintRaw(buf, binary.LittleEndian, ctx.ptrSize)
case ptrEncUleb:
ptr, _ = leb128.DecodeUnsigned(buf)
case ptrEncUdata2:
ptr, _ = util.ReadUintRaw(buf, binary.LittleEndian, 2)
ptr, _ = dwarf.ReadUintRaw(buf, binary.LittleEndian, 2)
case ptrEncSdata2:
ptr, _ = util.ReadUintRaw(buf, binary.LittleEndian, 2)
ptr, _ = dwarf.ReadUintRaw(buf, binary.LittleEndian, 2)
ptr = uint64(int16(ptr))
case ptrEncUdata4:
ptr, _ = util.ReadUintRaw(buf, binary.LittleEndian, 4)
ptr, _ = dwarf.ReadUintRaw(buf, binary.LittleEndian, 4)
case ptrEncSdata4:
ptr, _ = util.ReadUintRaw(buf, binary.LittleEndian, 4)
ptr, _ = dwarf.ReadUintRaw(buf, binary.LittleEndian, 4)
ptr = uint64(int32(ptr))
case ptrEncUdata8, ptrEncSdata8:
ptr, _ = util.ReadUintRaw(buf, binary.LittleEndian, 8)
ptr, _ = dwarf.ReadUintRaw(buf, binary.LittleEndian, 8)
case ptrEncSleb:
n, _ := leb128.DecodeSigned(buf)
ptr = uint64(n)

View File

@ -5,7 +5,7 @@ import (
"encoding/binary"
"errors"
"github.com/go-delve/delve/pkg/dwarf/util"
"github.com/go-delve/delve/pkg/dwarf"
)
// DebugAddrSection represents the debug_addr section of DWARFv5.
@ -22,7 +22,7 @@ func ParseAddr(data []byte) *DebugAddrSection {
return nil
}
r := &DebugAddrSection{data: data}
_, dwarf64, _, byteOrder := util.ReadDwarfLengthVersion(data)
_, dwarf64, _, byteOrder := dwarf.ReadDwarfLengthVersion(data)
r.byteOrder = byteOrder
data = data[6:]
if dwarf64 {
@ -56,5 +56,5 @@ func (addr *DebugAddr) Get(idx uint64) (uint64, error) {
return 0, errors.New("debug_addr section not present")
}
off := idx*uint64(addr.ptrSz) + addr.addrBase
return util.ReadUintRaw(bytes.NewReader(addr.data[off:]), addr.byteOrder, addr.ptrSz)
return dwarf.ReadUintRaw(bytes.NewReader(addr.data[off:]), addr.byteOrder, addr.ptrSz)
}

View File

@ -2,18 +2,16 @@
// 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.
//lint:file-ignore ST1021 imported file
package util
package godwarf
import (
"debug/dwarf"
"fmt"
)
// Data buffer being decoded.
// buf is data buffer being decoded.
type buf struct {
dwarf *dwarf.Data
format dataFormat
@ -23,7 +21,7 @@ type buf struct {
Err error
}
// Data format, other than byte order. This affects the handling of
// Data format, other than byte order. This affects the handling of
// certain field formats.
type dataFormat interface {
// DWARF version number. Zero means unknown.
@ -36,25 +34,27 @@ type dataFormat interface {
addrsize() int
}
// UnknownFormat is a struct for some parts of DWARF that have no data format, e.g., abbrevs.
type UnknownFormat struct{}
// 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 {
func (u unknownFormat) version() int {
return 0
}
func (u UnknownFormat) dwarf64() (bool, bool) {
func (u unknownFormat) dwarf64() (bool, bool) {
return false, false
}
func (u UnknownFormat) addrsize() int {
func (u unknownFormat) addrsize() int {
return 0
}
func MakeBuf(d *dwarf.Data, format dataFormat, name string, off dwarf.Offset, data []byte) buf {
// 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")

View File

@ -17,7 +17,6 @@ import (
"strconv"
"github.com/go-delve/delve/pkg/dwarf/op"
"github.com/go-delve/delve/pkg/dwarf/util"
)
const (
@ -827,7 +826,7 @@ func readType(d *dwarf.Data, name string, r *dwarf.Reader, off dwarf.Offset, typ
// Empty exprloc. f.ByteOffset=0.
break
}
b := util.MakeBuf(d, util.UnknownFormat{}, "location", 0, loc)
b := makeBuf(d, unknownFormat{}, "location", 0, loc)
op_ := op.Opcode(b.Uint8())
switch op_ {
case op.DW_OP_plus_uconst:

View File

@ -6,8 +6,8 @@ import (
"path"
"strings"
"github.com/go-delve/delve/pkg/dwarf"
"github.com/go-delve/delve/pkg/dwarf/leb128"
"github.com/go-delve/delve/pkg/dwarf/util"
)
// DebugLinePrologue prologue of .debug_line data.
@ -152,7 +152,7 @@ func parseDebugLinePrologue(dbl *DebugLineInfo, buf *bytes.Buffer) {
// parseIncludeDirs2 parses the directory table for DWARF version 2 through 4.
func parseIncludeDirs2(info *DebugLineInfo, buf *bytes.Buffer) bool {
for {
str, err := util.ParseString(buf)
str, err := dwarf.ReadString(buf)
if err != nil {
if info.Logf != nil {
info.Logf("error reading string: %v", err)
@ -186,7 +186,7 @@ func parseIncludeDirs5(info *DebugLineInfo, buf *bytes.Buffer) bool {
info.IncludeDirs = append(info.IncludeDirs, dirEntryFormReader.str)
case _DW_FORM_line_strp:
buf := bytes.NewBuffer(info.debugLineStr[dirEntryFormReader.u64:])
dir, _ := util.ParseString(buf)
dir, _ := dwarf.ReadString(buf)
info.IncludeDirs = append(info.IncludeDirs, dir)
default:
info.Logf("unsupported string form %#x", dirEntryFormReader.formCode)
@ -228,7 +228,7 @@ func readFileEntry(info *DebugLineInfo, buf *bytes.Buffer, exitOnEmptyPath bool)
entry := new(FileEntry)
var err error
entry.Path, err = util.ParseString(buf)
entry.Path, err = dwarf.ReadString(buf)
if err != nil {
if info.Logf != nil {
info.Logf("error reading file entry: %v", err)
@ -299,7 +299,7 @@ func parseFileEntries5(info *DebugLineInfo, buf *bytes.Buffer) bool {
p = fileEntryFormReader.str
case _DW_FORM_line_strp:
buf := bytes.NewBuffer(info.debugLineStr[fileEntryFormReader.u64:])
p, _ = util.ParseString(buf)
p, _ = dwarf.ReadString(buf)
default:
info.Logf("unsupported string form %#x", fileEntryFormReader.formCode)
}

View File

@ -5,8 +5,8 @@ import (
"encoding/binary"
"errors"
"github.com/go-delve/delve/pkg/dwarf"
"github.com/go-delve/delve/pkg/dwarf/leb128"
"github.com/go-delve/delve/pkg/dwarf/util"
)
const (
@ -157,7 +157,7 @@ func (rdr *formReader) next(buf *bytes.Buffer) bool {
rdr.u64, _ = leb128.DecodeUnsigned(buf)
case _DW_FORM_string:
rdr.str, _ = util.ParseString(buf)
rdr.str, _ = dwarf.ReadString(buf)
case _DW_FORM_strx3:
if buf.Len() < 3 {

View File

@ -7,8 +7,8 @@ import (
"fmt"
"io"
"github.com/go-delve/delve/pkg/dwarf"
"github.com/go-delve/delve/pkg/dwarf/leb128"
"github.com/go-delve/delve/pkg/dwarf/util"
)
type Location struct {
@ -503,7 +503,7 @@ func endsequence(sm *StateMachine, buf *bytes.Buffer) {
}
func setaddress(sm *StateMachine, buf *bytes.Buffer) {
addr, err := util.ReadUintRaw(buf, binary.LittleEndian, sm.ptrSize)
addr, err := dwarf.ReadUintRaw(buf, binary.LittleEndian, sm.ptrSize)
if err != nil {
panic(err)
}

View File

@ -13,8 +13,8 @@ import (
"runtime"
"testing"
pdwarf "github.com/go-delve/delve/pkg/dwarf"
"github.com/go-delve/delve/pkg/dwarf/leb128"
"github.com/go-delve/delve/pkg/dwarf/util"
)
func slurpGzip(path string) ([]byte, error) {
@ -139,7 +139,7 @@ func TestMultipleSequences(t *testing.T) {
instr.WriteByte(0)
leb128.EncodeUnsigned(instr, 9) // 1 + ptr_size
instr.WriteByte(DW_LINE_set_address)
util.WriteUint(instr, binary.LittleEndian, ptrSize, addr)
pdwarf.WriteUint(instr, binary.LittleEndian, ptrSize, addr)
}
write_DW_LNS_copy := func() {

View File

@ -5,9 +5,9 @@ import (
"encoding/binary"
"fmt"
"github.com/go-delve/delve/pkg/dwarf"
"github.com/go-delve/delve/pkg/dwarf/godwarf"
"github.com/go-delve/delve/pkg/dwarf/leb128"
"github.com/go-delve/delve/pkg/dwarf/util"
)
// Dwarf5Reader parses and presents DWARF loclist information for DWARF version 5 and later.
@ -24,7 +24,7 @@ func NewDwarf5Reader(data []byte) *Dwarf5Reader {
}
r := &Dwarf5Reader{data: data}
_, dwarf64, _, byteOrder := util.ReadDwarfLengthVersion(data)
_, dwarf64, _, byteOrder := dwarf.ReadDwarfLengthVersion(data)
r.byteOrder = byteOrder
data = data[6:]
@ -161,18 +161,18 @@ func (it *loclistsIterator) next() bool {
it.onRange = false
case _DW_LLE_base_address:
it.base, it.err = util.ReadUintRaw(it.buf, it.rdr.byteOrder, it.rdr.ptrSz)
it.base, it.err = dwarf.ReadUintRaw(it.buf, it.rdr.byteOrder, it.rdr.ptrSz)
it.base += it.staticBase
it.onRange = false
case _DW_LLE_start_end:
it.start, it.err = util.ReadUintRaw(it.buf, it.rdr.byteOrder, it.rdr.ptrSz)
it.end, it.err = util.ReadUintRaw(it.buf, it.rdr.byteOrder, it.rdr.ptrSz)
it.start, it.err = dwarf.ReadUintRaw(it.buf, it.rdr.byteOrder, it.rdr.ptrSz)
it.end, it.err = dwarf.ReadUintRaw(it.buf, it.rdr.byteOrder, it.rdr.ptrSz)
it.readInstr()
it.onRange = true
case _DW_LLE_start_length:
it.start, it.err = util.ReadUintRaw(it.buf, it.rdr.byteOrder, it.rdr.ptrSz)
it.start, it.err = dwarf.ReadUintRaw(it.buf, it.rdr.byteOrder, it.rdr.ptrSz)
length, _ := leb128.DecodeUnsigned(it.buf)
it.readInstr()
it.end = it.start + length

View File

@ -8,7 +8,7 @@ import (
"io"
"github.com/go-delve/delve/pkg/dwarf/leb128"
"github.com/go-delve/delve/pkg/dwarf/util"
"github.com/go-delve/delve/pkg/dwarf"
)
// Opcode represent a DWARF stack program instruction.
@ -213,7 +213,7 @@ func callframecfa(opcode Opcode, ctxt *context) error {
func addr(opcode Opcode, ctxt *context) error {
buf := ctxt.buf.Next(ctxt.ptrSize)
stack, err := util.ReadUintRaw(bytes.NewReader(buf), binary.LittleEndian, ctxt.ptrSize)
stack, err := dwarf.ReadUintRaw(bytes.NewReader(buf), binary.LittleEndian, ctxt.ptrSize)
if err != nil {
return err
}
@ -297,11 +297,11 @@ func constnu(opcode Opcode, ctxt *context) error {
b, err = ctxt.buf.ReadByte()
n = uint64(b)
case DW_OP_const2u:
n, err = util.ReadUintRaw(ctxt.buf, binary.LittleEndian, 2)
n, err = dwarf.ReadUintRaw(ctxt.buf, binary.LittleEndian, 2)
case DW_OP_const4u:
n, err = util.ReadUintRaw(ctxt.buf, binary.LittleEndian, 4)
n, err = dwarf.ReadUintRaw(ctxt.buf, binary.LittleEndian, 4)
case DW_OP_const8u:
n, err = util.ReadUintRaw(ctxt.buf, binary.LittleEndian, 8)
n, err = dwarf.ReadUintRaw(ctxt.buf, binary.LittleEndian, 8)
default:
panic("internal error")
}
@ -323,13 +323,13 @@ func constns(opcode Opcode, ctxt *context) error {
b, err = ctxt.buf.ReadByte()
n = uint64(int64(int8(b)))
case DW_OP_const2s:
n, err = util.ReadUintRaw(ctxt.buf, binary.LittleEndian, 2)
n, err = dwarf.ReadUintRaw(ctxt.buf, binary.LittleEndian, 2)
n = uint64(int64(int16(n)))
case DW_OP_const4s:
n, err = util.ReadUintRaw(ctxt.buf, binary.LittleEndian, 4)
n, err = dwarf.ReadUintRaw(ctxt.buf, binary.LittleEndian, 4)
n = uint64(int64(int32(n)))
case DW_OP_const8s:
n, err = util.ReadUintRaw(ctxt.buf, binary.LittleEndian, 8)
n, err = dwarf.ReadUintRaw(ctxt.buf, binary.LittleEndian, 8)
default:
panic("internal error")
}
@ -561,7 +561,7 @@ func deref(op Opcode, ctxt *context) error {
return err
}
x, err := util.ReadUintRaw(bytes.NewReader(buf), binary.LittleEndian, sz)
x, err := dwarf.ReadUintRaw(bytes.NewReader(buf), binary.LittleEndian, sz)
if err != nil {
return err
}

View File

@ -1,4 +1,4 @@
package util
package dwarf
import (
"bytes"
@ -6,54 +6,10 @@ import (
"encoding/binary"
"fmt"
"io"
"github.com/go-delve/delve/pkg/dwarf/leb128"
)
// ByteReaderWithLen is a io.ByteReader with a Len method. This interface is
// satisfied by both bytes.Buffer and bytes.Reader.
//
// Deprecated: use leb128.Reader.
type ByteReaderWithLen interface {
io.ByteReader
io.Reader
Len() int
}
// DecodeULEB128 decodes an unsigned Little Endian Base 128
// represented number.
//
// Deprecated: use leb128.DecodeUnsigned.
func DecodeULEB128(buf ByteReaderWithLen) (uint64, uint32) {
return leb128.DecodeUnsigned(buf)
}
// DecodeSLEB128 decodes a signed Little Endian Base 128
// represented number.
//
// Deprecated: use leb128.DecodeUnsigned.
func DecodeSLEB128(buf ByteReaderWithLen) (int64, uint32) {
return leb128.DecodeSigned(buf)
}
// EncodeULEB128 encodes x to the unsigned Little Endian Base 128 format
// into out.
//
// Deprecated: use leb128.EncodeUnsigned.
func EncodeULEB128(out io.ByteWriter, x uint64) {
leb128.EncodeUnsigned(out, x)
}
// EncodeSLEB128 encodes x to the signed Little Endian Base 128 format
// into out.
//
// Deprecated: use leb128.EncodeSigned.
func EncodeSLEB128(out io.ByteWriter, x int64) {
leb128.EncodeSigned(out, x)
}
// ParseString reads a null-terminated string from data.
func ParseString(data *bytes.Buffer) (string, error) {
// ReadString reads a null-terminated string from data.
func ReadString(data *bytes.Buffer) (string, error) {
str, err := data.ReadString(0x0)
if err != nil {
return "", err

View File

@ -1,13 +1,15 @@
package util
package dwarf_test
import (
"bytes"
"testing"
"github.com/go-delve/delve/pkg/dwarf"
)
func TestParseString(t *testing.T) {
func TestReadString(t *testing.T) {
bstr := bytes.NewBuffer([]byte{'h', 'i', 0x0, 0xFF, 0xCC})
str, _ := ParseString(bstr)
str, _ := dwarf.ReadString(bstr)
if str != "hi" {
t.Fatalf("String was not parsed correctly %#v", str)

View File

@ -23,13 +23,13 @@ import (
"sync"
"time"
pdwarf "github.com/go-delve/delve/pkg/dwarf"
"github.com/go-delve/delve/pkg/dwarf/frame"
"github.com/go-delve/delve/pkg/dwarf/godwarf"
"github.com/go-delve/delve/pkg/dwarf/line"
"github.com/go-delve/delve/pkg/dwarf/loclist"
"github.com/go-delve/delve/pkg/dwarf/op"
"github.com/go-delve/delve/pkg/dwarf/reader"
"github.com/go-delve/delve/pkg/dwarf/util"
"github.com/go-delve/delve/pkg/goversion"
"github.com/go-delve/delve/pkg/logflags"
"github.com/go-delve/delve/pkg/proc/debuginfod"
@ -2029,7 +2029,7 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB
image.runtimeTypeToDIE = make(map[uint64]runtimeTypeDIE)
ctxt := newLoadDebugInfoMapsContext(bi, image, util.ReadUnitVersions(debugInfoBytes))
ctxt := newLoadDebugInfoMapsContext(bi, image, pdwarf.ReadUnitVersions(debugInfoBytes))
reader := image.DwarfReader()
@ -2217,7 +2217,7 @@ func (bi *BinaryInfo) loadDebugInfoMapsCompileUnit(ctxt *loadDebugInfoMapsContex
var addr uint64
if loc, ok := entry.Val(dwarf.AttrLocation).([]byte); ok {
if len(loc) == bi.Arch.PtrSize()+1 && op.Opcode(loc[0]) == op.DW_OP_addr {
addr, _ = util.ReadUintRaw(bytes.NewReader(loc[1:]), binary.LittleEndian, bi.Arch.PtrSize())
addr, _ = pdwarf.ReadUintRaw(bytes.NewReader(loc[1:]), binary.LittleEndian, bi.Arch.PtrSize())
}
}
if !cu.isgo {