All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.toDex.ConstantVisitor Maven / Gradle / Ivy

package soot.toDex;

/*-
 * #%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 org.jf.dexlib2.Opcode;
import org.jf.dexlib2.iface.reference.StringReference;
import org.jf.dexlib2.iface.reference.TypeReference;
import org.jf.dexlib2.immutable.reference.ImmutableStringReference;
import org.jf.dexlib2.immutable.reference.ImmutableTypeReference;

import soot.jimple.AbstractConstantSwitch;
import soot.jimple.ClassConstant;
import soot.jimple.DoubleConstant;
import soot.jimple.FloatConstant;
import soot.jimple.IntConstant;
import soot.jimple.LongConstant;
import soot.jimple.NullConstant;
import soot.jimple.Stmt;
import soot.jimple.StringConstant;
import soot.toDex.instructions.Insn;
import soot.toDex.instructions.Insn11n;
import soot.toDex.instructions.Insn21c;
import soot.toDex.instructions.Insn21s;
import soot.toDex.instructions.Insn31i;
import soot.toDex.instructions.Insn51l;
import soot.util.Switchable;

/**
 * A visitor that builds a list of instructions from the Jimple constants it visits.
*
* Use {@link Switchable#apply(soot.util.Switch)} with this visitor to add statements. These are added to the instructions in * the {@link StmtVisitor}.
* Do not forget to use {@link #setDestination(Register)} to set the storage location for the constant. * * @see StmtVisitor */ public class ConstantVisitor extends AbstractConstantSwitch { private StmtVisitor stmtV; private Register destinationReg; private Stmt origStmt; public ConstantVisitor(StmtVisitor stmtV) { this.stmtV = stmtV; } public void setDestination(Register destinationReg) { this.destinationReg = destinationReg; } public void setOrigStmt(Stmt stmt) { this.origStmt = stmt; } @Override public void defaultCase(Object o) { // const* opcodes not used since there seems to be no point in doing so: // CONST_HIGH16, CONST_WIDE_HIGH16 throw new Error("unknown Object (" + o.getClass() + ") as Constant: " + o); } @Override public void caseStringConstant(StringConstant s) { StringReference ref = new ImmutableStringReference(s.value); stmtV.addInsn(new Insn21c(Opcode.CONST_STRING, destinationReg, ref), origStmt); } @Override public void caseClassConstant(ClassConstant c) { TypeReference referencedClass = new ImmutableTypeReference(c.getValue()); stmtV.addInsn(new Insn21c(Opcode.CONST_CLASS, destinationReg, referencedClass), origStmt); } @Override public void caseLongConstant(LongConstant l) { long constant = l.value; stmtV.addInsn(buildConstWideInsn(constant), origStmt); } private Insn buildConstWideInsn(long literal) { if (SootToDexUtils.fitsSigned16(literal)) { return new Insn21s(Opcode.CONST_WIDE_16, destinationReg, (short) literal); } else if (SootToDexUtils.fitsSigned32(literal)) { return new Insn31i(Opcode.CONST_WIDE_32, destinationReg, (int) literal); } else { return new Insn51l(Opcode.CONST_WIDE, destinationReg, literal); } } @Override public void caseDoubleConstant(DoubleConstant d) { long longBits = Double.doubleToLongBits(d.value); stmtV.addInsn(buildConstWideInsn(longBits), origStmt); } @Override public void caseFloatConstant(FloatConstant f) { int intBits = Float.floatToIntBits(f.value); stmtV.addInsn(buildConstInsn(intBits), origStmt); } private Insn buildConstInsn(int literal) { if (SootToDexUtils.fitsSigned4(literal)) { return new Insn11n(Opcode.CONST_4, destinationReg, (byte) literal); } else if (SootToDexUtils.fitsSigned16(literal)) { return new Insn21s(Opcode.CONST_16, destinationReg, (short) literal); } else { return new Insn31i(Opcode.CONST, destinationReg, literal); } } @Override public void caseIntConstant(IntConstant i) { stmtV.addInsn(buildConstInsn(i.value), origStmt); } @Override public void caseNullConstant(NullConstant v) { // dex bytecode spec says: "In terms of bitwise representation, (Object) // null == (int) 0." stmtV.addInsn(buildConstInsn(0), origStmt); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy