]> ruderich.org/simon Gitweb - blhc/blhc.git/blobdiff - bin/blhc
Add --ignore-flag and --ignore-line options.
[blhc/blhc.git] / bin / blhc
index 4713e287ad870f96d15ba8d6829fa54cf817970d..87a798810773fda45e7404de658b2a2ddbb4fe22 100755 (executable)
--- a/bin/blhc
+++ b/bin/blhc
@@ -426,6 +426,8 @@ my $option_help    = 0;
 my $option_version = 0;
 my $option_pie     = 0;
 my $option_bindnow = 0;
+my @option_ignore_flag = ();
+my @option_ignore_line = ();
 my $option_all     = 0;
 my $option_arch    = undef;
 my $option_buildd  = 0;
@@ -437,6 +439,9 @@ if (not Getopt::Long::GetOptions(
             'pie'      => \$option_pie,
             'bindnow'  => \$option_bindnow,
             'all'      => \$option_all,
+            # Ignore.
+            'ignore-flag=s' => \@option_ignore_flag,
+            'ignore-line=s' => \@option_ignore_line,
             # Misc.
             'color'    => \$option_color,
             'arch=s'   => \$option_arch,
@@ -480,16 +485,36 @@ if ($option_all) {
     $option_bindnow = 1;
 }
 
+# Strip flags which should be ignored.
+if (scalar @option_ignore_flag > 0) {
+    my %ignores = map { $_ => 1 } @option_ignore_flag;
+    foreach my $flags (@flag_refs) {
+        @{$flags} = grep {
+            # Flag found as string.
+            not exists $ignores{$_}
+            # Flag found as string representation of regexp.
+                and (not defined $flag_renames{$_}
+                        or not exists $ignores{$flag_renames{$_}})
+            } @{$flags};
+    }
+}
+
 # Precompile all flag regexps. any_flags_used(), all_flags_used() get a lot
 # faster with this.
 foreach my $flags (@flag_refs_all) {
     @{$flags} = compile_flag_regexp(\%flag_renames, @{$flags});
 }
 
+# Precompile ignore line regexps, also anchor at beginning and end of line.
+foreach my $ignore (@option_ignore_line) {
+    $ignore = qr/^$ignore$/;
+}
+
 # Final exit code.
 my $exit = 0;
 
-FILE: foreach my $file (@ARGV) {
+FILE:
+foreach my $file (@ARGV) {
     print "checking '$file'...\n" if scalar @ARGV > 1;
 
     open my $fh, '<', $file or die "$!: $file";
@@ -632,10 +657,10 @@ FILE: foreach my $file (@ARGV) {
             # Ignore lines with no compiler commands.
             next if not $non_verbose
                     and not $line =~ /\b$cc_regex(?:\s|\\)/o;
-            # Ignore lines with no filenames with extensions. May miss
-            # some non-verbose builds (e.g. "gcc -o test" [sic!]), but
-            # shouldn't be a problem as the log will most likely contain
-            # other non-verbose commands which are detected.
+            # Ignore lines with no filenames with extensions. May miss some
+            # non-verbose builds (e.g. "gcc -o test" [sic!]), but shouldn't be
+            # a problem as the log will most likely contain other non-verbose
+            # commands which are detected.
             next if not $non_verbose
                     and not $line =~ /$file_extension_regex/o;
 
@@ -649,8 +674,8 @@ FILE: foreach my $file (@ARGV) {
                                 /xo;
             next if $line =~ /^\s*(?:- )?(?:HOST_)?(?:CC|CXX)\s*=\s*$cc_regex_full\s*$/o;
 
-            # Check if additional hardening options were used. Used to
-            # ensure they are used for the complete build.
+            # Check if additional hardening options were used. Used to ensure
+            # they are used for the complete build.
             $harden_pie     = 1 if any_flags_used($line, @def_cflags_pie, @def_ldflags_pie);
             $harden_bindnow = 1 if any_flags_used($line, @def_ldflags_bindnow);
 
@@ -726,9 +751,15 @@ FILE: foreach my $file (@ARGV) {
         @ldflags = (@ldflags, @def_ldflags_bindnow);
     }
 
+LINE:
     for (my $i = 0; $i < scalar @input; $i++) {
         my $line = $input[$i];
 
+        # Ignore line if requested.
+        foreach my $ignore (@option_ignore_line) {
+            next LINE if $line =~ /$ignore/;
+        }
+
         my $skip = 0;
         if (is_non_verbose_build($line, $input[$i + 1], \$skip)) {
             if (not $option_buildd) {
@@ -981,6 +1012,23 @@ Don't require Term::ANSIColor.
 
 Use colored (ANSI) output for warning messages.
 
+=item B<--ignore-flag> I<flag>
+
+Don't print an error when the specific flag is missing in a compiler line.
+I<flag> is a string.
+
+Used to prevent false positives. This option can be specified multiple times.
+
+=item B<--ignore-line> I<regex>
+
+Ignore lines matching the given Perl regex. I<regex> is automatically anchored
+at the beginning and end of the line to prevent false negatives.
+
+B<NOTE>: Not the input lines are checked, but the lines which are displayed in
+warnings (which have line continuation resolved).
+
+Used to prevent false positives. This option can be specified multiple times.
+
 =item B<--pie>
 
 Force check for all +pie hardening flags. By default it's auto detected.