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.
package sootup.analysis.interprocedural.icfg;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2022-2023 Palaniappan Muthuraman, Jonas Klauke
* %%
* 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.*;
import java.util.stream.Collectors;
import sootup.callgraph.CallGraph;
import sootup.core.graph.BasicBlock;
import sootup.core.graph.StmtGraph;
import sootup.core.jimple.common.expr.JNewExpr;
import sootup.core.jimple.common.stmt.JAssignStmt;
import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.model.SootMethod;
import sootup.core.signatures.MethodSignature;
import sootup.core.signatures.MethodSubSignature;
import sootup.core.types.VoidType;
import sootup.core.util.DotExporter;
import sootup.core.views.View;
public class ICFGDotExporter {
public static String buildICFGGraph(
Map> signatureToStmtGraph, View view, CallGraph callGraph) {
final StringBuilder sb = new StringBuilder();
DotExporter.buildDiGraphObject(sb);
Map calls;
calls = computeCalls(signatureToStmtGraph, view, callGraph);
for (Map.Entry> entry : signatureToStmtGraph.entrySet()) {
String graph = DotExporter.buildGraph(entry.getValue(), true, calls, entry.getKey());
sb.append(graph).append("\n");
}
sb.append("}");
return sb.toString();
}
/**
* This method finds out all the calls made in the given StmtGraphs, so it can be edged to other
* methods.
*/
public static Map computeCalls(
Map> stmtGraphSet, View view, CallGraph callgraph) {
Map calls = new HashMap<>();
for (Map.Entry> entry : stmtGraphSet.entrySet()) {
StmtGraph> stmtGraph = entry.getValue();
MethodSignature source = entry.getKey();
Collection extends BasicBlock>> blocks;
try {
blocks = stmtGraph.getBlocksSorted();
} catch (Exception e) {
blocks = stmtGraph.getBlocks();
}
for (BasicBlock> block : blocks) {
List stmts = block.getStmts();
for (Stmt stmt : stmts) {
if (stmt.containsInvokeExpr()) {
MethodSignature target = stmt.getInvokeExpr().getMethodSignature();
int hashCode = stmt.hashCode();
calls.put(hashCode, target);
// compute all the classes that are made to the subclasses as well
connectEdgesToSubClasses(source, target, view, calls, callgraph);
} else if (stmt instanceof JAssignStmt) {
JAssignStmt jAssignStmt = (JAssignStmt) stmt;
Integer currentHashCode = stmt.hashCode();
if (jAssignStmt.getRightOp() instanceof JNewExpr) {
// if the statement is a new expression, then there will be calls to its static
// initializers (init and clinit), so need to compute calls to them as well
for (MethodSignature methodSignature : stmtGraphSet.keySet()) {
SootMethod clintMethod =
view.getMethod(methodSignature.getDeclClassType().getStaticInitializer())
.orElse(null);
if (clintMethod != null) {
if (!calls.containsKey(stmt.hashCode())) {
calls.put(stmt.hashCode(), methodSignature);
} else {
MethodSignature secondInitMethodSignature = calls.get(currentHashCode);
currentHashCode =
stmtGraphSet.get(secondInitMethodSignature).getStartingStmt().hashCode();
calls.put(currentHashCode, methodSignature);
}
}
}
}
}
}
}
}
return calls;
}
public static Set getMethodSignatureInSubClass(
MethodSignature source, MethodSignature target, CallGraph callGraph) {
if (!callGraph.containsMethod(source) || !callGraph.containsMethod(target)) {
return Collections.emptySet();
}
return callGraph.callsFrom(source).stream()
.filter(
methodSignature -> methodSignature.getSubSignature().equals(target.getSubSignature()))
.collect(Collectors.toSet());
}
public static void connectEdgesToSubClasses(
MethodSignature source,
MethodSignature target,
View view,
Map calls,
CallGraph callgraph) {
Set methodSignatureInSubClass =
getMethodSignatureInSubClass(source, target, callgraph);
methodSignatureInSubClass.forEach(
subclassmethodSignature -> {
Optional extends SootMethod> method = view.getMethod(target);
MethodSignature initMethod =
new MethodSignature(
subclassmethodSignature.getDeclClassType(),
new MethodSubSignature(
"", Collections.emptyList(), VoidType.getInstance()));
if (method.isPresent()
&& !subclassmethodSignature.toString().equals(initMethod.toString())) {
if (method.get().hasBody()) {
calls.put(
method.get().getBody().getStmtGraph().getStartingStmt().hashCode(),
subclassmethodSignature);
}
}
});
}
}