Exemplo n.º 1
0
TEST(IRInstruction, SelectCheckCast) {
  using namespace dex_asm;
  g_redex = new RedexContext();

  DexMethod* method =
      static_cast<DexMethod*>(DexMethod::make_method("Lfoo;", "bar", "V", {}));
  method->make_concrete(ACC_STATIC, 0);
  method->set_code(std::make_unique<IRCode>(method, 0));
  auto code = method->get_code();
  code->push_back(dasm(OPCODE_CHECK_CAST, get_object_type(), {1_v}));
  code->push_back(dasm(IOPCODE_MOVE_RESULT_PSEUDO_OBJECT, {0_v}));
  instruction_lowering::lower(method);

  // check that we inserted a move opcode before the check-cast
  auto it = code->begin();
  EXPECT_EQ(
      *it->dex_insn,
      *(new DexInstruction(DOPCODE_MOVE_OBJECT))->set_dest(0)->set_src(0, 1));
  ++it;
  EXPECT_EQ(*it->dex_insn,
            *(new DexOpcodeType(DOPCODE_CHECK_CAST, get_object_type()))
                 ->set_src(0, 0));

  delete g_redex;
}
Exemplo n.º 2
0
 DexMethod* get_fresh_method(const std::string& name) {
   DexMethod* method = static_cast<DexMethod*>(DexMethod::make_method(
       m_type, DexString::make_string(name), m_proto));
   method->make_concrete(ACC_PUBLIC | ACC_STATIC, false);
   method->set_code(std::make_unique<IRCode>(method, 1));
   m_creator->add_method(method);
   return method;
 }
Exemplo n.º 3
0
/*
 * Helper function to run select and then extract the resulting instruction
 * from the instruction list. The only reason it's a list is that const-cast
 * IRInstructions can expand into two instructions due to select. Everything
 * else is a simple one-to-one instruction mapping, and that's the case that
 * this makes easy to test.
 */
IRInstruction* select_instruction(IRInstruction* insn) {
  DexMethod* method =
      static_cast<DexMethod*>(DexMethod::make_method("Lfoo;", "bar", "V", {}));
  method->make_concrete(ACC_STATIC, 0);
  method->set_code(std::make_unique<IRCode>(method, 0));
  auto code = method->get_code();
  code->push_back(insn);
  instruction_lowering::lower(method);
  return code->begin()->insn;
}
Exemplo n.º 4
0
void EquivalenceTest::generate(DexClass* cls) {
  setup(cls);
  auto ret = DexType::make_type("I");
  auto args = DexTypeList::make_type_list({});
  auto proto = DexProto::make_proto(ret, args); // I()
  DexMethod* before = static_cast<DexMethod*>(DexMethod::make_method(
      cls->get_type(), DexString::make_string("before_" + test_name()), proto));
  before->make_concrete(ACC_PUBLIC | ACC_STATIC, false);
  before->set_code(std::make_unique<IRCode>(before, 0));
  build_method(before);
  cls->add_method(before);
  auto after = DexMethod::make_method_from(
      before, cls->get_type(), DexString::make_string("after_" + test_name()));
  cls->add_method(after);
  transform_method(after);
}
Exemplo n.º 5
0
  // add a void->void static method to our dex_class
  DexMethod* make_void_method(const char* method_name,
                              const IRInstructionList& insns) const {
    auto ret = get_void_type();
    auto args = DexTypeList::make_type_list({});
    auto proto = DexProto::make_proto(ret, args); // I()
    DexMethod* method = static_cast<DexMethod*>(DexMethod::make_method(
        dex_class->get_type(), DexString::make_string(method_name), proto));
    method->make_concrete(ACC_PUBLIC | ACC_STATIC, false);
    // FIXME we should determine the actual number of temp regs used from
    // the IRInstructionList
    method->set_code(std::make_unique<IRCode>(method, 0));

    // import our instructions
    auto mt = method->get_code();
    for (const auto& insn_ptr : insns.instructions) {
      mt->push_back(new IRInstruction(*insn_ptr));
    }
    return method;
  }
Exemplo n.º 6
0
 virtual void setup(DexClass* cls) {
   auto ret = DexType::make_type("I");
   auto arg = DexType::make_type("I");
   auto args = DexTypeList::make_type_list({arg, arg});
   auto proto = DexProto::make_proto(ret, args); // I(I, I)
   m_callee =
       DexMethod::make_method(cls->get_type(),
                              DexString::make_string("callee_" + test_name()),
                              proto);
   m_callee->make_concrete(
       ACC_PUBLIC | ACC_STATIC, std::make_unique<DexCode>(), false);
   {
     using namespace dex_asm;
     MethodTransformer mt(m_callee);
     // note that this method will not behave the same way if v0 and v1 get
     // mapped to the same register
     mt->push_back(dasm(OPCODE_ADD_INT_2ADDR, {0_v, 1_v}));
     mt->push_back(dasm(OPCODE_ADD_INT_2ADDR, {1_v, 0_v}));
     mt->push_back(dasm(OPCODE_RETURN, {1_v}));
     m_callee->get_code()->set_registers_size(2);
     m_callee->get_code()->set_ins_size(2);
   }
   cls->add_method(m_callee);
 }