All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
soot.sootify.StmtTemplatePrinter Maven / Gradle / Ivy
package soot.sootify;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 2018 Raja Vallée-Rai and others
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import soot.PatchingChain;
import soot.Unit;
import soot.UnitBox;
import soot.Value;
import soot.jimple.AssignStmt;
import soot.jimple.BreakpointStmt;
import soot.jimple.EnterMonitorStmt;
import soot.jimple.ExitMonitorStmt;
import soot.jimple.GotoStmt;
import soot.jimple.IdentityStmt;
import soot.jimple.IfStmt;
import soot.jimple.IntConstant;
import soot.jimple.InvokeStmt;
import soot.jimple.LookupSwitchStmt;
import soot.jimple.NopStmt;
import soot.jimple.RetStmt;
import soot.jimple.ReturnStmt;
import soot.jimple.ReturnVoidStmt;
import soot.jimple.StmtSwitch;
import soot.jimple.TableSwitchStmt;
import soot.jimple.ThrowStmt;
class StmtTemplatePrinter implements StmtSwitch {
private final TemplatePrinter p;
private final ValueTemplatePrinter vtp; // text for expression
private List jumpTargets = new ArrayList();
public StmtTemplatePrinter(TemplatePrinter templatePrinter, PatchingChain units) {
this.p = templatePrinter;
this.vtp = new ValueTemplatePrinter(p);
for (Unit u : units) {
for (UnitBox ub : u.getUnitBoxes()) {
jumpTargets.add(ub.getUnit());
}
}
final List unitsList = new ArrayList(units);
Collections.sort(jumpTargets, new Comparator() {
public int compare(Unit o1, Unit o2) {
return unitsList.indexOf(o1) - unitsList.indexOf(o2);
}
});
for (int i = 0; i < jumpTargets.size(); i++) {
p.println("NopStmt jumpTarget" + i + "= Jimple.v().newNopStmt();");
}
}
private String nameOfJumpTarget(Unit u) {
if (!isJumpTarget(u)) {
throw new InternalError("not a jumpt target! " + u);
}
return "jumpTarget" + jumpTargets.indexOf(u);
}
private boolean isJumpTarget(Unit u) {
return jumpTargets.contains(u);
}
private String printValueAssignment(Value value, String varName) {
return vtp.printValueAssignment(value, varName);
}
private void printStmt(Unit u, String... ops) {
String stmtClassName = u.getClass().getSimpleName();
if (stmtClassName.charAt(0) == 'J') {
stmtClassName = stmtClassName.substring(1);
}
if (isJumpTarget(u)) {
String nameOfJumpTarget = nameOfJumpTarget(u);
p.println("units.add(" + nameOfJumpTarget + ");");
}
p.print("units.add(");
printFactoryMethodCall(stmtClassName, ops);
p.printlnNoIndent(");");
}
private void printFactoryMethodCall(String stmtClassName, String... ops) {
p.printNoIndent("Jimple.v().new");
p.printNoIndent(stmtClassName);
p.printNoIndent("(");
int i = 1;
for (String op : ops) {
p.printNoIndent(op);
if (i < ops.length) {
p.printNoIndent(",");
}
i++;
}
p.printNoIndent(")");
}
public void caseThrowStmt(ThrowStmt stmt) {
String varName = printValueAssignment(stmt.getOp(), "op");
printStmt(stmt, varName);
}
public void caseTableSwitchStmt(TableSwitchStmt stmt) {
p.openBlock();
String varName = printValueAssignment(stmt.getKey(), "key");
int lowIndex = stmt.getLowIndex();
p.println("int lowIndex=" + lowIndex + ";");
int highIndex = stmt.getHighIndex();
p.println("int highIndex=" + highIndex + ";");
p.println("List targets = new LinkedList();");
for (Unit s : stmt.getTargets()) {
String nameOfJumpTarget = nameOfJumpTarget(s);
p.println("targets.add(" + nameOfJumpTarget + ")");
}
Unit defaultTarget = stmt.getDefaultTarget();
p.println("Unit defaultTarget = " + nameOfJumpTarget(defaultTarget) + ";");
printStmt(stmt, varName, "lowIndex", "highIndex", "targets", "defaultTarget");
p.closeBlock();
}
public void caseReturnVoidStmt(ReturnVoidStmt stmt) {
printStmt(stmt);
}
public void caseReturnStmt(ReturnStmt stmt) {
String varName = printValueAssignment(stmt.getOp(), "retVal");
printStmt(stmt, varName);
}
public void caseRetStmt(RetStmt stmt) {
String varName = printValueAssignment(stmt.getStmtAddress(), "stmtAddress");
printStmt(stmt, varName);
}
public void caseNopStmt(NopStmt stmt) {
printStmt(stmt);
}
public void caseLookupSwitchStmt(LookupSwitchStmt stmt) {
p.openBlock();
String keyVarName = printValueAssignment(stmt.getKey(), "key");
p.println("List lookupValues = new LinkedList();");
int i = 0;
for (IntConstant c : (List) stmt.getLookupValues()) {
vtp.suggestVariableName("lookupValue" + i);
c.apply(vtp);
i++;
p.println("lookupValues.add(lookupValue" + i + ");");
}
p.println("List targets = new LinkedList();");
for (Unit u : stmt.getTargets()) {
String nameOfJumpTarget = nameOfJumpTarget(u);
p.println("targets.add(" + nameOfJumpTarget + ")");
}
Unit defaultTarget = stmt.getDefaultTarget();
p.println("Unit defaultTarget=" + defaultTarget.toString() + ";");
printStmt(stmt, keyVarName, "lookupValues", "targets", "defaultTarget");
p.closeBlock();
}
public void caseInvokeStmt(InvokeStmt stmt) {
String varName = printValueAssignment(stmt.getInvokeExpr(), "ie");
printStmt(stmt, varName);
}
public void caseIfStmt(IfStmt stmt) {
String varName = printValueAssignment(stmt.getCondition(), "condition");
Unit target = stmt.getTarget();
vtp.suggestVariableName("target");
String targetName = vtp.getLastAssignedVarName();
p.println("Unit " + targetName + "=" + nameOfJumpTarget(target) + ";");
printStmt(stmt, varName, targetName);
}
public void caseIdentityStmt(IdentityStmt stmt) {
String varName = printValueAssignment(stmt.getLeftOp(), "lhs");
String varName2 = printValueAssignment(stmt.getRightOp(), "idRef");
printStmt(stmt, varName, varName2);
}
public void caseGotoStmt(GotoStmt stmt) {
Unit target = stmt.getTarget();
vtp.suggestVariableName("target");
String targetName = vtp.getLastAssignedVarName();
p.println("Unit " + targetName + "=" + nameOfJumpTarget(target) + ";");
printStmt(stmt, targetName);
}
public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
String varName = printValueAssignment(stmt.getOp(), "monitor");
printStmt(stmt, varName);
}
public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
String varName = printValueAssignment(stmt.getOp(), "monitor");
printStmt(stmt, varName);
}
public void caseBreakpointStmt(BreakpointStmt stmt) {
printStmt(stmt);
}
public void caseAssignStmt(AssignStmt stmt) {
String varName = printValueAssignment(stmt.getLeftOp(), "lhs");
String varName2 = printValueAssignment(stmt.getRightOp(), "rhs");
printStmt(stmt, varName, varName2);
}
public void defaultCase(Object obj) {
throw new InternalError("should never be called");
}
}