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 7use strict; 8 9sub 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 16my %param_map; 17 18my $UNKNOWN = 1; 19my $NOTFOUND = 2; 20my $FOUND = 3; 21 22my $path; 23 24sub 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 38sub 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 67sub 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 83sub 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 94sub 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 106sub 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 115my $file = shift(); 116if (!$file) { 117 usage(); 118} 119 120if (! -e $file) { 121 printf("Error: $file does not exist.\n"); 122 exit(1); 123} 124 125print("Loading functions...\n"); 126load_all($file); 127 128while (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} 147