提交 c4413308 编写于 作者: A Alessandro Arzilli 提交者: Derek Parker

proc: remove (*EvalScope).globalFor (#1658)

上级 f0a90319
...@@ -212,12 +212,14 @@ func TestDwarfExprLoclist(t *testing.T) { ...@@ -212,12 +212,14 @@ func TestDwarfExprLoclist(t *testing.T) {
mainfn := bi.LookupFunc["main.main"] mainfn := bi.LookupFunc["main.main"]
mem := newFakeMemory(defaultCFA, uint16(before), uint16(after)) 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, &regs), Mem: mem, BinInfo: bi} scope := &proc.EvalScope{Location: proc.Location{PC: PC, Fn: mainfn}, Regs: dwarfRegisters(bi, &regs), Mem: mem, BinInfo: bi}
uintExprCheck(t, scope, "a", before) uintExprCheck(t, scope, "a", before)
scope.PC = 0x40800 scope.PC = 0x40800
scope.Regs.Regs[scope.Regs.PCRegNum].Uint64Val = scope.PC
uintExprCheck(t, scope, "a", after) uintExprCheck(t, scope, "a", after)
} }
......
...@@ -108,7 +108,7 @@ func (scope *EvalScope) Locals() ([]*Variable, error) { ...@@ -108,7 +108,7 @@ func (scope *EvalScope) Locals() ([]*Variable, error) {
hasScopes := false hasScopes := false
for varReader.Next() { for varReader.Next() {
entry := varReader.Entry() entry := varReader.Entry()
val, err := scope.extractVarInfoFromEntry(entry) val, err := extractVarInfoFromEntry(scope.BinInfo, scope.image(), scope.Regs, scope.Mem, entry)
if err != nil { if err != nil {
// skip variables that we can't parse yet // skip variables that we can't parse yet
continue continue
...@@ -249,45 +249,6 @@ func (scope *EvalScope) setValue(dstv, srcv *Variable, srcExpr string) error { ...@@ -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()) 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). // EvalVariable returns the value of the given expression (backwards compatibility).
func (scope *EvalScope) EvalVariable(name string, cfg LoadConfig) (*Variable, error) { func (scope *EvalScope) EvalVariable(name string, cfg LoadConfig) (*Variable, error) {
return scope.EvalExpression(name, cfg) return scope.EvalExpression(name, cfg)
...@@ -364,6 +325,11 @@ func filterVariables(vars []*Variable, pred func(v *Variable) bool) []*Variable ...@@ -364,6 +325,11 @@ func filterVariables(vars []*Variable, pred func(v *Variable) bool) []*Variable
return r 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. // PackageVariables returns the name, value, and type of all package variables in the application.
func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) { func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) {
var vars []*Variable var vars []*Variable
...@@ -389,7 +355,7 @@ func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) { ...@@ -389,7 +355,7 @@ func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) {
} }
// Ignore errors trying to extract values // 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 { if err != nil {
continue continue
} }
...@@ -410,13 +376,13 @@ func (scope *EvalScope) findGlobal(name string) (*Variable, error) { ...@@ -410,13 +376,13 @@ func (scope *EvalScope) findGlobal(name string) (*Variable, error) {
if err != nil { if err != nil {
return nil, err 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 { for _, fn := range scope.BinInfo.Functions {
if fn.Name == name || strings.HasSuffix(fn.Name, "/"+name) { if fn.Name == name || strings.HasSuffix(fn.Name, "/"+name) {
//TODO(aarzilli): convert function entry into a function type? //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.Value = constant.MakeString(fn.Name)
r.Base = uintptr(fn.Entry) r.Base = uintptr(fn.Entry)
r.loaded = true r.loaded = true
...@@ -430,7 +396,7 @@ func (scope *EvalScope) findGlobal(name string) (*Variable, error) { ...@@ -430,7 +396,7 @@ func (scope *EvalScope) findGlobal(name string) (*Variable, error) {
if err != nil { if err != nil {
return nil, err 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 { switch v.Kind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
v.Value = constant.MakeInt64(cval.value) v.Value = constant.MakeInt64(cval.value)
...@@ -447,9 +413,6 @@ func (scope *EvalScope) findGlobal(name string) (*Variable, error) { ...@@ -447,9 +413,6 @@ func (scope *EvalScope) findGlobal(name string) (*Variable, error) {
} }
return nil, fmt.Errorf("could not find symbol value for %s", name) 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. // image returns the image containing the current function.
func (scope *EvalScope) image() *Image { func (scope *EvalScope) image() *Image {
...@@ -522,7 +485,7 @@ func (scope *EvalScope) evalToplevelTypeCast(t ast.Expr, cfg LoadConfig) (*Varia ...@@ -522,7 +485,7 @@ func (scope *EvalScope) evalToplevelTypeCast(t ast.Expr, cfg LoadConfig) (*Varia
return nil, converr return nil, converr
} }
for i, ch := range []byte(constant.StringVal(argv.Value)) { 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.loaded = true
e.Value = constant.MakeInt64(int64(ch)) e.Value = constant.MakeInt64(int64(ch))
v.Children = append(v.Children, *e) v.Children = append(v.Children, *e)
...@@ -536,7 +499,7 @@ func (scope *EvalScope) evalToplevelTypeCast(t ast.Expr, cfg LoadConfig) (*Varia ...@@ -536,7 +499,7 @@ func (scope *EvalScope) evalToplevelTypeCast(t ast.Expr, cfg LoadConfig) (*Varia
return nil, converr return nil, converr
} }
for i, ch := range constant.StringVal(argv.Value) { 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.loaded = true
e.Value = constant.MakeInt64(int64(ch)) e.Value = constant.MakeInt64(int64(ch))
v.Children = append(v.Children, *e) v.Children = append(v.Children, *e)
...@@ -741,7 +704,7 @@ func (scope *EvalScope) evalTypeCast(node *ast.CallExpr) (*Variable, error) { ...@@ -741,7 +704,7 @@ func (scope *EvalScope) evalTypeCast(node *ast.CallExpr) (*Variable, error) {
n, _ := constant.Int64Val(argv.Value) 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 return v, nil
case *godwarf.UintType: case *godwarf.UintType:
......
...@@ -315,7 +315,7 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) { ...@@ -315,7 +315,7 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) {
} }
switch len(fncall.retvars) { switch len(fncall.retvars) {
case 0: case 0:
r := scope.newVariable("", 0, nil, nil) r := newVariable("", 0, nil, scope.BinInfo, nil)
r.loaded = true r.loaded = true
r.Unreadable = errors.New("no return values") r.Unreadable = errors.New("no return values")
return r, nil return r, nil
...@@ -323,7 +323,7 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) { ...@@ -323,7 +323,7 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) {
return fncall.retvars[0], nil return fncall.retvars[0], nil
default: default:
// create a fake variable without address or type to return multiple values // 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.loaded = true
r.Children = make([]Variable, len(fncall.retvars)) r.Children = make([]Variable, len(fncall.retvars))
for i := range fncall.retvars { for i := range fncall.retvars {
...@@ -778,7 +778,7 @@ func readTopstackVariable(thread Thread, regs Registers, typename string, loadCf ...@@ -778,7 +778,7 @@ func readTopstackVariable(thread Thread, regs Registers, typename string, loadCf
if err != nil { if err != nil {
return nil, err 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) v.loadValue(loadCfg)
if v.Unreadable != nil { if v.Unreadable != nil {
return nil, v.Unreadable return nil, v.Unreadable
......
...@@ -812,6 +812,44 @@ func readVarEntry(varEntry *dwarf.Entry, image *Image) (entry reader.Entry, name ...@@ -812,6 +812,44 @@ func readVarEntry(varEntry *dwarf.Entry, image *Image) (entry reader.Entry, name
return entry, name, typ, nil 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. // If v is a pointer a new variable is returned containing the value pointed by v.
func (v *Variable) maybeDereference() *Variable { func (v *Variable) maybeDereference() *Variable {
if v.Unreadable != nil { if v.Unreadable != nil {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册