예제 #1
0
파일: DebugInfo.java 프로젝트: 9hao/ZjDroid
 @Nonnull
 @Override
 public VariableSizeIterator<String> getParameterNames(@Nullable DexReader reader) {
   if (reader == null) {
     reader = dexFile.readerAt(debugInfoOffset);
     reader.skipUleb128();
   }
   // TODO: make sure dalvik doesn't allow more parameter names than we have parameters
   final int parameterNameCount = reader.readSmallUleb128();
   return new VariableSizeIterator<String>(reader, parameterNameCount) {
     @Override
     protected String readNextItem(@Nonnull DexReader reader, int index) {
       return dexFile.getOptionalString(reader.readSmallUleb128() - 1);
     }
   };
 }
예제 #2
0
  @Nonnull
  public static String asString(@Nonnull DexBackedDexFile dexFile, int methodIndex) {
    int methodOffset = dexFile.getMethodIdItemOffset(methodIndex);
    int classIndex = dexFile.readUshort(methodOffset + CLASS_OFFSET);
    String classType = dexFile.getType(classIndex);

    int protoIndex = dexFile.readUshort(methodOffset + PROTO_OFFSET);
    String protoString = ProtoIdItem.asString(dexFile, protoIndex);

    int nameIndex = dexFile.readSmallUint(methodOffset + NAME_OFFSET);
    String methodName = dexFile.getString(nameIndex);

    return String.format("%s->%s%s", classType, methodName, protoString);
  }
예제 #3
0
  @Nonnull
  public static List<Set<? extends DexBackedAnnotation>> getParameterAnnotations(
      @Nonnull final DexBackedDexFile dexFile, final int annotationSetListOffset) {
    if (annotationSetListOffset > 0) {
      final int size = dexFile.readSmallUint(annotationSetListOffset);

      return new FixedSizeList<Set<? extends DexBackedAnnotation>>() {
        @Nonnull
        @Override
        public Set<? extends DexBackedAnnotation> readItem(int index) {
          int annotationSetOffset = dexFile.readSmallUint(annotationSetListOffset + 4 + index * 4);
          return getAnnotations(dexFile, annotationSetOffset);
        }

        @Override
        public int size() {
          return size;
        }
      };
    }
    return ImmutableList.of();
  }
예제 #4
0
  @Nonnull
  public static Set<? extends DexBackedAnnotation> getAnnotations(
      @Nonnull final DexBackedDexFile dexFile, final int annotationSetOffset) {
    if (annotationSetOffset != 0) {
      final int size = dexFile.readSmallUint(annotationSetOffset);
      return new FixedSizeSet<DexBackedAnnotation>() {
        @Nonnull
        @Override
        public DexBackedAnnotation readItem(int index) {
          int annotationOffset = dexFile.readSmallUint(annotationSetOffset + 4 + (4 * index));
          return new DexBackedAnnotation(dexFile, annotationOffset);
        }

        @Override
        public int size() {
          return size;
        }
      };
    }

    return ImmutableSet.of();
  }
예제 #5
0
파일: DebugInfo.java 프로젝트: 9hao/ZjDroid
    @Nonnull
    @Override
    public Iterator<DebugItem> iterator() {
      DexReader reader = dexFile.readerAt(debugInfoOffset);
      final int lineNumberStart = reader.readBigUleb128();
      int registerCount = methodImpl.getRegisterCount();

      // TODO: does dalvik allow references to invalid registers?
      final LocalInfo[] locals = new LocalInfo[registerCount];
      Arrays.fill(locals, EMPTY_LOCAL_INFO);

      DexBackedMethod method = methodImpl.method;

      // Create a MethodParameter iterator that uses our DexReader instance to read the parameter
      // names.
      // After we have finished iterating over the parameters, reader will "point to" the beginning
      // of the
      // debug instructions
      final Iterator<? extends MethodParameter> parameterIterator =
          new ParameterIterator(
              method.getParameterTypes(),
              method.getParameterAnnotations(),
              getParameterNames(reader));

      // first, we grab all the parameters and temporarily store them at the beginning of locals,
      // disregarding any wide types
      int parameterIndex = 0;
      if (!AccessFlags.STATIC.isSet(methodImpl.method.getAccessFlags())) {
        // add the local info for the "this" parameter
        locals[parameterIndex++] =
            new LocalInfo() {
              @Override
              public String getName() {
                return "this";
              }

              @Override
              public String getType() {
                return methodImpl.method.getDefiningClass();
              }

              @Override
              public String getSignature() {
                return null;
              }
            };
      }
      while (parameterIterator.hasNext()) {
        locals[parameterIndex++] = parameterIterator.next();
      }

      if (parameterIndex < registerCount) {
        // now, we push the parameter locals back to their appropriate register, starting from the
        // end
        int localIndex = registerCount - 1;
        while (--parameterIndex > -1) {
          LocalInfo currentLocal = locals[parameterIndex];
          String type = currentLocal.getType();
          if (type != null && (type.equals("J") || type.equals("D"))) {
            localIndex--;
            if (localIndex == parameterIndex) {
              // there's no more room to push, the remaining registers are already in the correct
              // place
              break;
            }
          }
          locals[localIndex] = currentLocal;
          locals[parameterIndex] = EMPTY_LOCAL_INFO;
          localIndex--;
        }
      }

      return new VariableSizeLookaheadIterator<DebugItem>(dexFile, reader.getOffset()) {
        private int codeAddress = 0;
        private int lineNumber = lineNumberStart;

        @Nullable
        protected DebugItem readNextItem(@Nonnull DexReader reader) {
          while (true) {
            int next = reader.readUbyte();
            switch (next) {
              case DebugItemType.END_SEQUENCE:
                {
                  return null;
                }
              case DebugItemType.ADVANCE_PC:
                {
                  int addressDiff = reader.readSmallUleb128();
                  codeAddress += addressDiff;
                  continue;
                }
              case DebugItemType.ADVANCE_LINE:
                {
                  int lineDiff = reader.readSleb128();
                  lineNumber += lineDiff;
                  continue;
                }
              case DebugItemType.START_LOCAL:
                {
                  int register = reader.readSmallUleb128();
                  String name = dexFile.getOptionalString(reader.readSmallUleb128() - 1);
                  String type = dexFile.getOptionalType(reader.readSmallUleb128() - 1);
                  ImmutableStartLocal startLocal =
                      new ImmutableStartLocal(codeAddress, register, name, type, null);
                  locals[register] = startLocal;
                  return startLocal;
                }
              case DebugItemType.START_LOCAL_EXTENDED:
                {
                  int register = reader.readSmallUleb128();
                  String name = dexFile.getOptionalString(reader.readSmallUleb128() - 1);
                  String type = dexFile.getOptionalType(reader.readSmallUleb128() - 1);
                  String signature = dexFile.getOptionalString(reader.readSmallUleb128() - 1);
                  ImmutableStartLocal startLocal =
                      new ImmutableStartLocal(codeAddress, register, name, type, signature);
                  locals[register] = startLocal;
                  return startLocal;
                }
              case DebugItemType.END_LOCAL:
                {
                  int register = reader.readSmallUleb128();
                  LocalInfo localInfo = locals[register];
                  boolean replaceLocalInTable = true;
                  if (localInfo instanceof EndLocal) {
                    localInfo = EMPTY_LOCAL_INFO;
                    // don't replace the local info in locals. The new EndLocal won't have any info
                    // at all,
                    // and we dont want to wipe out what's there, so that it is available for a
                    // subsequent
                    // RestartLocal
                    replaceLocalInTable = false;
                  }
                  ImmutableEndLocal endLocal =
                      new ImmutableEndLocal(
                          codeAddress,
                          register,
                          localInfo.getName(),
                          localInfo.getType(),
                          localInfo.getSignature());
                  if (replaceLocalInTable) {
                    locals[register] = endLocal;
                  }
                  return endLocal;
                }
              case DebugItemType.RESTART_LOCAL:
                {
                  int register = reader.readSmallUleb128();
                  LocalInfo localInfo = locals[register];
                  ImmutableRestartLocal restartLocal =
                      new ImmutableRestartLocal(
                          codeAddress,
                          register,
                          localInfo.getName(),
                          localInfo.getType(),
                          localInfo.getSignature());
                  locals[register] = restartLocal;
                  return restartLocal;
                }
              case DebugItemType.PROLOGUE_END:
                {
                  return new ImmutablePrologueEnd(codeAddress);
                }
              case DebugItemType.EPILOGUE_BEGIN:
                {
                  return new ImmutableEpilogueBegin(codeAddress);
                }
              case DebugItemType.SET_SOURCE_FILE:
                {
                  String sourceFile = dexFile.getOptionalString(reader.readSmallUleb128() - 1);
                  return new ImmutableSetSourceFile(codeAddress, sourceFile);
                }
              default:
                {
                  int adjusted = next - 0x0A;
                  codeAddress += adjusted / 15;
                  lineNumber += (adjusted % 15) - 4;
                  return new ImmutableLineNumber(codeAddress, lineNumber);
                }
            }
          }
        }
      };
    }
  public DexBackedSparseSwitchPayload(@Nonnull DexBackedDexFile dexFile, int instructionStart) {
    super(dexFile, Opcode.SPARSE_SWITCH_PAYLOAD, instructionStart);

    elementCount = dexFile.readUshort(instructionStart + ELEMENT_COUNT_OFFSET);
  }
예제 #7
0
 @Nonnull
 public Set<? extends DexBackedAnnotation> getClassAnnotations() {
   return getAnnotations(dexFile, dexFile.readSmallUint(directoryOffset));
 }
예제 #8
0
 public int getParameterAnnotationCount() {
   return dexFile.readSmallUint(directoryOffset + PARAMETER_COUNT_OFFSET);
 }
예제 #9
0
 public int getMethodAnnotationCount() {
   return dexFile.readSmallUint(directoryOffset + METHOD_COUNT_OFFSET);
 }
예제 #10
0
 public int getFieldAnnotationCount() {
   return dexFile.readSmallUint(directoryOffset + FIELD_COUNT_OFFSET);
 }