Search in sources :

Example 1 with ExceptionRange

use of org.mapleir.flowgraph.ExceptionRange in project maple-ir by LLVM-but-worse.

the class SSAGenPass method canTransferHandlers.

private boolean canTransferHandlers(BasicBlock db, BasicBlock ub) {
    List<ExceptionRange<BasicBlock>> dr = db.getProtectingRanges();
    List<ExceptionRange<BasicBlock>> ur = ub.getProtectingRanges();
    int drs = dr.size(), urs = ur.size();
    boolean transferable = false;
    if (drs > 0) {
        if (urs == 0) {
        // we can clone the range information.
        // for(ExceptionRange<BasicBlock> e : dr) {
        // e.addVertex(ub);
        // builder.graph.addEdge(ub, new TryCatchEdge<>(ub, e));
        // }
        // 
        // transferable = true;
        } else {
            dr.removeAll(ur);
            if (dr.size() == 0) {
                transferable = true;
            }
        }
    } else if (urs == 0) {
        transferable = true;
    }
    return transferable;
}
Also used : ExceptionRange(org.mapleir.flowgraph.ExceptionRange) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint)

Example 2 with ExceptionRange

use of org.mapleir.flowgraph.ExceptionRange in project maple-ir by LLVM-but-worse.

the class GenerationPass method makeRanges.

private void makeRanges(List<BasicBlock> order) {
    // System.out.println(builder.graph);
    // BasicDotConfiguration<ControlFlowGraph, BasicBlock, FlowEdge<BasicBlock>> config = new BasicDotConfiguration<>(DotConfiguration.GraphType.DIRECTED);
    // DotWriter<ControlFlowGraph, BasicBlock, FlowEdge<BasicBlock>> writer = new DotWriter<>(config, builder.graph);
    // writer.removeAll().add(new ControlFlowGraphDecorator().setFlags(ControlFlowGraphDecorator.OPT_DEEP)).setName("test9999").export();
    Map<String, ExceptionRange<BasicBlock>> ranges = new HashMap<>();
    for (TryCatchBlockNode tc : builder.method.tryCatchBlocks) {
        // System.out.printf("from %d to %d, handler:%d, type:%s.%n", insns.indexOf(tc.start), insns.indexOf(tc.end), insns.indexOf(tc.handler), tc.type);
        // System.out.println(String.format("%s:%s:%s", BasicBlock.createBlockName(insns.indexOf(tc.start)), BasicBlock.createBlockName(insns.indexOf(tc.end)), builder.graph.getBlock(tc.handler).getId()));
        int start = builder.graph.getBlock(tc.start).getNumericId();
        int end = builder.graph.getBlock(tc.end).getNumericId() - 1;
        List<BasicBlock> range = range(order, start, end);
        BasicBlock handler = builder.graph.getBlock(tc.handler);
        String key = String.format("%d:%d:%s", start, end, handler.getNumericId());
        ExceptionRange<BasicBlock> erange;
        if (ranges.containsKey(key)) {
            erange = ranges.get(key);
        } else {
            erange = new ExceptionRange<>(tc);
            erange.setHandler(handler);
            erange.addVertices(range);
            ranges.put(key, erange);
            if (!erange.isContiguous()) {
                System.out.println(erange + " not contiguous");
            }
            builder.graph.addRange(erange);
        }
        /* add L; so that the internal descriptor here matches the
			 * one provided by Type.getType(Class) and therefore
			 * ExceptionAnalysis.getType(Class). 
			 * 
			 * 26/08/17: changed Type.getType to return consistent
			 * object refs and to not create Types of sort METHOD
			 * if the given descriptor isn't intended for getType
			 * (getObjectType instead), shouldn't have this problem now.*/
        erange.addType(tc.type != null ? Type.getType("L" + tc.type + ";") : TypeUtils.THROWABLE);
        ListIterator<BasicBlock> lit = range.listIterator();
        while (lit.hasNext()) {
            BasicBlock block = lit.next();
            builder.graph.addEdge(block, new TryCatchEdge<>(block, erange));
        }
    }
}
Also used : ExceptionRange(org.mapleir.flowgraph.ExceptionRange) BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Example 3 with ExceptionRange

use of org.mapleir.flowgraph.ExceptionRange in project maple-ir by LLVM-but-worse.

the class NaturalisationPass1 method mergeImmediates.

int mergeImmediates() {
    class MergePair {

        final BasicBlock src;

        final BasicBlock dst;

        MergePair(BasicBlock src, BasicBlock dst) {
            this.src = src;
            this.dst = dst;
        }
    }
    List<MergePair> merges = new ArrayList<>();
    Map<BasicBlock, BasicBlock> remap = new HashMap<>();
    Map<BasicBlock, List<ExceptionRange<BasicBlock>>> ranges = new HashMap<>();
    for (BasicBlock b : builder.graph.vertices()) {
        BasicBlock in = b.getIncomingImmediate();
        if (in == null) {
            continue;
        }
        if (in.isFlagSet(BasicBlock.FLAG_NO_MERGE)) {
            continue;
        }
        Set<FlowEdge<BasicBlock>> inSuccs = in.getSuccessors(e -> !(e instanceof TryCatchEdge));
        if (inSuccs.size() != 1 || builder.graph.getReverseEdges(b).size() != 1) {
            continue;
        }
        List<ExceptionRange<BasicBlock>> range1 = b.getProtectingRanges();
        List<ExceptionRange<BasicBlock>> range2 = in.getProtectingRanges();
        if (!range1.equals(range2)) {
            continue;
        }
        ranges.put(b, range1);
        ranges.put(in, range2);
        merges.add(new MergePair(in, b));
        remap.put(in, in);
        remap.put(b, b);
    }
    for (MergePair p : merges) {
        BasicBlock src = remap.get(p.src);
        BasicBlock dst = p.dst;
        dst.transfer(src);
        for (FlowEdge<BasicBlock> e : builder.graph.getEdges(dst)) {
            // to clone these.
            if (e.getType() != FlowEdges.TRYCATCH) {
                BasicBlock edst = e.dst();
                edst = remap.getOrDefault(edst, edst);
                builder.graph.addEdge(src, e.clone(src, edst));
            }
        }
        builder.graph.removeVertex(dst);
        remap.put(dst, src);
        for (ExceptionRange<BasicBlock> r : ranges.get(src)) {
            r.removeVertex(dst);
        }
        for (ExceptionRange<BasicBlock> r : ranges.get(dst)) {
            r.removeVertex(dst);
        }
    // System.out.printf("Merged %s into %s.%n", dst.getId(), src.getId());
    }
    // we need to update the assigns map if we change the cfg.
    for (Entry<Local, Set<BasicBlock>> e : builder.assigns.entrySet()) {
        Set<BasicBlock> set = e.getValue();
        Set<BasicBlock> copy = new HashSet<>(set);
        for (BasicBlock b : copy) {
            BasicBlock r = remap.getOrDefault(b, b);
            if (r != b) {
                set.remove(b);
                set.add(r);
            }
        }
    }
    return merges.size();
}
Also used : FlowEdge(org.mapleir.flowgraph.edges.FlowEdge) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) BasicBlock(org.mapleir.ir.cfg.BasicBlock) ArrayList(java.util.ArrayList) Local(org.mapleir.ir.locals.Local) TryCatchEdge(org.mapleir.flowgraph.edges.TryCatchEdge) ExceptionRange(org.mapleir.flowgraph.ExceptionRange) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 4 with ExceptionRange

use of org.mapleir.flowgraph.ExceptionRange in project maple-ir by LLVM-but-worse.

the class MethodNodePrinter method emitHandlers.

private void emitHandlers(ControlFlowGraph cfg) {
    List<ExceptionRange<BasicBlock>> ranges = cfg.getRanges();
    if (ranges.size() > 0) {
        List<BasicBlock> allNodes = new ArrayList<>(cfg.vertices());
        List<Map<String, String>> handlerEntries = new ArrayList<>();
        for (ExceptionRange<BasicBlock> range : ranges) {
            List<BasicBlock> nodes = range.getNodes();
            // key order for nice print
            Map<String, String> entry = new LinkedHashMap<>();
            entry.put("start", nodes.get(0).getDisplayName());
            BasicBlock end = nodes.get(nodes.size() - 1);
            // exclusive
            BasicBlock endNext = allNodes.get(allNodes.indexOf(end) + 1);
            entry.put("end", endNext.getDisplayName());
            entry.put("handler", range.getHandler().getDisplayName());
            handlerEntries.add(entry);
        }
        this.emitDirective("handlers", handlerEntries);
    }
}
Also used : ExceptionRange(org.mapleir.flowgraph.ExceptionRange) BasicBlock(org.mapleir.ir.cfg.BasicBlock) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

ExceptionRange (org.mapleir.flowgraph.ExceptionRange)4 BasicBlock (org.mapleir.ir.cfg.BasicBlock)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 FlowEdge (org.mapleir.flowgraph.edges.FlowEdge)1 TryCatchEdge (org.mapleir.flowgraph.edges.TryCatchEdge)1 Constraint (org.mapleir.ir.cfg.builder.ssaopt.Constraint)1 Local (org.mapleir.ir.locals.Local)1