219 lines
5.3 KiB
Go
219 lines
5.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/google/blueprint/parser"
|
|
)
|
|
|
|
var (
|
|
result = make(map[string]string)
|
|
defaults = make(map[string]string)
|
|
Root = ""
|
|
)
|
|
|
|
var (
|
|
exitCode = 0
|
|
)
|
|
|
|
func report(err error) {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
exitCode = 2
|
|
}
|
|
|
|
func usage() {
|
|
usageViolation("")
|
|
}
|
|
|
|
func usageViolation(violation string) {
|
|
fmt.Fprintln(os.Stderr, violation)
|
|
fmt.Fprintln(os.Stderr, "usage: fuzzparser [flags] [path ...]")
|
|
flag.PrintDefaults()
|
|
os.Exit(2)
|
|
}
|
|
|
|
func processFile(filename string, out io.Writer) error {
|
|
f, err := os.Open(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
return processReader(filename, f, out)
|
|
}
|
|
|
|
func processReader(filename string, in io.Reader, out io.Writer) error {
|
|
src, err := ioutil.ReadAll(in)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
r := bytes.NewBuffer(src)
|
|
file, errs := parser.ParseAndEval(filename, r, parser.NewScope(nil))
|
|
|
|
modules := findModules(file)
|
|
// First collect all the defaults into a dictionary
|
|
for _, mod := range modules {
|
|
if mod.Type == "cc_defaults" {
|
|
default_name := ""
|
|
for _, prop := range mod.Map.Properties {
|
|
if prop.Name == "name" {
|
|
value := prop.Value.String()
|
|
default_name = value[1:strings.Index(value, "@")-1]
|
|
} else if prop.Name == "static_libs" || prop.Name == "shared_libs" {
|
|
value := prop.Value.String()
|
|
for strings.Index(value, "\"") > -1 {
|
|
value = value[strings.Index(value, "\"")+1:]
|
|
lib_name := value[:strings.Index(value, "\"")]
|
|
if _ , ok := defaults[default_name]; ok {
|
|
defaults[default_name] += "," + lib_name
|
|
} else {
|
|
defaults[default_name] += lib_name
|
|
}
|
|
value = value[strings.Index(value, "\"")+1:]
|
|
}
|
|
} else if prop.Name == "defaults" {
|
|
// Get the defaults of the default
|
|
value := prop.Value.String()
|
|
for strings.Index(value, "\"") > -1 {
|
|
value = value[strings.Index(value, "\"")+1:]
|
|
sub_default_name := value[:strings.Index(value, "\"")]
|
|
if _ , ok := defaults[default_name]; ok {
|
|
defaults[default_name] += "," + defaults[sub_default_name]
|
|
} else {
|
|
defaults[default_name] += defaults[sub_default_name]
|
|
}
|
|
value = value[strings.Index(value, "\"")+1:]
|
|
}
|
|
} else if prop.Name == "target" {
|
|
value := prop.Value.String()
|
|
if default_name == "binder_fuzz_defaults" {
|
|
fmt.Printf("---> target value for %s: %s\n", default_name ,value)
|
|
}
|
|
for strings.Index(value, "\"") > -1 {
|
|
value = value[strings.Index(value, "\"")+1:]
|
|
lib := value[:strings.Index(value, "\"")]
|
|
if _ , ok := defaults[default_name]; ok {
|
|
defaults[default_name] += "," + lib
|
|
} else {
|
|
defaults[default_name] += lib
|
|
}
|
|
value = value[strings.Index(value, "\"")+1:]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, mod := range modules {
|
|
if mod.Type == "cc_fuzz" {
|
|
fuzzer_name := ""
|
|
for _, prop := range mod.Map.Properties {
|
|
// First get the name of the fuzzer
|
|
if prop.Name == "name" {
|
|
value := prop.Value.String()
|
|
fuzzer_name = value[1:strings.Index(value, "@")-1]
|
|
} else if prop.Name == "defaults" {
|
|
value := prop.Value.String()
|
|
if strings.Index(value, "@") == 0 {
|
|
value = value[1:]
|
|
}
|
|
default_name := value[strings.Index(value, "[")+2: strings.Index(value, "@")-1]
|
|
if _, ok := result[fuzzer_name]; ok {
|
|
result[fuzzer_name] += "," + defaults[default_name]
|
|
} else {
|
|
result[fuzzer_name] += defaults[default_name]
|
|
}
|
|
} else if prop.Name == "static_libs" || prop.Name == "shared_libs" {
|
|
value := prop.Value.String()
|
|
for strings.Index(value, "\"") > -1 {
|
|
value = value[strings.Index(value, "\"")+1:]
|
|
lib_name := value[:strings.Index(value, "\"")]
|
|
if _ , ok := result[fuzzer_name]; ok {
|
|
result[fuzzer_name] += "," + lib_name
|
|
} else {
|
|
result[fuzzer_name] += lib_name
|
|
}
|
|
value = value[strings.Index(value, "\"")+1:]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(errs) > 0 {
|
|
for _, err := range errs {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
}
|
|
return fmt.Errorf("%d parsing errors", len(errs))
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
func findModules(file *parser.File) (modules []*parser.Module) {
|
|
if file != nil {
|
|
for _, def := range file.Defs {
|
|
if module, ok := def.(*parser.Module); ok {
|
|
modules = append(modules, module)
|
|
}
|
|
}
|
|
}
|
|
return modules
|
|
}
|
|
|
|
func walkDir(path string) {
|
|
visitFile := func(path string, f os.FileInfo, err error) error {
|
|
if err == nil && f.Name() == "Android.bp" {
|
|
err = processFile(path, os.Stdout)
|
|
}
|
|
if err != nil {
|
|
fmt.Printf("ERROR")
|
|
report(err)
|
|
}
|
|
return nil
|
|
}
|
|
fmt.Printf("Parsing %s recursively...\n", path)
|
|
filepath.Walk(path, visitFile)
|
|
}
|
|
|
|
func main() {
|
|
flag.Usage = usage
|
|
flag.Parse()
|
|
|
|
for i := 0; i < flag.NArg(); i++ {
|
|
Root := flag.Arg(i)
|
|
fmt.Printf("Root %s\n", Root)
|
|
switch dir, err := os.Stat(Root); {
|
|
case err != nil:
|
|
report(err)
|
|
case dir.IsDir():
|
|
walkDir(Root)
|
|
default:
|
|
if err := processFile(Root, os.Stdout); err != nil {
|
|
report(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
fmt.Printf("-------------------------------------\n")
|
|
fmt.Printf("Fuzzer name -------Library name------\n")
|
|
if len(result) > 0 {
|
|
for k, v := range result {
|
|
if len(v) == 0 {
|
|
v = "NOT FOUND"
|
|
}
|
|
fmt.Printf("%s:%s\n", k, v)
|
|
}
|
|
}
|
|
|
|
os.Exit(exitCode)
|
|
}
|