Esempio n. 1
0
void change_visibility(DexMethod* method) {
  auto code = method->get_code();
  always_assert(code != nullptr);

  editable_cfg_adapter::iterate(code, [](MethodItemEntry& mie) {
    auto insn = mie.insn;

    if (insn->has_field()) {
      auto cls = type_class(insn->get_field()->get_class());
      if (cls != nullptr && !cls->is_external()) {
        set_public(cls);
      }
      auto field =
          resolve_field(insn->get_field(), is_sfield_op(insn->opcode())
              ? FieldSearch::Static : FieldSearch::Instance);
      if (field != nullptr && field->is_concrete()) {
        set_public(field);
        set_public(type_class(field->get_class()));
        // FIXME no point in rewriting opcodes in the method
        insn->set_field(field);
      }
    } else if (insn->has_method()) {
      auto cls = type_class(insn->get_method()->get_class());
      if (cls != nullptr && !cls->is_external()) {
        set_public(cls);
      }
      auto current_method = resolve_method(
          insn->get_method(), opcode_to_search(insn));
      if (current_method != nullptr && current_method->is_concrete()) {
        set_public(current_method);
        set_public(type_class(current_method->get_class()));
        // FIXME no point in rewriting opcodes in the method
        insn->set_method(current_method);
      }
    } else if (insn->has_type()) {
      auto type = insn->get_type();
      auto cls = type_class(type);
      if (cls != nullptr && !cls->is_external()) {
        set_public(cls);
      }
    }
    return editable_cfg_adapter::LOOP_CONTINUE;
  });

  std::vector<DexType*> types;
  if (code->editable_cfg_built()) {
    code->cfg().gather_catch_types(types);
  } else {
    code->gather_catch_types(types);
  }
  for (auto type : types) {
    auto cls = type_class(type);
    if (cls != nullptr && !cls->is_external()) {
      set_public(cls);
    }
  }
}
Esempio n. 2
0
//--------------------------clone_shallow--------------------------------------
JVMState* JVMState::clone_shallow() const {
    JVMState* n = has_method() ? new JVMState(_method, _caller) : new JVMState(0);
    n->set_bci(_bci);
    n->set_locoff(_locoff);
    n->set_stkoff(_stkoff);
    n->set_monoff(_monoff);
    n->set_endoff(_endoff);
    n->set_sp(_sp);
    n->set_map(_map);
    return n;
}
Esempio n. 3
0
// The instruction format doesn't tell us the width of registers for invoke
// so we inspect the signature of the method we're calling
bool IRInstruction::invoke_src_is_wide(size_t i) const {
  always_assert(has_method());

  // virtual methods have `this` as the 0th register argument, but the
  // arg list does NOT include `this`
  if (!is_invoke_static(m_opcode)) {
    if (i == 0) {
      // reference to `this`. References are never wide
      return false;
    }
    --i;
  }

  const std::deque<DexType*>& args =
      m_method->get_proto()->get_args()->get_type_list();
  return is_wide_type(args[i]);
}
Esempio n. 4
0
uint64_t IRInstruction::hash() const {
  std::vector<uint64_t> bits;
  bits.push_back(opcode());

  for (size_t i = 0; i < srcs_size(); i++) {
    bits.push_back(src(i));
  }

  if (dests_size() > 0) {
    bits.push_back(dest());
  }

  if (has_data()) {
    size_t size = get_data()->data_size();
    const auto& data = get_data()->data();
    for (size_t i = 0; i < size; i++) {
      bits.push_back(data[i]);
    }
  }

  if (has_type()) {
    bits.push_back(reinterpret_cast<uint64_t>(get_type()));
  }
  if (has_field()) {
    bits.push_back(reinterpret_cast<uint64_t>(get_field()));
  }
  if (has_method()) {
    bits.push_back(reinterpret_cast<uint64_t>(get_method()));
  }
  if (has_string()) {
    bits.push_back(reinterpret_cast<uint64_t>(get_string()));
  }
  if (has_literal()) {
    bits.push_back(get_literal());
  }

  uint64_t result = 0;
  for (uint64_t elem : bits) {
    result ^= elem;
  }
  return result;
}
Esempio n. 5
0
MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) {
	StringName mdname = method_name.name;
#else
MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const char *method_name, const Variant **p_defs, int p_defcount) {
	StringName mdname = StaticCString::create(method_name);
#endif

	OBJTYPE_WLOCK;
	ERR_FAIL_COND_V(!p_bind, NULL);
	p_bind->set_name(mdname);

	String instance_type = p_bind->get_instance_class();

#ifdef DEBUG_ENABLED

	if (has_method(instance_type, mdname)) {
		ERR_EXPLAIN("Class " + String(instance_type) + " already has a method " + String(mdname));
		ERR_FAIL_V(NULL);
	}
#endif

	ClassInfo *type = classes.getptr(instance_type);
	if (!type) {
		ERR_PRINTS("Couldn't bind method '" + mdname + "' for instance: " + instance_type);
		memdelete(p_bind);
		ERR_FAIL_V(NULL);
	}

	if (type->method_map.has(mdname)) {
		memdelete(p_bind);
		// overloading not supported
		ERR_EXPLAIN("Method already bound: " + instance_type + "::" + mdname);
		ERR_FAIL_V(NULL);
	}

#ifdef DEBUG_METHODS_ENABLED

	if (method_name.args.size() > p_bind->get_argument_count()) {
		memdelete(p_bind);
		ERR_EXPLAIN("Method definition provides more arguments than the method actually has: " + instance_type + "::" + mdname);
		ERR_FAIL_V(NULL);
	}

	p_bind->set_argument_names(method_name.args);

	type->method_order.push_back(mdname);
#endif

	type->method_map[mdname] = p_bind;

	Vector<Variant> defvals;

	defvals.resize(p_defcount);
	for (int i = 0; i < p_defcount; i++) {

		defvals.write[i] = *p_defs[p_defcount - i - 1];
	}

	p_bind->set_default_arguments(defvals);
	p_bind->set_hint_flags(p_flags);
	return p_bind;
}
 ciMethod*         method() const { assert(has_method(), ""); return _method; }