1*1f5207b7SJohn Levon#!/usr/bin/gvpr -f 2*1f5207b7SJohn Levon// Compute the reverse partition of the chosen function 3*1f5207b7SJohn Levon// 4*1f5207b7SJohn Levon// Run with graph ... | return-paths | subg-rev -a functionname 5*1f5207b7SJohn Levon 6*1f5207b7SJohn Levon 7*1f5207b7SJohn LevonBEGIN { 8*1f5207b7SJohn Levon // Find the immediate parent subgraph of this object 9*1f5207b7SJohn Levon graph_t find_owner(obj_t o, graph_t g) 10*1f5207b7SJohn Levon { 11*1f5207b7SJohn Levon graph_t g1; 12*1f5207b7SJohn Levon for (g1 = fstsubg(g); g1; g1 = nxtsubg(g1)) 13*1f5207b7SJohn Levon if(isIn(g1,o)) return g1; 14*1f5207b7SJohn Levon return NULL; 15*1f5207b7SJohn Levon } 16*1f5207b7SJohn Levon} 17*1f5207b7SJohn Levon 18*1f5207b7SJohn LevonBEG_G { 19*1f5207b7SJohn Levon graph_t calls[]; // Crude hash table for tracking who calls what 20*1f5207b7SJohn Levon graph_t sg = subg ($, "reachable"); 21*1f5207b7SJohn Levon graph_t target, g, g2; 22*1f5207b7SJohn Levon edge_t e; 23*1f5207b7SJohn Levon int i; 24*1f5207b7SJohn Levon 25*1f5207b7SJohn Levon $tvtype = TV_rev; 26*1f5207b7SJohn Levon 27*1f5207b7SJohn Levon // find the ep corresponding to ARG[0] 28*1f5207b7SJohn Levon for (g = fstsubg($G); g; g = nxtsubg(g)) { 29*1f5207b7SJohn Levon if(g.fun == ARGV[0]) { 30*1f5207b7SJohn Levon node_t n; 31*1f5207b7SJohn Levon n = node($,g.ep); 32*1f5207b7SJohn Levon $tvroot = n; 33*1f5207b7SJohn Levon n.style = "filled"; 34*1f5207b7SJohn Levon target = g; 35*1f5207b7SJohn Levon break; 36*1f5207b7SJohn Levon } 37*1f5207b7SJohn Levon } 38*1f5207b7SJohn Levon if(!target) { 39*1f5207b7SJohn Levon printf(2, "Function %s not found\n", ARGV[0]); 40*1f5207b7SJohn Levon exit(1); 41*1f5207b7SJohn Levon } 42*1f5207b7SJohn Levon 43*1f5207b7SJohn Levon // Add the incoming call edges to the allowed call list 44*1f5207b7SJohn Levon i = 0; 45*1f5207b7SJohn Levon for(e = fstin(n); e; e = nxtin(e)) { 46*1f5207b7SJohn Levon if (e.op = "call") { 47*1f5207b7SJohn Levon g2 = find_owner(e.tail, $G); 48*1f5207b7SJohn Levon calls[sprintf("%s%d", g2.name, ++i)] = g; 49*1f5207b7SJohn Levon } 50*1f5207b7SJohn Levon } 51*1f5207b7SJohn Levon} 52*1f5207b7SJohn Levon 53*1f5207b7SJohn Levon 54*1f5207b7SJohn LevonE [op == "ret"] { 55*1f5207b7SJohn Levon 56*1f5207b7SJohn Levon // This is a return edge. Allow the corresponding call 57*1f5207b7SJohn Levon g = find_owner(head, $G); 58*1f5207b7SJohn Levon i = 0; 59*1f5207b7SJohn Levon while(calls[sprintf("%s%d", g.name, ++i)]) { 60*1f5207b7SJohn Levon } 61*1f5207b7SJohn Levon calls[sprintf("%s%d", g.name, i)] = find_owner(tail, $G); 62*1f5207b7SJohn Levon g2 = find_owner(tail, $G); 63*1f5207b7SJohn Levon} 64*1f5207b7SJohn Levon 65*1f5207b7SJohn Levon 66*1f5207b7SJohn LevonN [split == 1] { 67*1f5207b7SJohn Levon 68*1f5207b7SJohn Levon // Ignore returns back to the target function 69*1f5207b7SJohn Levon for (e = fstin($); e; e = nxtin(e)) 70*1f5207b7SJohn Levon if (e.op == "ret" && isIn(target,e.tail)) 71*1f5207b7SJohn Levon delete($G,e); 72*1f5207b7SJohn Levon} 73*1f5207b7SJohn Levon 74*1f5207b7SJohn LevonN { 75*1f5207b7SJohn Levon $tvroot = NULL; 76*1f5207b7SJohn Levon 77*1f5207b7SJohn Levon for (e = fstin($); e; e = nxtin(e)) { 78*1f5207b7SJohn Levon if (e.op == "call") { 79*1f5207b7SJohn Levon int found = 0; 80*1f5207b7SJohn Levon g = find_owner(e.tail, $G); 81*1f5207b7SJohn Levon i = 0; 82*1f5207b7SJohn Levon while(calls[sprintf("%s%d", g.name, ++i)]) { 83*1f5207b7SJohn Levon if (isIn(calls[sprintf("%s%d", g.name, i)],e.head)) 84*1f5207b7SJohn Levon found = 1; 85*1f5207b7SJohn Levon } 86*1f5207b7SJohn Levon g2 = find_owner(e.head, $G); 87*1f5207b7SJohn Levon if (!found) delete($G, e); 88*1f5207b7SJohn Levon } 89*1f5207b7SJohn Levon } 90*1f5207b7SJohn Levon 91*1f5207b7SJohn Levon for (g = fstsubg($G); g; g = nxtsubg(g)) { 92*1f5207b7SJohn Levon if(isIn(g,$) && g != sg) { 93*1f5207b7SJohn Levon subnode (copy(sg, g), $); 94*1f5207b7SJohn Levon } 95*1f5207b7SJohn Levon } 96*1f5207b7SJohn Levon} 97*1f5207b7SJohn Levon 98*1f5207b7SJohn LevonEND_G { 99*1f5207b7SJohn Levon induce(sg); 100*1f5207b7SJohn Levon write(sg); 101*1f5207b7SJohn Levon} 102