mirror of
https://github.com/go-delve/delve.git
synced 2025-08-06 05:26:59 +02:00
proc: handle moving of direct interface flag in Go 1.26 (#4032)
This flag in internal/abi.Type is moving from the Kind_ field to the TFlag field. See https://go-review.googlesource.com/c/go/+/681936 A few of the other Kind fields dlv doesn't use (and don't exist in Go anymore), so this code can be simplified somewhat.
This commit is contained in:
parent
a40a5e057b
commit
091ff50645
@ -67,10 +67,8 @@ const internal/runtime/maps.ctrlEmpty = 128
|
|||||||
|
|
||||||
const kindDirectIface|internal/abi.KindDirectIface = 32
|
const kindDirectIface|internal/abi.KindDirectIface = 32
|
||||||
|
|
||||||
const kindGCProg|internal/abi.KindGCProg = 64
|
|
||||||
|
|
||||||
const kindMask|internal/abi.KindMask = 31
|
|
||||||
|
|
||||||
const minTopHash = 4
|
const minTopHash = 4
|
||||||
or const minTopHash = 5
|
or const minTopHash = 5
|
||||||
|
|
||||||
|
const tflagDirectIface|internal/abi.TFlagDirectIface = 32
|
||||||
|
|
||||||
|
@ -1026,7 +1026,7 @@ type Image struct {
|
|||||||
func (image *Image) registerRuntimeTypeToDIE(entry *dwarf.Entry, ardr *reader.Reader) {
|
func (image *Image) registerRuntimeTypeToDIE(entry *dwarf.Entry, ardr *reader.Reader) {
|
||||||
if off, ok := entry.Val(godwarf.AttrGoRuntimeType).(uint64); ok {
|
if off, ok := entry.Val(godwarf.AttrGoRuntimeType).(uint64); ok {
|
||||||
if _, ok := image.runtimeTypeToDIE[off]; !ok {
|
if _, ok := image.runtimeTypeToDIE[off]; !ok {
|
||||||
image.runtimeTypeToDIE[off] = runtimeTypeDIE{entry.Offset, -1}
|
image.runtimeTypeToDIE[off] = runtimeTypeDIE{entry.Offset}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,16 @@ import (
|
|||||||
|
|
||||||
// The kind field in runtime._type is a reflect.Kind value plus
|
// The kind field in runtime._type is a reflect.Kind value plus
|
||||||
// some extra flags defined here.
|
// some extra flags defined here.
|
||||||
// See equivalent declaration in $GOROOT/src/reflect/type.go
|
// See equivalent declaration in $GOROOT/src/internal/abi/type.go
|
||||||
const (
|
const (
|
||||||
|
// Go 1.25 and earlier
|
||||||
kindDirectIface = 1 << 5 // +rtype kindDirectIface|internal/abi.KindDirectIface
|
kindDirectIface = 1 << 5 // +rtype kindDirectIface|internal/abi.KindDirectIface
|
||||||
kindGCProg = 1 << 6 // +rtype kindGCProg|internal/abi.KindGCProg
|
// Go 1.26 and later
|
||||||
kindNoPointers = 1 << 7
|
tflagDirectIface = 1 << 5 // +rtype go1.26 tflagDirectIface|internal/abi.TFlagDirectIface
|
||||||
kindMask = (1 << 5) - 1 // +rtype kindMask|internal/abi.KindMask
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type runtimeTypeDIE struct {
|
type runtimeTypeDIE struct {
|
||||||
offset dwarf.Offset
|
offset dwarf.Offset
|
||||||
kind int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func pointerTo(typ godwarf.Type, arch *Arch) godwarf.Type {
|
func pointerTo(typ godwarf.Type, arch *Arch) godwarf.Type {
|
||||||
@ -80,7 +79,7 @@ func (ctxt *loadDebugInfoMapsContext) lookupAbstractOrigin(bi *BinaryInfo, off d
|
|||||||
// debug_info
|
// debug_info
|
||||||
// - After go1.11 the runtimeTypeToDIE map is used to look up the address of
|
// - After go1.11 the runtimeTypeToDIE map is used to look up the address of
|
||||||
// the type and map it directly to a DIE.
|
// the type and map it directly to a DIE.
|
||||||
func RuntimeTypeToDIE(_type *Variable, dataAddr uint64, mds []ModuleData) (typ godwarf.Type, kind int64, err error) {
|
func RuntimeTypeToDIE(_type *Variable, dataAddr uint64, mds []ModuleData) (typ godwarf.Type, directIface bool, err error) {
|
||||||
bi := _type.bi
|
bi := _type.bi
|
||||||
|
|
||||||
_type = _type.maybeDereference()
|
_type = _type.maybeDereference()
|
||||||
@ -94,21 +93,37 @@ func RuntimeTypeToDIE(_type *Variable, dataAddr uint64, mds []ModuleData) (typ g
|
|||||||
if rtdie, ok := so.runtimeTypeToDIE[_type.Addr-md.types]; ok {
|
if rtdie, ok := so.runtimeTypeToDIE[_type.Addr-md.types]; ok {
|
||||||
typ, err := godwarf.ReadType(so.dwarf, so.index, rtdie.offset, so.typeCache)
|
typ, err := godwarf.ReadType(so.dwarf, so.index, rtdie.offset, so.typeCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, fmt.Errorf("invalid interface type: %v", err)
|
return nil, false, fmt.Errorf("invalid interface type: %v", err)
|
||||||
|
}
|
||||||
|
// Figure out whether interfaces with this concrete type are direct or not.
|
||||||
|
// Go 1.26 and beyond have this flag in the TFlag field.
|
||||||
|
// Go 1.25 and earlier have this flag in the Kind field.
|
||||||
|
// If either flag is set, consider it direct.
|
||||||
|
var direct bool
|
||||||
|
if tflagField := _type.loadFieldNamed("TFlag"); tflagField != nil && tflagField.Value != nil {
|
||||||
|
tflag, _ := constant.Int64Val(tflagField.Value)
|
||||||
|
if tflag&tflagDirectIface != 0 {
|
||||||
|
direct = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if rtdie.kind == -1 {
|
|
||||||
if kindField := _type.loadFieldNamed("kind"); kindField != nil && kindField.Value != nil {
|
if kindField := _type.loadFieldNamed("kind"); kindField != nil && kindField.Value != nil {
|
||||||
rtdie.kind, _ = constant.Int64Val(kindField.Value)
|
kind, _ := constant.Int64Val(kindField.Value)
|
||||||
|
if kind&kindDirectIface != 0 {
|
||||||
|
direct = true
|
||||||
|
}
|
||||||
} else if kindField := _type.loadFieldNamed("Kind_"); kindField != nil && kindField.Value != nil {
|
} else if kindField := _type.loadFieldNamed("Kind_"); kindField != nil && kindField.Value != nil {
|
||||||
rtdie.kind, _ = constant.Int64Val(kindField.Value)
|
kind, _ := constant.Int64Val(kindField.Value)
|
||||||
|
if kind&kindDirectIface != 0 {
|
||||||
|
direct = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return typ, rtdie.kind, nil
|
|
||||||
|
return typ, direct, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, 0, errors.New("could not resolve interface type")
|
return nil, false, errors.New("could not resolve interface type")
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolveParametricType returns the real type of t if t is a parametric
|
// resolveParametricType returns the real type of t if t is a parametric
|
||||||
|
@ -2135,14 +2135,14 @@ func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
typ, kind, err := RuntimeTypeToDIE(_type, data.Addr, mds)
|
typ, directIface, err := RuntimeTypeToDIE(_type, data.Addr, mds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.Unreadable = err
|
v.Unreadable = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
deref := false
|
deref := false
|
||||||
if kind&kindDirectIface == 0 {
|
if !directIface {
|
||||||
realtyp := godwarf.ResolveTypedef(typ)
|
realtyp := godwarf.ResolveTypedef(typ)
|
||||||
if _, isptr := realtyp.(*godwarf.PtrType); !isptr {
|
if _, isptr := realtyp.(*godwarf.PtrType); !isptr {
|
||||||
typ = pointerTo(typ, v.bi.Arch)
|
typ = pointerTo(typ, v.bi.Arch)
|
||||||
|
Loading…
Reference in New Issue
Block a user