diff --git a/go/app/cmd/execute.go b/go/app/cmd/execute.go index 1af67f1..e7af131 100644 --- a/go/app/cmd/execute.go +++ b/go/app/cmd/execute.go @@ -2,6 +2,7 @@ package cmd import ( _ "github.com/thunderbrewhq/binana/go/app/cmd/add_symbol" + _ "github.com/thunderbrewhq/binana/go/app/cmd/fix_labels" _ "github.com/thunderbrewhq/binana/go/app/cmd/lint" _ "github.com/thunderbrewhq/binana/go/app/cmd/make" _ "github.com/thunderbrewhq/binana/go/app/cmd/make_samples" diff --git a/go/app/cmd/fix_labels/fix_labels.go b/go/app/cmd/fix_labels/fix_labels.go new file mode 100644 index 0000000..2f93f26 --- /dev/null +++ b/go/app/cmd/fix_labels/fix_labels.go @@ -0,0 +1,37 @@ +package fix_labels + +import ( + "github.com/spf13/cobra" + "github.com/thunderbrewhq/binana/go/app" + "github.com/thunderbrewhq/binana/go/app/cmd/root" + "github.com/thunderbrewhq/binana/go/app/util" +) + +var fix_labels_cmd = cobra.Command{ + Use: "fix-labels fixlist capture-regex fix-pattern", + Args: cobra.MinimumNArgs(3), + Short: "quickly edit symbols by regex matching tokens against a list of known good symbols", + Run: run_fix_labels_cmd, +} + +func init() { + f := fix_labels_cmd.Flags() + f.StringP("symbols", "s", "", "optional: specify a file to read from instead of stdin") + root.RootCmd.AddCommand(&fix_labels_cmd) +} + +func run_fix_labels_cmd(cmd *cobra.Command, args []string) { + f := cmd.Flags() + var ( + err error + params util.FixLabelsParams + ) + params.Input, err = f.GetString("symbols") + if err != nil { + app.Fatal(err) + } + params.FixList = args[0] + params.Capture = args[1] + params.FixPattern = args[2] + util.FixLabels(¶ms) +} diff --git a/go/app/cmd/query/query.go b/go/app/cmd/query/query.go index 24aa513..69bf91a 100644 --- a/go/app/cmd/query/query.go +++ b/go/app/cmd/query/query.go @@ -24,7 +24,7 @@ func init() { f.StringSlice("program", nil, "a list of programs to return tokens for") f.StringSlice("os", nil, "a list of kernel names to return tokens for (windows, darwin, linux)") f.StringSlice("arch", nil, "a list of CPU architectures to return tokens for (ppc, 386, amd64)") - f.String("present", "normal", "control the way tokens are presented to console (normal, name-only)") + f.String("present", "normal", "control the way tokens are presented to console (name, sample-name)") f.Bool("quote", false, "quote strings before presenting") root.RootCmd.AddCommand(&query_cmd) } diff --git a/go/app/profile/lint.go b/go/app/profile/lint.go index c69745d..fa62611 100644 --- a/go/app/profile/lint.go +++ b/go/app/profile/lint.go @@ -11,6 +11,7 @@ import ( type linter struct { warnings uint64 named_functions_count uint64 + typed_function_count uint64 } func (linter *linter) warn(s *symbols.TableEntry, f string, args ...any) { @@ -54,6 +55,10 @@ func Lint(params *LintParams) { linter.warn(entry, "does not have an end address\n") } } + + if entry.Symbol.DataType != "" { + linter.typed_function_count++ + } } } @@ -62,4 +67,9 @@ func Lint(params *LintParams) { fmt.Printf("%d out of %d functions named (%f%%)\n", linter.named_functions_count, Profile.Info.FunctionCount, ratio*100.0) fmt.Printf("%d warnings generated\n", linter.warnings) } + + if linter.named_functions_count != 0 { + typed_ratio := float64(linter.typed_function_count) / float64(linter.named_functions_count) + fmt.Printf("%d out of %d (%f%%) named functions have type information", linter.typed_function_count, linter.named_functions_count, typed_ratio*100.0) + } } diff --git a/go/app/util/fix-labels.go b/go/app/util/fix-labels.go new file mode 100644 index 0000000..c2cf0ce --- /dev/null +++ b/go/app/util/fix-labels.go @@ -0,0 +1,93 @@ +package util + +import ( + "bufio" + "fmt" + "io" + "os" + "regexp" + "strings" + + "github.com/thunderbrewhq/binana/go/symbols" +) + +type FixLabelsParams struct { + // the input symbols file + Input string + // the list of fixed symbol names + FixList string + // regex to capture a word that will be matched against the fixlist + Capture string + // pattern to insert the match into so it may be checked against the fixlist + FixPattern string +} + +func read_fixlist(path string) ([]string, error) { + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + + var lines []string + scanner := bufio.NewScanner(file) + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + return lines, scanner.Err() +} + +func FixLabels(params *FixLabelsParams) { + capture := regexp.MustCompile(params.Capture) + var ( + input io.Reader + input_file *os.File + fixlist []string + table symbols.Table + err error + ) + + if params.Input != "" { + input_file, err = os.Open(params.Input) + if err != nil { + return + } + input = input_file + } else { + input = os.Stdin + } + + if params.FixList == "" { + panic("must have fix list") + } + + fixlist, err = read_fixlist(params.FixList) + if err != nil { + panic(err) + } + + table.Init() + if err = table.LoadFile(params.Input, input); err != nil { + return + } + if input_file != nil { + input_file.Close() + } + + for entry := range table.Entries() { + symbol := entry.Symbol + matches := capture.FindAllStringSubmatch(symbol.Name, 1) + if len(matches) > 0 { + //fmt.Fprintln(os.Stderr, "matches: ", matches) + match := matches[0][1] + fixed_match := strings.Replace(params.FixPattern, "$", match, 1) + for _, fix := range fixlist { + if strings.ToUpper(fixed_match) == strings.ToUpper(fix) { + symbol.Name = fix + break + } + } + } + fmt.Println(symbol.String()) + } +} diff --git a/go/app/util/query.go b/go/app/util/query.go index 36de465..556d994 100644 --- a/go/app/util/query.go +++ b/go/app/util/query.go @@ -39,7 +39,7 @@ type QueryParams struct { MaxBuild uint32 // Regular expression for tokens (symbols/type information) Token string - // If true, Token is a POSIX regular expression + // If true, Token is a RE2 regular expression RegEx bool } @@ -202,9 +202,9 @@ func Query(params *QueryParams) { var token_query token_query token_query.params = params if params.RegEx { - token_query.token_regexp = regexp.MustCompilePOSIX(token_query.params.Token) + token_query.token_regexp = regexp.MustCompile(token_query.params.Token) } else { - token_query.token_regexp = regexp.MustCompilePOSIX(regexp.QuoteMeta(params.Token)) + token_query.token_regexp = regexp.MustCompile(regexp.QuoteMeta(params.Token)) } if err := token_query.load_sample_database(); err != nil {