Skip to content

Commit

Permalink
proc: remove old method to resolve the type of an interface to a DIE (g…
Browse files Browse the repository at this point in the history
…o-delve#3150)

Before 1.11 we used to read a bunch of runtime structures to determine
the runtime type of an interface variable. This had significant
dependencies on private structs of the Go runtime and the code is
broken for versions of Go after 1.17.
Remove all this code, since it is no longer used and doesn't work with
newer versions of Go anyway.
  • Loading branch information
aarzilli authored Sep 29, 2022
1 parent ec5fcc0 commit 02d46b0
Show file tree
Hide file tree
Showing 3 changed files with 2 additions and 621 deletions.
7 changes: 1 addition & 6 deletions pkg/proc/bininfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@ type BinaryInfo struct {

gStructOffset uint64

// nameOfRuntimeType maps an address of a runtime._type struct to its
// decoded name. Used with versions of Go <= 1.10 to figure out the DIE of
// the concrete type of interfaces.
nameOfRuntimeType map[uint64]nameOfRuntimeTypeEntry

// consts[off] lists all the constants with the type defined at offset off.
consts constantsMap

Expand Down Expand Up @@ -639,7 +634,7 @@ type ElfDynamicSection struct {

// NewBinaryInfo returns an initialized but unloaded BinaryInfo struct.
func NewBinaryInfo(goos, goarch string) *BinaryInfo {
r := &BinaryInfo{GOOS: goos, nameOfRuntimeType: make(map[uint64]nameOfRuntimeTypeEntry), logger: logflags.DebuggerLogger()}
r := &BinaryInfo{GOOS: goos, logger: logflags.DebuggerLogger()}

// TODO: find better way to determine proc arch (perhaps use executable file info).
switch goarch {
Expand Down
129 changes: 0 additions & 129 deletions pkg/proc/moduledata.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package proc

import (
"go/constant"
"unsafe"
)

// delve counterpart to runtime.moduledata
type moduleData struct {
text, etext uint64
Expand Down Expand Up @@ -83,127 +78,3 @@ func findModuleDataForType(bi *BinaryInfo, mds []moduleData, typeAddr uint64, me
}
return nil
}

func resolveTypeOff(bi *BinaryInfo, mds []moduleData, typeAddr, off uint64, mem MemoryReadWriter) (*Variable, error) {
// See runtime.(*_type).typeOff in $GOROOT/src/runtime/type.go
md := findModuleDataForType(bi, mds, typeAddr, mem)

rtyp, err := bi.findType("runtime._type")
if err != nil {
return nil, err
}

if md == nil {
v, err := reflectOffsMapAccess(bi, off, mem)
if err != nil {
return nil, err
}
v.loadValue(LoadConfig{false, 1, 0, 0, -1, 0})
addr, _ := constant.Int64Val(v.Value)
return v.newVariable(v.Name, uint64(addr), rtyp, mem), nil
}

if t, _ := md.typemapVar.mapAccess(newConstant(constant.MakeUint64(uint64(off)), mem)); t != nil {
return t, nil
}

res := md.types + off

return newVariable("", uint64(res), rtyp, bi, mem), nil
}

func resolveNameOff(bi *BinaryInfo, mds []moduleData, typeAddr, off uint64, mem MemoryReadWriter) (name, tag string, pkgpathoff int32, err error) {
// See runtime.resolveNameOff in $GOROOT/src/runtime/type.go
for _, md := range mds {
if typeAddr >= md.types && typeAddr < md.etypes {
return loadName(bi, md.types+off, mem)
}
}

v, err := reflectOffsMapAccess(bi, off, mem)
if err != nil {
return "", "", 0, err
}

resv := v.maybeDereference()
if resv.Unreadable != nil {
return "", "", 0, resv.Unreadable
}

return loadName(bi, resv.Addr, mem)
}

func reflectOffsMapAccess(bi *BinaryInfo, off uint64, mem MemoryReadWriter) (*Variable, error) {
scope := globalScope(nil, bi, bi.Images[0], mem)
reflectOffs, err := scope.findGlobal("runtime", "reflectOffs")
if err != nil {
return nil, err
}

reflectOffsm, err := reflectOffs.structMember("m")
if err != nil {
return nil, err
}

return reflectOffsm.mapAccess(newConstant(constant.MakeUint64(uint64(off)), mem))
}

const (
// flags for the name struct (see 'type name struct' in $GOROOT/src/reflect/type.go)
nameflagExported = 1 << 0
nameflagHasTag = 1 << 1
nameflagHasPkg = 1 << 2
)

func loadName(bi *BinaryInfo, addr uint64, mem MemoryReadWriter) (name, tag string, pkgpathoff int32, err error) {
off := addr
namedata := make([]byte, 3)
_, err = mem.ReadMemory(namedata, off)
off += 3
if err != nil {
return "", "", 0, err
}

namelen := uint16(namedata[1])<<8 | uint16(namedata[2])

rawstr := make([]byte, int(namelen))
_, err = mem.ReadMemory(rawstr, off)
off += uint64(namelen)
if err != nil {
return "", "", 0, err
}

name = string(rawstr)

if namedata[0]&nameflagHasTag != 0 {
taglendata := make([]byte, 2)
_, err = mem.ReadMemory(taglendata, off)
off += 2
if err != nil {
return "", "", 0, err
}
taglen := uint16(taglendata[0])<<8 | uint16(taglendata[1])

rawstr := make([]byte, int(taglen))
_, err = mem.ReadMemory(rawstr, off)
off += uint64(taglen)
if err != nil {
return "", "", 0, err
}

tag = string(rawstr)
}

if namedata[0]&nameflagHasPkg != 0 {
pkgdata := make([]byte, 4)
_, err = mem.ReadMemory(pkgdata, off)
if err != nil {
return "", "", 0, err
}

// see func pkgPath in $GOROOT/src/reflect/type.go
copy((*[4]byte)(unsafe.Pointer(&pkgpathoff))[:], pkgdata)
}

return name, tag, pkgpathoff, nil
}
Loading

0 comments on commit 02d46b0

Please sign in to comment.