Skip to content

Commit

Permalink
LocalNameStandardizer: dont rename Local if Type is not handled;
Browse files Browse the repository at this point in the history
TypeAssigner: change augmentation in cases of BottomType to unknownType
  • Loading branch information
swissiety committed Nov 6, 2023
1 parent 1a1b66f commit 5489b09
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ public enum BytecodeBodyInterceptors {
new UnusedLocalEliminator(),
new ConditionalBranchFolder(),
new EmptySwitchEliminator(),
new TypeAssigner()
// ms: is already called from typeassigner? new LocalNameStandardizer()
// new LocalNameStandardizer(),
);
new TypeAssigner(),
new LocalNameStandardizer());

@Nonnull private final List<BodyInterceptor> bodyInterceptors;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,72 +173,74 @@ public void interceptBody(@Nonnull Body.BodyBuilder builder, @Nonnull View<?> vi
allEssential &= isEssential;
}

if (containsInvoke || !allEssential) {
// Add all the statements which are used to compute values for the essential statements,
// recursively
allDefs = Body.collectDefs(stmtGraph.getNodes());

if (!allEssential) {
Set<Stmt> essentialStmts = new HashSet<>(stmts.size());
while (!deque.isEmpty()) {
Stmt stmt = deque.removeFirst();
if (essentialStmts.add(stmt)) {
for (Value value : stmt.getUses()) {
if (value instanceof Local) {
Local local = (Local) value;
Collection<Stmt> defs = allDefs.get(local);
if (defs != null) {
deque.addAll(defs);
}
if (!containsInvoke && allEssential) {
return;
}

// Add all the statements which are used to compute values for the essential statements,
// recursively
allDefs = Body.collectDefs(stmtGraph.getNodes());

if (!allEssential) {
Set<Stmt> essentialStmts = new HashSet<>(stmts.size());
while (!deque.isEmpty()) {
Stmt stmt = deque.removeFirst();
if (essentialStmts.add(stmt)) {
for (Value value : stmt.getUses()) {
if (value instanceof Local) {
Local local = (Local) value;
Collection<Stmt> defs = allDefs.get(local);
if (defs != null) {
deque.addAll(defs);
}
}
}
}
}

// Remove the dead statements
for (Stmt stmt : stmts) {
if (!essentialStmts.contains(stmt)) {
stmtGraph.removeNode(stmt);
}
// Remove the dead statements
for (Stmt stmt : stmts) {
if (!essentialStmts.contains(stmt)) {
stmtGraph.removeNode(stmt);
}
}
}

if (containsInvoke) {
allUses = Body.collectUses(stmtGraph.getNodes());
// Eliminate dead assignments from invokes such as x = f(), where x is no longer used
List<JAssignStmt> postProcess = new ArrayList<>();
for (Stmt stmt : stmts) {
if (stmt instanceof JAssignStmt) {
JAssignStmt assignStmt = (JAssignStmt) stmt;
if (assignStmt.containsInvokeExpr()) {
// Just find one use of Value which is essential
boolean deadAssignment = true;

List<Value> values = assignStmt.getUses();
for (Value value : values) {
if (!(value instanceof LValue)) {
continue;
}
for (Stmt use : allUses.get(value)) {
if (stmtGraph.containsNode(use)) {
deadAssignment = false;
break;
}
}
if (containsInvoke) {
allUses = Body.collectUses(stmtGraph.getNodes());
// Eliminate dead assignments from invokes such as x = f(), where x is no longer used
List<JAssignStmt> postProcess = new ArrayList<>();
for (Stmt stmt : stmts) {
if (stmt instanceof JAssignStmt) {
JAssignStmt assignStmt = (JAssignStmt) stmt;
if (assignStmt.containsInvokeExpr()) {
// Just find one use of Value which is essential
boolean deadAssignment = true;

List<Value> values = assignStmt.getUses();
for (Value value : values) {
if (!(value instanceof LValue)) {
continue;
}
if (deadAssignment) {
postProcess.add(assignStmt);
for (Stmt use : allUses.get(value)) {
if (stmtGraph.containsNode(use)) {
deadAssignment = false;
break;
}
}
}
if (deadAssignment) {
postProcess.add(assignStmt);
}
}
}
}

for (JAssignStmt assignStmt : postProcess) {
// Transform it into a simple invoke
Stmt newInvoke =
Jimple.newInvokeStmt(assignStmt.getInvokeExpr(), assignStmt.getPositionInfo());
stmtGraph.replaceNode(assignStmt, newInvoke);
}
for (JAssignStmt assignStmt : postProcess) {
// Transform it into a simple invoke
Stmt newInvoke =
Jimple.newInvokeStmt(assignStmt.getInvokeExpr(), assignStmt.getPositionInfo());
stmtGraph.replaceNode(assignStmt, newInvoke);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.model.Body;
import sootup.core.transform.BodyInterceptor;
import sootup.core.types.Type;
import sootup.core.views.View;
import sootup.java.bytecode.interceptors.typeresolving.types.BottomType;

// https://github.com/Sable/soot/blob/master/src/main/java/soot/jimple/toolkits/scalar/LocalNameStandardizer.java

Expand Down Expand Up @@ -64,10 +66,18 @@ public void interceptBody(@Nonnull Body.BodyBuilder builder, @Nonnull View<?> vi
while (iterator.hasNext()) {
Local local = iterator.next();
Local newLocal;
Type type = local.getType();

if (type instanceof BottomType) {
// TODO: log that likely the jimple is not formed correctly
// TODO: handle module signatures
type = view.getIdentifierFactory().getClassType("java.lang.Object");
}

if (local.isFieldLocal()) {
newLocal = lgen.generateFieldLocal(local.getType());
newLocal = lgen.generateFieldLocal(type);
} else {
newLocal = lgen.generateLocal(local.getType());
newLocal = lgen.generateLocal(type);
}
builder.replaceLocal(local, newLocal);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,10 @@
*/
public class TypeAssigner implements BodyInterceptor {

private final boolean standardizeNames;

public TypeAssigner() {
standardizeNames = true;
}

/**
* @param autoStandardizeNames controls whether the LocalNameStandardizer should execute after the
* type assignment
*/
public TypeAssigner(boolean autoStandardizeNames) {
this.standardizeNames = autoStandardizeNames;
}
public TypeAssigner() {}

@Override
public void interceptBody(@Nonnull Body.BodyBuilder builder, @Nonnull View<?> view) {
if (new TypeResolver((JavaView) view).resolve(builder) && standardizeNames) {
LocalNameStandardizer standardizer = new LocalNameStandardizer();
standardizer.interceptBody(builder, view);
}
new TypeResolver((JavaView) view).resolve(builder);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,22 @@ public CastCounter(
}

public int getCastCount(@Nonnull Typing typing) {
this.castCount = 0;
this.countOnly = true;
castCount = 0;
countOnly = true;
setTyping(typing);
for (Stmt stmt : builder.getStmts()) {
stmt.accept(this);
}
return this.castCount;
return castCount;
}

public int getCastCount() {
return this.castCount;
return castCount;
}

public void insertCastStmts(@Nonnull Typing typing) {
this.castCount = 0;
this.countOnly = false;
castCount = 0;
countOnly = false;
setTyping(typing);
for (Stmt stmt : Lists.newArrayList(builder.getStmts())) {
stmt.accept(this);
Expand All @@ -91,7 +91,7 @@ public void visit(@Nonnull Value value, @Nonnull Type stdType, @Nonnull Stmt stm
if (hierarchy.isAncestor(stdType, evaType)) {
return;
}
this.castCount++;
castCount++;
return;
}

Expand All @@ -112,8 +112,7 @@ public void visit(@Nonnull Value value, @Nonnull Type stdType, @Nonnull Stmt stm
if (evaType == null || hierarchy.isAncestor(stdType, evaType)) {
return;
}
this.castCount++;
// TODO: modifiers later must be added
castCount++;

final MutableStmtGraph stmtGraph = builder.getStmtGraph();
Local old_local;
Expand Down Expand Up @@ -143,18 +142,18 @@ public void visit(@Nonnull Value value, @Nonnull Type stdType, @Nonnull Stmt stm
newStmt = ((AbstractDefinitionStmt) stmt).withNewDef(new_local);
}
if (graph.containsNode(stmt)) {
builder.replaceStmt(stmt, newStmt);
this.stmt2NewStmt.put(oriStmt, newStmt);
graph.replaceNode(stmt, newStmt);
stmt2NewStmt.put(oriStmt, newStmt);
}
}

private void addUpdatedValue(Value oldValue, Value newValue, Stmt stmt) {
Map<Value, Value> map;
if (!this.changedValues.containsKey(stmt)) {
if (!changedValues.containsKey(stmt)) {
map = new HashMap<>();
this.changedValues.put(stmt, map);
changedValues.put(stmt, map);
} else {
map = this.changedValues.get(stmt);
map = changedValues.get(stmt);
}
map.put(oldValue, newValue);
if (stmt instanceof JAssignStmt && stmt.containsArrayRef()) {
Expand Down Expand Up @@ -183,7 +182,7 @@ private void addUpdatedValue(Value oldValue, Value newValue, Stmt stmt) {
}

private Local generateTempLocal(@Nonnull Type type) {
String name = "#l" + newLocalsCount++;
String name = "$#l" + newLocalsCount++;
return Jimple.newLocal(name, type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sootup.core.graph.StmtGraph;
import sootup.core.graph.MutableStmtGraph;
import sootup.core.jimple.basic.LValue;
import sootup.core.jimple.basic.Local;
import sootup.core.jimple.basic.Value;
Expand Down Expand Up @@ -56,7 +56,7 @@ public abstract class TypeChecker extends AbstractStmtVisitor<Stmt> {
private Typing typing;
protected final Body.BodyBuilder builder;

protected final StmtGraph<?> graph;
protected final MutableStmtGraph graph;

private static final Logger logger = LoggerFactory.getLogger(TypeChecker.class);

Expand All @@ -79,7 +79,7 @@ public void caseInvokeStmt(@Nonnull JInvokeStmt stmt) {

@Override
public void caseAssignStmt(@Nonnull JAssignStmt stmt) {
Value lhs = stmt.getLeftOp();
LValue lhs = stmt.getLeftOp();
Value rhs = stmt.getRightOp();
Type type_lhs = null;
if (lhs instanceof Local) {
Expand All @@ -96,10 +96,10 @@ public void caseAssignStmt(@Nonnull JAssignStmt stmt) {
Type type_rhs = typing.getType((Local) rhs);
// if base type of lhs is an object-like-type, retrieve its base type from array
// allocation site.
if (Type.isObjectLikeType(type_base)
|| (Type.isObject(type_base) && type_rhs instanceof PrimitiveType)) {
Map<LValue, Collection<Stmt>> defs =
Body.collectDefs(builder.getStmtGraph().getNodes());
if (type_base != null
&& (Type.isObjectLikeType(type_base)
|| (Type.isObject(type_base) && type_rhs instanceof PrimitiveType))) {
Map<LValue, Collection<Stmt>> defs = Body.collectDefs(graph.getNodes());
Collection<Stmt> defStmts = defs.get(base);
boolean findDef = false;
if (defStmts != null) {
Expand All @@ -118,18 +118,23 @@ public void caseAssignStmt(@Nonnull JAssignStmt stmt) {
}
}
}
if (!findDef) {
if (!findDef && type_rhs != null) {
arrayType = Type.createArrayType(type_rhs, 1);
}
}
}
if (arrayType == null) {
if (arrayType == null && type_base != null) {
arrayType = Type.createArrayType(type_base, 1);
}
}

if (arrayType == null) {
return;
}
type_lhs = arrayType.getElementType();
visit(base, arrayType, stmt);
visit(lhs, type_lhs, stmt);

} else if (lhs instanceof JFieldRef) {
if (lhs instanceof JInstanceFieldRef) {
visit(
Expand All @@ -151,7 +156,7 @@ public void caseAssignStmt(@Nonnull JAssignStmt stmt) {
arrayType = (ArrayType) type_base;
} else {
if (type_base instanceof NullType || Type.isObjectLikeType(type_base)) {
Map<LValue, Collection<Stmt>> defs = Body.collectDefs(builder.getStmtGraph().getNodes());
Map<LValue, Collection<Stmt>> defs = Body.collectDefs(graph.getNodes());
Deque<StmtLocalPair> worklist = new ArrayDeque<>();
Set<StmtLocalPair> visited = new HashSet<>();
worklist.add(new StmtLocalPair(stmt, base));
Expand Down
Loading

0 comments on commit 5489b09

Please sign in to comment.