Beispiel #1
0
 public static void writeTo(IndentingWriter writer, long val) throws IOException {
   if (val < 0) {
     writer.write("-0x");
     writer.printUnsignedLongAsHex(-val);
     writer.write('L');
   } else {
     writer.write("0x");
     writer.printUnsignedLongAsHex(val);
     writer.write('L');
   }
 }
Beispiel #2
0
 public static void writeSignedIntOrLongTo(IndentingWriter writer, long val) throws IOException {
   if (val < 0) {
     writer.write("-0x");
     writer.printUnsignedLongAsHex(-val);
     if (val < Integer.MIN_VALUE) {
       writer.write('L');
     }
   } else {
     writer.write("0x");
     writer.printUnsignedLongAsHex(val);
     if (val > Integer.MAX_VALUE) {
       writer.write('L');
     }
   }
 }
  @Override
  public boolean writeTo(IndentingWriter writer) throws IOException {
    Opcode opcode = instruction.getOpcode();
    String verificationErrorName = null;
    String referenceString = null;

    boolean commentOutInstruction = false;

    if (instruction instanceof Instruction20bc) {
      int verificationError = ((Instruction20bc) instruction).getVerificationError();
      verificationErrorName = VerificationError.getVerificationErrorName(verificationError);
      if (verificationErrorName == null) {
        writer.write("#was invalid verification error type: ");
        writer.printSignedIntAsDec(verificationError);
        writer.write("\n");
        verificationErrorName = "generic-error";
      }
    }

    if (instruction instanceof ReferenceInstruction) {
      ReferenceInstruction referenceInstruction = (ReferenceInstruction) instruction;
      try {
        Reference reference = referenceInstruction.getReference();

        String classContext = null;
        if (methodDef.classDef.options.useImplicitReferences) {
          classContext = methodDef.method.getDefiningClass();
        }

        referenceString = ReferenceUtil.getReferenceString(reference, classContext);
        assert referenceString != null;
      } catch (InvalidItemIndex ex) {
        writer.write("#");
        writer.write(ex.getMessage());
        writer.write("\n");
        commentOutInstruction = true;

        referenceString =
            String.format(
                "%s@%d",
                ReferenceType.toString(referenceInstruction.getReferenceType()),
                ex.getInvalidIndex());
      } catch (ReferenceType.InvalidReferenceTypeException ex) {
        writer.write("#invalid reference type: ");
        writer.printSignedIntAsDec(ex.getReferenceType());
        commentOutInstruction = true;

        referenceString = "invalid_reference";
      }
    }

    if (instruction instanceof Instruction31t) {
      boolean validPayload = true;

      switch (instruction.getOpcode()) {
        case PACKED_SWITCH:
          int baseAddress =
              methodDef.getPackedSwitchBaseAddress(
                  this.codeAddress + ((Instruction31t) instruction).getCodeOffset());
          if (baseAddress == -1) {
            validPayload = false;
          }
          break;
        case SPARSE_SWITCH:
          baseAddress =
              methodDef.getSparseSwitchBaseAddress(
                  this.codeAddress + ((Instruction31t) instruction).getCodeOffset());
          if (baseAddress == -1) {
            validPayload = false;
          }
          break;
        case FILL_ARRAY_DATA:
          try {
            methodDef.findPayloadOffset(
                this.codeAddress + ((Instruction31t) instruction).getCodeOffset(),
                Opcode.ARRAY_PAYLOAD);
          } catch (InvalidSwitchPayload ex) {
            validPayload = false;
          }
          break;
        default:
          throw new ExceptionWithContext("Invalid 31t opcode: %s", instruction.getOpcode());
      }

      if (!validPayload) {
        writer.write("#invalid payload reference\n");
        commentOutInstruction = true;
      }
    }

    if (opcode.odexOnly()) {
      if (!isAllowedOdex(opcode)) {
        writer.write("#disallowed odex opcode\n");
        commentOutInstruction = true;
      }
    }

    if (commentOutInstruction) {
      writer.write("#");
    }

    switch (instruction.getOpcode().format) {
      case Format10t:
        writeOpcode(writer);
        writer.write(' ');
        writeTargetLabel(writer);
        break;
      case Format10x:
        if (instruction instanceof UnknownInstruction) {
          writer.write("#unknown opcode: 0x");
          writer.printUnsignedLongAsHex(((UnknownInstruction) instruction).getOriginalOpcode());
          writer.write('\n');
        }
        writeOpcode(writer);
        break;
      case Format11n:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeLiteral(writer);
        break;
      case Format11x:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        break;
      case Format12x:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeSecondRegister(writer);
        break;
      case Format20bc:
        writeOpcode(writer);
        writer.write(' ');
        writer.write(verificationErrorName);
        writer.write(", ");
        writer.write(referenceString);
        break;
      case Format20t:
      case Format30t:
        writeOpcode(writer);
        writer.write(' ');
        writeTargetLabel(writer);
        break;
      case Format21c:
      case Format31c:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writer.write(referenceString);
        break;
      case Format21ih:
      case Format21lh:
      case Format21s:
      case Format31i:
      case Format51l:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeLiteral(writer);
        if (instruction.getOpcode().setsWideRegister()) {
          writeCommentIfLikelyDouble(writer);
        } else {
          boolean isResourceId = writeCommentIfResourceId(writer);
          if (!isResourceId) writeCommentIfLikelyFloat(writer);
        }
        break;
      case Format21t:
      case Format31t:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeTargetLabel(writer);
        break;
      case Format22b:
      case Format22s:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeSecondRegister(writer);
        writer.write(", ");
        writeLiteral(writer);
        break;
      case Format22c:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeSecondRegister(writer);
        writer.write(", ");
        writer.write(referenceString);
        break;
      case Format22cs:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeSecondRegister(writer);
        writer.write(", ");
        writeFieldOffset(writer);
        break;
      case Format22t:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeSecondRegister(writer);
        writer.write(", ");
        writeTargetLabel(writer);
        break;
      case Format22x:
      case Format32x:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeSecondRegister(writer);
        break;
      case Format23x:
        writeOpcode(writer);
        writer.write(' ');
        writeFirstRegister(writer);
        writer.write(", ");
        writeSecondRegister(writer);
        writer.write(", ");
        writeThirdRegister(writer);
        break;
      case Format25x:
        writeOpcode(writer);
        writer.write(' ');
        writeInvoke25xRegisters(writer); // vC, {vD, ...}
        break;
      case Format35c:
        writeOpcode(writer);
        writer.write(' ');
        writeInvokeRegisters(writer);
        writer.write(", ");
        writer.write(referenceString);
        break;
      case Format35mi:
        writeOpcode(writer);
        writer.write(' ');
        writeInvokeRegisters(writer);
        writer.write(", ");
        writeInlineIndex(writer);
        break;
      case Format35ms:
        writeOpcode(writer);
        writer.write(' ');
        writeInvokeRegisters(writer);
        writer.write(", ");
        writeVtableIndex(writer);
        break;
      case Format3rc:
        writeOpcode(writer);
        writer.write(' ');
        writeInvokeRangeRegisters(writer);
        writer.write(", ");
        writer.write(referenceString);
        break;
      case Format3rmi:
        writeOpcode(writer);
        writer.write(' ');
        writeInvokeRangeRegisters(writer);
        writer.write(", ");
        writeInlineIndex(writer);
        break;
      case Format3rms:
        writeOpcode(writer);
        writer.write(' ');
        writeInvokeRangeRegisters(writer);
        writer.write(", ");
        writeVtableIndex(writer);
        break;
      default:
        assert false;
        return false;
    }

    if (commentOutInstruction) {
      writer.write("\nnop");
    }

    return true;
  }
 protected void writeFieldOffset(IndentingWriter writer) throws IOException {
   writer.write("field@0x");
   writer.printUnsignedLongAsHex(((FieldOffsetInstruction) instruction).getFieldOffset());
 }