/** * Walks the method and determines which internal subroutine(s), if any, * each instruction is a method of. */ private void markSubroutines() { BitSet anyvisited = new BitSet(); // First walk the main subroutine and find all those instructions which // can be reached without invoking any JSR at all markSubroutineWalk(mainSubroutine, 0, anyvisited); // Go through the head of each subroutine and find any nodes reachable // to that subroutine without following any JSR links. for (Iterator<Map.Entry<LabelNode, BitSet>> it = subroutineHeads .entrySet().iterator(); it.hasNext();) { Map.Entry<LabelNode, BitSet> entry = it.next(); LabelNode lab = entry.getKey(); BitSet sub = entry.getValue(); int index = instructions.indexOf(lab); markSubroutineWalk(sub, index, anyvisited); } }
@Override public void visit(Branch.Condition.Nil cond) { assert (destLabel != null); il.add(new VarInsnNode(ALOAD, slot(cond.addr()))); if (!isSub() || resolver.isLocalLabel(destLabel)) { // local jump il.add(new JumpInsnNode(IFNULL, l(destLabel))); } else { // non-local jump LabelNode l_nojump = new LabelNode(); il.add(new JumpInsnNode(IFNONNULL, l_nojump)); il.add(_nonLocalGoto(destLabel)); il.add(l_nojump); il.add(new FrameNode(F_SAME, 0, null, 0, null)); } }
@Override public void visit(Branch.Condition.Bool cond) { assert (destLabel != null); il.add(new VarInsnNode(ALOAD, slot(cond.addr()))); il.add(ConversionMethods.booleanValueOf()); if (!isSub() || resolver.isLocalLabel(destLabel)) { // local jump il.add(new JumpInsnNode(cond.expected() ? IFNE : IFEQ, l(destLabel))); } else { // non-local jump LabelNode l_nojump = new LabelNode(); il.add(new JumpInsnNode(cond.expected() ? IFEQ : IFNE, l_nojump)); il.add(_nonLocalGoto(destLabel)); il.add(l_nojump); il.add(new FrameNode(F_SAME, 0, null, 0, null)); } }
@Override public void visit(Branch.Condition.NumLoopEnd cond) { assert (destLabel != null); il.add(new VarInsnNode(ALOAD, slot(cond.var()))); il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(Number.class))); il.add(new VarInsnNode(ALOAD, slot(cond.limit()))); il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(Number.class))); il.add(new VarInsnNode(ALOAD, slot(cond.step()))); il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(Number.class))); il.add(DispatchMethods.continueLoop()); if (!isSub() || resolver.isLocalLabel(destLabel)) { // local jump il.add(new JumpInsnNode(IFEQ, l(destLabel))); } else { // non-local jump LabelNode l_nojump = new LabelNode(); il.add(new JumpInsnNode(IFNE, l_nojump)); il.add(_nonLocalGoto(destLabel)); il.add(l_nojump); il.add(new FrameNode(F_SAME, 0, null, 0, null)); } }
private InsnList dispatchTable(List<LabelNode> extLabels, List<LabelNode> resumptionLabels, LabelNode errorStateLabel) { InsnList il = new InsnList(); assert (!extLabels.isEmpty()); ArrayList<LabelNode> labels = new ArrayList<>(); labels.addAll(extLabels); labels.addAll(resumptionLabels); LabelNode[] labelArray = labels.toArray(new LabelNode[labels.size()]); int min = 1 - extLabels.size(); int max = resumptionLabels.size(); il.add(new VarInsnNode(ILOAD, LV_RESUME)); il.add(new TableSwitchInsnNode(min, max, errorStateLabel, labelArray)); return il; }
protected InsnList resumptionHandler(LabelNode label) { InsnList il = new InsnList(); il.add(label); il.add(ASMUtils.frameSame1(UnresolvedControlThrowable.class)); il.add(createSnapshot()); // register snapshot with the control exception il.add(new MethodInsnNode( INVOKEVIRTUAL, Type.getInternalName(UnresolvedControlThrowable.class), "resolve", Type.getMethodType( Type.getType(ResolvedControlThrowable.class), Type.getType(Resumable.class), Type.getType(Object.class)).getDescriptor(), false)); // rethrow il.add(new InsnNode(ATHROW)); return il; }
public void replaceLabels(Map<LabelNode, LabelNode> labelMap, Set<LabelNode> usedLabels) { for (AbstractInsnNode insn : list) switch (insn.getType()) { case LABEL: AbstractInsnNode insn2 = insn.clone(labelMap); if (insn2 == insn)//identity mapping continue; if (usedLabels.contains(insn2)) throw new IllegalStateException("LabelNode cannot be a part of two InsnLists"); list.replace(insn, insn2); break; case JUMP_INSN: case FRAME: case LOOKUPSWITCH_INSN: case TABLESWITCH_INSN: list.replace(insn, insn.clone(labelMap)); } for(Entry<LabelNode, LabelNode> entry : labelMap.entrySet()) { String key = labels.inverse().get(entry.getKey()); if(key != null) labels.put(key, entry.getValue()); } }
/** * Pulls all common labels from other into this * @return this */ public ASMBlock mergeLabels(ASMBlock other) { if(labels.isEmpty() || other.labels.isEmpty()) return this; //common labels, give them our nodes HashMap<LabelNode, LabelNode> labelMap = list.identityLabelMap(); for(Entry<String, LabelNode> entry : other.labels.entrySet()) { LabelNode old = labels.get(entry.getKey()); if(old != null) labelMap.put(old, entry.getValue()); } HashSet<LabelNode> usedLabels = new HashSet<LabelNode>(); for (AbstractInsnNode insn = other.list.list.getFirst(); insn != null; insn = insn.getNext()) if(insn.getType() == LABEL) usedLabels.add((LabelNode) insn); replaceLabels(labelMap, usedLabels); return this; }
private int getLabelIdx(LabelNode l) { int idx; if(l instanceof BlockLabelNode) { idx = ((BlockLabelNode)l).idx; } else { idx = mn.instructions.indexOf(l); } // search for the "real" instruction for(;;) { int type = mn.instructions.get(idx).getType(); if(type != AbstractInsnNode.LABEL && type != AbstractInsnNode.LINE) { return idx; } idx++; } }
private void convertTableSwitchInsn(TableSwitchInsnNode insn) { StackFrame frame = getFrame(insn); if (units.containsKey(insn)) { frame.mergeIn(pop()); return; } Operand key = popImmediate(); UnitBox dflt = Jimple.v().newStmtBox(null); List<UnitBox> targets = new ArrayList<UnitBox>(insn.labels.size()); labels.put(insn.dflt, dflt); for (LabelNode ln : insn.labels) { UnitBox box = Jimple.v().newStmtBox(null); targets.add(box); labels.put(ln, box); } TableSwitchStmt tss = Jimple.v().newTableSwitchStmt(key.stackOrValue(), insn.min, insn.max, targets, dflt); key.addBox(tss.getKeyBox()); frame.in(key); frame.boxes(tss.getKeyBox()); setUnit(insn, tss); }
private void convertLabel(LabelNode ln) { if (!trapHandlers.containsKey(ln)) return; StackFrame frame = getFrame(ln); Operand[] out = frame.out(); Operand opr; if (out == null) { CaughtExceptionRef ref = Jimple.v().newCaughtExceptionRef(); Local stack = newStackLocal(); DefinitionStmt as = Jimple.v().newIdentityStmt(stack, ref); opr = new Operand(ln, ref); opr.stack = stack; frame.out(opr); setUnit(ln, as); } else { opr = out[0]; } push(opr); }
public static InsnList getImportantList(InsnList list) { if (list.size() == 0) { return list; } HashMap<LabelNode, LabelNode> labels = new HashMap<>(); for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if (insn instanceof LabelNode) { labels.put((LabelNode) insn, (LabelNode) insn); } } InsnList importantNodeList = new InsnList(); for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if (insn instanceof LabelNode || insn instanceof LineNumberNode) { continue; } importantNodeList.add(insn.clone(labels)); } return importantNodeList; }
private static InsnListSection insnListMatchesL(InsnList haystack, InsnList needle, int start, HashSet<LabelNode> controlFlowLabels) { int h = start, n = 0; for (; h < haystack.size() && n < needle.size(); h++) { AbstractInsnNode insn = haystack.get(h); if (insn.getType() == 15) { continue; } if (insn.getType() == 8 && !controlFlowLabels.contains(insn)) { continue; } if (!insnEqual(haystack.get(h), needle.get(n))) { return null; } n++; } if (n != needle.size()) { return null; } return new InsnListSection(haystack, start, h - 1); }
private byte[] transformPlayer(byte[] bytes) { ClassNode clazz = ASMHelper.createClassNode(bytes); MethodNode method = ASMHelper.findMethod(clazz, ASMNames.MD_PLAYER_UPDATE); InsnList needle = new InsnList(); needle.add(new VarInsnNode(Opcodes.ALOAD, 0)); needle.add(ASMHelper.getFieldInsnNode(Opcodes.GETFIELD, ASMNames.FD_PLAYER_WORLD_OBJ)); needle.add(ASMHelper.getMethodInsnNode(Opcodes.INVOKEVIRTUAL, ASMNames.MD_WORLD_IS_DAY, false)); LabelNode l2 = new LabelNode(); needle.add(new JumpInsnNode(Opcodes.IFEQ, l2)); AbstractInsnNode insertPoint = ASMHelper.findFirstNodeFromNeedle(method.instructions, needle); method.instructions.remove(insertPoint.getNext().getNext()); method.instructions.set(insertPoint.getNext(), ASMHelper.getMethodInsnNode(Opcodes.INVOKESTATIC, ASMNames.MD_RM_HELPER_SLEEP_PLAEYR, false)); return ASMHelper.createBytes(clazz, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); }
private void patchMenu(ClassNode node) { Logger.Info("Patching menu (" + node.name + ".class)"); Iterator<MethodNode> methodNodeList = node.methods.iterator(); while (methodNodeList.hasNext()) { MethodNode methodNode = methodNodeList.next(); // Menu swap hook if (methodNode.name.equals("e") && methodNode.desc.equals("(II)V")) { AbstractInsnNode first = methodNode.instructions.getFirst(); LabelNode label = new LabelNode(); methodNode.instructions.insertBefore(first, new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.insertBefore(first, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Menu", "switchList", "(Ljava/lang/Object;)Z")); methodNode.instructions.insertBefore(first, new JumpInsnNode(Opcodes.IFGT, label)); methodNode.instructions.insertBefore(first, new InsnNode(Opcodes.RETURN)); methodNode.instructions.insertBefore(first, label); } } }
/** * Gets the path that branches to a true value. * * @return The path that branches to a true value. */ public Optional<BasicBlock> trueBranch() { if (successors.size() == 1) { return Optional.of(successors.get(0)); } BasicInstruction endInsn = exit(); if (endInsn.insn instanceof JumpInsnNode) { LabelNode label = ((JumpInsnNode) endInsn.insn).label; for (BasicBlock successor : successors) { BasicInstruction startInsn = successor.entry(); if (startInsn != null && label == startInsn.insn) { return Optional.of(successor); } } } return Optional.empty(); }
/** Adds an exception try block node to this graph */ protected void exception(@NonNull AbstractInsnNode from, @NonNull TryCatchBlockNode tcb) { // Add tcb's to all instructions in the range LabelNode start = tcb.start; LabelNode end = tcb.end; // exclusive // Add exception edges for all method calls in the range AbstractInsnNode curr = start; Node handlerNode = getNode(tcb.handler); while (curr != end && curr != null) { if (curr.getType() == AbstractInsnNode.METHOD_INSN) { // Method call; add exception edge to handler if (tcb.type == null) { // finally block: not an exception path getNode(curr).addSuccessor(handlerNode); } getNode(curr).addExceptionPath(handlerNode); } curr = curr.getNext(); } }
private void visitTableSwitchInsnNode(TableSwitchInsnNode node) { ExpressionStack stack = mState.getActiveStack(); int defaultLabel = stack.getLabelId(node.dflt.getLabel()); Map<Integer, String> labelCaseMap = new HashMap<>(); for (int i = 0; i <= node.max - node.min; i++) { int labelId = stack.getLabelId(((LabelNode) node.labels.get(i)).getLabel()); String caseKey = String.valueOf(node.min + i); labelCaseMap.put(labelId, caseKey); } labelCaseMap.put(defaultLabel, SwitchExpression.CaseExpression.DEFAULT); SwitchExpression switchExp = new SwitchExpression(node.getOpcode()); mState.moveNode(); updateSwitchWithCases(switchExp, defaultLabel, labelCaseMap); stack.push(switchExp); }
public BranchCoverage(MethodNode method) { this.targetLabels = new ArrayList<>(); this.visitedLabels = new ArrayList<>(); AbstractInsnNode instructions[] = method.instructions.toArray(); for (AbstractInsnNode current : instructions) { if (current instanceof LabelNode) { targetLabels.add(((LabelNode) current).getLabel().toString()); } } int lastOpcode = instructions[instructions.length - 1].getOpcode(); if (lastOpcode == Opcodes.IRETURN || lastOpcode == Opcodes.RETURN || lastOpcode == Opcodes.ARETURN || lastOpcode == Opcodes.DRETURN || lastOpcode == Opcodes.LRETURN) { } else { targetLabels.remove(targetLabels.size() - 1); } }
private void transformDamageItem(MethodNode method) { InsnList postEvent = new InsnList(); LabelNode label = new LabelNode(new Label()); postEvent.add(new TypeInsnNode(Opcodes.NEW, DAMAGE_ITEM_EVENT.getInternalName())); postEvent.add(new InsnNode(Opcodes.DUP)); postEvent.add(new VarInsnNode(Opcodes.ALOAD, 2)); postEvent.add(new VarInsnNode(Opcodes.ILOAD, 1)); postEvent.add(new VarInsnNode(Opcodes.ALOAD, 0)); postEvent.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, DAMAGE_ITEM_EVENT_INIT.getOwnerInternalName(), DAMAGE_ITEM_EVENT_INIT.getEnvName(), DAMAGE_ITEM_EVENT_INIT.getDesc(), false)); postEvent.add(new VarInsnNode(Opcodes.ASTORE, 3)); postEvent.add(new FieldInsnNode(Opcodes.GETSTATIC, EVENTHANDLER_DAMAGE_ITEM.getOwnerInternalName(), EVENTHANDLER_DAMAGE_ITEM.getEnvName(), EVENTHANDLER_DAMAGE_ITEM.getDesc())); postEvent.add(new VarInsnNode(Opcodes.ALOAD, 3)); postEvent.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, POST.getOwnerInternalName(), POST.getEnvName(), POST.getDesc(), false)); postEvent.add(new JumpInsnNode(Opcodes.IFEQ, label)); postEvent.add(new InsnNode(Opcodes.RETURN)); postEvent.add(label); postEvent.add(new FrameNode(Opcodes.F_APPEND, 1, new Object[] {DAMAGE_ITEM_EVENT.getInternalName()}, 0, null)); postEvent.add(new VarInsnNode(Opcodes.ALOAD, 3)); postEvent.add(new FieldInsnNode(Opcodes.GETFIELD, DAMAGE.getOwnerInternalName(), DAMAGE.getEnvName(), DAMAGE.getDesc())); postEvent.add(new VarInsnNode(Opcodes.ISTORE, 1)); method.instructions.insert(postEvent); }
/** * Compares two objects and performs some action if the objects are the same (uses == to check if same, not the equals method). * @param lhs left hand side instruction list -- must leave an object on the stack * @param rhs right hand side instruction list -- must leave an object on the stack * @param action action to perform if results of {@code lhs} and {@code rhs} are equal * @return instructions instruction list to perform some action if two objects are equal * @throws NullPointerException if any argument is {@code null} */ public static InsnList ifObjectsEqual(InsnList lhs, InsnList rhs, InsnList action) { Validate.notNull(lhs); Validate.notNull(rhs); Validate.notNull(action); InsnList ret = new InsnList(); LabelNode notEqualLabelNode = new LabelNode(); ret.add(lhs); ret.add(rhs); ret.add(new JumpInsnNode(Opcodes.IF_ACMPNE, notEqualLabelNode)); ret.add(action); ret.add(notEqualLabelNode); return ret; }
public static InsnList getImportantList(InsnList list) { if (list.size() == 0) { return list; } HashMap<LabelNode, LabelNode> labels = new HashMap<LabelNode, LabelNode>(); for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if (insn instanceof LabelNode) { labels.put((LabelNode) insn, (LabelNode) insn); } } InsnList importantNodeList = new InsnList(); for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if (insn instanceof LabelNode || insn instanceof LineNumberNode) { continue; } importantNodeList.add(insn.clone(labels)); } return importantNodeList; }
private static byte[] dumpBytecode(MethodNode methodNode) { // Calculate label offsets -- required for hash calculation // we only care about where the labels are in relation to the opcode instructions -- we don't care about things like // LocalVariableNode or other ancillary data because these can change without the actual logic changing List<AbstractInsnNode> onlyInstructionsAndLabels = Arrays.stream(methodNode.instructions.toArray()) .filter(x -> x instanceof LabelNode || x.getOpcode() != -1) .collect(Collectors.toList()); Map<Label, Integer> labelOffsets = onlyInstructionsAndLabels.stream() .filter(x -> x instanceof LabelNode) .map(x -> (LabelNode) x) .collect(Collectors.toMap(x -> x.getLabel(), x -> onlyInstructionsAndLabels.indexOf(x))); // Hash based on overall structures and instructions+operands try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream daos = new DataOutputStream(baos);) { MethodVisitor daosDumpMethodVisitor = new DumpToDaosMethodVisitor(daos, labelOffsets); methodNode.accept(daosDumpMethodVisitor); daos.flush(); // doesn't really need it -- just incase return baos.toByteArray(); } catch (IOException ioe) { throw new IllegalStateException(ioe); // should never happen } }
public void visitInsnList(InsnList list) { text.clear(); if (labelNames == null) { labelNames = new HashMap<Label, String>(); } else { labelNames.clear(); } buildingLabelMap = true; for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { if (insn.getType() == 8) { visitLabel(((LabelNode) insn).getLabel()); } } text.clear(); buildingLabelMap = false; for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) { _visitInsn(insn); } }
/** * Compares two integers and performs some action if the integers are equal. * @param lhs left hand side instruction list -- must leave an int on the stack * @param rhs right hand side instruction list -- must leave an int on the stack * @param action action to perform if results of {@code lhs} and {@code rhs} are equal * @return instructions instruction list to perform some action if two ints are equal * @throws NullPointerException if any argument is {@code null} */ public static InsnList ifIntegersEqual(InsnList lhs, InsnList rhs, InsnList action) { Validate.notNull(lhs); Validate.notNull(rhs); Validate.notNull(action); InsnList ret = new InsnList(); LabelNode notEqualLabelNode = new LabelNode(); ret.add(lhs); ret.add(rhs); ret.add(new JumpInsnNode(Opcodes.IF_ICMPNE, notEqualLabelNode)); ret.add(action); ret.add(notEqualLabelNode); return ret; }
private void addTraceStart() { InsnList il = new InsnList(); int methodParametersIndex = addMethodParametersVariable(il); addGetMethodInvocation(il); addStoreMethod(il); addGetCallback(il); il.add(new VarInsnNode(Opcodes.ALOAD, this.methodVarIndex)); il.add(new VarInsnNode(Opcodes.ALOAD, methodParametersIndex)); il.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "org/brutusin/instrumentation/Callback", "onStart", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/String;", false)); this.executionIdIndex = getFistAvailablePosition(); il.add(new VarInsnNode(Opcodes.ASTORE, this.executionIdIndex)); this.mn.maxLocals++; this.startNode = new LabelNode(); this.mn.instructions.insert(startNode); this.mn.instructions.insert(il); }
private void addCatchBlock(LabelNode startNode, LabelNode endNode) { InsnList il = new InsnList(); LabelNode handlerNode = new LabelNode(); il.add(handlerNode); int exceptionVariablePosition = getFistAvailablePosition(); il.add(new VarInsnNode(Opcodes.ASTORE, exceptionVariablePosition)); this.methodOffset++; // Actualizamos el offset addGetCallback(il); il.add(new VarInsnNode(Opcodes.ALOAD, this.methodVarIndex)); il.add(new VarInsnNode(Opcodes.ALOAD, exceptionVariablePosition)); il.add(new VarInsnNode(Opcodes.ALOAD, this.executionIdIndex)); il.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "org/brutusin/instrumentation/Callback", "onThrowableUncatched", "(Ljava/lang/Object;Ljava/lang/Throwable;Ljava/lang/String;)V", false)); il.add(new VarInsnNode(Opcodes.ALOAD, exceptionVariablePosition)); il.add(new InsnNode(Opcodes.ATHROW)); TryCatchBlockNode blockNode = new TryCatchBlockNode(startNode, endNode, handlerNode, null); this.mn.tryCatchBlocks.add(blockNode); this.mn.instructions.add(il); }
private void registerSwitchInstruction(BytecodeInstruction v) { if (!v.isSwitch()) throw new IllegalArgumentException("expect a switch instruction"); LabelNode defaultLabel = null; switch (v.getASMNode().getOpcode()) { case Opcodes.TABLESWITCH: TableSwitchInsnNode tableSwitchNode = (TableSwitchInsnNode) v.getASMNode(); registerTableSwitchCases(v, tableSwitchNode); defaultLabel = tableSwitchNode.dflt; break; case Opcodes.LOOKUPSWITCH: LookupSwitchInsnNode lookupSwitchNode = (LookupSwitchInsnNode) v.getASMNode(); registerLookupSwitchCases(v, lookupSwitchNode); defaultLabel = lookupSwitchNode.dflt; break; default: throw new IllegalStateException( "expect ASMNode of a switch to either be a LOOKUP- or TABLESWITCH"); } registerDefaultCase(v, defaultLabel); }
protected boolean isVarBetweenBounds(final AbstractInsnNode var, final LabelNode lo, final LabelNode hi) { AbstractInsnNode x; boolean loFound = false; for (x = var; !(x == null || loFound); x = x.getPrevious()) { loFound = x == lo; } if (!loFound) return false; boolean hiFound = false; for (x = var; !(x == null || hiFound); x = x.getNext()) { hiFound = x == hi; } return hiFound; }
private void registerSwitchLabel(Branch b, LabelNode targetLabel) { if (switchLabels.get(targetLabel) == null) switchLabels.put(targetLabel, new ArrayList<Branch>()); List<Branch> oldList = switchLabels.get(targetLabel); if (oldList.contains(b)) throw new IllegalStateException( "branch already registered for this switch label"); oldList.add(b); // TODO several Branches can map to one Label, so switchLabels should // either map from branches to labels, not the other way around. or it // should map labels to a list of branches // this stems from the fact that empty case: blocks do not have their // own label // TODO STOPPED HERE switchLabels.put(targetLabel, oldList); }
private void insertControlDependencyPlaceholder(MethodNode mn, AbstractInsnNode insnNode) { Label label = new Label(); LabelNode labelNode = new LabelNode(label); //BooleanTestabilityPlaceholderTransformer.addControlDependencyPlaceholder(label, // insnNode); mn.instructions.insertBefore(insnNode, labelNode); //instructions.insertBefore(insnNode, new LdcInsnNode(0)); //mn.instructions.insertBefore(insnNode, new LdcInsnNode(0)); mn.instructions.insertBefore(insnNode, new LdcInsnNode( getControlDependentBranchID(mn, insnNode))); mn.instructions.insertBefore(insnNode, new LdcInsnNode(getApproximationLevel(mn, insnNode))); logger.info("Control dependent branch id: " + getControlDependentBranchID(mn, insnNode)); logger.info("Approximation level: " + getApproximationLevel(mn, insnNode)); }
/** * <p> * addDefaultCaseInstrumentation * </p> * * @param v * a {@link org.evosuite.graphs.cfg.BytecodeInstruction} object. * @param instrumentation * a {@link org.objectweb.asm.tree.InsnList} object. * @param mySwitch * a {@link org.objectweb.asm.tree.AbstractInsnNode} object. * @param defaultLabel * a {@link org.objectweb.asm.tree.LabelNode} object. * @param caseLabel * a {@link org.objectweb.asm.tree.LabelNode} object. * @param endLabel * a {@link org.objectweb.asm.tree.LabelNode} object. */ protected void addDefaultCaseInstrumentation(BytecodeInstruction v, InsnList instrumentation, AbstractInsnNode mySwitch, LabelNode defaultLabel, LabelNode caseLabel, LabelNode endLabel) { int defaultCaseBranchId = BranchPool.getInstance(classLoader).getDefaultBranchForSwitch(v).getActualBranchId(); // add helper switch instrumentation.add(new InsnNode(Opcodes.DUP)); instrumentation.add(mySwitch); // add call for default case not covered instrumentation.add(caseLabel); addDefaultCaseNotCoveredCall(v, instrumentation, defaultCaseBranchId); // jump over default (break) instrumentation.add(new JumpInsnNode(Opcodes.GOTO, endLabel)); // add call for default case covered instrumentation.add(defaultLabel); addDefaultCaseCoveredCall(v, instrumentation, defaultCaseBranchId); instrumentation.add(endLabel); }
private static AbstractInsnNode getDefault(Type type) { if (type.equals(Type.BOOLEAN_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.INT_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.BYTE_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.CHAR_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.DOUBLE_TYPE)) { return new LdcInsnNode(0.0); } else if (type.equals(Type.FLOAT_TYPE)) { return new LdcInsnNode(0.0F); } else if (type.equals(Type.INT_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.LONG_TYPE)) { return new LdcInsnNode(0L); } else if (type.equals(Type.SHORT_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.VOID_TYPE)) { return new LabelNode(); } else { return new InsnNode(Opcodes.ACONST_NULL); } }
/** {@inheritDoc} */ @Override public List<Mutation> apply(MethodNode mn, String className, String methodName, BytecodeInstruction instruction, Frame frame) { List<Mutation> mutations = new LinkedList<Mutation>(); JumpInsnNode node = (JumpInsnNode) instruction.getASMNode(); LabelNode target = node.label; // insert mutation into bytecode with conditional JumpInsnNode mutation = new JumpInsnNode(getOpposite(node.getOpcode()), target); // insert mutation into pool Mutation mutationObject = MutationPool.addMutation(className, methodName, NAME, instruction, mutation, Mutation.getDefaultInfectionDistance()); mutations.add(mutationObject); return mutations; }
@Test public void insertMultipleNodes() { MethodNode mthdNode = new MethodNode(); MethodEditor editor = createMethodEditor1(mthdNode); editor.setInsertMode(); boolean result = editor.apply(editor.newInstructionBuilder() .varInsn(VarInsnOpcodes.ALOAD, 0) .methodInsn(MethodInsnOpcodes.INVOKEVIRTUAL, "A", "A.a", "()J")); assertEquals(true, result); assertEquals(2, editor.getCursor()); assertEquals(11, getMethodNode(editor).instructions.size()); assertTrue(getMethodNode(editor).instructions.get(0) instanceof VarInsnNode); assertTrue(getMethodNode(editor).instructions.get(1) instanceof MethodInsnNode); assertTrue(getMethodNode(editor).instructions.get(2) instanceof LabelNode); }