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