| #!/usr/bin/perl -w |
| # SPDX-License-Identifier: GPL-2.0 |
| # |
| # kabisyms - a script tools to generate kabi baseline and check symbol |
| # referance relationship. |
| # |
| # Author: Xie XiuQi <xiexiuqi@huawei.com> |
| # Copyright (C) 2019 Huawei, Inc. |
| # |
| # This software may be freely redistributed under the terms of the GNU |
| # General Public License (GPL). |
| # |
| # usage: |
| # ./scripts/kabisyms -k <symlist> -s <symvers> -o <output> |
| # ./scripts/kabisyms -k <symlist> -d <kabideps> -o <output> |
| |
| use 5.010; |
| |
| use strict; |
| use Getopt::Long; |
| use File::Basename; |
| |
| my $SYMLIST; |
| my $SYMVERS; |
| my $KABIDEPS; |
| my $OUTPUT = "Module.kabi"; |
| my $VERBOSE; |
| |
| my $PROG = basename $0; |
| |
| sub usage { |
| say "usage:"; |
| say " $PROG [--symlist|k] [--symvers|s] [--kabideps|d] [--output|o] [--verbose|v] [--help|h|?]"; |
| say " -k|--symlist"; |
| say " symbol list (filename)"; |
| say " -s|--symvers"; |
| say " Module.symvers"; |
| say " -d|--kabideps"; |
| say " kabideps"; |
| say " -o|--output"; |
| say " filename of output"; |
| say " -v|--verbose:"; |
| say " show more info"; |
| say " -h|-?|--help:"; |
| say " show this usage"; |
| say " examples:"; |
| say " ./scripts/kabisyms -k <symlist> -s <symvers> -o <output>"; |
| say " ./scripts/kabisyms -k <symlist> -d <kabideps> -o <output>"; |
| exit 0; |
| } |
| |
| usage() unless (@ARGV); |
| my $result = GetOptions( |
| 'symlist|k=s' => \$SYMLIST, |
| 'symvers|s=s' => \$SYMVERS, |
| 'kabideps|d=s' => \$KABIDEPS, |
| 'output|o=s' => \$OUTPUT, |
| 'verbose|v!' => \$VERBOSE, |
| 'help|h|?' => \&usage, |
| ) or usage(); |
| |
| my @syms; |
| my @symvers; |
| my @kabideps; |
| |
| if ($SYMLIST) { |
| @syms = `cat $SYMLIST`; chomp @syms; |
| } |
| else { |
| usage(); |
| } |
| |
| if ($SYMVERS) { |
| @symvers = `cat $SYMVERS`; chomp @symvers; |
| } |
| elsif ($KABIDEPS) { |
| @kabideps = `cat $KABIDEPS`; chomp @kabideps; |
| } |
| else { |
| usage(); |
| } |
| |
| sub check_sym { |
| my $sym = shift; |
| my @res; |
| my $found; |
| |
| foreach (@symvers) { |
| if (/^\s*$/) { |
| next; |
| } |
| |
| if (/^0x[0-9a-fA-F]+\s+$sym\s+/) { |
| printf OUT "%s\n", $_; |
| $found = 1; |
| last; |
| } |
| } |
| |
| printf "%s is not included in %s\n", $sym, $SYMVERS if (!$found); |
| } |
| |
| sub check_deps { |
| my $sym = shift; |
| my @res; |
| my $found; |
| |
| foreach (@kabideps) { |
| if (/^\s*$/) { |
| next; |
| } |
| |
| if (/^\s*$sym:/) { |
| printf OUT "%s\n", $_; |
| $found = 1; |
| last; |
| } |
| } |
| |
| printf "%s is not included in %s\n", $sym, $KABIDEPS if (!$found); |
| } |
| |
| my $output = $OUTPUT; |
| |
| open(OUT, ">", "$output") |
| || die "can't open >$output : $!"; |
| |
| my $total = @syms; |
| my $count; |
| for (@syms) { |
| if ($SYMVERS) { |
| check_sym($_); |
| } |
| elsif ($KABIDEPS) { |
| check_deps($_); |
| } |
| printf "\r%d/%d", ++$count, $total if ($VERBOSE); |
| } |
| printf "output to %s\n", $OUTPUT; |
| |
| close OUT; |