1 #!/usr/bin/perl
   2 
   3 use strict;
   4 
   5 sub usage()
   6 {
   7     print "$0 <smatch output file> <function> <parameter>\n";
   8     print "Give this program a function and parameter and it follows to find\n";
   9     print "how the parameter gets passed down to lower levels.\n'";
  10     exit(1);
  11 }
  12 
  13 my %param_map;
  14 
  15 my $UNUSED   = 0;
  16 my $USED     = 1;
  17 
  18 sub print_link($)
  19 {
  20     my $link = shift;
  21 
  22     $link =~ s/%/ /;
  23     print "$link\n";
  24 }
  25 
  26 sub recurse($)
  27 {
  28     my $link = shift;
  29 
  30     if ($param_map{$link}{used} == $USED) {
  31         return;
  32     }
  33     ${param_map}{$link}->{used} = $USED;
  34 
  35     print_link($link);
  36 
  37     foreach my $l (@{$param_map{$link}{links}}){
  38         recurse($l);
  39     }
  40 
  41 }
  42 
  43 sub follow($$)
  44 {
  45     my $f = shift;
  46     my $p = shift;
  47 
  48     recurse("$f%$p");
  49 }
  50 
  51 sub add_link($$)
  52 {
  53     my $one = shift;
  54     my $two = shift;
  55 
  56     if (!defined($param_map{$one})) {
  57         $param_map{$one} = {used => $UNUSED, links => []};
  58     }
  59     push @{$param_map{$one}{links}}, $two;
  60 }
  61 
  62 sub load_all($)
  63 {
  64     my $file = shift;
  65 
  66     open(FILE, "<$file");
  67     while (<FILE>) {
  68         if (/.*?:\d+ (.*?)\(\) info: param_mapper (\d+) => (.*?) (\d+)/) {
  69             add_link("$1%$2", "$3%$4");
  70         }
  71     }
  72 }
  73 
  74 sub set_all_unused()
  75 {
  76     foreach my $func (keys %param_map){
  77         ($param_map{$func}{used} = $UNUSED);
  78     }
  79 
  80 }
  81 
  82 my $file = shift();
  83 my $func = shift();
  84 my $param = shift();
  85 
  86 if (!defined($file) or !defined($func) or !defined($param)) {
  87     usage();
  88 }
  89 
  90 if (! -e $file) {
  91     printf("Error:  $file does not exist.\n");
  92     exit(1);
  93 }
  94 
  95 load_all($file);
  96 
  97 while (1) {
  98     follow($func, $param);
  99 
 100     $func = shift();
 101     $param = shift();
 102     if (!defined($func) || !defined($param)) {
 103         last;
 104     }
 105     set_all_unused();
 106 }