Skip to content

Commit

Permalink
Merge branch 'develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenArzt authored Aug 27, 2024
2 parents 1d5f9c5 + 027c7ba commit 9a73239
Show file tree
Hide file tree
Showing 133 changed files with 2,251 additions and 377 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/soot-oss/soot)

# IMPORTANT: Soot is now succeeded by SootUp!
**In December 2022, we have officially released [SootUp](https://soot-oss.github.io/SootUp/announce/), a version of Soot with a completely overhauled, more modular, testable, maintainable and usable architecture. Please check this out in case you wish to start a new program-analysis project.**
**In December 2022, we have officially released [SootUp](https://soot-oss.github.io/SootUp/), a version of Soot with a completely overhauled, more modular, testable, maintainable and usable architecture. Please check this out in case you wish to start a new program-analysis project.**

Since there has been some confusion: SootUp is not yet feature-complete. Therefore, the "old" Soot needs to live on for the time being, especially for projects that require instrumentation capabilities or robust Android support. The "old" Soot is still being maintained until it can safely be dropped for a feature-complete successor.

# Using Soot? Let us know about it!
We are regularly applying for funding to help us maintain Soot. You can help us immensely by letting us know about [**projects that use Soot**](https://github.com/soot-oss/soot/wiki/Users-of-Soot), both commercially or in the form of research tools.
Expand Down Expand Up @@ -107,8 +109,6 @@ If you cannot work with the prebuild versions and need to build Soot on your own

Soot follows the git-flow convention. Releases and hotfixes are maintained in the master branch.
Development happens in the develop branch. To catch the bleeding edge of Soot, check out the latter.
In case of any questions, please consult the Soot
mailing list at: http://www.sable.mcgill.ca/mailman/listinfo/soot-list/

# How do I contribute to Soot?

Expand Down
4 changes: 4 additions & 0 deletions doc/soot_options.html
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,10 @@ <H2><A name="section_2">Input Options</A></H2>
<td><tt>-drop-bodies-after-load </tt><br></td>
<td colspan="2">Drop the method source after it has served its purpose of loading the method body</td>
</tr>
<tr>
<td><tt>-nc </tt><br><tt>-native-code </tt><br></td>
<td colspan="2">Enables native methods to be concrete. Needed for analyzing the Java Native Interface.</td>
</tr>
</table>
<H2><A name="section_3">Output Options</A></H2>
<table border="3">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,12 @@ private boolean createNewConfig() {
if (boolRes != defBoolRes) {
getConfig().put(getInput_Optionsdrop_bodies_after_load_widget().getAlias(), new Boolean(boolRes));
}
boolRes = getInput_Optionsnative_code_widget().getButton().getSelection();
defBoolRes = false;

if (boolRes != defBoolRes) {
getConfig().put(getInput_Optionsnative_code_widget().getAlias(), new Boolean(boolRes));
}
stringRes = getInput_Optionssoot_classpath_widget().getText().getText();
defStringRes = "";

Expand Down Expand Up @@ -4899,6 +4905,16 @@ public BooleanOptionWidget getInput_Optionsdrop_bodies_after_load_widget() {
return Input_Optionsdrop_bodies_after_load_widget;
}

private BooleanOptionWidget Input_Optionsnative_code_widget;

private void setInput_Optionsnative_code_widget(BooleanOptionWidget widget) {
Input_Optionsnative_code_widget = widget;
}

public BooleanOptionWidget getInput_Optionsnative_code_widget() {
return Input_Optionsnative_code_widget;
}


private ListOptionWidget Input_Optionsprocess_dir_widget;

Expand Down Expand Up @@ -9020,6 +9036,17 @@ private Composite Input_OptionsCreate(Composite parent) {

setInput_Optionsdrop_bodies_after_load_widget(new BooleanOptionWidget(editGroupInput_Options, SWT.NONE, new OptionData("Drop method source after loading bodies", "", "","drop-bodies-after-load", "\nEach method is associated with a method source for loading its \nbody. When this option is disabled, a reference to this source \nis kept around even after the body has already been loaded. This \nis a waste of memory for most use cases. When this option is \nenabled, the reference is dropped, allowing for garbage \ncollection of the method source. On the other hand, if the body \nis ever released, it cannot easily be recovered (i.e., loaded \nagain) easily.", defaultBool)));

defKey = ""+" "+""+" "+"nc native-code";
defKey = defKey.trim();

if (isInDefList(defKey)) {
defaultBool = getBoolDef(defKey);
} else {
defaultBool = false;
}

setInput_Optionsnative_code_widget(new BooleanOptionWidget(editGroupInput_Options, SWT.NONE, new OptionData("Enable native code", "", "","nc native-code", "\nThis option is needed, when analyzing native code. Particularly \nwhen using the Java Native Interface (JNI). If this option is \nenabled (set true), it allows native methods to be concrete. \nThis flag will be checked in the SootMethod.isConcrete() method, \nallowing native methods to have a body.", defaultBool)));

data = new OptionData [] {

new OptionData("Class File",
Expand Down
31 changes: 16 additions & 15 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.5.0-SNAPSHOT</version>
<version>4.6.0-SNAPSHOT</version>
<description>A Java Optimization Framework</description>
<url>https://soot-oss.github.io/soot</url>
<organization>
Expand Down Expand Up @@ -54,26 +54,26 @@
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<xml-maven-plugin.version>1.0.2</xml-maven-plugin.version>
<maven-resources-plugin.version>3.2.0</maven-resources-plugin.version>
<build-helper-maven-plugin.version>3.3.0</build-helper-maven-plugin.version>
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
<maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
<maven-javadoc-plugin.version>3.4.0</maven-javadoc-plugin.version>
<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>
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version>
<maven-assembly-plugin.version>3.7.1</maven-assembly-plugin.version>
<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
<maven-source-plugin.version>3.3.0</maven-source-plugin.version>
<maven-javadoc-plugin.version>3.6.3</maven-javadoc-plugin.version>
<maven-nexus-staging-plugin.version>1.6.13</maven-nexus-staging-plugin.version>
<maven-gpg-plugin.version>3.0.1</maven-gpg-plugin.version>
<maven-gpg-plugin.version>3.2.2</maven-gpg-plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-checkstyle-plugin.version>3.1.2</maven-checkstyle-plugin.version>
<maven-checkstyle-plugin.version>3.3.1</maven-checkstyle-plugin.version>
<checkstyle.version>8.18</checkstyle.version>
<checkstyle.dir.path>${basedir}/codingstyle</checkstyle.dir.path>
<checkstyle.file.path>${checkstyle.dir.path}/soot_checkstyle_checks.xml</checkstyle.file.path>
<checkstyle.failOnViolation>true</checkstyle.failOnViolation>
<licence-check.failOnMissingHeader>true</licence-check.failOnMissingHeader>
<testcase.groups.excluded>categories.Java9Test,categories.Java11Test</testcase.groups.excluded>
<asm.version>9.6</asm.version>
<asm.version>9.7</asm.version>
</properties>
<build>
<finalName>sootclasses-trunk</finalName>
Expand Down Expand Up @@ -576,12 +576,12 @@
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.21.7</version>
<version>3.25.3</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.21.2</version>
<version>3.25.3</version>
</dependency>
</dependencies>

Expand Down Expand Up @@ -657,6 +657,7 @@
<configuration>
<!-- This is necessary for gpg to not try to use the pinentry programs -->
<gpgArguments>
<arg>--batch</arg>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
Expand Down
4 changes: 4 additions & 0 deletions src/main/generated/options/soot/AntTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@ public void setdrop_bodies_after_load(boolean arg) {
if(arg) addArg("-drop-bodies-after-load");
}

public void setnative_code(boolean arg) {
if(arg) addArg("-native-code");
}

public void setoutput_dir(String arg) {
addArg("-output-dir");
addArg(arg);
Expand Down
10 changes: 10 additions & 0 deletions src/main/generated/options/soot/options/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,11 @@ else if (false
|| option.equals("no-drop-bodies-after-load")
)
drop_bodies_after_load = false;
else if (false
|| option.equals("nc")
|| option.equals("native-code")
)
native_code = true;
else if (false
|| option.equals("d")
|| option.equals("output-dir")
Expand Down Expand Up @@ -1656,6 +1661,10 @@ public int src_prec() {
private boolean drop_bodies_after_load = true;
public void set_drop_bodies_after_load(boolean setting) { drop_bodies_after_load = setting; }

public boolean native_code() { return native_code; }
private boolean native_code = false;
public void set_native_code(boolean setting) { native_code = setting; }

public String output_dir() { return output_dir; }
public void set_output_dir(String setting) { output_dir = setting; }
private String output_dir = "";
Expand Down Expand Up @@ -1889,6 +1898,7 @@ public String getUsage() {
+ padOpt("-polyglot", "Use Java 1.4 Polyglot frontend instead of JastAdd")
+ padOpt("-permissive-resolving", "Use alternative sources when classes cannot be found using the normal resolving strategy")
+ padOpt("-drop-bodies-after-load", "Drop the method source after it has served its purpose of loading the method body")
+ padOpt("-nc, -native-code", "Enables native methods to be concrete. Needed for analyzing the Java Native Interface.")
+ "\nOutput Options:\n"
+ padOpt("-d ARG -output-dir ARG", "Store output files in ARG")
+ padOpt("-f ARG -output-format ARG", "Set output format for Soot")
Expand Down
32 changes: 18 additions & 14 deletions src/main/java/soot/AbstractASMBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,12 @@ protected void generateMethods() {
if (va == null) {
continue;
}
for (AnnotationTag at : va.getAnnotations()) {
AnnotationVisitor av = mv.visitParameterAnnotation(j, at.getType(),
(va.getVisibility() == AnnotationConstants.RUNTIME_VISIBLE));
generateAnnotationElems(av, at.getElems(), true);
if (va.hasAnnotations()) {
for (AnnotationTag at : va.getAnnotations()) {
AnnotationVisitor av = mv.visitParameterAnnotation(j, at.getType(),
(va.getVisibility() == AnnotationConstants.RUNTIME_VISIBLE));
generateAnnotationElems(av, at.getElems(), true);
}
}
}
}
Expand Down Expand Up @@ -503,17 +505,19 @@ protected void generateAnnotations(Object visitor, Host host) {
// Find all VisibilityAnnotationTags
VisibilityAnnotationTag vat = (VisibilityAnnotationTag) t;
boolean runTimeVisible = (vat.getVisibility() == AnnotationConstants.RUNTIME_VISIBLE);
for (AnnotationTag at : vat.getAnnotations()) {
AnnotationVisitor av = null;
if (visitor instanceof ClassVisitor) {
av = ((ClassVisitor) visitor).visitAnnotation(at.getType(), runTimeVisible);
} else if (visitor instanceof FieldVisitor) {
av = ((FieldVisitor) visitor).visitAnnotation(at.getType(), runTimeVisible);
} else if (visitor instanceof MethodVisitor) {
av = ((MethodVisitor) visitor).visitAnnotation(at.getType(), runTimeVisible);
}
if (vat.hasAnnotations()) {
for (AnnotationTag at : vat.getAnnotations()) {
AnnotationVisitor av = null;
if (visitor instanceof ClassVisitor) {
av = ((ClassVisitor) visitor).visitAnnotation(at.getType(), runTimeVisible);
} else if (visitor instanceof FieldVisitor) {
av = ((FieldVisitor) visitor).visitAnnotation(at.getType(), runTimeVisible);
} else if (visitor instanceof MethodVisitor) {
av = ((MethodVisitor) visitor).visitAnnotation(at.getType(), runTimeVisible);
}

generateAnnotationElems(av, at.getElems(), true);
generateAnnotationElems(av, at.getElems(), true);
}
}
} else if (t instanceof AnnotationDefaultTag && host instanceof SootMethod) {
// Visit AnnotationDefault on methods
Expand Down
20 changes: 14 additions & 6 deletions src/main/java/soot/FastHierarchy.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
Expand All @@ -58,6 +57,7 @@
public class FastHierarchy {

protected static final int USE_INTERVALS_BOUNDARY = 100;
private final boolean isDotNet = Options.v().src_prec() == Options.src_prec_dotnet;

protected Table<SootClass, NumberedString, SootMethod> typeToVtbl = HashBasedTable.create();

Expand Down Expand Up @@ -306,8 +306,16 @@ public boolean canStoreType(final Type child, final Type parent) {
// From Java Language Spec 2nd ed., Chapter 10, Arrays
return base == rtObject || base == rtSerializable || base == rtCloneable;
} else {
// We can story any_subtype_of(x) in a variable of type x
RefType childBase = ((AnySubType) child).getBase();
if (childBase == parent) {
return true;
}

// If the child is any_subtype_of(x) and the parent is not x, this only works if all known subclasses of x
// cast-compatible to the parent
Deque<SootClass> worklist = new ArrayDeque<SootClass>();
SootClass base = ((AnySubType) child).getBase().getSootClass();
SootClass base = childBase.getSootClass();
if (base.isInterface()) {
worklist.addAll(getAllImplementersOfInterface(base));
} else {
Expand Down Expand Up @@ -877,7 +885,7 @@ private SootMethod resolveMethod(final SootClass baseType, final SootClass decla
// When there is no proper dispatch found, we simply return null to let the caller decide what to do
SootMethod candidate = null;
boolean calleeExist = declaringClass.getMethodUnsafe(subsignature) != null;
for (SootClass concreteType = baseType; concreteType != null && ignoreList.add(concreteType);) {
for (SootClass concreteType = baseType; concreteType != null;) {
candidate = getSignaturePolymorphicMethod(concreteType, name, parameterTypes, returnType);
if (candidate != null) {
if (!calleeExist || isVisible(concreteType, declaringClass, candidate.getModifiers())) {
Expand All @@ -904,7 +912,7 @@ private SootMethod resolveMethod(final SootClass baseType, final SootClass decla
// determining the most specific super interface
HashSet<SootClass> interfaceIgnoreList = new HashSet<>();
for (SootClass concreteType = baseType; concreteType != null;) {
Queue<SootClass> worklist = new LinkedList<>(concreteType.getInterfaces());
Queue<SootClass> worklist = new ArrayDeque<>(concreteType.getInterfaces());
// we have to determine the "most specific super interface"
while (!worklist.isEmpty()) {
SootClass iFace = worklist.poll();
Expand Down Expand Up @@ -941,7 +949,7 @@ private SootMethod resolveMethod(final SootClass baseType, final SootClass decla
return candidate;
}

private boolean isHandleDefaultMethods() {
protected boolean isHandleDefaultMethods() {
int version = Options.v().java_version();
return version == 0 || version > 7;
}
Expand Down Expand Up @@ -985,7 +993,7 @@ private SootMethod getSignaturePolymorphicMethod(SootClass concreteType, String
returnType = method.getReturnType();
}
// if dotnet structs or generics
if (Options.v().src_prec() == Options.src_prec_dotnet) {
if (isDotNet) {
if (method.getParameterCount() == parameterTypes.size() && canStoreType(returnType, method.getReturnType())) {
boolean canStore = true;
for (int i = 0; i < method.getParameterCount(); i++) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/soot/MethodToContexts.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ public MethodToContexts(Iterator<MethodOrMethodContext> it) {
public void add(Iterator<MethodOrMethodContext> it) {
while (it.hasNext()) {
MethodOrMethodContext momc = it.next();
add(momc);
if (momc != null) {
add(momc);
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/main/java/soot/ModuleUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ public final ModuleClassNameWrapper makeWrapper(String className) {
* @return true, if module mode is used
*/
public static boolean module_mode() {
return G.v().soot_ModuleUtil().isInModuleMode();
}

/**
* Check if Soot is run with module mode enabled.
*
* @return true, if module mode is used
*/
public boolean isInModuleMode() {
return !Options.v().soot_modulepath().isEmpty();
}

Expand Down
7 changes: 4 additions & 3 deletions src/main/java/soot/RefType.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ protected RefType(String className) {
}

public static RefType v() {
if (ModuleUtil.module_mode()) {
return G.v().soot_ModuleRefType();
G g = G.v();
if (g.soot_ModuleUtil().isInModuleMode()) {
return g.soot_ModuleRefType();
} else {
return G.v().soot_RefType();
return g.soot_RefType();
}
}

Expand Down
18 changes: 14 additions & 4 deletions src/main/java/soot/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,11 @@ public Scene(Singletons.Global g) {
}

public static Scene v() {
if (ModuleUtil.module_mode()) {
return G.v().soot_ModuleScene();
G g = G.v();
if (g.soot_ModuleUtil().isInModuleMode()) {
return g.soot_ModuleScene();
} else {
return G.v().soot_Scene();
return g.soot_Scene();
}
}

Expand Down Expand Up @@ -2072,7 +2073,7 @@ public void setDoneResolving() {
doneResolving = true;
}

void setResolving(boolean value) {
public void setResolving(boolean value) {
doneResolving = value;
}

Expand Down Expand Up @@ -2202,4 +2203,13 @@ public LocalCreation createLocalCreation(Chain<Local> locals) {
public LocalCreation createLocalCreation(Chain<Local> locals, String prefix) {
return new DefaultLocalCreation(locals, prefix);
}

/**
* Resets the sootClassPath to null.
* This method allows for subsequent calls to {@link #loadNecessaryClasses()}
* to recompute and load the classes using updated configurations if provided.
*/
public void resetSootClassPathCache() {
this.sootClassPath = null;
}
}
2 changes: 1 addition & 1 deletion src/main/java/soot/SootMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public boolean isPhantom() {
* Returns true if this method is not phantom, abstract or native, i.e. this method can have a body.
*/
public boolean isConcrete() {
return !isPhantom() && !isAbstract() && !isNative();
return !isPhantom() && !isAbstract() && (!isNative() || Options.v().native_code());
}

/**
Expand Down
Loading

0 comments on commit 9a73239

Please sign in to comment.