use of org.jf.dexlib2.builder.Label in project atlas by alibaba.
the class MethodDefinition method addTries.
private void addTries(List<MethodItem> methodItems) {
List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks = methodImpl.getTryBlocks();
if (tryBlocks.size() == 0) {
return;
}
int lastInstructionAddress = instructionOffsetMap.getInstructionCodeOffset(instructions.size() - 1);
int codeSize = lastInstructionAddress + instructions.get(instructions.size() - 1).getCodeUnits();
for (TryBlock<? extends ExceptionHandler> tryBlock : tryBlocks) {
int startAddress = tryBlock.getStartCodeAddress();
int endAddress = startAddress + tryBlock.getCodeUnitCount();
if (startAddress >= codeSize) {
throw new RuntimeException(String.format("Try start offset %d is past the end of the code block.", startAddress));
}
// Note: not >=. endAddress == codeSize is valid, when the try covers the last instruction
if (endAddress > codeSize) {
throw new RuntimeException(String.format("Try end offset %d is past the end of the code block.", endAddress));
}
/**
* The end address points to the address immediately after the end of the last
* instruction that the try block covers. We want the .catch directive and end_try
* label to be associated with the last covered instruction, so we need to get
* the address for that instruction
*/
int lastCoveredIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(endAddress - 1, false);
int lastCoveredAddress = instructionOffsetMap.getInstructionCodeOffset(lastCoveredIndex);
for (ExceptionHandler handler : tryBlock.getExceptionHandlers()) {
int handlerAddress = handler.getHandlerCodeAddress();
if (handlerAddress >= codeSize) {
throw new ExceptionWithContext("Exception handler offset %d is past the end of the code block.", handlerAddress);
}
//use the address from the last covered instruction
CatchMethodItem catchMethodItem = new CatchMethodItem(classDef.options, labelCache, lastCoveredAddress, handler.getExceptionType(), startAddress, endAddress, handlerAddress);
methodItems.add(catchMethodItem);
}
}
}
use of org.jf.dexlib2.builder.Label in project smali by JesusFreke.
the class SmalideaPackedSwitchPayload method getSwitchElements.
@Nonnull
@Override
public List<? extends SwitchElement> getSwitchElements() {
final SmaliLiteral startKey = psiInstruction.getPackedSwitchStartKey();
assert startKey != null;
List<SmaliPackedSwitchElement> elements = psiInstruction.getPackedSwitchElements();
SmaliMethod smaliMethod = psiInstruction.getParentMethod();
SmaliInstruction packedSwitchInstruction = InstructionUtils.findFirstInstructionWithTarget(smaliMethod, Opcode.PACKED_SWITCH, psiInstruction.getOffset());
final int baseOffset;
if (packedSwitchInstruction == null) {
baseOffset = 0;
} else {
baseOffset = packedSwitchInstruction.getOffset();
}
List<SwitchElement> newElements = Lists.newArrayList();
// TODO: check for integer wraparound (how does art/dalvik handle that?)
int initialKey = (int) startKey.getIntegralValue();
for (int i = 0; i < elements.size(); i++) {
final SmaliPackedSwitchElement element = elements.get(i);
final int key = initialKey + i;
newElements.add(new SwitchElement() {
@Override
public int getKey() {
return key;
}
@Override
public int getOffset() {
SmaliLabelReference labelReference = element.getTarget();
if (labelReference == null) {
return 0;
}
SmaliLabel label = labelReference.resolve();
if (label == null) {
return 0;
}
return label.getOffset() - baseOffset;
}
});
}
return newElements;
}
use of org.jf.dexlib2.builder.Label in project smali by JesusFreke.
the class SmalideaSparseSwitchPayload method getSwitchElements.
@Nonnull
@Override
public List<? extends SwitchElement> getSwitchElements() {
List<SmaliSparseSwitchElement> elements = psiInstruction.getSparseSwitchElements();
SmaliMethod smaliMethod = psiInstruction.getParentMethod();
SmaliInstruction sparseSwitchInstruction = InstructionUtils.findFirstInstructionWithTarget(smaliMethod, Opcode.SPARSE_SWITCH, psiInstruction.getOffset());
final int baseOffset;
if (sparseSwitchInstruction == null) {
baseOffset = 0;
} else {
baseOffset = sparseSwitchInstruction.getOffset();
}
return Lists.transform(elements, new Function<SmaliSparseSwitchElement, SwitchElement>() {
@Override
public SwitchElement apply(final SmaliSparseSwitchElement element) {
return new SwitchElement() {
@Override
public int getKey() {
return (int) element.getKey().getIntegralValue();
}
@Override
public int getOffset() {
SmaliLabelReference labelReference = element.getTarget();
if (labelReference == null) {
return 0;
}
SmaliLabel label = labelReference.resolve();
if (label == null) {
return 0;
}
return label.getOffset() - baseOffset;
}
};
}
});
}
use of org.jf.dexlib2.builder.Label in project smali by JesusFreke.
the class FixGotoTest method testFixGotoToGoto16.
@Test
public void testFixGotoToGoto16() {
MethodImplementationBuilder builder = new MethodImplementationBuilder(1);
Label gotoTarget = builder.getLabel("gotoTarget");
builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, gotoTarget));
for (int i = 0; i < 500; i++) {
builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
}
builder.addLabel("gotoTarget");
builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
MethodImplementation impl = builder.getMethodImplementation();
List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions());
Assert.assertEquals(502, instructions.size());
Assert.assertEquals(Opcode.GOTO_16, instructions.get(0).getOpcode());
Assert.assertEquals(502, ((OffsetInstruction) instructions.get(0)).getCodeOffset());
}
use of org.jf.dexlib2.builder.Label in project smali by JesusFreke.
the class FixGotoTest method testFixGoto16ToGoto32.
@Test
public void testFixGoto16ToGoto32() {
MethodImplementationBuilder builder = new MethodImplementationBuilder(1);
Label gotoTarget = builder.getLabel("gotoTarget");
builder.addInstruction(new BuilderInstruction20t(Opcode.GOTO_16, gotoTarget));
for (int i = 0; i < 70000; i++) {
builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
}
builder.addLabel("gotoTarget");
builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
MethodImplementation impl = builder.getMethodImplementation();
List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions());
Assert.assertEquals(70002, instructions.size());
Assert.assertEquals(Opcode.GOTO_32, instructions.get(0).getOpcode());
Assert.assertEquals(70003, ((OffsetInstruction) instructions.get(0)).getCodeOffset());
}
Aggregations