go-callvis 源码分析
Posted golang算法架构leetcode技术php
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go-callvis 源码分析相关的知识,希望对你有一定的参考价值。
go-callvis 是一个可视化调用调用链路图的静态源码分析工具
https://github.com/ofabry/go-callvis
它的实现非常简洁
examples handler.go output.go
Makefile analysis.go go.mod images version.go
README.md dot.go go.sum main.go
首先看下main.go文件
首先解析了一系列参数然后调用
Analysis = new(analysis)
if err := Analysis.DoAnalysis("", tests, args); err != nil {
log.Fatal(err)
}
最后起了一个http服务,可以支持在线可视化
type analysis struct {
opts *renderOpts
prog *ssa.Program
pkgs []*ssa.Package
mains []*ssa.Package
result *pointer.Result
}
定义在analysis.go文件里,重点是通过下面这个函数进行代码分析的
func (a *analysis) DoAnalysis(
dir string,
tests bool,
args []string,
) error
调用
"golang.org/x/tools/go/packages"
里面的
initial, err := packages.Load(cfg, args...)
加载包里面所有的文件,然后调用
"golang.org/x/tools/go/ssa/ssautil"
里面的
prog, pkgs := ssautil.AllPackages(initial, 0)
prog.Build()
对源码进行ssa转化
然后找到入口的main函数
mains, err := mainPackages(pkgs)
就是判断包名和函数名
p.Pkg.Name() == "main" && p.Func("main")
然后用
"golang.org/x/tools/go/pointer"
的指针分析,进行依赖分析
result, err := pointer.Analyze(config)
至此,完成了源码的依赖分析,然后应用dot语言,转化成图像。
func outputDot(fname string, outputFormat string) {
// get cmdline default for analysis
Analysis.OptsSetup()
if e := Analysis.ProcessListArgs(); e != nil {
log.Fatalf("%v\n", e)
}
output, err := Analysis.Render()
SSA在Go1.7中被引入,这个特性对编译器的性能有很大的提高,但是也导致编译过程有些减速。下面来结合网上的资粮和书籍,简单说明一下SSA以及SSA的应用。
SSA 代表 static single-assignment,是一种IR(中间表示代码),要保证每个变量只被赋值一次。这个能帮助简化编译器的优化算法。
y := 1
y := 2
x := y
比如上面这段代码,y = 1
其实是不可用的,这个要通过定义的可达分析来确定y
是要用1还是2,而SSA有一个标识符可以称之为版本或者“代“。
y1 := 1
y2 := 2
x1 := y2
这样就没有任何间接值了。用SSA表示的好处是对于同一个变量的无关使用表示成不同“代”,可以方便很多编译器的优化算法的实现。
指向分析,是指通过对源程序的分析近似地求出源程序中指针表达式所指向的目标。
以上是关于go-callvis 源码分析的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段
Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段
mysql jdbc源码分析片段 和 Tomcat's JDBC Pool
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段