use of org.jf.dexlib2.iface.instruction.Instruction in project atlas by alibaba.
the class InstructionMethodItem method writeInvokeRangeRegisters.
protected void writeInvokeRangeRegisters(IndentingWriter writer) throws IOException {
RegisterRangeInstruction instruction = (RegisterRangeInstruction) this.instruction;
int regCount = instruction.getRegisterCount();
if (regCount == 0) {
writer.write("{}");
} else {
int startRegister = instruction.getStartRegister();
methodDef.registerFormatter.writeRegisterRange(writer, startRegister, startRegister + regCount - 1);
}
}
use of org.jf.dexlib2.iface.instruction.Instruction in project atlas by alibaba.
the class InstructionMethodItem method writeInvoke25xRegisters.
protected void writeInvoke25xRegisters(IndentingWriter writer) throws IOException {
OneFixedFourParameterRegisterInstruction instruction = (OneFixedFourParameterRegisterInstruction) this.instruction;
final int parameterRegCount = instruction.getParameterRegisterCount();
// fixed register always present
writeRegister(writer, instruction.getRegisterFixedC());
writer.write(", {");
switch(parameterRegCount) {
case 1:
writeRegister(writer, instruction.getRegisterParameterD());
break;
case 2:
writeRegister(writer, instruction.getRegisterParameterD());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterE());
break;
case 3:
writeRegister(writer, instruction.getRegisterParameterD());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterE());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterF());
break;
case 4:
writeRegister(writer, instruction.getRegisterParameterD());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterE());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterF());
writer.write(", ");
writeRegister(writer, instruction.getRegisterParameterG());
break;
}
writer.write('}');
}
use of org.jf.dexlib2.iface.instruction.Instruction in project atlas by alibaba.
the class MethodDefinition method findPayloadOffset.
public int findPayloadOffset(int targetOffset, Opcode type) {
int targetIndex;
try {
targetIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(targetOffset);
} catch (InvalidInstructionOffset ex) {
throw new InvalidSwitchPayload(targetOffset);
}
//TODO: does dalvik let you pad with multiple nops?
//TODO: does dalvik let a switch instruction point to a non-payload instruction?
Instruction instruction = instructions.get(targetIndex);
if (instruction.getOpcode() != type) {
// maybe it's pointing to a NOP padding instruction. Look at the next instruction
if (instruction.getOpcode() == Opcode.NOP) {
targetIndex += 1;
if (targetIndex < instructions.size()) {
instruction = instructions.get(targetIndex);
if (instruction.getOpcode() == type) {
return instructionOffsetMap.getInstructionCodeOffset(targetIndex);
}
}
}
throw new InvalidSwitchPayload(targetOffset);
} else {
return targetOffset;
}
}
use of org.jf.dexlib2.iface.instruction.Instruction in project atlas by alibaba.
the class MethodDefinition method addInstructionMethodItems.
private void addInstructionMethodItems(List<MethodItem> methodItems) {
int currentCodeAddress = 0;
for (int i = 0; i < effectiveInstructions.size(); i++) {
Instruction instruction = effectiveInstructions.get(i);
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction);
methodItems.add(methodItem);
if (i != effectiveInstructions.size() - 1) {
methodItems.add(new BlankMethodItem(currentCodeAddress));
}
if (classDef.options.addCodeOffsets) {
methodItems.add(new MethodItem(currentCodeAddress) {
@Override
public double getSortOrder() {
return -1000;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write("#@");
writer.printUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
return true;
}
});
}
if (!classDef.options.noAccessorComments && (instruction instanceof ReferenceInstruction)) {
Opcode opcode = instruction.getOpcode();
if (opcode.referenceType == ReferenceType.METHOD) {
MethodReference methodReference = null;
try {
methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();
} catch (InvalidItemIndex ex) {
// just ignore it for now. We'll deal with it later, when processing the instructions
// themselves
}
if (methodReference != null && SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
AccessedMember accessedMember = classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
if (accessedMember != null) {
methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
}
}
}
}
currentCodeAddress += instruction.getCodeUnits();
}
}
use of org.jf.dexlib2.iface.instruction.Instruction 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);
}
}
}
Aggregations