
* tests: update to cope with go1.7 SSA compiler * de-vendored golang.org/x/debug/dwarf We need our own tweaked version * dwarf/debug/dwarf: always use the entry's name attribute Using the name attribute leads to better type names as well as fixes inconsistencies between 1.5, 1.6 and 1.7. * proc: Updated loadInterface to work with go1.7 go1.7 changed the internal representation of types, removing the string field from runtime._type. Updated loadInterface to use the new str field.
88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package proc
|
|
|
|
import (
|
|
"go/constant"
|
|
)
|
|
|
|
// delve counterpart to runtime.moduledata
|
|
type moduleData struct {
|
|
types, etypes uintptr
|
|
}
|
|
|
|
func (dbp *Process) loadModuleData() (err error) {
|
|
dbp.loadModuleDataOnce.Do(func() {
|
|
scope := &EvalScope{Thread: dbp.CurrentThread, PC: 0, CFA: 0}
|
|
var md *Variable
|
|
md, err = scope.packageVarAddr("runtime.firstmoduledata")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for md.Addr != 0 {
|
|
var typesVar, etypesVar, nextVar *Variable
|
|
var types, etypes uint64
|
|
|
|
if typesVar, err = md.structMember("types"); err != nil {
|
|
return
|
|
}
|
|
if etypesVar, err = md.structMember("etypes"); err != nil {
|
|
return
|
|
}
|
|
if nextVar, err = md.structMember("next"); err != nil {
|
|
return
|
|
}
|
|
if types, err = typesVar.asUint(); err != nil {
|
|
return
|
|
}
|
|
if etypes, err = etypesVar.asUint(); err != nil {
|
|
return
|
|
}
|
|
|
|
dbp.moduleData = append(dbp.moduleData, moduleData{uintptr(types), uintptr(etypes)})
|
|
|
|
md = nextVar.maybeDereference()
|
|
if md.Unreadable != nil {
|
|
err = md.Unreadable
|
|
return
|
|
}
|
|
}
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
func (dbp *Process) resolveNameOff(typeAddr uintptr, off uintptr) (uintptr, error) {
|
|
// See runtime.resolveNameOff in $GOROOT/src/runtime/type.go
|
|
if err := dbp.loadModuleData(); err != nil {
|
|
return 0, err
|
|
}
|
|
for _, md := range dbp.moduleData {
|
|
if typeAddr >= md.types && typeAddr < md.etypes {
|
|
return md.types + off, nil
|
|
}
|
|
}
|
|
|
|
scope := &EvalScope{Thread: dbp.CurrentThread, PC: 0, CFA: 0}
|
|
reflectOffs, err := scope.packageVarAddr("runtime.reflectOffs")
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
reflectOffsm, err := reflectOffs.structMember("m")
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
v, err := reflectOffsm.mapAccess(newConstant(constant.MakeUint64(uint64(off)), dbp.CurrentThread))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
resv := v.maybeDereference()
|
|
if resv.Unreadable != nil {
|
|
return 0, resv.Unreadable
|
|
}
|
|
|
|
return resv.Addr, nil
|
|
}
|