use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.
the class ConstantExpressionEvaluatorPass method accept.
@Override
public PassResult accept(PassContext pcxt) {
AnalysisContext cxt = pcxt.getAnalysis();
branchesEvaluated = 0;
exprsEvaluated = 0;
IPConstAnalysisVisitor vis = new IPConstAnalysisVisitor(cxt);
IPAnalysis.create(cxt, vis);
for (; ; ) {
int prevExprsEval = exprsEvaluated;
int prevBranchesEval = branchesEvaluated;
for (ClassNode cn : cxt.getApplication().iterate()) {
for (MethodNode m : cn.getMethods()) {
processMethod(m, vis, cxt.getIRCache().getFor(m));
}
}
if (prevExprsEval == exprsEvaluated && prevBranchesEval == branchesEvaluated) {
break;
}
}
System.out.printf(" evaluated %d constant expressions.%n", exprsEvaluated);
System.out.printf(" eliminated %d constant branches.%n", branchesEvaluated);
return PassResult.with(pcxt, this).finished(exprsEvaluated).make();
}
use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.
the class MethodRenamerPass method accept.
@Override
public PassResult accept(PassContext pcxt) {
AnalysisContext cxt = pcxt.getAnalysis();
ApplicationClassSource source = cxt.getApplication();
InvocationResolver resolver = cxt.getInvocationResolver();
Map<MethodNode, String> remapped = new HashMap<>();
int totalMethods = 0;
for (ClassNode cn : source.iterate()) {
totalMethods += cn.getMethods().size();
}
int i = RenamingUtil.computeMinimum(totalMethods);
for (ClassNode cn : source.iterate()) {
for (MethodNode m : cn.getMethods()) {
if (!heuristic.shouldRename(m.getName(), m.node.access)) {
// System.out.println("Heuristic bypass meth " + m.name);
continue;
}
if (remapped.containsKey(m)) {
continue;
}
if (Modifier.isStatic(m.node.access)) {
if (!m.getName().equals("<clinit>") && !SimpleApplicationContext.isMainMethod(m)) {
String newName = RenamingUtil.createName(i++);
remapped.put(m, newName);
}
} else {
if (!m.getName().equals("<init>")) {
// Set<ClassNode> classes = source.getStructures().dfsTree(m.owner, true, true, true);
// Set<MethodNode> methods = getVirtualMethods(cxt, classes, m.name, m.desc);
Set<MethodNode> methods = resolver.getHierarchyMethodChain(m.owner, m.getName(), m.node.desc, true);
if (canRename(cxt, methods)) {
String newName = RenamingUtil.createName(i++);
for (MethodNode o : methods) {
// Set<MethodNode> s2 = InvocationResolver.getHierarchyMethodChain(cxt, o.owner, o.name, m.desc, true);
/*if(!methods.equals(s2)) {
System.err.printf("m: %s%n", m);
System.err.printf("o: %s%n", o);
System.err.println("this ms::");
for(MethodNode s : methods) {
System.err.printf(" %s%n", s);
}
System.err.println("o ms::");
for(MethodNode s : s2) {
System.err.printf(" %s%n", s);
}
throw new IllegalStateException();
}*/
/*if(remapped.containsKey(o)) {
System.err.printf("m: %s%n", m);
System.err.printf("o: %s%n", o);
System.err.println("this ms::");
for(MethodNode s : methods) {
System.err.printf(" %s%n", s);
}
System.err.println("o ms::");
for(MethodNode s : InvocationResolver.getHierarchyMethodChain(cxt, o.owner, o.name, m.desc, true)) {
System.err.printf(" %s%n", s);
}
System.err.println(" o debugset::");
for(MethodNode s : debugMap.get(o)) {
System.err.printf(" %s%n", s);
}
System.err.printf("on: %s%n", remapped.get(o));
System.err.printf("nn: %s%n", newName);
throw new IllegalStateException();
}*/
remapped.put(o, newName);
}
/*for(MethodNode hm : methods) {
debugMap.put(hm, methods);
}*/
} else {
System.out.println(" can't rename: " + methods);
}
}
}
}
}
rename(cxt, remapped, true);
System.out.printf(" Remapped %d/%d methods.%n", remapped.size(), totalMethods);
return PassResult.with(pcxt, this).finished().make();
}
use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.
the class MethodRenamerPass method rename.
public static void rename(AnalysisContext cxt, Map<MethodNode, String> remapped, boolean warn) {
ApplicationClassSource source = cxt.getApplication();
InvocationResolver resolver = cxt.getInvocationResolver();
for (ClassNode cn : source.iterate()) {
{
if (cn.node.outerMethod != null) {
// ClassNode owner = tree.getClass(cn.node.outerClass);
System.out.println("Outer: " + cn.node.outerClass + "." + cn.node.outerMethod + " " + cn.node.outerMethodDesc);
cn.node.outerClass = null;
cn.node.outerMethod = null;
cn.node.outerMethodDesc = null;
// System.out.println(owner.name);
// do {
// for(MethodNode m : owner.methods) {
// System.out.println(m);
// if(m.name.equals(cn.outerMethod) && m.desc.equals(cn.outerMethodDesc)) {
// System.out.println("m: " + m);
// }
// }
// owner = tree.getClass(owner.superName);
// System.out.println(cn.superName);
// System.out.println(owner);
// } while(owner != null);
}
}
Set<Expr> visited = new HashSet<>();
for (MethodNode m : cn.getMethods()) {
ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == Opcode.INVOKE) {
InvocationExpr invoke = (InvocationExpr) e;
if (invoke.isDynamic())
throw new UnsupportedOperationException();
if (visited.contains(invoke)) {
throw new RuntimeException(invoke.toString());
}
visited.add(invoke);
if (invoke.getOwner().startsWith("[")) {
System.err.println(" ignore array object invoke: " + invoke + ", owner: " + invoke.getOwner());
continue;
}
if (invoke.isStatic()) {
MethodNode site = resolver.resolveStaticCall(invoke.getOwner(), invoke.getName(), invoke.getDesc());
if (site != null) {
if (remapped.containsKey(site)) {
invoke.setName(remapped.get(site));
} else {
if (warn && mustMark(source, invoke.getOwner())) {
System.err.println(" invalid site(s): " + invoke);
}
}
} else {
if (mustMark(source, invoke.getOwner())) {
System.err.printf(" can't resolve(s) %s ; %s.%s %s%n", invoke, invoke.getOwner(), invoke.getName(), invoke.getDesc());
if (invoke.getOwner().equals("hey")) {
for (MethodNode mm : cxt.getApplication().findClassNode(invoke.getOwner()).getMethods()) {
System.out.println(mm);
}
throw new UnsupportedOperationException();
}
}
}
} else {
// Set<MethodNode> sites = resolver.resolveVirtualCalls(invoke.getOwner(), invoke.getName(), invoke.getDesc());
// Set<ClassNode> classes = source.getStructures().dfsTree(cn, true, true, true);
// Set<MethodNode> sites = getVirtualMethods(cxt, classes, invoke.getName(), invoke.getDesc());
Set<MethodNode> sites = resolver.getHierarchyMethodChain(source.findClassNode(invoke.getOwner()), invoke.getName(), invoke.getDesc(), true);
if (sites.size() > 0) {
/* all of the sites must be linked by the same name,
* so we can use any to find the new name. */
boolean anyContains = false;
boolean allContains = true;
for (MethodNode s : sites) {
anyContains |= remapped.containsKey(s);
allContains &= remapped.containsKey(s);
}
if (anyContains && !allContains) {
System.err.println("mismatch: ");
// System.err.println(classes);
System.err.println(sites);
throw new RuntimeException();
}
MethodNode site = sites.iterator().next();
if (remapped.containsKey(site)) {
invoke.setName(remapped.get(site));
} else {
if (warn && !site.getName().equals("<init>") && canRename(cxt, sites)) {
System.err.println(" invalid site(v): " + invoke + ", " + sites);
}
}
} else {
if (mustMark(source, invoke.getOwner())) {
System.err.println(" can't resolve(v) " + invoke + ", owner: " + invoke.getOwner() + " desc " + invoke.getDesc());
// System.err.println(" classes: " + classes);
}
}
}
}
}
}
}
}
}
/* Rename the methods after as we need to resolve
* them using the old names during the invocation
* analysis above. */
for (Entry<MethodNode, String> e : remapped.entrySet()) {
// System.out.printf("%s -> %s%n", e.getKey(), e.getValue());
e.getKey().node.name = e.getValue();
}
}
use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.
the class ReflectiveFunctorFactory method makeBase.
private MethodNode makeBase(String name, String desc) {
ClassNode owner = new ClassNode();
owner.node.version = Opcodes.V1_7;
owner.node.name = name;
owner.node.superName = "java/lang/Object";
owner.node.access = Opcodes.ACC_PUBLIC;
MethodNode m = new MethodNode(new org.objectweb.asm.tree.MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "eval", desc, null, null), owner);
owner.addMethod(m);
return m;
}
use of org.mapleir.asm.ClassNode in project maple-ir by LLVM-but-worse.
the class ReflectiveFunctorFactory method buildBridge.
private <T> EvaluationFunctor<T> buildBridge(MethodNode m) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
ClassNode owner = m.owner;
owner.node.accept(cw);
byte[] bytes = cw.toByteArray();
Class<?> clazz = classLoader.make(owner.getName(), bytes);
for (Method method : clazz.getDeclaredMethods()) {
if (method.getName().equals("eval")) {
EvaluationFunctor<T> f = new ReflectiveFunctor<>(method);
cache.put(owner.getName(), f);
return f;
}
}
throw new UnsupportedOperationException();
}
Aggregations