/* case_label = {constant} case minus? integer_constant | {default} default; */ public void outAConstantCaseLabel(AConstantCaseLabel node) { String s = (String) mProductions.removeLast(); int sign = 1; if (node.getMinus() != null) sign = -1; if (s.endsWith("L")) { mProductions.addLast(LongConstant.v(sign * Long.parseLong(s.substring(0, s.length() - 1)))); } else mProductions.addLast(IntConstant.v(sign * Integer.parseInt(s))); }
public void outAIntegerConstant(AIntegerConstant node) { String s = (String) mProductions.removeLast(); StringBuffer buf = new StringBuffer(); if (node.getMinus() != null) buf.append('-'); buf.append(s); s = buf.toString(); if (s.endsWith("L")) { mProductions.addLast(LongConstant.v(Long.parseLong(s.substring(0, s.length() - 1)))); } else mProductions.addLast(IntConstant.v(Integer.parseInt(s))); }
public class Walker extends DepthFirstAdapter { boolean debug = false; LinkedList mProductions = new LinkedList(); SootClass mSootClass = null; Map mLocals = null; Value mValue = IntConstant.v(1); Map mLabelToStmtMap; // maps a label to the stmt following it in the jimple source Map mLabelToPatchList; // maps a label to the a list of stmts that refer to the label (ie goto // lableX) protected SootResolver mResolver; public Walker(SootResolver resolver) { mResolver = resolver; if (debug) { mProductions = new LinkedList() { public Object removeLast() { Object o = super.removeLast(); if (debug) G.v().out.println("popped: " + o); return o; } }; } } public Walker(SootClass sc, SootResolver resolver) { mSootClass = sc; mResolver = resolver; } public void outStart(Start node) { SootClass c = (SootClass) mProductions.removeLast(); } public SootClass getSootClass() { if (mSootClass == null) throw new RuntimeException("did not parse class yet...."); return mSootClass; } /* file = modifier* file_type class_name extends_clause? implements_clause? file_body; */ public void inAFile(AFile node) { if (debug) G.v().out.println("reading class " + node.getClassName()); } public void caseAFile(AFile node) { inAFile(node); { Object temp[] = node.getModifier().toArray(); for (int i = 0; i < temp.length; i++) { ((PModifier) temp[i]).apply(this); } } if (node.getFileType() != null) { node.getFileType().apply(this); } if (node.getClassName() != null) { node.getClassName().apply(this); } String className = (String) mProductions.removeLast(); if (mSootClass == null) { mSootClass = new SootClass(className); mSootClass.setResolvingLevel(SootClass.BODIES); } else { if (!mSootClass.getName().equals(className)) throw new RuntimeException( "Invalid SootClass for this JimpleAST. The SootClass provided is of type: >" + mSootClass.getName() + "< whereas this parse tree is for type: >" + className + "<"); } if (node.getExtendsClause() != null) { node.getExtendsClause().apply(this); } if (node.getImplementsClause() != null) { node.getImplementsClause().apply(this); } if (node.getFileBody() != null) { node.getFileBody().apply(this); } outAFile(node); } public void outAFile(AFile node) { // not not pop members; they have been taken care of. List implementsList = null; String superClass = null; String classType = null; if (node.getImplementsClause() != null) { implementsList = (List) mProductions.removeLast(); } if (node.getExtendsClause() != null) { superClass = (String) mProductions.removeLast(); } classType = (String) mProductions.removeLast(); int modifierCount = node.getModifier().size(); int modifierFlags = processModifiers(node.getModifier()); if (classType.equals("interface")) modifierFlags |= Modifier.INTERFACE; mSootClass.setModifiers(modifierFlags); if (superClass != null) { mSootClass.setSuperclass(mResolver.makeClassRef(superClass)); } if (implementsList != null) { Iterator implIt = implementsList.iterator(); while (implIt.hasNext()) { SootClass interfaceClass = mResolver.makeClassRef((String) implIt.next()); mSootClass.addInterface(interfaceClass); } } mProductions.addLast(mSootClass); } /* member = {field} modifier* type name semicolon | {method} modifier* type name l_paren parameter_list? r_paren throws_clause? method_body; */ public void outAFieldMember(AFieldMember node) { int modifier = 0; Type type = null; String name = null; name = (String) mProductions.removeLast(); type = (Type) mProductions.removeLast(); modifier = processModifiers(node.getModifier()); SootField f = new SootField(name, type, modifier); mSootClass.addField(f); } public void outAMethodMember(AMethodMember node) { int modifier = 0; Type type; String name; List parameterList = null; List throwsClause = null; JimpleBody methodBody = null; if (node.getMethodBody() instanceof AFullMethodBody) methodBody = (JimpleBody) mProductions.removeLast(); if (node.getThrowsClause() != null) throwsClause = (List) mProductions.removeLast(); if (node.getParameterList() != null) { parameterList = (List) mProductions.removeLast(); } else { parameterList = new ArrayList(); } Object o = mProductions.removeLast(); name = (String) o; type = (Type) mProductions.removeLast(); modifier = processModifiers(node.getModifier()); SootMethod method; if (throwsClause != null) method = new SootMethod(name, parameterList, type, modifier, throwsClause); else method = new SootMethod(name, parameterList, type, modifier); mSootClass.addMethod(method); if (method.isConcrete()) { methodBody.setMethod(method); method.setActiveBody(methodBody); } else if (node.getMethodBody() instanceof AFullMethodBody) throw new RuntimeException("Impossible: !concrete => ! instanceof"); } /* type = {void} void | {novoid} nonvoid_type; */ public void outAVoidType(AVoidType node) { mProductions.addLast(VoidType.v()); } /* nonvoid_type = {base} base_type_no_name array_brackets*; {quoted} quoted_name array_brackets* | {ident} identifier array_brackets* | {full_ident} full_identifier array_brackets*; */ public void outABaseNonvoidType(ABaseNonvoidType node) { Type t = (Type) mProductions.removeLast(); int dim = node.getArrayBrackets().size(); if (dim > 0) t = ArrayType.v(t, dim); mProductions.addLast(t); } public void outAQuotedNonvoidType(AQuotedNonvoidType node) { String typeName = (String) mProductions.removeLast(); Type t = RefType.v(typeName); int dim = node.getArrayBrackets().size(); if (dim > 0) t = ArrayType.v(t, dim); mProductions.addLast(t); } public void outAIdentNonvoidType(AIdentNonvoidType node) { String typeName = (String) mProductions.removeLast(); Type t = RefType.v(typeName); int dim = node.getArrayBrackets().size(); if (dim > 0) t = ArrayType.v(t, dim); mProductions.addLast(t); } public void outAFullIdentNonvoidType(AFullIdentNonvoidType node) { String typeName = (String) mProductions.removeLast(); Type t = RefType.v(typeName); int dim = node.getArrayBrackets().size(); if (dim > 0) t = ArrayType.v(t, dim); mProductions.addLast(t); } /* base_type_no_name = {boolean} boolean | {byte} byte | {char} char | {short} short | {int} int | {long} long | {float} float | {double} double | {null} null_type; */ public void outABooleanBaseTypeNoName(ABooleanBaseTypeNoName node) { mProductions.addLast(BooleanType.v()); } public void outAByteBaseTypeNoName(AByteBaseTypeNoName node) { mProductions.addLast(ByteType.v()); } public void outACharBaseTypeNoName(ACharBaseTypeNoName node) { mProductions.addLast(CharType.v()); } public void outAShortBaseTypeNoName(AShortBaseTypeNoName node) { mProductions.addLast(ShortType.v()); } public void outAIntBaseTypeNoName(AIntBaseTypeNoName node) { mProductions.addLast(IntType.v()); } public void outALongBaseTypeNoName(ALongBaseTypeNoName node) { mProductions.addLast(LongType.v()); } public void outAFloatBaseTypeNoName(AFloatBaseTypeNoName node) { mProductions.addLast(FloatType.v()); } public void outADoubleBaseTypeNoName(ADoubleBaseTypeNoName node) { mProductions.addLast(DoubleType.v()); } public void outANullBaseTypeNoName(ANullBaseTypeNoName node) { mProductions.addLast(NullType.v()); } /* base_type = {boolean} boolean | {byte} byte | {char} char | {short} short | {int} int | {long} long | {float} float | {double} double | {null} null_type | {class_name} class_name; */ public void outABooleanBaseType(ABooleanBaseType node) { mProductions.addLast(BooleanType.v()); } public void outAByteBaseType(AByteBaseType node) { mProductions.addLast(ByteType.v()); } public void outACharBaseType(ACharBaseType node) { mProductions.addLast(CharType.v()); } public void outAShortBaseType(AShortBaseType node) { mProductions.addLast(ShortType.v()); } public void outAIntBaseType(AIntBaseType node) { mProductions.addLast(IntType.v()); } public void outALongBaseType(ALongBaseType node) { mProductions.addLast(LongType.v()); } public void outAFloatBaseType(AFloatBaseType node) { mProductions.addLast(FloatType.v()); } public void outADoubleBaseType(ADoubleBaseType node) { mProductions.addLast(DoubleType.v()); } public void outANullBaseType(ANullBaseType node) { mProductions.addLast(NullType.v()); } public void outAClassNameBaseType(AClassNameBaseType node) { String type = (String) mProductions.removeLast(); if (type.equals("int")) throw new RuntimeException(); mProductions.addLast(RefType.v(type)); } /* method_body = {empty} semicolon | {full} l_brace declaration* statement* catch_clause* r_brace; */ public void inAFullMethodBody(AFullMethodBody node) { mLocals = new HashMap(); mLabelToStmtMap = new HashMap(); mLabelToPatchList = new HashMap(); } public void outAFullMethodBody(AFullMethodBody node) { Object catchClause = null; JimpleBody jBody = Jimple.v().newBody(); if (node.getCatchClause() != null) { int size = node.getCatchClause().size(); for (int i = 0; i < size; i++) jBody.getTraps().addFirst((Trap) mProductions.removeLast()); } if (node.getStatement() != null) { int size = node.getStatement().size(); Unit lastStmt = null; for (int i = 0; i < size; i++) { Object o = mProductions.removeLast(); if (o instanceof Unit) { jBody.getUnits().addFirst(o); lastStmt = (Unit) o; } else if (o instanceof String) { if (lastStmt == null) throw new RuntimeException("impossible"); mLabelToStmtMap.put(o, lastStmt); } else throw new RuntimeException("impossible"); } } if (node.getDeclaration() != null) { int size = node.getDeclaration().size(); for (int i = 0; i < size; i++) { List localList = (List) mProductions.removeLast(); int listSize = localList.size(); for (int j = listSize - 1; j >= 0; j--) jBody.getLocals().addFirst(localList.get(j)); } } Iterator it = mLabelToPatchList.keySet().iterator(); while (it.hasNext()) { String label = (String) it.next(); Unit target = (Unit) mLabelToStmtMap.get(label); Iterator patchIt = ((List) mLabelToPatchList.get(label)).iterator(); while (patchIt.hasNext()) { UnitBox box = (UnitBox) patchIt.next(); box.setUnit(target); } } /* Iterator it = mLabelToStmtMap.keySet().iterator(); while(it.hasNext()) { String label = (String) it.next(); Unit target = (Unit) mLabelToStmtMap.get(label); List l = (List) mLabelToPatchList.get(label); if(l != null) { Iterator patchIt = l.iterator(); while(patchIt.hasNext()) { UnitBox box = (UnitBox) patchIt.next(); box.setUnit(target); } } } */ mProductions.addLast(jBody); } public void outANovoidType(ANovoidType node) {} /* parameter_list = {single} parameter | {multi} parameter comma parameter_list; */ public void outASingleParameterList(ASingleParameterList node) { List l = new ArrayList(); l.add((Type) mProductions.removeLast()); mProductions.addLast(l); } public void outAMultiParameterList(AMultiParameterList node) { List l = (List) mProductions.removeLast(); l.add(0, (Type) mProductions.removeLast()); mProductions.addLast(l); } /* arg_list = {single} immediate | {multi} immediate comma arg_list; */ public void outASingleArgList(ASingleArgList node) { List l = new ArrayList(); l.add((Value) mProductions.removeLast()); mProductions.addLast(l); } public void outAMultiArgList(AMultiArgList node) { List l = (List) mProductions.removeLast(); l.add(0, (Value) mProductions.removeLast()); mProductions.addLast(l); } /* class_name_list = {class_name_single} class_name | {class_name_multi} class_name comma class_name_list; */ public void outAClassNameSingleClassNameList(AClassNameSingleClassNameList node) { List l = new ArrayList(); l.add((String) mProductions.removeLast()); mProductions.addLast(l); } public void outAClassNameMultiClassNameList(AClassNameMultiClassNameList node) { List l = (List) mProductions.removeLast(); l.add(0, (String) mProductions.removeLast()); mProductions.addLast(l); } /* file_type = {class} [theclass]:class | {interface} interface; */ public void outAClassFileType(AClassFileType node) { mProductions.addLast("class"); } public void outAInterfaceFileType(AInterfaceFileType node) { mProductions.addLast("interface"); } /* catch_clause = catch [name]:class_name from [from_label]:label_name to [to_label]:label_name with [with_label]:label_name semicolon; */ // public void caseACatchClause(ACatchClause node){} public void outACatchClause(ACatchClause node) { String exceptionName; UnitBox withUnit, fromUnit, toUnit; withUnit = Jimple.v().newStmtBox(null); addBoxToPatch((String) mProductions.removeLast(), withUnit); toUnit = Jimple.v().newStmtBox(null); addBoxToPatch((String) mProductions.removeLast(), toUnit); fromUnit = Jimple.v().newStmtBox(null); addBoxToPatch((String) mProductions.removeLast(), fromUnit); exceptionName = (String) mProductions.removeLast(); Trap trap = Jimple.v().newTrap(mResolver.makeClassRef(exceptionName), fromUnit, toUnit, withUnit); mProductions.addLast(trap); } /* declaration = jimple_type local_name_list semicolon; */ public void outADeclaration(ADeclaration node) { List localNameList = (List) mProductions.removeLast(); Type type = (Type) mProductions.removeLast(); Iterator it = localNameList.iterator(); List localList = new ArrayList(); while (it.hasNext()) { Local l = Jimple.v().newLocal((String) it.next(), type); mLocals.put(l.getName(), l); localList.add(l); } mProductions.addLast(localList); } /* jimple_type = {unknown} unknown | {nonvoid} nonvoid_type; */ public void outAUnknownJimpleType(AUnknownJimpleType node) { mProductions.addLast(UnknownType.v()); } /* local_name_list = {single} local_name | {multi} local_name comma local_name_list; */ public void outASingleLocalNameList(ASingleLocalNameList node) { List l = new ArrayList(); l.add((String) mProductions.removeLast()); mProductions.addLast(l); } public void outAMultiLocalNameList(AMultiLocalNameList node) { List l = (List) mProductions.removeLast(); l.add(0, (String) mProductions.removeLast()); mProductions.addLast(l); } /* statement = {label} label_name colon | {breakpoint} breakpoint semicolon | {entermonitor} entermonitor immediate semicolon | {exitmonitor} exitmonitor immediate semicolon | {switch} switch l_paren immediate r_paren l_brace case_stmt+ r_brace semicolon | {identity} local_name colon_equals at_identifier type semicolon | {identity_no_type} local_name colon_equals at_identifier semicolon | {assign} variable equals expression semicolon | {if} if bool_expr goto_stmt | {goto} goto_stmt | {nop} nop semicolon | {ret} ret immediate? semicolon | {return} return immediate? semicolon | {throw} throw immediate semicolon | {invoke} invoke_expr semicolon; */ public void outALabelStatement(ALabelStatement node) {} public void outABreakpointStatement(ABreakpointStatement node) { Unit u = Jimple.v().newBreakpointStmt(); mProductions.addLast(u); } public void outAEntermonitorStatement(AEntermonitorStatement node) { Value op = (Value) mProductions.removeLast(); Unit u = Jimple.v().newEnterMonitorStmt(op); mProductions.addLast(u); } public void outAExitmonitorStatement(AExitmonitorStatement node) { Value op = (Value) mProductions.removeLast(); Unit u = Jimple.v().newExitMonitorStmt(op); mProductions.addLast(u); } /* case_label = {constant} case minus? integer_constant | {default} default; */ /* case_stmt = case_label colon goto_stmt; */ public void outACaseStmt(ACaseStmt node) { String labelName = (String) mProductions.removeLast(); UnitBox box = Jimple.v().newStmtBox(null); addBoxToPatch(labelName, box); Value labelValue = null; if (node.getCaseLabel() instanceof AConstantCaseLabel) labelValue = (Value) mProductions.removeLast(); // if labelValue == null, this is the default label. if (labelValue == null) mProductions.addLast(box); else { Object[] valueTargetPair = new Object[2]; valueTargetPair[0] = labelValue; valueTargetPair[1] = box; mProductions.addLast(valueTargetPair); } } public void outATableswitchStatement(ATableswitchStatement node) { List targets = new ArrayList(); UnitBox defaultTarget = null; int lowIndex = 0, highIndex = 0; if (node.getCaseStmt() != null) { int size = node.getCaseStmt().size(); for (int i = 0; i < size; i++) { Object valueTargetPair = mProductions.removeLast(); if (valueTargetPair instanceof UnitBox) { if (defaultTarget != null) throw new RuntimeException("error: can't ;have more than 1 default stmt"); defaultTarget = (UnitBox) valueTargetPair; } else { Object[] pair = (Object[]) valueTargetPair; if ((i == 0 && defaultTarget == null) || (i == 1 && defaultTarget != null)) highIndex = ((IntConstant) pair[0]).value; if (i == (size - 1)) lowIndex = ((IntConstant) pair[0]).value; targets.add(0, pair[1]); } } } else { throw new RuntimeException("error: switch stmt has no case stmts"); } Value key = (Value) mProductions.removeLast(); Unit switchStmt = Jimple.v().newTableSwitchStmt(key, lowIndex, highIndex, targets, defaultTarget); mProductions.addLast(switchStmt); } public void outALookupswitchStatement(ALookupswitchStatement node) { List lookupValues = new ArrayList(); List targets = new ArrayList(); UnitBox defaultTarget = null; if (node.getCaseStmt() != null) { int size = node.getCaseStmt().size(); for (int i = 0; i < size; i++) { Object valueTargetPair = mProductions.removeLast(); if (valueTargetPair instanceof UnitBox) { if (defaultTarget != null) throw new RuntimeException("error: can't ;have more than 1 default stmt"); defaultTarget = (UnitBox) valueTargetPair; } else { Object[] pair = (Object[]) valueTargetPair; lookupValues.add(0, pair[0]); targets.add(0, pair[1]); } } } else { throw new RuntimeException("error: switch stmt has no case stmts"); } Value key = (Value) mProductions.removeLast(); Unit switchStmt = Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget); mProductions.addLast(switchStmt); } public void outAIdentityStatement(AIdentityStatement node) { Type identityRefType = (Type) mProductions.removeLast(); String atClause = (String) mProductions.removeLast(); Value local = (Value) mLocals.get(mProductions.removeLast()); // the local ref from it's identifier Value ref = null; if (atClause.startsWith("@this")) { ref = Jimple.v().newThisRef((RefType) identityRefType); } else if (atClause.startsWith("@parameter")) { int index = Integer.parseInt(atClause.substring(10, atClause.length() - 1)); ref = Jimple.v().newParameterRef(identityRefType, index); } else throw new RuntimeException( "shouldn't @caughtexception be handled by outAIdentityNoTypeStatement: got" + atClause); Unit u = Jimple.v().newIdentityStmt(local, ref); mProductions.addLast(u); } public void outAIdentityNoTypeStatement(AIdentityNoTypeStatement node) { mProductions.removeLast(); // get rid of @caughtexception string presently on top of the stack Value local = (Value) mLocals.get(mProductions.removeLast()); // the local ref from it's identifier Unit u = Jimple.v().newIdentityStmt(local, Jimple.v().newCaughtExceptionRef()); mProductions.addLast(u); } public void outAAssignStatement(AAssignStatement node) { Value rvalue = (Value) mProductions.removeLast(); Value variable = (Value) mProductions.removeLast(); Unit u = Jimple.v().newAssignStmt(variable, rvalue); mProductions.addLast(u); } public void outAIfStatement(AIfStatement node) { String targetLabel = (String) mProductions.removeLast(); Value condition = (Value) mProductions.removeLast(); UnitBox box = Jimple.v().newStmtBox(null); Unit u = Jimple.v().newIfStmt(condition, box); addBoxToPatch(targetLabel, box); mProductions.addLast(u); } public void outAReturnStatement(AReturnStatement node) { Value v; Stmt s = null; if (node.getImmediate() != null) { v = (Value) mProductions.removeLast(); s = Jimple.v().newReturnStmt(v); } else { s = Jimple.v().newReturnVoidStmt(); } mProductions.addLast(s); } public void outAGotoStatement(AGotoStatement node) { String targetLabel = (String) mProductions.removeLast(); UnitBox box = Jimple.v().newStmtBox(null); Unit branch = Jimple.v().newGotoStmt(box); addBoxToPatch(targetLabel, box); mProductions.addLast(branch); } public void outANopStatement(ANopStatement node) { Unit u = Jimple.v().newNopStmt(); mProductions.addLast(u); } public void outARetStatement(ARetStatement node) { throw new RuntimeException("ret not yet implemented."); } public void outAThrowStatement(AThrowStatement node) { Value op = (Value) mProductions.removeLast(); Unit u = Jimple.v().newThrowStmt(op); mProductions.addLast(u); } public void outAInvokeStatement(AInvokeStatement node) { Value op = (Value) mProductions.removeLast(); Unit u = Jimple.v().newInvokeStmt(op); mProductions.addLast(u); } /* case_label = {constant} case minus? integer_constant | {default} default; */ public void outAConstantCaseLabel(AConstantCaseLabel node) { String s = (String) mProductions.removeLast(); int sign = 1; if (node.getMinus() != null) sign = -1; if (s.endsWith("L")) { mProductions.addLast(LongConstant.v(sign * Long.parseLong(s.substring(0, s.length() - 1)))); } else mProductions.addLast(IntConstant.v(sign * Integer.parseInt(s))); } /* immediate = {local} local_name | {constant} constant; */ public void outALocalImmediate(ALocalImmediate node) { String local = (String) mProductions.removeLast(); Local l = (Local) mLocals.get(local); if (l == null) throw new RuntimeException("did not find local: " + local); mProductions.addLast(l); } /* constant = {integer} minus? integer_constant | {float} minus? float_constant | {string} string_constant | {null} null; */ public void outANullConstant(ANullConstant node) { mProductions.addLast(NullConstant.v()); } public void outAIntegerConstant(AIntegerConstant node) { String s = (String) mProductions.removeLast(); StringBuffer buf = new StringBuffer(); if (node.getMinus() != null) buf.append('-'); buf.append(s); s = buf.toString(); if (s.endsWith("L")) { mProductions.addLast(LongConstant.v(Long.parseLong(s.substring(0, s.length() - 1)))); } else mProductions.addLast(IntConstant.v(Integer.parseInt(s))); } public void outAStringConstant(AStringConstant node) { String s = (String) mProductions.removeLast(); mProductions.addLast(StringConstant.v(s)); /* try { String t = StringTools.getUnEscapedStringOf(s); mProductions.push(StringConstant.v(t)); } catch(RuntimeException e) { G.v().out.println(s); throw e; } */ } public void outAClzzConstant(AClzzConstant node) { String s = (String) mProductions.removeLast(); mProductions.addLast(ClassConstant.v(s)); } /* ('#' (('-'? 'Infinity') | 'NaN') ('f' | 'F')? ) ; */ public void outAFloatConstant(AFloatConstant node) { String s = (String) mProductions.removeLast(); boolean isDouble = true; float value = 0; double dvalue = 0; if (s.endsWith("f") || s.endsWith("F")) isDouble = false; if (s.charAt(0) == '#') { if (s.charAt(1) == '-') { if (isDouble) dvalue = Double.NEGATIVE_INFINITY; else value = Float.NEGATIVE_INFINITY; } else if (s.charAt(1) == 'I') { if (isDouble) dvalue = Double.POSITIVE_INFINITY; else value = Float.POSITIVE_INFINITY; } else { if (isDouble) dvalue = Double.NaN; else value = Float.NaN; } } else { StringBuffer buf = new StringBuffer(); if (node.getMinus() != null) buf.append('-'); buf.append(s); s = buf.toString(); if (isDouble) dvalue = Double.parseDouble(s); else value = Float.parseFloat(s); } Object res; if (isDouble) res = DoubleConstant.v(dvalue); else res = FloatConstant.v(value); mProductions.addLast(res); } /* binop_expr = [left]:immediate binop [right]:immediate; */ public void outABinopExpr(ABinopExpr node) { Value right = (Value) mProductions.removeLast(); BinopExpr expr = (BinopExpr) mProductions.removeLast(); Value left = (Value) mProductions.removeLast(); expr.setOp1(left); expr.setOp2(right); mProductions.addLast(expr); } public void outABinopBoolExpr(ABinopBoolExpr node) {} public void outAUnopExpression(AUnopExpression node) {} /* binop = {and} and | {or} or | {xor} xor | {mod} mod | {cmp} cmp | {cmpg} cmpg | {cmpl} cmpl | {cmpeq} cmpeq | {cmpne} cmpne | {cmpgt} cmpgt | {cmpge} cmpge | {cmplt} cmplt | {cmple} cmple | {shl} shl | {shr} shr | {ushr} ushr | {plus} plus | {minus} minus | {mult} mult | {div} div; */ public void outAAndBinop(AAndBinop node) { mProductions.addLast(Jimple.v().newAndExpr(mValue, mValue)); } public void outAOrBinop(AOrBinop node) { mProductions.addLast(Jimple.v().newOrExpr(mValue, mValue)); } public void outAXorBinop(AXorBinop node) { mProductions.addLast(Jimple.v().newXorExpr(mValue, mValue)); } public void outAModBinop(AModBinop node) { mProductions.addLast(Jimple.v().newRemExpr(mValue, mValue)); } public void outACmpBinop(ACmpBinop node) { mProductions.addLast(Jimple.v().newCmpExpr(mValue, mValue)); } public void outACmpgBinop(ACmpgBinop node) { mProductions.addLast(Jimple.v().newCmpgExpr(mValue, mValue)); } public void outACmplBinop(ACmplBinop node) { mProductions.addLast(Jimple.v().newCmplExpr(mValue, mValue)); } public void outACmpeqBinop(ACmpeqBinop node) { mProductions.addLast(Jimple.v().newEqExpr(mValue, mValue)); } public void outACmpneBinop(ACmpneBinop node) { mProductions.addLast(Jimple.v().newNeExpr(mValue, mValue)); } public void outACmpgtBinop(ACmpgtBinop node) { mProductions.addLast(Jimple.v().newGtExpr(mValue, mValue)); } public void outACmpgeBinop(ACmpgeBinop node) { mProductions.addLast(Jimple.v().newGeExpr(mValue, mValue)); } public void outACmpltBinop(ACmpltBinop node) { mProductions.addLast(Jimple.v().newLtExpr(mValue, mValue)); } public void outACmpleBinop(ACmpleBinop node) { mProductions.addLast(Jimple.v().newLeExpr(mValue, mValue)); } public void outAShlBinop(AShlBinop node) { mProductions.addLast(Jimple.v().newShlExpr(mValue, mValue)); } public void outAShrBinop(AShrBinop node) { mProductions.addLast(Jimple.v().newShrExpr(mValue, mValue)); } public void outAUshrBinop(AUshrBinop node) { mProductions.addLast(Jimple.v().newUshrExpr(mValue, mValue)); } public void outAPlusBinop(APlusBinop node) { mProductions.addLast(Jimple.v().newAddExpr(mValue, mValue)); } public void outAMinusBinop(AMinusBinop node) { mProductions.addLast(Jimple.v().newSubExpr(mValue, mValue)); } public void outAMultBinop(AMultBinop node) { mProductions.addLast(Jimple.v().newMulExpr(mValue, mValue)); } public void outADivBinop(ADivBinop node) { mProductions.addLast(Jimple.v().newDivExpr(mValue, mValue)); } /* throws_clause = throws class_name_list; */ public void outAThrowsClause(AThrowsClause node) { List l = (List) mProductions.removeLast(); Iterator it = l.iterator(); List exceptionClasses = new ArrayList(l.size()); while (it.hasNext()) { String className = (String) it.next(); exceptionClasses.add(mResolver.makeClassRef(className)); } mProductions.addLast(exceptionClasses); } /* variable = {reference} reference | {local} local_name; */ public void outALocalVariable(ALocalVariable node) { String local = (String) mProductions.removeLast(); Local l = (Local) mLocals.get(local); if (l == null) throw new RuntimeException("did not find local: " + local); mProductions.addLast(l); } /* public void caseAReferenceVariable(AReferenceVariable node) { } */ /* array_ref = identifier fixed_array_descriptor; */ public void outAArrayRef(AArrayRef node) { Value immediate = (Value) mProductions.removeLast(); String identifier = (String) mProductions.removeLast(); Local l = (Local) mLocals.get(identifier); if (l == null) throw new RuntimeException("did not find local: " + identifier); mProductions.addLast(Jimple.v().newArrayRef(l, immediate)); } /* field_ref = {local} local_name dot field_signature | {sig} field_signature; */ public void outALocalFieldRef(ALocalFieldRef node) { SootFieldRef field = (SootFieldRef) mProductions.removeLast(); String local = (String) mProductions.removeLast(); Local l = (Local) mLocals.get(local); if (l == null) throw new RuntimeException("did not find local: " + local); mProductions.addLast(Jimple.v().newInstanceFieldRef(l, field)); } public void outASigFieldRef(ASigFieldRef node) { SootFieldRef field = (SootFieldRef) mProductions.removeLast(); field = Scene.v().makeFieldRef(field.declaringClass(), field.name(), field.type(), true); mProductions.addLast(Jimple.v().newStaticFieldRef(field)); } /* field_signature = cmplt [class_name]:class_name [first]:colon type [field_name]:name cmpgt; */ public void outAFieldSignature(AFieldSignature node) { String className, fieldName; Type t; fieldName = (String) mProductions.removeLast(); t = (Type) mProductions.removeLast(); className = (String) mProductions.removeLast(); SootClass cl = mResolver.makeClassRef(className); SootFieldRef field = Scene.v().makeFieldRef(cl, fieldName, t, false); mProductions.addLast(field); } /* expression = {new} new_expr | {cast} l_paren nonvoid_type r_paren local_name | {instanceof} immediate instanceof nonvoid_type | {invoke} invoke_expr | {reference} reference | {binop} binop_expr | {unop} unop_expr | {immediate} immediate; */ public void outACastExpression(ACastExpression node) { Value val = (Value) mProductions.removeLast(); Type type = (Type) mProductions.removeLast(); mProductions.addLast(Jimple.v().newCastExpr(val, type)); } public void outAInstanceofExpression(AInstanceofExpression node) { Type nonvoidType = (Type) mProductions.removeLast(); Value immediate = (Value) mProductions.removeLast(); mProductions.addLast(Jimple.v().newInstanceOfExpr(immediate, nonvoidType)); } /* unop_expr = unop immediate; */ public void outAUnopExpr(AUnopExpr node) { Value v = (Value) mProductions.removeLast(); UnopExpr expr = (UnopExpr) mProductions.removeLast(); expr.setOp(v); mProductions.addLast(expr); } /* unop = {lengthof} lengthof | {neg} neg; */ public void outALengthofUnop(ALengthofUnop node) { mProductions.addLast(Jimple.v().newLengthExpr(mValue)); } public void outANegUnop(ANegUnop node) { mProductions.addLast(Jimple.v().newNegExpr(mValue)); } /* invoke_expr = {nonstatic} nonstatic_invoke local_name dot method_signature l_paren arg_list? r_paren | {static} staticinvoke method_signature l_paren arg_list? r_paren; */ public void outANonstaticInvokeExpr(ANonstaticInvokeExpr node) { List args; if (node.getArgList() != null) args = (List) mProductions.removeLast(); else args = new ArrayList(); SootMethodRef method = (SootMethodRef) mProductions.removeLast(); String local = (String) mProductions.removeLast(); Local l = (Local) mLocals.get(local); if (l == null) throw new RuntimeException("did not find local: " + local); Node invokeType = (Node) node.getNonstaticInvoke(); Expr invokeExpr; if (invokeType instanceof ASpecialNonstaticInvoke) { invokeExpr = Jimple.v().newSpecialInvokeExpr(l, method, args); } else if (invokeType instanceof AVirtualNonstaticInvoke) { invokeExpr = Jimple.v().newVirtualInvokeExpr(l, method, args); } else { if (debug) if (!(invokeType instanceof AInterfaceNonstaticInvoke)) throw new RuntimeException("expected interface invoke."); invokeExpr = Jimple.v().newInterfaceInvokeExpr(l, method, args); } mProductions.addLast(invokeExpr); } public void outAStaticInvokeExpr(AStaticInvokeExpr node) { List args; if (node.getArgList() != null) args = (List) mProductions.removeLast(); else args = new ArrayList(); SootMethodRef method = (SootMethodRef) mProductions.removeLast(); method = Scene.v() .makeMethodRef( method.declaringClass(), method.name(), method.parameterTypes(), method.returnType(), true); mProductions.addLast(Jimple.v().newStaticInvokeExpr(method, args)); } /* method_signature = cmplt [class_name]:class_name [first]:colon type [method_name]:name l_paren parameter_list? r_paren cmpgt; */ public void outAMethodSignature(AMethodSignature node) { String className, methodName; List parameterList = new ArrayList(); Type returnType; if (node.getParameterList() != null) parameterList = (List) mProductions.removeLast(); methodName = (String) mProductions.removeLast(); Type type = (Type) mProductions.removeLast(); className = (String) mProductions.removeLast(); SootClass sootClass = mResolver.makeClassRef(className); SootMethodRef sootMethod = Scene.v().makeMethodRef(sootClass, methodName, parameterList, type, false); mProductions.addLast(sootMethod); } /* new_expr = {simple} new base_type | {array} newarray l_paren nonvoid_type r_paren fixed_array_descriptor | {multi} newmultiarray l_paren base_type r_paren array_descriptor+; */ public void outASimpleNewExpr(ASimpleNewExpr node) { mProductions.addLast(Jimple.v().newNewExpr((RefType) mProductions.removeLast())); } public void outAArrayNewExpr(AArrayNewExpr node) { Value size = (Value) mProductions.removeLast(); Type type = (Type) mProductions.removeLast(); mProductions.addLast(Jimple.v().newNewArrayExpr(type, size)); } public void outAMultiNewExpr(AMultiNewExpr node) { LinkedList arrayDesc = node.getArrayDescriptor(); int descCnt = arrayDesc.size(); List sizes = new LinkedList(); Iterator it = arrayDesc.iterator(); while (it.hasNext()) { AArrayDescriptor o = (AArrayDescriptor) it.next(); if (o.getImmediate() != null) sizes.add(0, (Value) mProductions.removeLast()); else break; } Type type = (Type) mProductions.removeLast(); ArrayType arrayType = ArrayType.v(type, descCnt); mProductions.addLast(Jimple.v().newNewMultiArrayExpr(arrayType, sizes)); } public void defaultCase(Node node) { if (node instanceof TQuotedName || node instanceof TFullIdentifier || node instanceof TIdentifier || node instanceof TStringConstant || node instanceof TIntegerConstant || node instanceof TFloatConstant || node instanceof TAtIdentifier) { if (debug) G.v().out.println("Default case -pushing token:" + ((Token) node).getText()); String tokenString = ((Token) node).getText(); if (node instanceof TStringConstant || node instanceof TQuotedName) { tokenString = tokenString.substring(1, tokenString.length() - 1); } if (node instanceof TIdentifier || node instanceof TFullIdentifier || node instanceof TQuotedName || node instanceof TStringConstant) { try { tokenString = StringTools.getUnEscapedStringOf(tokenString); } catch (RuntimeException e) { G.v().out.println(tokenString); throw e; } } mProductions.addLast(tokenString); } } protected int processModifiers(List l) { int modifier = 0; Iterator it = l.iterator(); while (it.hasNext()) { Object t = it.next(); if (t instanceof AAbstractModifier) modifier |= Modifier.ABSTRACT; else if (t instanceof AFinalModifier) modifier |= Modifier.FINAL; else if (t instanceof ANativeModifier) modifier |= Modifier.NATIVE; else if (t instanceof APublicModifier) modifier |= Modifier.PUBLIC; else if (t instanceof AProtectedModifier) modifier |= Modifier.PROTECTED; else if (t instanceof APrivateModifier) modifier |= Modifier.PRIVATE; else if (t instanceof AStaticModifier) modifier |= Modifier.STATIC; else if (t instanceof ASynchronizedModifier) modifier |= Modifier.SYNCHRONIZED; else if (t instanceof ATransientModifier) modifier |= Modifier.TRANSIENT; else if (t instanceof AVolatileModifier) modifier |= Modifier.VOLATILE; else if (t instanceof AEnumModifier) modifier |= Modifier.ENUM; else if (t instanceof AAnnotationModifier) modifier |= Modifier.ANNOTATION; else throw new RuntimeException( "Impossible: modifier unknown - Have you added a new modifier and not updated this file?"); } return modifier; } private void addBoxToPatch(String aLabelName, UnitBox aUnitBox) { List patchList = (List) mLabelToPatchList.get(aLabelName); if (patchList == null) { patchList = new ArrayList(); mLabelToPatchList.put(aLabelName, patchList); } patchList.add(aUnitBox); } }