Skip to content

Commit

Permalink
Merge branch 'develop' into buildfix
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenArzt authored Sep 28, 2024
2 parents 96d4a90 + f4ff4c8 commit 05f342b
Show file tree
Hide file tree
Showing 13 changed files with 400 additions and 42 deletions.
9 changes: 7 additions & 2 deletions .classpath
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/main/generated/protobuf"/>
<classpathentry kind="src" output="target/classes" path="src/main/generated/protobuf">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/systemTest-target-classes" path="src/systemTest/targets"/>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
Expand Down Expand Up @@ -44,7 +49,7 @@
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Use Java 8
- name: Use Java 11
uses: actions/setup-java@v1
with:
java-version: '8'
java-version: '11'
- name: Deploy artifacts
uses: samuelmeuli/action-maven-publish@v1
with:
Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>org.soot-oss</groupId>
<artifactId>soot</artifactId>
<name>Soot - a J*va Optimization Framework</name>
<version>4.6.0-SNAPSHOT</version>
<version>4.6.0</version>
<description>A Java Optimization Framework</description>
<url>https://soot-oss.github.io/soot</url>
<organization>
Expand Down Expand Up @@ -52,8 +52,8 @@
<url>https://github.com/soot-oss/soot</url>
</scm>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<xml-maven-plugin.version>1.1.0</xml-maven-plugin.version>
<maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
<build-helper-maven-plugin.version>3.5.0</build-helper-maven-plugin.version>
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/soot/ISootClassAddedListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package soot;

/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2002 Ondrej Lhotak
* %%
* 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
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/

/**
* Interface to notify client code that a new class has been added to the scene
*
* @author Steven Arzt
*
*/
public interface ISootClassAddedListener {

/**
* Callback that is invoked when a SootClass has been added to the scene
*
* @param sc
* The SootClass that as been added
*/
public void onSootClassAdded(SootClass sc);

}
51 changes: 51 additions & 0 deletions src/main/java/soot/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import pxb.android.axml.AxmlReader;
import pxb.android.axml.AxmlVisitor;
import pxb.android.axml.NodeVisitor;

import soot.dexpler.DalvikThrowAnalysis;
import soot.dotnet.exceptiontoolkits.DotnetThrowAnalysis;
import soot.dotnet.members.DotnetMethod;
Expand All @@ -79,6 +80,7 @@
import soot.util.Chain;
import soot.util.HashChain;
import soot.util.IterableNumberer;
import soot.util.NumberedString;
import soot.util.StringNumberer;

/**
Expand Down Expand Up @@ -132,6 +134,8 @@ public class Scene {
private AndroidVersionInfo androidSDKVersionInfo;
private int androidAPIVersion = -1;

protected List<ISootClassAddedListener> classAddedListeners = new ArrayList<>(4);

public Scene(Singletons.Global g) {
setReservedNames();

Expand Down Expand Up @@ -846,6 +850,8 @@ protected void addClassSilent(SootClass c) {
}
nameToClass.computeIfAbsent(c.getName(), k -> c.getType());
}

classAddedListeners.stream().forEach(l -> l.onSootClassAdded(c));
}

public void removeClass(SootClass c) {
Expand Down Expand Up @@ -2044,6 +2050,30 @@ public SootMethodRef makeMethodRef(SootClass declaringClass, String name, List<T
}
}

/** Create an unresolved reference to a method. */
public SootMethodRef makeMethodRef(SootClass declaringClass, String subsig, boolean isStatic) {
NumberedString numbered = Scene.v().getSubSigNumberer().findOrAdd(subsig);
MethodSubSignature sootSubsig = new MethodSubSignature(numbered);
if (PolymorphicMethodRef.handlesClass(declaringClass)) {
return new PolymorphicMethodRef(declaringClass, sootSubsig.getMethodName(), sootSubsig.getParameterTypes(),
sootSubsig.getReturnType(), isStatic);
} else {
return new SootMethodRefImpl(declaringClass, sootSubsig.getMethodName(), sootSubsig.getParameterTypes(),
sootSubsig.getReturnType(), isStatic);
}
}

/** Create an unresolved reference to a method. */
public SootMethodRef makeMethodRef(SootClass declaringClass, MethodSubSignature subsig, boolean isStatic) {
if (PolymorphicMethodRef.handlesClass(declaringClass)) {
return new PolymorphicMethodRef(declaringClass, subsig.getMethodName(), subsig.getParameterTypes(),
subsig.getReturnType(), isStatic);
} else {
return new SootMethodRefImpl(declaringClass, subsig.getMethodName(), subsig.getParameterTypes(),
subsig.getReturnType(), isStatic);
}
}

/** Create an unresolved reference to a constructor. */
public SootMethodRef makeConstructorRef(SootClass declaringClass, List<Type> parameterTypes) {
return makeMethodRef(declaringClass, SootMethod.constructorName, parameterTypes, VoidType.v(), false);
Expand Down Expand Up @@ -2211,4 +2241,25 @@ public LocalCreation createLocalCreation(Chain<Local> locals, String prefix) {
public void resetSootClassPathCache() {
this.sootClassPath = null;
}

/**
* Registers a new listener that is invoked when a new SootClass is added to the scene
*
* @param listener
* The listener that shall be invoked when a new SootClass is added to the scene
*/
public void registerSootClassAddedListener(ISootClassAddedListener listener) {
classAddedListeners.add(listener);
}

/**
* Unrgisters a listener that processes new SootClases being added to the scene
*
* @param listener
* The listener to remove
*/
public void unregisterSootClassAddedListener(ISootClassAddedListener listener) {
classAddedListeners.remove(listener);

}
}
11 changes: 10 additions & 1 deletion src/main/java/soot/asm/AsmMethodSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/

import static org.objectweb.asm.Opcodes.ACONST_NULL;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ANEWARRAY;
Expand Down Expand Up @@ -1104,6 +1103,16 @@ private void convertInsn(InsnNode insn) {
} else if (op >= IRETURN && op <= ARETURN) {
convertReturnInsn(insn);
} else if (op == RETURN) {
// We might be at the end of the stack, but there is still a dangling instruction, i.e., a method call whose return
// value
// was never used. Since the method may have side effects, we need to handle the call.
if (!stack.isEmpty()) {
Operand o1 = pop();
if (!units.containsKey(o1.insn)) {
InvokeExpr iexpr = (InvokeExpr) getFrame(o1.insn).out()[0].value;
setUnit(o1.insn, Jimple.v().newInvokeStmt(iexpr));
}
}
if (!units.containsKey(insn)) {
setUnit(insn, Jimple.v().newReturnVoidStmt());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
* @author Marc Miltenberger
*/
public class ByReferenceWrapperGenerator {
public static final String WRAPPER_FIELD_NAME = "r";
public static final String WRAPPER_CLASS_NAME = "ByReferenceWrappers.Wrapper";

public synchronized static SootClass getWrapperClass(Type t) {
Expand All @@ -61,7 +62,7 @@ public synchronized static SootClass getWrapperClass(Type t) {
}
SootClass sc = scene.makeSootClass(name, Modifier.FINAL | Modifier.STATIC);
sc.setApplicationClass();
SootField r = scene.makeSootField("r", RefType.v("System.Object"));
SootField r = scene.makeSootField(WRAPPER_FIELD_NAME, RefType.v("System.Object"));
r.setModifiers(Modifier.PUBLIC);
sc.addField(r);

Expand Down Expand Up @@ -120,7 +121,7 @@ public static Unit getUnwrapCall(SootClass wrapperClass, Value argToUnwrap, Valu
}

public static SootField getWrapperField(SootClass wrapperClass) {
return wrapperClass.getFieldByName("r");
return wrapperClass.getFieldByName(WRAPPER_FIELD_NAME);
}

/**
Expand All @@ -134,7 +135,7 @@ public static SootField getWrapperField(SootClass wrapperClass) {
*/
public static Unit getUpdateWrappedValueCall(Local wrapped, Local unwrapped) {
RefType rt = (RefType) wrapped.getType();
SootField f = rt.getSootClass().getFieldByName("r");
SootField f = rt.getSootClass().getFieldByName(WRAPPER_FIELD_NAME);
Jimple j = Jimple.v();
return j.newAssignStmt(j.newInstanceFieldRef(wrapped, f.makeRef()), unwrapped);

Expand Down
21 changes: 17 additions & 4 deletions src/main/java/soot/jimple/spark/pag/PAG.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import soot.jimple.InvokeExpr;
import soot.jimple.NewExpr;
import soot.jimple.NullConstant;
import soot.jimple.StaticInvokeExpr;
import soot.jimple.Stmt;
import soot.jimple.VirtualInvokeExpr;
import soot.jimple.spark.builder.GlobalNodeFactory;
Expand All @@ -84,6 +85,7 @@
import soot.jimple.toolkits.callgraph.VirtualEdgesSummaries.DeferredVirtualEdgeTarget;
import soot.jimple.toolkits.callgraph.VirtualEdgesSummaries.InstanceinvokeSource;
import soot.jimple.toolkits.callgraph.VirtualEdgesSummaries.InvocationVirtualEdgeTarget;
import soot.jimple.toolkits.callgraph.VirtualEdgesSummaries.StaticinvokeSource;
import soot.jimple.toolkits.callgraph.VirtualEdgesSummaries.VirtualEdge;
import soot.jimple.toolkits.callgraph.VirtualEdgesSummaries.VirtualEdgeSource;
import soot.jimple.toolkits.callgraph.VirtualEdgesSummaries.VirtualEdgeTarget;
Expand Down Expand Up @@ -1086,19 +1088,24 @@ public void addCallTarget(Edge e) {
}
VirtualEdgesSummaries summaries = getOnFlyCallGraph().ofcgb().getVirtualEdgeSummaries();
InvokeExpr ie = e.srcStmt().getInvokeExpr();
VirtualEdge ve = summaries.getVirtualEdgesMatchingSubSig(new MethodSubSignature(ie.getMethodRef().getSubSignature()));
VirtualEdge ve = null;
if (ie instanceof InstanceInvokeExpr) {
ve = summaries.getVirtualEdgesMatchingSubSig(new MethodSubSignature(ie.getMethodRef().getSubSignature()));
} else if (ie instanceof StaticInvokeExpr) {
ve = summaries.getVirtualEdgesMatchingFunction(ie.getMethodRef().getSignature());
}
// if there is no virtual edge there is no point in continuing
if (ve == null) {
return;
}
// The source is equal for direct and indirect targets
VirtualEdgeSource edgeSrc = ve.getSource();

if (edgeSrc instanceof InstanceinvokeSource) {
if (edgeSrc instanceof InstanceinvokeSource || edgeSrc instanceof StaticinvokeSource) {
for (VirtualEdgeTarget edgeTgt : ve.getTargets()) {
if (edgeTgt instanceof InvocationVirtualEdgeTarget) {
for (Local local : getOnFlyCallGraph().ofcgb().getReceiversOfVirtualEdge((InvocationVirtualEdgeTarget) edgeTgt,
ie)) {
InvocationVirtualEdgeTarget ieEdgeTgt = (InvocationVirtualEdgeTarget) edgeTgt;
for (Local local : getOnFlyCallGraph().ofcgb().getReceiversOfVirtualEdge(ieEdgeTgt, ie)) {
Node parm = srcmpag.nodeFactory().getNode(local);
parm = srcmpag.parameterize(parm, e.srcCtxt());
parm = parm.getReplacement();
Expand All @@ -1111,6 +1118,12 @@ public void addCallTarget(Edge e) {
// Make an edge from caller.argument to callee.this
addEdge(parm, thiz);
pval = addInterproceduralAssignment(parm, thiz, e);

// We need to ensure that the target method exists, at least as a phantom
if (local.getType() instanceof RefType) {
RefType rtTarget = (RefType) local.getType();
Scene.v().makeMethodRef(rtTarget.getSootClass(), ieEdgeTgt.getTargetMethod(), false).resolve();
}
}
} else if (edgeTgt instanceof DeferredVirtualEdgeTarget && e.srcStmt() instanceof AssignStmt
&& ie.getMethodRef().getReturnType() instanceof RefType) {
Expand Down
9 changes: 4 additions & 5 deletions src/main/java/soot/jimple/spark/solver/PropWorklist.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

public class PropWorklist extends Propagator {
private static final Logger logger = LoggerFactory.getLogger(PropWorklist.class);
protected final Set<VarNode> varNodeWorkList = new TreeSet<VarNode>();
protected final TreeSet<VarNode> varNodeWorkList = new TreeSet<VarNode>();

public PropWorklist(PAG pag) {
this.pag = pag;
Expand All @@ -75,10 +75,9 @@ public void propagate() {
if (verbose) {
logger.debug("Worklist has " + varNodeWorkList.size() + " nodes.");
}
while (!varNodeWorkList.isEmpty()) {
VarNode src = varNodeWorkList.iterator().next();
varNodeWorkList.remove(src);
handleVarNode(src);
VarNode vsrc;
while ((vsrc = varNodeWorkList.pollFirst()) != null) {
handleVarNode(vsrc);
}
if (verbose) {
logger.debug("Now handling field references");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package soot.jimple.toolkits.callgraph;

import java.lang.reflect.Constructor;

/*-
* #%L
* Soot - a J*va Optimization Framework
Expand Down Expand Up @@ -96,7 +94,6 @@
import soot.jimple.StringConstant;
import soot.jimple.VirtualInvokeExpr;
import soot.jimple.spark.pag.AllocDotField;
import soot.jimple.spark.pag.PAG;
import soot.jimple.toolkits.annotation.nullcheck.NullnessAnalysis;
import soot.jimple.toolkits.callgraph.ConstantArrayAnalysis.ArrayTypes;
import soot.jimple.toolkits.callgraph.VirtualEdgesSummaries.DeferredVirtualEdgeTarget;
Expand Down Expand Up @@ -810,17 +807,21 @@ protected void findReceivers(SootMethod m, Body b) {
if (ie instanceof InstanceInvokeExpr) {
InstanceInvokeExpr iie = (InstanceInvokeExpr) ie;
Local receiver = (Local) iie.getBase();
MethodSubSignature subSig = new MethodSubSignature(iie.getMethodRef());

VirtualEdge virtualEdge = virtualEdgeSummaries.getVirtualEdgesMatchingSubSig(subSig);
if (virtualEdge != null) {
for (VirtualEdgeTarget t : virtualEdge.targets) {
if (t instanceof InvocationVirtualEdgeTarget) {
processVirtualEdgeSummary(m, s, receiver, (InvocationVirtualEdgeTarget) t, virtualEdge.edgeType);
} else if (t instanceof DeferredVirtualEdgeTarget) {
addVirtualCallSite(s, m, receiver, iie, new MethodSubSignature(iie.getMethodRef()), Kind.GENERIC_FAKE);
if (!(iie instanceof SpecialInvokeExpr)) {
MethodSubSignature subSig = new MethodSubSignature(iie.getMethodRef());

VirtualEdge virtualEdge = virtualEdgeSummaries.getVirtualEdgesMatchingSubSig(subSig);
if (virtualEdge != null) {
for (VirtualEdgeTarget t : virtualEdge.targets) {
if (t instanceof InvocationVirtualEdgeTarget) {
processVirtualEdgeSummary(m, s, receiver, (InvocationVirtualEdgeTarget) t, virtualEdge.edgeType);
} else if (t instanceof DeferredVirtualEdgeTarget) {
addVirtualCallSite(s, m, receiver, iie, new MethodSubSignature(iie.getMethodRef()), Kind.GENERIC_FAKE);
}
}
}
} else {
addEdge(m, s, ie.getMethod(), Kind.SPECIAL);
}

// if (!hasVirtualEdge || !iie.getMethod().isPhantom())
Expand Down Expand Up @@ -970,7 +971,7 @@ private void getImplicitTargets(SootMethod source) {
if (!source.isConcrete()) {
return;
}
if (source.getSubSignature().contains("<init>")) {
if (source.isConstructor()) {
handleInit(source, scl);
}
for (Unit u : source.retrieveActiveBody().getUnits()) {
Expand Down
Loading

0 comments on commit 05f342b

Please sign in to comment.