use of soot.jimple.AssignStmt in project soot by Sable.
the class ConstantInitializerToTagTransformer method transformClass.
/**
* Transforms the given class, i.e. scans for a <clinit> method and
* generates new constant value tags for all constant assignments to static
* final fields.
*
* @param sc
* The class to transform
* @param removeAssignments
* True if the assignments inside the <clinit> method shall be
* removed, otherwise false
*/
public void transformClass(SootClass sc, boolean removeAssignments) {
// If this class has no <clinit> method, we're done
SootMethod smInit = sc.getMethodByNameUnsafe("<clinit>");
if (smInit == null || !smInit.isConcrete())
return;
Set<SootField> nonConstantFields = new HashSet<SootField>();
Map<SootField, ConstantValueTag> newTags = new HashMap<SootField, ConstantValueTag>();
// in case of
Set<SootField> removeTagList = new HashSet<SootField>();
for (Iterator<Unit> itU = smInit.getActiveBody().getUnits().snapshotIterator(); itU.hasNext(); ) {
Unit u = itU.next();
if (u instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) u;
if (assign.getLeftOp() instanceof StaticFieldRef && assign.getRightOp() instanceof Constant) {
SootField field = null;
try {
field = ((StaticFieldRef) assign.getLeftOp()).getField();
if (field == null || nonConstantFields.contains(field))
continue;
} catch (ConflictingFieldRefException ex) {
// Ignore this statement
continue;
}
if (field.getDeclaringClass().equals(sc) && field.isStatic() && field.isFinal()) {
// Do we already have a constant value for this field?
boolean found = false;
for (Tag t : field.getTags()) {
if (t instanceof ConstantValueTag) {
if (checkConstantValue((ConstantValueTag) t, (Constant) assign.getRightOp())) {
// the assignment.
if (removeAssignments)
itU.remove();
} else {
logger.debug("" + "WARNING: Constant value for field '" + field + "' mismatch between code (" + assign.getRightOp() + ") and constant table (" + t + ")");
removeTagList.add(field);
}
found = true;
break;
}
}
if (!found) {
// tags.
if (!checkConstantValue(newTags.get(field), (Constant) assign.getRightOp())) {
nonConstantFields.add(field);
newTags.remove(field);
removeTagList.add(field);
continue;
}
ConstantValueTag newTag = createConstantTagFromValue((Constant) assign.getRightOp());
if (newTag != null)
newTags.put(field, newTag);
}
}
} else if (assign.getLeftOp() instanceof StaticFieldRef) {
// a non-constant is assigned to the field
try {
SootField sf = ((StaticFieldRef) assign.getLeftOp()).getField();
if (sf != null)
removeTagList.add(sf);
} catch (ConflictingFieldRefException ex) {
// let's assume that a broken field doesn't cause any
// harm
}
}
}
}
// Do the actual assignment
for (Entry<SootField, ConstantValueTag> entry : newTags.entrySet()) {
SootField field = entry.getKey();
if (removeTagList.contains(field))
continue;
field.addTag(entry.getValue());
}
if (removeAssignments && !newTags.isEmpty())
for (Iterator<Unit> itU = smInit.getActiveBody().getUnits().snapshotIterator(); itU.hasNext(); ) {
Unit u = itU.next();
if (u instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) u;
if (assign.getLeftOp() instanceof FieldRef)
try {
SootField fld = ((FieldRef) assign.getLeftOp()).getField();
if (fld != null && newTags.containsKey(fld))
itU.remove();
} catch (ConflictingFieldRefException ex) {
// Ignore broken code
}
}
}
// remove constant tags
for (SootField sf : removeTagList) {
if (removeTagList.contains(sf)) {
List<Tag> toRemoveTagList = new ArrayList<Tag>();
for (Tag t : sf.getTags()) {
if (t instanceof ConstantValueTag) {
toRemoveTagList.add(t);
}
}
for (Tag t : toRemoveTagList) {
sf.getTags().remove(t);
}
}
}
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class AsmMethodSource method assignReadOps.
private void assignReadOps(Local l) {
if (stack.isEmpty())
return;
for (Operand opr : stack) {
if (opr == DWORD_DUMMY || opr.stack != null || (l == null && opr.value instanceof Local))
continue;
if (l != null && !opr.value.equivTo(l)) {
List<ValueBox> uses = opr.value.getUseBoxes();
boolean noref = true;
for (ValueBox use : uses) {
Value val = use.getValue();
if (val.equivTo(l)) {
noref = false;
break;
}
}
if (noref)
continue;
}
int op = opr.insn.getOpcode();
if (l == null && op != GETFIELD && op != GETSTATIC && (op < IALOAD && op > SALOAD))
continue;
Local stack = newStackLocal();
opr.stack = stack;
AssignStmt as = Jimple.v().newAssignStmt(stack, opr.value);
opr.updateBoxes();
setUnit(opr.insn, as);
}
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class AsmMethodSource method convertPutFieldInsn.
private void convertPutFieldInsn(FieldInsnNode insn) {
boolean instance = insn.getOpcode() == PUTFIELD;
StackFrame frame = getFrame(insn);
Operand[] out = frame.out();
Operand opr, rvalue;
Type type;
if (out == null) {
SootClass declClass = Scene.v().getSootClass(AsmUtil.toQualifiedName(insn.owner));
type = AsmUtil.toJimpleType(insn.desc);
Value val;
SootFieldRef ref;
rvalue = popImmediate(type);
if (!instance) {
ref = Scene.v().makeFieldRef(declClass, insn.name, type, true);
val = Jimple.v().newStaticFieldRef(ref);
frame.in(rvalue);
} else {
Operand base = popLocal();
ref = Scene.v().makeFieldRef(declClass, insn.name, type, false);
InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(base.stackOrValue(), ref);
val = ifr;
base.addBox(ifr.getBaseBox());
frame.in(rvalue, base);
}
opr = new Operand(insn, val);
frame.out(opr);
AssignStmt as = Jimple.v().newAssignStmt(val, rvalue.stackOrValue());
rvalue.addBox(as.getRightOpBox());
if (!instance) {
frame.boxes(as.getRightOpBox());
} else {
frame.boxes(as.getRightOpBox(), ((InstanceFieldRef) val).getBaseBox());
}
setUnit(insn, as);
} else {
opr = out[0];
type = opr.<FieldRef>value().getFieldRef().type();
rvalue = pop(type);
if (!instance) {
/* PUTSTATIC only needs one operand on the stack, the rvalue */
frame.mergeIn(rvalue);
} else {
/* PUTFIELD has a rvalue and a base */
frame.mergeIn(rvalue, pop());
}
}
/*
* in case any static field or array is read from, and the static constructor
* or the field this instruction writes to, modifies that field, write out any
* previous read from field/array
*/
assignReadOps(null);
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class AsmMethodSource method convertArrayStoreInsn.
private void convertArrayStoreInsn(InsnNode insn) {
int op = insn.getOpcode();
boolean dword = op == LASTORE || op == DASTORE;
StackFrame frame = getFrame(insn);
if (!units.containsKey(insn)) {
Operand valu = dword ? popImmediateDual() : popImmediate();
Operand indx = popImmediate();
Operand base = popLocal();
ArrayRef ar = Jimple.v().newArrayRef(base.stackOrValue(), indx.stackOrValue());
indx.addBox(ar.getIndexBox());
base.addBox(ar.getBaseBox());
AssignStmt as = Jimple.v().newAssignStmt(ar, valu.stackOrValue());
valu.addBox(as.getRightOpBox());
frame.in(valu, indx, base);
frame.boxes(as.getRightOpBox(), ar.getIndexBox(), ar.getBaseBox());
setUnit(insn, as);
} else {
frame.mergeIn(dword ? popDual() : pop(), pop(), pop());
}
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class CastAndReturnInliner method internalTransform.
@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
Iterator<Unit> it = body.getUnits().snapshotIterator();
while (it.hasNext()) {
Unit u = it.next();
if (u instanceof GotoStmt) {
GotoStmt gtStmt = (GotoStmt) u;
if (gtStmt.getTarget() instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) gtStmt.getTarget();
if (assign.getRightOp() instanceof CastExpr) {
CastExpr ce = (CastExpr) assign.getRightOp();
// We have goto that ends up at a cast statement
Unit nextStmt = body.getUnits().getSuccOf(assign);
if (nextStmt instanceof ReturnStmt) {
ReturnStmt retStmt = (ReturnStmt) nextStmt;
if (retStmt.getOp() == assign.getLeftOp()) {
// We need to replace the GOTO with the return
ReturnStmt newStmt = (ReturnStmt) retStmt.clone();
newStmt.setOp(ce.getOp());
for (Trap t : body.getTraps()) for (UnitBox ubox : t.getUnitBoxes()) if (ubox.getUnit() == gtStmt)
ubox.setUnit(newStmt);
while (!gtStmt.getBoxesPointingToThis().isEmpty()) gtStmt.getBoxesPointingToThis().get(0).setUnit(newStmt);
body.getUnits().swapWith(gtStmt, newStmt);
}
}
}
}
}
}
}
Aggregations