diff --git a/analyzer/analyzer.go b/analyzer/analyzer.go index a339330..003adcb 100644 --- a/analyzer/analyzer.go +++ b/analyzer/analyzer.go @@ -13,7 +13,7 @@ import ( type Analyzer interface { // Analyze analyzes the provided source code and returns any issues found. // TODO: better to update the code to take a reader interface instead of path - Analyze(path string, withTrace bool) ([]*Issue, error) + Analyze(path string, withTrace bool, skipWarnings bool) ([]*Issue, error) // TraceStack generates callstack for a function to debug TraceStack(path string, function string) (*CallStack, error) diff --git a/analyzer/opcode/opcode.go b/analyzer/opcode/opcode.go index 7807149..f058b9c 100644 --- a/analyzer/opcode/opcode.go +++ b/analyzer/opcode/opcode.go @@ -22,7 +22,7 @@ func NewAnalyser(profile *profile.VMProfile) analyzer.Analyzer { return &opcode{profile: profile} } -func (op *opcode) Analyze(path string, withTrace bool) ([]*analyzer.Issue, error) { +func (op *opcode) Analyze(path string, withTrace bool, skipWarnings bool) ([]*analyzer.Issue, error) { callGraph, err := op.buildCallGraph(path) if err != nil { return nil, err @@ -55,6 +55,9 @@ func (op *opcode) Analyze(path string, withTrace bool) ([]*analyzer.Issue, error ), } if common.ShouldIgnoreSource(source, op.profile.IgnoredFunctions) { + if skipWarnings { + continue + } opts = append(opts, analyzer.WithSeverity(analyzer.IssueSeverityWarning)) } if !withTrace { diff --git a/analyzer/syscall/asm_syscall.go b/analyzer/syscall/asm_syscall.go index 894d2e3..cf4c984 100644 --- a/analyzer/syscall/asm_syscall.go +++ b/analyzer/syscall/asm_syscall.go @@ -32,7 +32,7 @@ func NewAssemblySyscallAnalyser(profile *profile.VMProfile) analyzer.Analyzer { // Analyze scans an assembly file for syscalls and detects compatibility issues. // //nolint:cyclop -func (a *asmSyscallAnalyser) Analyze(path string, withTrace bool) ([]*analyzer.Issue, error) { +func (a *asmSyscallAnalyser) Analyze(path string, withTrace bool, skipWarnings bool) ([]*analyzer.Issue, error) { callGraph, err := a.buildCallGraph(path) if err != nil { return nil, err @@ -70,10 +70,16 @@ func (a *asmSyscallAnalyser) Analyze(path string, withTrace bool) ([]*analyzer.I for _, source := range sources { severity := analyzer.IssueSeverityCritical if common.ShouldIgnoreSource(source, a.profile.IgnoredFunctions) { + if skipWarnings { + continue + } severity = analyzer.IssueSeverityWarning } message := fmt.Sprintf("Potential Incompatible Syscall Detected: %d", syscall.Number) if slices.Contains(a.profile.NOOPSyscalls, syscall.Number) { + if skipWarnings { + continue + } message = fmt.Sprintf("Potential NOOP Syscall Detected: %d", syscall.Number) severity = analyzer.IssueSeverityWarning } diff --git a/analyzer/syscall/go_syscall.go b/analyzer/syscall/go_syscall.go index 51ccf07..91ab86c 100644 --- a/analyzer/syscall/go_syscall.go +++ b/analyzer/syscall/go_syscall.go @@ -40,7 +40,7 @@ func NewGOSyscallAnalyser(profile *profile.VMProfile) analyzer.Analyzer { // Analyze scans a Go binary for syscalls and detects compatibility issues. // //nolint:cyclop -func (a *goSyscallAnalyser) Analyze(path string, withTrace bool) ([]*analyzer.Issue, error) { +func (a *goSyscallAnalyser) Analyze(path string, withTrace bool, skipWarnings bool) ([]*analyzer.Issue, error) { cg, fset, err := a.buildCallGraph(path) if err != nil { return nil, err @@ -59,6 +59,9 @@ func (a *goSyscallAnalyser) Analyze(path string, withTrace bool) ([]*analyzer.Is severity := analyzer.IssueSeverityCritical message := fmt.Sprintf("Potential Incompatible Syscall Detected: %d", syscll.num) if slices.Contains(a.profile.NOOPSyscalls, syscll.num) { + if skipWarnings { + continue + } severity = analyzer.IssueSeverityWarning message = fmt.Sprintf("Potential NOOP Syscall Detected: %d", syscll.num) } diff --git a/cmd/analyze.go b/cmd/analyze.go index 107534b..0f66ceb 100644 --- a/cmd/analyze.go +++ b/cmd/analyze.go @@ -54,6 +54,12 @@ var ( Required: false, Value: false, } + SkipWarnings = &cli.BoolFlag{ + Name: "skip-warnings", + Usage: "skip the issue with severity warning", + Required: false, + Value: false, + } BaselineReport = &cli.StringFlag{ Name: "baseline-report", @@ -76,6 +82,7 @@ func CreateAnalyzeCommand(action cli.ActionFunc) *cli.Command { FormatFlag, ReportOutputPathFlag, TraceFlag, + SkipWarnings, BaselineReport, }, } @@ -104,6 +111,7 @@ func AnalyzeCompatibility(ctx *cli.Context) error { reportOutputPath := ctx.Path(ReportOutputPathFlag.Name) analysisType := ctx.String(AnalysisTypeFlag.Name) withTrace := ctx.Bool(TraceFlag.Name) + skipWarnings := ctx.Bool(SkipWarnings.Name) baselineReport := ctx.Path(BaselineReport.Name) disassemblyPath, err = disassemble(vmProfile, source, disassemblyPath) @@ -111,7 +119,7 @@ func AnalyzeCompatibility(ctx *cli.Context) error { return fmt.Errorf("error disassembling the file: %w", err) } - issues, err := analyze(vmProfile, disassemblyPath, analysisType, withTrace) + issues, err := analyze(vmProfile, disassemblyPath, analysisType, withTrace, skipWarnings) if err != nil { return fmt.Errorf("analysis failed: %w", err) } @@ -146,19 +154,19 @@ func disassemble(prof *profile.VMProfile, path, outputPath string) (string, erro } // analyze runs the selected analyzer(s). -func analyze(prof *profile.VMProfile, disassemblyPath, mode string, withTrace bool) ([]*analyzer.Issue, error) { +func analyze(prof *profile.VMProfile, disassemblyPath, mode string, withTrace bool, skipWarnings bool) ([]*analyzer.Issue, error) { if mode == "opcode" { - return opcode.NewAnalyser(prof).Analyze(disassemblyPath, withTrace) + return opcode.NewAnalyser(prof).Analyze(disassemblyPath, withTrace, skipWarnings) } if mode == "syscall" { - return syscall.NewAssemblySyscallAnalyser(prof).Analyze(disassemblyPath, withTrace) + return syscall.NewAssemblySyscallAnalyser(prof).Analyze(disassemblyPath, withTrace, skipWarnings) } // by default analyze both - opIssues, err := opcode.NewAnalyser(prof).Analyze(disassemblyPath, withTrace) + opIssues, err := opcode.NewAnalyser(prof).Analyze(disassemblyPath, withTrace, skipWarnings) if err != nil { return nil, err } - sysIssues, err := syscall.NewAssemblySyscallAnalyser(prof).Analyze(disassemblyPath, withTrace) + sysIssues, err := syscall.NewAssemblySyscallAnalyser(prof).Analyze(disassemblyPath, withTrace, skipWarnings) if err != nil { return nil, err }