/**
   * Validates an encoded debug info stream against data used to encode it, throwing an exception if
   * they do not match. Used to validate the encoder.
   *
   * @param info encoded debug info
   * @param file {@code non-null;} file to refer to during decoding
   * @param ref {@code non-null;} method whose info is being decoded
   * @param code {@code non-null;} original code object that was encoded
   * @param isStatic whether the method is static
   */
  public static void validateEncode(
      byte[] info, DexFile file, CstMethodRef ref, DalvCode code, boolean isStatic) {
    PositionList pl = code.getPositions();
    LocalList ll = code.getLocals();
    DalvInsnList insns = code.getInsns();
    int codeSize = insns.codeSize();
    int countRegisters = insns.getRegistersSize();

    try {
      validateEncode0(info, codeSize, countRegisters, isStatic, ref, file, pl, ll);
    } catch (RuntimeException ex) {
      System.err.println("instructions:");
      insns.debugPrint(System.err, "  ", true);
      System.err.println("local list:");
      ll.debugPrint(System.err, "  ");
      throw ExceptionWithContext.withContext(ex, "while processing " + ref.toHuman());
    }
  }
Esempio n. 2
0
  /**
   * Helper for {@link #encode} to do most of the work.
   *
   * @param file null-ok; file to refer to during encoding
   * @param prefix null-ok; prefix to attach to each line of output
   * @param debugPrint null-ok; if specified, an alternate output for annotations
   * @param out null-ok; if specified, where annotations should go
   * @param consume whether to claim to have consumed output for <code>out</code>
   * @return non-null; the encoded array
   */
  private byte[] encode0(
      DexFile file, String prefix, PrintWriter debugPrint, AnnotatedOutput out, boolean consume) {
    PositionList positions = code.getPositions();
    LocalList locals = code.getLocals();
    DalvInsnList insns = code.getInsns();
    int codeSize = insns.codeSize();
    int regSize = insns.getRegistersSize();

    DebugInfoEncoder encoder =
        new DebugInfoEncoder(positions, locals, file, codeSize, regSize, isStatic, ref);

    byte[] result;

    if ((debugPrint == null) && (out == null)) {
      result = encoder.convert();
    } else {
      result = encoder.convertAndAnnotate(prefix, debugPrint, out, consume);
    }

    return result;
  }
Esempio n. 3
0
  /** Helper that updates the dex statistics. */
  private static void updateDexStatistics(
      CfOptions cfOptions,
      DexOptions dexOptions,
      RopMethod optRmeth,
      RopMethod nonOptRmeth,
      LocalVariableInfo locals,
      int paramSize,
      int originalByteCount) {
    /*
     * Run rop->dex again on optimized vs. non-optimized method to
     * collect statistics. We have to totally convert both ways,
     * since converting the "real" method getting added to the
     * file would corrupt it (by messing with its constant pool
     * indices).
     */

    DalvCode optCode =
        RopTranslator.translate(optRmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
    DalvCode nonOptCode =
        RopTranslator.translate(nonOptRmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);

    /*
     * Fake out the indices, so code.getInsns() can work well enough
     * for the current purpose.
     */

    DalvCode.AssignIndicesCallback callback =
        new DalvCode.AssignIndicesCallback() {
          public int getIndex(Constant cst) {
            // Everything is at index 0!
            return 0;
          }
        };

    optCode.assignIndices(callback);
    nonOptCode.assignIndices(callback);

    CodeStatistics.updateDexStatistics(nonOptCode, optCode);
    CodeStatistics.updateOriginalByteCount(originalByteCount);
  }