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

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

上级 f0a90319
......@@ -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, &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)
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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册