mirror of
https://github.com/thunderbrewhq/binana.git
synced 2026-05-03 05:03:50 +00:00
feat(bna): implement fix-labels command
The fix-labels command will fix a symbol file by automatically renaming labels matching a certain regex, and looking for the captured parameter in a "fixlist" i.e. a newline delimited list of OG names.
This commit is contained in:
parent
d020e6ba36
commit
cbb42eb953
6 changed files with 145 additions and 4 deletions
|
|
@ -2,6 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "github.com/thunderbrewhq/binana/go/app/cmd/add_symbol"
|
_ "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/lint"
|
||||||
_ "github.com/thunderbrewhq/binana/go/app/cmd/make"
|
_ "github.com/thunderbrewhq/binana/go/app/cmd/make"
|
||||||
_ "github.com/thunderbrewhq/binana/go/app/cmd/make_samples"
|
_ "github.com/thunderbrewhq/binana/go/app/cmd/make_samples"
|
||||||
|
|
|
||||||
37
go/app/cmd/fix_labels/fix_labels.go
Normal file
37
go/app/cmd/fix_labels/fix_labels.go
Normal file
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ func init() {
|
||||||
f.StringSlice("program", nil, "a list of programs to return tokens for")
|
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("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.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")
|
f.Bool("quote", false, "quote strings before presenting")
|
||||||
root.RootCmd.AddCommand(&query_cmd)
|
root.RootCmd.AddCommand(&query_cmd)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
type linter struct {
|
type linter struct {
|
||||||
warnings uint64
|
warnings uint64
|
||||||
named_functions_count uint64
|
named_functions_count uint64
|
||||||
|
typed_function_count uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (linter *linter) warn(s *symbols.TableEntry, f string, args ...any) {
|
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")
|
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 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)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
93
go/app/util/fix-labels.go
Normal file
93
go/app/util/fix-labels.go
Normal file
|
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ type QueryParams struct {
|
||||||
MaxBuild uint32
|
MaxBuild uint32
|
||||||
// Regular expression for tokens (symbols/type information)
|
// Regular expression for tokens (symbols/type information)
|
||||||
Token string
|
Token string
|
||||||
// If true, Token is a POSIX regular expression
|
// If true, Token is a RE2 regular expression
|
||||||
RegEx bool
|
RegEx bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,9 +202,9 @@ func Query(params *QueryParams) {
|
||||||
var token_query token_query
|
var token_query token_query
|
||||||
token_query.params = params
|
token_query.params = params
|
||||||
if params.RegEx {
|
if params.RegEx {
|
||||||
token_query.token_regexp = regexp.MustCompilePOSIX(token_query.params.Token)
|
token_query.token_regexp = regexp.MustCompile(token_query.params.Token)
|
||||||
} else {
|
} 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 {
|
if err := token_query.load_sample_database(); err != nil {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue