@Nonnull private BuilderSparseSwitchPayload newBuilderSparseSwitchPayload(@Nonnull MethodLocation location, @Nonnull int[] codeAddressToIndex, @Nonnull SparseSwitchPayload instruction) { List<? extends SwitchElement> switchElements = instruction.getSwitchElements(); if (switchElements.size() == 0) { return new BuilderSparseSwitchPayload(null); } MethodLocation switchLocation = findSwitchForPayload(location); int baseAddress; if (switchLocation == null) { baseAddress = 0; } else { baseAddress = switchLocation.codeAddress; } List<SwitchLabelElement> labelElements = Lists.newArrayList(); for (SwitchElement element : switchElements) { labelElements.add(new SwitchLabelElement(element.getKey(), newLabel(codeAddressToIndex, element.getOffset() + baseAddress))); } return new BuilderSparseSwitchPayload(labelElements); }
public void write(@Nonnull SparseSwitchPayload instruction) { try { writer.writeUbyte(0); writer.writeUbyte(instruction.getOpcode().value >> 8); List<? extends SwitchElement> elements = instruction.getSwitchElements(); writer.writeUshort(elements.size()); for (SwitchElement element: elements) { writer.writeInt(element.getKey()); } for (SwitchElement element: elements) { writer.writeInt(element.getOffset()); } } catch (IOException ex) { throw new RuntimeException(ex); } }
public void write(@Nonnull SparseSwitchPayload instruction) { try { writer.writeUbyte(0); writer.writeUbyte(getOpcodeValue(instruction.getOpcode()) >> 8); List<? extends SwitchElement> elements = Ordering.from(switchElementComparator).immutableSortedCopy( instruction.getSwitchElements()); writer.writeUshort(elements.size()); for (SwitchElement element: elements) { writer.writeInt(element.getKey()); } for (SwitchElement element: elements) { writer.writeInt(element.getOffset()); } } catch (IOException ex) { throw new RuntimeException(ex); } }
@Override protected Stmt switchStatement(DexBody body, Instruction targetData, Local key) { SparseSwitchPayload i = (SparseSwitchPayload) targetData; List<? extends SwitchElement> seList = i.getSwitchElements(); // the default target always follows the switch statement int defaultTargetAddress = codeAddress + instruction.getCodeUnits(); Unit defaultTarget = body.instructionAtAddress(defaultTargetAddress).getUnit(); List<IntConstant> lookupValues = new ArrayList<IntConstant>(); List<Unit> targets = new ArrayList<Unit>(); for (SwitchElement se : seList) { lookupValues.add(IntConstant.v(se.getKey())); int offset = se.getOffset(); targets.add(body.instructionAtAddress(codeAddress + offset).getUnit()); } LookupSwitchStmt switchStmt = Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget); setUnit(switchStmt); addTags(switchStmt); if (IDalvikTyper.ENABLE_DVKTYPER) { DalvikTyper.v().setType(switchStmt.getKeyBox(), IntType.v(), true); } return switchStmt; }
public void write(@Nonnull SparseSwitchPayload instruction) { try { writer.writeUbyte(0); writer.writeUbyte(getOpcodeValue(instruction.getOpcode()) >> 8); List<? extends SwitchElement> elements = Ordering.from(switchElementComparator).immutableSortedCopy( instruction.getSwitchElements()); writer.writeUshort(elements.size()); for (SwitchElement element: elements) { writer.writeInt(element.getKey()); } for (SwitchElement element: elements) { writer.writeInt(element.getOffset()); } } catch (IOException ex) { throw new RuntimeException(ex); } }
@Nonnull public static ImmutableSparseSwitchPayload of(SparseSwitchPayload instruction) { if (instruction instanceof ImmutableSparseSwitchPayload) { return (ImmutableSparseSwitchPayload)instruction; } return new ImmutableSparseSwitchPayload( instruction.getSwitchElements()); }
private void annotateSparseSwitchPayload(@Nonnull AnnotatedBytes out, @Nonnull SparseSwitchPayload instruction) { List<? extends SwitchElement> elements = instruction.getSwitchElements(); out.annotate(2, instruction.getOpcode().name); out.indent(); out.annotate(2, "size = %d", elements.size()); if (elements.size() > 0) { out.annotate(0, "keys:"); out.indent(); for (int i=0; i<elements.size(); i++) { out.annotate(4, "key[%d] = %d", i, elements.get(i).getKey()); } out.deindent(); out.annotate(0, "targets:"); out.indent(); for (int i=0; i<elements.size(); i++) { out.annotate(4, "target[%d] = %d", i, elements.get(i).getOffset()); } out.deindent(); } out.deindent(); }
@Nonnull public static ImmutableSparseSwitchPayload of(SparseSwitchPayload instruction) { if (instruction instanceof ImmutableSparseSwitchPayload) { return (ImmutableSparseSwitchPayload)instruction; } return new ImmutableSparseSwitchPayload( instruction.getSwitchElements()); }
private void annotateSparseSwitchPayload(@Nonnull AnnotatedBytes out, @Nonnull SparseSwitchPayload instruction) { List<? extends SwitchElement> elements = instruction.getSwitchElements(); out.annotate(2, instruction.getOpcode().name); out.indent(); out.annotate(2, "size = %d", elements.size()); if (elements.size() > 0) { out.annotate(0, "keys:"); out.indent(); for (int i=0; i<elements.size(); i++) { out.annotate(4, "key[%d] = %d", i, elements.get(i).getKey()); } out.deindent(); out.annotate(0, "targets:"); out.indent(); for (int i=0; i<elements.size(); i++) { out.annotate(4, "target[%d] = %d", i, elements.get(i).getOffset()); } out.deindent(); } out.deindent(); }
@Nonnull public static ImmutableSparseSwitchPayload of(SparseSwitchPayload instruction) { if (instruction instanceof ImmutableSparseSwitchPayload) { return (ImmutableSparseSwitchPayload)instruction; } return new ImmutableSparseSwitchPayload( instruction.getSwitchElements()); }
private void annotateSparseSwitchPayload(@Nonnull AnnotatedBytes out, @Nonnull SparseSwitchPayload instruction) { List<? extends SwitchElement> elements = instruction.getSwitchElements(); out.annotate(2, instruction.getOpcode().name); out.indent(); out.annotate(2, "size = %d", elements.size()); if (elements.size() > 0) { out.annotate(0, "keys:"); out.indent(); for (int i=0; i<elements.size(); i++) { out.annotate(4, "key[%d] = %d", i, elements.get(i).getKey()); } out.deindent(); out.annotate(0, "targets:"); out.indent(); for (int i=0; i<elements.size(); i++) { out.annotate(4, "target[%d] = %d", i, elements.get(i).getOffset()); } out.deindent(); } out.deindent(); }
@Nonnull private BuilderSparseSwitchPayload newBuilderSparseSwitchPayload(@Nonnull MethodLocation location, @Nonnull int[] codeAddressToIndex, @Nonnull SparseSwitchPayload instruction) { List<? extends SwitchElement> switchElements = instruction.getSwitchElements(); if (switchElements.size() == 0) { return new BuilderSparseSwitchPayload(null); } MethodLocation switchLocation = findSwitchForPayload(location); int baseAddress; if (switchLocation == null) { baseAddress = 0; } else { baseAddress = switchLocation.codeAddress; } List<SwitchLabelElement> labelElements = Lists.newArrayList(); for (SwitchElement element: switchElements) { labelElements.add(new SwitchLabelElement(element.getKey(), newLabel(codeAddressToIndex, element.getOffset() + baseAddress))); } return new BuilderSparseSwitchPayload(labelElements); }
@Nonnull private BuilderSparseSwitchPayload newBuilderSparseSwitchPayload(@Nonnull MethodLocation location, @Nonnull int[] codeAddressToIndex, @Nonnull SparseSwitchPayload instruction) { List<? extends SwitchElement> switchElements = instruction.getSwitchElements(); if (switchElements.size() == 0) { return new BuilderSparseSwitchPayload(null); } MethodLocation switchLocation = findSwitchForPayload(location); int baseAddress; if (switchLocation == null) { baseAddress = 0; } else { baseAddress = switchLocation.codeAddress; } List<SwitchLabelElement> labelElements = Lists.newArrayList(); for (SwitchElement element: switchElements) { labelElements.add(new SwitchLabelElement(element.getKey(), newLabel(codeAddressToIndex, element.getOffset() + baseAddress))); } return new BuilderSparseSwitchPayload(labelElements); }
@Nonnull private BuilderSparseSwitchPayload newBuilderSparseSwitchPayload(@Nonnull MethodLocation location, @Nonnull int[] codeAddressToIndex, @Nonnull SparseSwitchPayload instruction) { List<? extends SwitchElement> switchElements = instruction.getSwitchElements(); if (switchElements.size() == 0) { return new BuilderSparseSwitchPayload(null); } MethodLocation switchLocation = findSwitchForPayload(location); int baseAddress; if (switchLocation == null) { baseAddress = 0; } else { baseAddress = switchLocation.codeAddress; } List<SwitchLabelElement> labelElements = Lists.newArrayList(); for (SwitchElement element : switchElements) { labelElements.add(new SwitchLabelElement(element.getKey(), newLabel(codeAddressToIndex, element.getOffset() + baseAddress))); } return new BuilderSparseSwitchPayload(labelElements); }
@Nonnull private BuilderSparseSwitchPayload newBuilderSparseSwitchPayload(@Nonnull MethodLocation location, @Nonnull int[] codeAddressToIndex, @Nonnull SparseSwitchPayload instruction) { List<? extends SwitchElement> switchElements = instruction.getSwitchElements(); if (switchElements.size() == 0) { return new BuilderSparseSwitchPayload(null); } MethodLocation switchLocation = findSwitchForPayload(location); int baseAddress; if (switchLocation == null) { baseAddress = 0; } else { baseAddress = switchLocation.codeAddress; } List<SwitchLabelElement> labelElements = Lists.newArrayList(); for (SwitchElement element: switchElements) { labelElements.add(new SwitchLabelElement(element.getKey(), newLabel(codeAddressToIndex, element.getOffset() + baseAddress))); } return new BuilderSparseSwitchPayload(labelElements); }
public SparseSwitchMethodItem(MethodDefinition methodDef, int codeAddress, SparseSwitchPayload instruction) { super(methodDef, codeAddress, instruction); int baseCodeAddress = methodDef.getSparseSwitchBaseAddress(codeAddress); targets = new ArrayList<SparseSwitchTarget>(); if (baseCodeAddress >= 0) { for (SwitchElement switchElement: instruction.getSwitchElements()) { LabelMethodItem label = methodDef.getLabelCache().internLabel( new LabelMethodItem( methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(), "sswitch_")); targets.add(new SparseSwitchLabelTarget(switchElement.getKey(), label)); } } else { commentedOut = true; //if we couldn't determine a base address, just use relative offsets rather than labels for (SwitchElement switchElement: instruction.getSwitchElements()) { targets.add(new SparseSwitchOffsetTarget(switchElement.getKey(), switchElement.getOffset())); } } }
public SparseSwitchMethodItem(MethodDefinition methodDef, int codeAddress, SparseSwitchPayload instruction) { super(methodDef, codeAddress, instruction); int baseCodeAddress = methodDef.getSparseSwitchBaseAddress(codeAddress); targets = new ArrayList<SparseSwitchTarget>(); if (baseCodeAddress >= 0) { for (SwitchElement switchElement: instruction.getSwitchElements()) { LabelMethodItem label = methodDef.getLabelCache().internLabel( new LabelMethodItem( methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(), "sswitch_")); targets.add(new SparseSwitchLabelTarget(switchElement.getKey(), label)); } } else { commentedOut = true; //if we couldn't determine a base address, just use relative offsets rather than labels for (SwitchElement switchElement: instruction.getSwitchElements()) { targets.add(new SparseSwitchOffsetTarget(switchElement.getKey(), switchElement.getOffset())); } } }
public SparseSwitchMethodItem(MethodDefinition methodDef, int codeAddress, SparseSwitchPayload instruction) { super(methodDef, codeAddress, instruction); int baseCodeAddress = methodDef.getSparseSwitchBaseAddress(codeAddress); targets = new ArrayList<SparseSwitchTarget>(); if (baseCodeAddress >= 0) { for (SwitchElement switchElement: instruction.getSwitchElements()) { LabelMethodItem label = methodDef.getLabelCache().internLabel( new LabelMethodItem( methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(), "sswitch_")); targets.add(new SparseSwitchLabelTarget(switchElement.getKey(), label)); } } else { commentedOut = true; //if we couldn't determine a base address, just use relative offsets rather than labels for (SwitchElement switchElement: instruction.getSwitchElements()) { targets.add(new SparseSwitchOffsetTarget(switchElement.getKey(), switchElement.getOffset())); } } }
public SparseSwitchMethodItem(MethodDefinition methodDef, int codeAddress, SparseSwitchPayload instruction) { super(methodDef, codeAddress, instruction); int baseCodeAddress = methodDef.getSparseSwitchBaseAddress(codeAddress); targets = new ArrayList<SparseSwitchTarget>(); if (baseCodeAddress >= 0) { for (SwitchElement switchElement: instruction.getSwitchElements()) { LabelMethodItem label = methodDef.getLabelCache().internLabel( new LabelMethodItem( methodDef.classDef.options, baseCodeAddress + switchElement.getOffset(), "sswitch_")); targets.add(new SparseSwitchLabelTarget(switchElement.getKey(), label)); } } else { //if we couldn't determine a base address, just use relative offsets rather than labels for (SwitchElement switchElement: instruction.getSwitchElements()) { targets.add(new SparseSwitchOffsetTarget(switchElement.getKey(), switchElement.getOffset())); } } }
Assert.assertEquals(3, payload.getSwitchElements().size()); Assert.assertEquals(-20, payload.getSwitchElements().get(0).getOffset()); Assert.assertEquals(-2, payload.getSwitchElements().get(1).getOffset()); Assert.assertEquals(-1, payload.getSwitchElements().get(2).getOffset());