mirror of
https://github.com/go-delve/delve.git
synced 2025-10-27 12:05:21 +08:00
proc: remove (*EvalScope).globalFor (#1658)
This commit is contained in:
committed by
Derek Parker
parent
f0a9031969
commit
c441330822
@ -212,12 +212,14 @@ func TestDwarfExprLoclist(t *testing.T) {
|
||||
mainfn := bi.LookupFunc["main.main"]
|
||||
|
||||
mem := newFakeMemory(defaultCFA, uint16(before), uint16(after))
|
||||
regs := linutil.AMD64Registers{Regs: &linutil.AMD64PtraceRegs{}}
|
||||
const PC = 0x40100
|
||||
regs := linutil.AMD64Registers{Regs: &linutil.AMD64PtraceRegs{Rip: PC}}
|
||||
|
||||
scope := &proc.EvalScope{Location: proc.Location{PC: 0x40100, Fn: mainfn}, Regs: dwarfRegisters(bi, ®s), Mem: mem, BinInfo: bi}
|
||||
scope := &proc.EvalScope{Location: proc.Location{PC: PC, Fn: mainfn}, Regs: dwarfRegisters(bi, ®s), Mem: mem, BinInfo: bi}
|
||||
|
||||
uintExprCheck(t, scope, "a", before)
|
||||
scope.PC = 0x40800
|
||||
scope.Regs.Regs[scope.Regs.PCRegNum].Uint64Val = scope.PC
|
||||
uintExprCheck(t, scope, "a", after)
|
||||
}
|
||||
|
||||
|
||||
@ -108,7 +108,7 @@ func (scope *EvalScope) Locals() ([]*Variable, error) {
|
||||
hasScopes := false
|
||||
for varReader.Next() {
|
||||
entry := varReader.Entry()
|
||||
val, err := scope.extractVarInfoFromEntry(entry)
|
||||
val, err := extractVarInfoFromEntry(scope.BinInfo, scope.image(), scope.Regs, scope.Mem, entry)
|
||||
if err != nil {
|
||||
// skip variables that we can't parse yet
|
||||
continue
|
||||
@ -249,45 +249,6 @@ func (scope *EvalScope) setValue(dstv, srcv *Variable, srcExpr string) error {
|
||||
return fmt.Errorf("can not set variables of type %s (not implemented)", dstv.Kind.String())
|
||||
}
|
||||
|
||||
// Extracts the name and type of a variable from a dwarf entry
|
||||
// then executes the instructions given in the DW_AT_location attribute to grab the variable's address
|
||||
func (scope *EvalScope) extractVarInfoFromEntry(varEntry *dwarf.Entry) (*Variable, error) {
|
||||
if varEntry == nil {
|
||||
return nil, fmt.Errorf("invalid entry")
|
||||
}
|
||||
|
||||
if varEntry.Tag != dwarf.TagFormalParameter && varEntry.Tag != dwarf.TagVariable {
|
||||
return nil, fmt.Errorf("invalid entry tag, only supports FormalParameter and Variable, got %s", varEntry.Tag.String())
|
||||
}
|
||||
|
||||
entry, n, t, err := readVarEntry(varEntry, scope.image())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, pieces, descr, err := scope.BinInfo.Location(entry, dwarf.AttrLocation, scope.PC, scope.Regs)
|
||||
mem := scope.Mem
|
||||
if pieces != nil {
|
||||
addr = fakeAddress
|
||||
var cmem *compositeMemory
|
||||
cmem, err = newCompositeMemory(scope.Mem, scope.Regs, pieces)
|
||||
if cmem != nil {
|
||||
mem = cmem
|
||||
}
|
||||
}
|
||||
|
||||
v := scope.newVariable(n, uintptr(addr), t, mem)
|
||||
if pieces != nil {
|
||||
v.Flags |= VariableFakeAddress
|
||||
}
|
||||
v.LocationExpr = descr
|
||||
v.DeclLine, _ = entry.Val(dwarf.AttrDeclLine).(int64)
|
||||
if err != nil {
|
||||
v.Unreadable = err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// EvalVariable returns the value of the given expression (backwards compatibility).
|
||||
func (scope *EvalScope) EvalVariable(name string, cfg LoadConfig) (*Variable, error) {
|
||||
return scope.EvalExpression(name, cfg)
|
||||
@ -364,6 +325,11 @@ func filterVariables(vars []*Variable, pred func(v *Variable) bool) []*Variable
|
||||
return r
|
||||
}
|
||||
|
||||
func regsReplaceStaticBase(regs op.DwarfRegisters, image *Image) op.DwarfRegisters {
|
||||
regs.StaticBase = image.StaticBase
|
||||
return regs
|
||||
}
|
||||
|
||||
// PackageVariables returns the name, value, and type of all package variables in the application.
|
||||
func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) {
|
||||
var vars []*Variable
|
||||
@ -389,7 +355,7 @@ func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) {
|
||||
}
|
||||
|
||||
// Ignore errors trying to extract values
|
||||
val, err := scope.globalFor(image).extractVarInfoFromEntry(entry)
|
||||
val, err := extractVarInfoFromEntry(scope.BinInfo, image, regsReplaceStaticBase(scope.Regs, image), scope.Mem, entry)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@ -410,13 +376,13 @@ func (scope *EvalScope) findGlobal(name string) (*Variable, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return scope.globalFor(pkgvar.cu.image).extractVarInfoFromEntry(entry)
|
||||
return extractVarInfoFromEntry(scope.BinInfo, pkgvar.cu.image, regsReplaceStaticBase(scope.Regs, pkgvar.cu.image), scope.Mem, entry)
|
||||
}
|
||||
}
|
||||
for _, fn := range scope.BinInfo.Functions {
|
||||
if fn.Name == name || strings.HasSuffix(fn.Name, "/"+name) {
|
||||
//TODO(aarzilli): convert function entry into a function type?
|
||||
r := scope.globalFor(fn.cu.image).newVariable(fn.Name, uintptr(fn.Entry), &godwarf.FuncType{}, scope.Mem)
|
||||
r := newVariable(fn.Name, uintptr(fn.Entry), &godwarf.FuncType{}, scope.BinInfo, scope.Mem)
|
||||
r.Value = constant.MakeString(fn.Name)
|
||||
r.Base = uintptr(fn.Entry)
|
||||
r.loaded = true
|
||||
@ -430,7 +396,7 @@ func (scope *EvalScope) findGlobal(name string) (*Variable, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v := scope.globalFor(scope.BinInfo.Images[0]).newVariable(name, 0x0, t, scope.Mem)
|
||||
v := newVariable(name, 0x0, t, scope.BinInfo, scope.Mem)
|
||||
switch v.Kind {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v.Value = constant.MakeInt64(cval.value)
|
||||
@ -447,9 +413,6 @@ func (scope *EvalScope) findGlobal(name string) (*Variable, error) {
|
||||
}
|
||||
return nil, fmt.Errorf("could not find symbol value for %s", name)
|
||||
}
|
||||
func (scope *EvalScope) newVariable(name string, addr uintptr, dwarfType godwarf.Type, mem MemoryReadWriter) *Variable {
|
||||
return newVariable(name, addr, dwarfType, scope.BinInfo, mem)
|
||||
}
|
||||
|
||||
// image returns the image containing the current function.
|
||||
func (scope *EvalScope) image() *Image {
|
||||
@ -522,7 +485,7 @@ func (scope *EvalScope) evalToplevelTypeCast(t ast.Expr, cfg LoadConfig) (*Varia
|
||||
return nil, converr
|
||||
}
|
||||
for i, ch := range []byte(constant.StringVal(argv.Value)) {
|
||||
e := scope.newVariable("", argv.Addr+uintptr(i), targetType.(*godwarf.SliceType).ElemType, argv.mem)
|
||||
e := newVariable("", argv.Addr+uintptr(i), targetType.(*godwarf.SliceType).ElemType, scope.BinInfo, argv.mem)
|
||||
e.loaded = true
|
||||
e.Value = constant.MakeInt64(int64(ch))
|
||||
v.Children = append(v.Children, *e)
|
||||
@ -536,7 +499,7 @@ func (scope *EvalScope) evalToplevelTypeCast(t ast.Expr, cfg LoadConfig) (*Varia
|
||||
return nil, converr
|
||||
}
|
||||
for i, ch := range constant.StringVal(argv.Value) {
|
||||
e := scope.newVariable("", argv.Addr+uintptr(i), targetType.(*godwarf.SliceType).ElemType, argv.mem)
|
||||
e := newVariable("", argv.Addr+uintptr(i), targetType.(*godwarf.SliceType).ElemType, scope.BinInfo, argv.mem)
|
||||
e.loaded = true
|
||||
e.Value = constant.MakeInt64(int64(ch))
|
||||
v.Children = append(v.Children, *e)
|
||||
@ -741,7 +704,7 @@ func (scope *EvalScope) evalTypeCast(node *ast.CallExpr) (*Variable, error) {
|
||||
|
||||
n, _ := constant.Int64Val(argv.Value)
|
||||
|
||||
v.Children = []Variable{*(scope.newVariable("", uintptr(n), ttyp.Type, scope.Mem))}
|
||||
v.Children = []Variable{*(newVariable("", uintptr(n), ttyp.Type, scope.BinInfo, scope.Mem))}
|
||||
return v, nil
|
||||
|
||||
case *godwarf.UintType:
|
||||
|
||||
@ -315,7 +315,7 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) {
|
||||
}
|
||||
switch len(fncall.retvars) {
|
||||
case 0:
|
||||
r := scope.newVariable("", 0, nil, nil)
|
||||
r := newVariable("", 0, nil, scope.BinInfo, nil)
|
||||
r.loaded = true
|
||||
r.Unreadable = errors.New("no return values")
|
||||
return r, nil
|
||||
@ -323,7 +323,7 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) {
|
||||
return fncall.retvars[0], nil
|
||||
default:
|
||||
// create a fake variable without address or type to return multiple values
|
||||
r := scope.newVariable("", 0, nil, nil)
|
||||
r := newVariable("", 0, nil, scope.BinInfo, nil)
|
||||
r.loaded = true
|
||||
r.Children = make([]Variable, len(fncall.retvars))
|
||||
for i := range fncall.retvars {
|
||||
@ -778,7 +778,7 @@ func readTopstackVariable(thread Thread, regs Registers, typename string, loadCf
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v := scope.newVariable("", uintptr(regs.SP()), typ, scope.Mem)
|
||||
v := newVariable("", uintptr(regs.SP()), typ, scope.BinInfo, scope.Mem)
|
||||
v.loadValue(loadCfg)
|
||||
if v.Unreadable != nil {
|
||||
return nil, v.Unreadable
|
||||
|
||||
@ -812,6 +812,44 @@ func readVarEntry(varEntry *dwarf.Entry, image *Image) (entry reader.Entry, name
|
||||
return entry, name, typ, nil
|
||||
}
|
||||
|
||||
// Extracts the name and type of a variable from a dwarf entry
|
||||
// then executes the instructions given in the DW_AT_location attribute to grab the variable's address
|
||||
func extractVarInfoFromEntry(bi *BinaryInfo, image *Image, regs op.DwarfRegisters, mem MemoryReadWriter, varEntry *dwarf.Entry) (*Variable, error) {
|
||||
if varEntry == nil {
|
||||
return nil, fmt.Errorf("invalid entry")
|
||||
}
|
||||
|
||||
if varEntry.Tag != dwarf.TagFormalParameter && varEntry.Tag != dwarf.TagVariable {
|
||||
return nil, fmt.Errorf("invalid entry tag, only supports FormalParameter and Variable, got %s", varEntry.Tag.String())
|
||||
}
|
||||
|
||||
entry, n, t, err := readVarEntry(varEntry, image)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, pieces, descr, err := bi.Location(entry, dwarf.AttrLocation, regs.PC(), regs)
|
||||
if pieces != nil {
|
||||
addr = fakeAddress
|
||||
var cmem *compositeMemory
|
||||
cmem, err = newCompositeMemory(mem, regs, pieces)
|
||||
if cmem != nil {
|
||||
mem = cmem
|
||||
}
|
||||
}
|
||||
|
||||
v := newVariable(n, uintptr(addr), t, bi, mem)
|
||||
if pieces != nil {
|
||||
v.Flags |= VariableFakeAddress
|
||||
}
|
||||
v.LocationExpr = descr
|
||||
v.DeclLine, _ = entry.Val(dwarf.AttrDeclLine).(int64)
|
||||
if err != nil {
|
||||
v.Unreadable = err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// If v is a pointer a new variable is returned containing the value pointed by v.
|
||||
func (v *Variable) maybeDereference() *Variable {
|
||||
if v.Unreadable != nil {
|
||||
|
||||
Reference in New Issue
Block a user