Reputation: 76
hello i am new to static analysis and try to use golang's SSA package to analyze function code. i want to get a function's or a method's *ssa.Function in the package, get a function's *ssa.Function code is down, work success:
func GenBlockGraph(filename string, name string) *ssa.Function {
// Parse the source files.
fset := token.NewFileSet()
// read file content
src, err := os.ReadFile(filename)
if err != nil {
log.LogError.Println("Error reading file:", err)
}
f, err := parser.ParseFile(fset, filename, src, parser.ParseComments)
if err != nil {
log.LogError.Print(err) // parse error
}
files := []*ast.File{f}
// Create the type-checker's package.
pkg := types.NewPackage(f.Name.Name, "")
// Type-check the package, load dependencies.
// Create and build the SSA program.
res, _, err := ssautil.BuildPackage(
&types.Config{Importer: importer.Default()}, fset, pkg, files, ssa.SanityCheckFunctions)
if err != nil {
log.LogError.Print(err) // type error in some package
}
// Print out the package.
res.WriteTo(os.Stdout)
// Print out the package-level functions.
res.Func(name).WriteTo(os.Stdout)
return res.Func(name)
}
My question is how to get a method's *ssa.Function? For example get "func (p *China) Speak(slogan string) string"'s *ssa.Function:
package scene
import "fmt"
type Human interface {
Speak(str string) string
Language() string
}
type China struct {
name string
age int
}
func (p *China) Speak(slogan string) string {
return fmt.Sprintf("I am chinese, my name is %s, age is %s. my slogan is %s!", p.name, p.age, slogan)
}
func (p *China) Language() string {
return "Chinese"
}
type Germany struct {
name string
age int
}
func (p *Germany) Speak(slogan string) string {
return fmt.Sprintf("I am Germany, my name is %s, age is %s. my slogan is %s!", p.name, p.age, slogan)
}
func (p *Germany) Language() string {
return "Germany"
}
Upvotes: 0
Views: 66
Reputation: 76
func GetSSAFunction(ssaPkg *ssa.Package, structName string, funcName string) *ssa.Function {
if len(structName) == 0 {
return ssaPkg.Func(funcName)
} else {
t := ssaPkg.Type(structName)
ti := t.Type()
named, ok := ti.(*types.Named)
if !ok {
return nil
}
var key *types.Func
for i, n := 0, named.NumMethods(); i < n; i++ {
method := named.Method(i)
if method.Name() == funcName {
key = method
break
}
}
return ssaPkg.Prog.FuncValue(key)
}
}
this function solve my problem.
Upvotes: 0