private static void merge(InsnArg arg, LocalVar var) {
   if (arg != null && arg.isRegister()) {
     RegisterArg reg = (RegisterArg) arg;
     if (var.getRegNum() == reg.getRegNum()) {
       reg.mergeDebugInfo(var.getType(), var.getName());
     }
   }
 }
Exemple #2
0
 private static void renameVar(MethodNode mth, SSAVar[] vars, int[] vers, BlockNode block) {
   SSAVar[] inputVars = Arrays.copyOf(vars, vars.length);
   for (InsnNode insn : block.getInstructions()) {
     if (insn.getType() != InsnType.PHI) {
       for (InsnArg arg : insn.getArguments()) {
         if (!arg.isRegister()) {
           continue;
         }
         RegisterArg reg = (RegisterArg) arg;
         int regNum = reg.getRegNum();
         SSAVar var = vars[regNum];
         if (var == null) {
           throw new JadxRuntimeException(
               "Not initialized variable reg: "
                   + regNum
                   + ", insn: "
                   + insn
                   + ", block:"
                   + block
                   + ", method: "
                   + mth);
         }
         var.use(reg);
       }
     }
     RegisterArg result = insn.getResult();
     if (result != null) {
       int regNum = result.getRegNum();
       vars[regNum] = mth.makeNewSVar(regNum, vers, result);
     }
   }
   for (BlockNode s : block.getSuccessors()) {
     PhiListAttr phiList = s.get(AType.PHI_LIST);
     if (phiList == null) {
       continue;
     }
     int j = s.getPredecessors().indexOf(block);
     if (j == -1) {
       throw new JadxRuntimeException("Can't find predecessor for " + block + " " + s);
     }
     for (PhiInsn phiInsn : phiList.getList()) {
       if (j >= phiInsn.getArgsCount()) {
         continue;
       }
       int regNum = phiInsn.getResult().getRegNum();
       SSAVar var = vars[regNum];
       if (var == null) {
         continue;
       }
       var.use(phiInsn.getArg(j));
       var.setUsedInPhi(phiInsn);
     }
   }
   for (BlockNode domOn : block.getDominatesOn()) {
     renameVar(mth, vars, vers, domOn);
   }
   System.arraycopy(inputVars, 0, vars, 0, vars.length);
 }
Exemple #3
0
 private static void renameVariables(MethodNode mth) {
   int regsCount = mth.getRegsCount();
   SSAVar[] vars = new SSAVar[regsCount];
   int[] versions = new int[regsCount];
   // init method arguments
   for (RegisterArg arg : mth.getArguments(true)) {
     int regNum = arg.getRegNum();
     vars[regNum] = mth.makeNewSVar(regNum, versions, arg);
   }
   renameVar(mth, vars, versions, mth.getEnterBlock());
 }
Exemple #4
0
 private static void fixLastTryCatchAssign(MethodNode mth) {
   for (BlockNode block : mth.getBasicBlocks()) {
     PhiListAttr phiList = block.get(AType.PHI_LIST);
     if (phiList == null || !block.contains(AType.EXC_HANDLER)) {
       continue;
     }
     for (PhiInsn phi : phiList.getList()) {
       for (int i = 0; i < phi.getArgsCount(); i++) {
         RegisterArg arg = phi.getArg(i);
         InsnNode parentInsn = arg.getAssignInsn();
         if (parentInsn != null
             && parentInsn.getResult() != null
             && parentInsn.contains(AFlag.TRY_LEAVE)) {
           phi.removeArg(arg);
         }
       }
     }
   }
 }
 private int addrChange(int addr, int addrInc, int line) {
   int newAddr = addr + addrInc;
   for (int i = addr + 1; i <= newAddr; i++) {
     InsnNode insn = insnByOffset[i];
     if (insn == null) {
       continue;
     }
     for (InsnArg arg : insn.getArguments()) {
       if (arg.isRegister()) {
         activeRegisters[((RegisterArg) arg).getRegNum()] = arg;
       }
     }
     RegisterArg res = insn.getResult();
     if (res != null) {
       activeRegisters[res.getRegNum()] = res;
     }
   }
   setSourceLines(addr, newAddr, line);
   return newAddr;
 }
  public void process() throws DecodeException {
    int addr = 0;
    int line = section.readUleb128();

    int paramsCount = section.readUleb128();
    List<RegisterArg> mthArgs = mth.getArguments(false);
    assert paramsCount == mthArgs.size();

    for (int i = 0; i < paramsCount; i++) {
      int id = section.readUleb128() - 1;
      if (id != DexNode.NO_INDEX) {
        String name = dex.getString(id);
        mthArgs.get(i).setName(name);
      }
    }

    for (RegisterArg arg : mthArgs) {
      int rn = arg.getRegNum();
      locals[rn] = new LocalVar(arg);
      activeRegisters[rn] = arg;
    }

    // process '0' instruction
    addrChange(-1, 1, line);
    setLine(addr, line);

    int c = section.readByte() & 0xFF;
    while (c != DBG_END_SEQUENCE) {
      switch (c) {
        case DBG_ADVANCE_PC:
          {
            int addrInc = section.readUleb128();
            addr = addrChange(addr, addrInc, line);
            setLine(addr, line);
            break;
          }
        case DBG_ADVANCE_LINE:
          {
            line += section.readSleb128();
            break;
          }

        case DBG_START_LOCAL:
          {
            int regNum = section.readUleb128();
            int nameId = section.readUleb128() - 1;
            int type = section.readUleb128() - 1;
            LocalVar var = new LocalVar(dex, regNum, nameId, type, DexNode.NO_INDEX);
            startVar(var, addr, line);
            break;
          }
        case DBG_START_LOCAL_EXTENDED:
          {
            int regNum = section.readUleb128();
            int nameId = section.readUleb128() - 1;
            int type = section.readUleb128() - 1;
            int sign = section.readUleb128() - 1;
            LocalVar var = new LocalVar(dex, regNum, nameId, type, sign);
            startVar(var, addr, line);
            break;
          }
        case DBG_RESTART_LOCAL:
          {
            int regNum = section.readUleb128();
            LocalVar var = locals[regNum];
            if (var != null) {
              var.end(addr, line);
              setVar(var);
              var.start(addr, line);
            }
            break;
          }
        case DBG_END_LOCAL:
          {
            int regNum = section.readUleb128();
            LocalVar var = locals[regNum];
            if (var != null) {
              var.end(addr, line);
              setVar(var);
            }
            break;
          }

        case DBG_SET_PROLOGUE_END:
        case DBG_SET_EPILOGUE_BEGIN:
          // do nothing
          break;

        case DBG_SET_FILE:
          {
            int idx = section.readUleb128() - 1;
            if (idx != DexNode.NO_INDEX) {
              String sourceFile = dex.getString(idx);
              mth.addAttr(new SourceFileAttr(sourceFile));
            }
            break;
          }

        default:
          {
            if (c >= DBG_FIRST_SPECIAL) {
              int adjustedOpcode = c - DBG_FIRST_SPECIAL;
              int addrInc = adjustedOpcode / DBG_LINE_RANGE;
              addr = addrChange(addr, addrInc, line);
              line += DBG_LINE_BASE + (adjustedOpcode % DBG_LINE_RANGE);
              setLine(addr, line);
            } else {
              throw new DecodeException("Unknown debug insn code: " + c);
            }
            break;
          }
      }
      c = section.readByte() & 0xFF;
    }

    for (LocalVar var : locals) {
      if (var != null && !var.isEnd()) {
        var.end(addr, line);
        setVar(var);
      }
    }
    setSourceLines(addr, insnByOffset.length, line);
  }