1 #!/usr/bin/perl 2 3 # This script is supposed to help use the param_mapper output. 4 # Give it a function and parameter and it lists the functions 5 # and parameters which are basically equivalent. 6 7 use strict; 8 9 sub usage() 10 { 11 print("call_tree.pl <smatch output file>\n"); 12 print("call_tree.pl finds paths between two functions\n"); 13 exit(1); 14 } 15 16 my %param_map; 17 18 my $UNKNOWN = 1; 19 my $NOTFOUND = 2; 20 my $FOUND = 3; 21 22 my $path; 23 24 sub print_path() 25 { 26 my $i = 0; 27 28 foreach my $func (@{$path}) { 29 if ($i++) { 30 print(", "); 31 } 32 print("$func"); 33 } 34 print("\n"); 35 print("\n"); 36 } 37 38 sub recurse($$) 39 { 40 my $link = shift; 41 my $target = shift; 42 my $found = 0; 43 44 if ($link =~ /$target/) { 45 print_path(); 46 return 1; 47 } 48 if (%{$param_map{$link}}->{found} == $NOTFOUND) { 49 return 0; 50 } 51 52 %{$param_map{$link}}->{found} = $NOTFOUND; 53 54 foreach my $l (@{%{$param_map{$link}}->{links}}){ 55 push(@{$path}, $l); 56 $found = recurse($l, $target); 57 if (!$found) { 58 pop(@{$path}); 59 } else { 60 last; 61 } 62 } 63 64 return $found; 65 } 66 67 sub search($$) 68 { 69 my $start_func = shift; 70 my $end_func = shift; 71 72 foreach my $link (@{%{$param_map{$start_func}}->{links}}){ 73 %{$param_map{$start_func}}->{found} = $NOTFOUND; 74 foreach my $l (@{%{$param_map{$start_func}}->{links}}){ 75 %{$param_map{$l}}->{found} = $NOTFOUND; 76 } 77 $path = [$start_func, $link]; 78 %{$param_map{$link}}->{found} = $UNKNOWN; 79 recurse($link, $end_func); 80 } 81 } 82 83 sub add_link($$) 84 { 85 my $one = shift; 86 my $two = shift; 87 88 if (!defined($param_map{$one})) { 89 $param_map{$one} = {found => $UNKNOWN, links => []}; 90 } 91 push @{$param_map{$one}->{links}}, $two; 92 } 93 94 sub load_all($) 95 { 96 my $file = shift; 97 98 open(FILE, "<$file"); 99 while (<FILE>) { 100 if (/.*?:\d+ (.*?)\(\) info: func_call (.*)/) { 101 add_link("$1", "$2"); 102 } 103 } 104 } 105 106 sub set_all_unknown() 107 { 108 my $i = 0; 109 110 foreach my $func (keys %param_map){ 111 %{$param_map{$func}}->{found} = $UNKNOWN; 112 } 113 } 114 115 my $file = shift(); 116 if (!$file) { 117 usage(); 118 } 119 120 if (! -e $file) { 121 printf("Error: $file does not exist.\n"); 122 exit(1); 123 } 124 125 print("Loading functions...\n"); 126 load_all($file); 127 128 while (1) { 129 my $start_func; 130 my $end_func; 131 132 print("Enter the start function: "); 133 $start_func = <STDIN>; 134 $start_func =~ s/^\s+|\s+$//g; 135 print("Enter the target function: "); 136 $end_func = <STDIN>; 137 $end_func =~ s/^\s+|\s+$//g; 138 139 140 print("$start_func to $end_func\n"); 141 if ($start_func =~ /./ && $end_func =~ /./) { 142 search($start_func, $end_func); 143 } 144 145 set_all_unknown(); 146 }