Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
HugeYuan
delve
提交
c4413308
D
delve
项目概览
HugeYuan
/
delve
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
delve
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c4413308
编写于
8月 11, 2019
作者:
A
Alessandro Arzilli
提交者:
Derek Parker
8月 11, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
proc: remove (*EvalScope).globalFor (#1658)
上级
f0a90319
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
58 addition
and
55 deletion
+58
-55
pkg/proc/dwarf_expr_test.go
pkg/proc/dwarf_expr_test.go
+4
-2
pkg/proc/eval.go
pkg/proc/eval.go
+13
-50
pkg/proc/fncall.go
pkg/proc/fncall.go
+3
-3
pkg/proc/variables.go
pkg/proc/variables.go
+38
-0
未找到文件。
pkg/proc/dwarf_expr_test.go
浏览文件 @
c4413308
...
@@ -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
)
}
}
...
...
pkg/proc/eval.go
浏览文件 @
c4413308
...
@@ -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
:
...
...
pkg/proc/fncall.go
浏览文件 @
c4413308
...
@@ -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
...
...
pkg/proc/variables.go
浏览文件 @
c4413308
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录