use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class MethodNodePrinter method emitCode.
public void emitCode(MethodNode mn) {
ControlFlowGraph cfg = this.getCfg(mn);
this.emitHandlers(cfg);
this.sw.newline().print(".code {").tab();
this.emitCfg(cfg);
this.sw.untab().newline().print("}");
}
use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class DominanceLivenessAnalyser method reduce.
private ControlFlowGraph reduce(ControlFlowGraph cfg, Set<FastGraphEdge<BasicBlock>> back) {
ControlFlowGraph reducedCfg = cfg.copy();
for (FastGraphEdge<BasicBlock> e : back) {
reducedCfg.removeEdge(e.src(), (FlowEdge<BasicBlock>) e);
backTargets.add(e.dst());
backEdges.getNonNull(e.src()).add(e.dst());
}
return reducedCfg;
}
use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class SSAGenPass method splitBlock.
private BasicBlock splitBlock(BasicBlock b, int to) {
/* eg. split the block as follows:
*
* NAME:
* stmt1
* stmt2
* stmt3
* stmt4
* stmt5
* jump L1, L2
* [jump edge to L1]
* [jump edge to L2]
* [exception edges]
*
* split at 3, create a new block (incoming
* immediate), transfer instruction from 0
* to index into new block, create immediate
* edge to old block, clone exception edges,
* redirect pred edges.
*
* 1/9/16: we also need to modify the last
* statement of the pred blocks to
* point to NAME'.
*
* NAME':
* stmt1
* stmt2
* stmt3
* [immediate to NAME]
* NAME:
* stmt4
* stmt5
* jump L1, L2
* [jump edge to L1]
* [jump edge to L2]
* [exception edges]
*/
// split block
ControlFlowGraph cfg = builder.graph;
BasicBlock newBlock = new BasicBlock(cfg, graphSize++, new LabelNode());
b.transferUp(newBlock, to);
cfg.addVertex(newBlock);
// redo ranges
for (ExceptionRange<BasicBlock> er : cfg.getRanges()) {
if (er.containsVertex(b))
er.addVertexBefore(b, newBlock);
}
// redirect b preds into newBlock and remove them.
Set<FlowEdge<BasicBlock>> oldEdges = new HashSet<>(cfg.getReverseEdges(b));
for (FlowEdge<BasicBlock> e : oldEdges) {
BasicBlock p = e.src();
FlowEdge<BasicBlock> c;
if (e instanceof TryCatchEdge) {
// b is ehandler
TryCatchEdge<BasicBlock> tce = (TryCatchEdge<BasicBlock>) e;
if (tce.dst() != tce.erange.getHandler()) {
System.err.println(builder.method.owner + "#" + builder.method.name);
System.err.println(cfg);
System.err.println("Very odd split case. please investigate");
System.err.println("Offending postsplit block: " + b);
System.err.println("Offending newblock: " + newBlock);
System.err.println("Offending edge: " + tce);
System.err.println("Offending erange: " + tce.erange);
}
if (tce.erange.getHandler() != newBlock) {
tce.erange.setHandler(newBlock);
cfg.addEdge(tce.src(), tce.clone(tce.src(), null));
cfg.removeEdge(tce.src(), tce);
}
} else {
c = e.clone(p, newBlock);
cfg.addEdge(p, c);
cfg.removeEdge(p, e);
}
// Fix flow instruction targets
if (!p.isEmpty()) {
Stmt last = p.get(p.size() - 1);
int op = last.getOpcode();
if (e instanceof ConditionalJumpEdge) {
if (op != Opcode.COND_JUMP)
throw new IllegalArgumentException("wrong flow instruction");
ConditionalJumpStmt j = (ConditionalJumpStmt) last;
// assertTarget(last, j.getTrueSuccessor(), b);
if (j.getTrueSuccessor() == b)
j.setTrueSuccessor(newBlock);
} else if (e instanceof UnconditionalJumpEdge) {
if (op != Opcode.UNCOND_JUMP)
throw new IllegalArgumentException("wrong flow instruction");
UnconditionalJumpStmt j = (UnconditionalJumpStmt) last;
assertTarget(j, j.getTarget(), b);
j.setTarget(newBlock);
} else if (e instanceof SwitchEdge) {
if (op != Opcode.SWITCH_JUMP)
throw new IllegalArgumentException("wrong flow instruction.");
SwitchStmt s = (SwitchStmt) last;
for (Entry<Integer, BasicBlock> en : s.getTargets().entrySet()) {
BasicBlock t = en.getValue();
if (t == b) {
en.setValue(newBlock);
}
}
}
}
}
if (!checkCloneHandler(newBlock)) {
System.err.println(cfg);
System.err.println(newBlock.getDisplayName());
System.err.println(b.getDisplayName());
throw new IllegalStateException("the new block should always need a handler..?");
}
// clone exception edges
for (FlowEdge<BasicBlock> e : cfg.getEdges(b)) {
if (e.getType() == FlowEdges.TRYCATCH) {
// second param is discarded (?)
TryCatchEdge<BasicBlock> c = ((TryCatchEdge<BasicBlock>) e).clone(newBlock, null);
cfg.addEdge(newBlock, c);
}
}
// create immediate to newBlock
cfg.addEdge(newBlock, new ImmediateEdge<>(newBlock, b));
// update assigns
Set<Local> assignedLocals = new HashSet<>();
for (Stmt stmt : b) if (stmt.getOpcode() == Opcode.LOCAL_STORE)
assignedLocals.add(((CopyVarStmt) stmt).getVariable().getLocal());
for (Stmt stmt : newBlock) {
if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
Local copyLocal = ((CopyVarStmt) stmt).getVariable().getLocal();
Set<BasicBlock> set = builder.assigns.get(copyLocal);
set.add(newBlock);
if (!assignedLocals.contains(copyLocal))
set.remove(b);
}
}
return newBlock;
}
use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class Boot method main.
public static void main(String[] args) throws Exception {
sections = new LinkedList<>();
logging = true;
File rtjar = new File("res/rt.jar");
// Load input jar
File f = locateRevFile(135);
// File f = new File("res/allatori6.1san.jar");
section("Preparing to run on " + f.getAbsolutePath());
SingleJarDownloader<ClassNode> dl = new SingleJarDownloader<>(new JarInfo(f));
dl.download();
String name = f.getName().substring(0, f.getName().length() - 4);
// ApplicationClassSource app = new ApplicationClassSource(name, dl.getJarContents().getClassContents());
//
ApplicationClassSource app = new ApplicationClassSource("test", ClassHelper.parseClasses(CGExample.class));
// app.addLibraries(new InstalledRuntimeClassSource(app));
app.addLibraries(rt(app, rtjar), new InstalledRuntimeClassSource(app));
section("Initialising context.");
AnalysisContext cxt = new BasicAnalysisContext.BasicContextBuilder().setApplication(app).setInvocationResolver(new DefaultInvocationResolver(app)).setCache(new IRCache(ControlFlowGraphBuilder::build)).setApplicationContext(new SimpleApplicationContext(app)).build();
section("Expanding callgraph and generating cfgs.");
IRCallTracer tracer = new IRCallTracer(cxt);
for (MethodNode m : cxt.getApplicationContext().getEntryPoints()) {
// System.out.println(m);
tracer.trace(m);
if (m.instructions.size() > 500 && m.instructions.size() < 100) {
System.out.println(m);
System.out.println(cxt.getIRCache().get(m));
}
}
for (ClassNode cn : app.iterate()) {
TabbedStringWriter sw = new TabbedStringWriter();
sw.setTabString(" ");
IPropertyDictionary settings = PropertyHelper.createDictionary();
// settings.put(new BooleanProperty(ASMPrinter.PROP_ACCESS_FLAG_SAFE, true));
ClassPrinter cp = new ClassPrinter(sw, settings, new FieldNodePrinter(sw, settings), new MethodNodePrinter(sw, settings) {
@Override
protected ControlFlowGraph getCfg(MethodNode mn) {
return cxt.getIRCache().getFor(mn);
}
});
cp.print(cn);
System.out.println(sw.toString());
}
section0("...generated " + cxt.getIRCache().size() + " cfgs in %fs.%n", "Preparing to transform.");
// do passes
PassGroup masterGroup = new PassGroup("MasterController");
for (IPass p : getTransformationPasses()) {
masterGroup.add(p);
}
run(cxt, masterGroup);
// for(MethodNode m : cxt.getIRCache().getActiveMethods()) {
// if(m.instructions.size() > 100 && m.instructions.size() < 500) {
// System.out.println(cxt.getIRCache().get(m));
// }
// }
section("Retranslating SSA IR to standard flavour.");
for (Entry<MethodNode, ControlFlowGraph> e : cxt.getIRCache().entrySet()) {
MethodNode mn = e.getKey();
ControlFlowGraph cfg = e.getValue();
BoissinotDestructor.leaveSSA(cfg);
cfg.getLocals().realloc(cfg);
(new ControlFlowGraphDumper(cfg, mn)).dump();
}
section("Rewriting jar.");
// dumpJar(app, dl, masterGroup, "out/osb5.jar");
section("Finished.");
}
use of org.mapleir.ir.cfg.ControlFlowGraph in project maple-ir by LLVM-but-worse.
the class ConcreteStaticInvocationPass method accept.
@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
int fixed = 0;
InvocationResolver resolver = cxt.getInvocationResolver();
for (ClassNode cn : cxt.getApplication().iterate()) {
for (MethodNode mn : cn.methods) {
ControlFlowGraph cfg = cxt.getIRCache().getFor(mn);
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.isStatic()) {
MethodNode invoked = resolver.resolveStaticCall(invoke.getOwner(), invoke.getName(), invoke.getDesc());
if (invoked != null) {
if (!invoked.owner.name.equals(invoke.getOwner())) {
invoke.setOwner(invoked.owner.name);
fixed++;
}
}
}
}
}
}
}
}
}
System.out.printf(" corrected %d dodgy static calls.%n", fixed);
return fixed;
}
Aggregations