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