1#!/usr/bin/perl 2 3use strict; 4 5sub 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 13my %param_map; 14 15my $UNUSED = 0; 16my $USED = 1; 17 18sub print_link($) 19{ 20 my $link = shift; 21 22 $link =~ s/%/ /; 23 print "$link\n"; 24} 25 26sub 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 43sub follow($$) 44{ 45 my $f = shift; 46 my $p = shift; 47 48 recurse("$f%$p"); 49} 50 51sub 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 62sub 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 74sub set_all_unused() 75{ 76 foreach my $func (keys %param_map){ 77 ($param_map{$func}{used} = $UNUSED); 78 } 79 80} 81 82my $file = shift(); 83my $func = shift(); 84my $param = shift(); 85 86if (!defined($file) or !defined($func) or !defined($param)) { 87 usage(); 88} 89 90if (! -e $file) { 91 printf("Error: $file does not exist.\n"); 92 exit(1); 93} 94 95load_all($file); 96 97while (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} 107