Exemplo n.º 1
0
void create_runtime_exception_block(
    DexString* except_str, std::vector<IRInstruction*>& block) {
  // new-instance v0, Ljava/lang/RuntimeException; // type@3852
  // const-string v1, "Exception String e.g. Too many args" // string@7a6d
  // invoke-direct {v0, v1}, Ljava/lang/RuntimeException;.<init>:(Ljava/lang/String;)V
  // throw v0
  auto new_inst =
      (new IRInstruction(OPCODE_NEW_INSTANCE))
          ->set_type(DexType::make_type("Ljava/lang/RuntimeException;"));
  new_inst->set_dest(0);
  IRInstruction* const_inst =
      (new IRInstruction(OPCODE_CONST_STRING))->set_string(except_str);
  const_inst->set_dest(1);
  auto ret = DexType::make_type("V");
  auto arg = DexType::make_type("Ljava/lang/String;");
  auto args = DexTypeList::make_type_list({arg});
  auto proto = DexProto::make_proto(ret, args);
  auto meth = DexMethod::make_method(
    DexType::make_type("Ljava/lang/RuntimeException;"),
    DexString::make_string("<init>"), proto);
  auto invk = new IRInstruction(OPCODE_INVOKE_DIRECT);
  invk->set_method(meth);
  invk->set_arg_word_count(2);
  invk->set_src(0, 0); invk->set_src(1, 1);
  IRInstruction* throwinst = new IRInstruction(OPCODE_THROW);
  block.emplace_back(new_inst);
  block.emplace_back(const_inst);
  block.emplace_back(invk);
  block.emplace_back(throwinst);
}
Exemplo n.º 2
0
void DexInstruction::verify_encoding() const {
  auto test = m_count ? new DexInstruction(opcode()) : new DexInstruction(opcode(), 0);
  if (dests_size()) {
    test->set_dest(dest());
  }
  for (unsigned i = 0; i < srcs_size(); i++) {
    test->set_src(i, src(i));
  }
  if (has_range_base()) test->set_range_base(range_base());
  if (has_range_size()) test->set_range_size(range_size());
  if (has_arg_word_count()) test->set_arg_word_count(arg_word_count());
  if (has_literal()) test->set_literal(literal());
  if (has_offset()) test->set_offset(offset());

  assert_log(m_opcode == test->m_opcode, "%x %x\n", m_opcode, test->m_opcode);
  for (unsigned i = 0; i < m_count; i++) {
    assert_log(m_arg[i] == test->m_arg[i],
               "(%x %x) (%x %x)",
               m_opcode,
               m_arg[i],
               test->m_opcode,
               test->m_arg[i]);
  }

  delete test;
}
Exemplo n.º 3
0
void MethodBlock::new_array(DexType* type,
                            const Location& size,
                            const Location& dst) {
  auto insn = new IRInstruction(OPCODE_NEW_ARRAY);
  insn->set_type(type);
  insn->set_arg_word_count(1);
  insn->set_src(0, size.get_reg());
  push_instruction(insn);
  push_instruction((new IRInstruction(IOPCODE_MOVE_RESULT_PSEUDO_OBJECT))
                       ->set_dest(dst.get_reg()));
}
Exemplo n.º 4
0
void MethodBlock::invoke(DexOpcode opcode,
                         DexMethod* meth,
                         std::vector<Location>& args) {
  always_assert(is_invoke(opcode));
  auto invk = new DexOpcodeMethod(opcode, meth, 0);
  uint16_t arg_count = static_cast<uint16_t>(args.size());
  invk->set_arg_word_count(arg_count);
  for (uint16_t i = 0; i < arg_count; i++) {
    auto arg = args[i];
    invk->set_src(i, reg_num(arg));
  }
  if (arg_count > mc->out_count) mc->out_count = arg_count;
  push_instruction(invk);
}
Exemplo n.º 5
0
void IRInstruction::normalize_registers() {
  if (is_invoke(opcode())) {
    auto& args = get_method()->get_proto()->get_args()->get_type_list();
    size_t old_srcs_idx{0};
    size_t srcs_idx{0};
    if (m_opcode != OPCODE_INVOKE_STATIC) {
      ++srcs_idx;
      ++old_srcs_idx;
    }
    for (size_t args_idx = 0; args_idx < args.size(); ++args_idx) {
      always_assert_log(
          old_srcs_idx < srcs_size(),
          "Invalid arg indices in %s args_idx %d old_srcs_idx %d\n",
          SHOW(this),
          args_idx,
          old_srcs_idx);
      set_src(srcs_idx++, src(old_srcs_idx));
      old_srcs_idx += is_wide_type(args.at(args_idx)) ? 2 : 1;
    }
    always_assert(old_srcs_idx == srcs_size());
    set_arg_word_count(srcs_idx);
  }
}