/
pointer.go
77 lines (63 loc) · 1.71 KB
/
pointer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package main
import (
"flag"
"log"
"os"
"path/filepath"
"runtime/pprof"
"github.com/BarrensZeppelin/pointer"
"github.com/BarrensZeppelin/pointer/pkgutil"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/go/ssa"
"golang.org/x/tools/go/ssa/ssautil"
)
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
var dir = flag.String("dir", "", "alternative directory to run the go build tool in")
var gopath = flag.String("gopath", "", "override GOPATH in build tool")
func main() {
flag.Parse()
if flag.NArg() == 0 {
log.Fatal("Specify a package query on the command line")
}
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
defer func() {
if err := f.Close(); err != nil {
log.Fatal("Failed to close", f)
}
}()
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}
env := os.Environ()
if *gopath != "" {
abs, err := filepath.Abs(*gopath)
if err != nil {
log.Fatalf("Could not make %s absolute", *gopath)
}
env = append(env, "GOPATH=" + abs)
}
pkgs, err := pkgutil.LoadPackagesWithConfig(&packages.Config{
Mode: pkgutil.LoadMode,
Tests: true,
Dir: *dir,
Env: env,
}, flag.Args()...)
if err != nil {
log.Fatalf("Loading packages failed: %v", err)
}
log.Printf("Loaded %d packages", len(pkgs))
prog, _ := ssautil.AllPackages(pkgs, ssa.InstantiateGenerics)
prog.Build()
log.Println("Built packages")
res := pointer.Analyze(pointer.AnalysisConfig{
Program: prog,
EntryPackages: ssautil.MainPackages(prog.AllPackages()),
})
log.Printf("%d reachable functions", len(res.Reachable))
}