/** * */ package jayhorn.utils; import soottocfg.cfg.Program; import soottocfg.cfg.SourceLocation; import soottocfg.cfg.expression.IdentifierExpression; import soottocfg.cfg.expression.literal.IntegerLiteral; import soottocfg.cfg.method.CfgBlock; import soottocfg.cfg.method.Method; import soottocfg.cfg.statement.AssignStatement; import soottocfg.cfg.statement.CallStatement; import soottocfg.cfg.statement.PullStatement; import soottocfg.cfg.statement.PushStatement; import soottocfg.cfg.statement.Statement; import soottocfg.cfg.type.IntType; import soottocfg.cfg.variable.Variable; /** * @author schaef * */ public class CallingContextTransformer { public CallingContextTransformer() { } /** * Add IDs to track the calling context. There are different * strategies to do that. Currently, this only implements the * approach of assigning a unqiue number to every call statement and * passing that as extra parameter to all callees. The callee * then adds that to all pushes and pulls. * @param p */ public void transform(Program p) { insertOneLevelCallingContext(p); } private static final String CALLCONTEXT = "__callCtx"; /** * Each call statement gets a unique ID. Every time we call a method, * we pass the ID of the caller as an argument. This ID is also * passed into every pull and push. * @param p */ private void insertOneLevelCallingContext(Program p) { //Register new ghost expression for the caller id. GhostRegister.v().ghostVariableMap.put(CALLCONTEXT, IntType.instance()); //start from 1 because zero is reserved for main. int uniqueNumber = 1; SourceLocation loc; for (Method m : p.getMethods()) { Variable callID = new Variable("callID", IntType.instance()); m.getInParams().add(callID); Variable callIdLocal = new Variable("cIdLocal", IntType.instance()); m.addLocalVariable(callIdLocal); loc = m.getLocation(); if (m.isProgramEntryPoint()) { m.getSource().getStatements().add(0, new AssignStatement(m.getLocation(), new IdentifierExpression(loc, callIdLocal), new IntegerLiteral(loc, 0))); } else { m.getSource().getStatements().add(0, new AssignStatement(m.getLocation(), new IdentifierExpression(loc, callIdLocal), new IdentifierExpression(loc, callID))); } for (CfgBlock b : m.vertexSet()) { for (Statement s : b.getStatements()) { loc = s.getSourceLocation(); if (s instanceof CallStatement) { CallStatement cs = (CallStatement)s; cs.getArguments().add(new IntegerLiteral(loc, uniqueNumber++)); } else if (s instanceof PullStatement) { PullStatement ps = (PullStatement)s; ps.getGhostExpressions().add(new IdentifierExpression(loc, callIdLocal)); } else if (s instanceof PushStatement) { PushStatement ps = (PushStatement)s; ps.getGhostExpressions().add(new IdentifierExpression(loc, callIdLocal)); } } } } // System.err.println(p); } }