Example #1
0
 void exclude_referenced_bridgee(DexMethod* code_method, const DexCode& code) {
   auto const& insts = code.get_instructions();
   for (auto inst : insts) {
     if (!is_invoke(inst->opcode())) continue;
     auto method = static_cast<DexOpcodeMethod*>(inst)->get_method();
     auto range = m_potential_bridgee_refs.equal_range(
         MethodRef(method->get_class(), method->get_name(),
             method->get_proto()));
     for (auto it = range.first; it != range.second; ++it) {
       auto referenced_bridge = it->second;
       // Don't count the bridge itself
       if (referenced_bridge == code_method) continue;
       TRACE(BRIDGE,
             5,
             "Rejecting, reference `%s.%s.%s' in `%s' blocks `%s'\n",
             SHOW(method->get_class()),
             SHOW(method->get_name()),
             SHOW(method->get_proto()),
             SHOW(code_method),
             SHOW(referenced_bridge));
       m_bridges_to_bridgees.erase(referenced_bridge);
     }
   }
 }
Example #2
0
 void exclude_referenced_bridgee(DexMethod* code_method, IRCode& code) {
   for (auto& mie : InstructionIterable(&code)) {
     auto inst = mie.insn;
     if (!is_invoke(inst->opcode())) continue;
     auto method = inst->get_method();
     auto range = m_potential_bridgee_refs.equal_range(
         MethodRef(method->get_class(), method->get_name(),
             method->get_proto()));
     for (auto it = range.first; it != range.second; ++it) {
       auto referenced_bridge = it->second;
       // Don't count the bridge itself
       if (referenced_bridge == code_method) continue;
       TRACE(BRIDGE,
             5,
             "Rejecting, reference `%s.%s.%s' in `%s' blocks `%s'\n",
             SHOW(method->get_class()),
             SHOW(method->get_name()),
             SHOW(method->get_proto()),
             SHOW(code_method),
             SHOW(referenced_bridge));
       m_bridges_to_bridgees.erase(referenced_bridge);
     }
   }
 }
Example #3
0
  void search_hierarchy_for_matches(DexMethod* bridge, DexMethod* bridgee) {
    /*
     * Direct reference.  The only one if it's non-virtual.
     */
    auto clstype = bridgee->get_class();
    auto name = bridgee->get_name();
    auto proto = bridgee->get_proto();
    TRACE(BRIDGE, 5, "   %s %s %s\n", SHOW(clstype), SHOW(name), SHOW(proto));
    m_potential_bridgee_refs.emplace(MethodRef(clstype, name, proto), bridge);
    if (!bridgee->is_virtual()) return;

    /*
     * Search super classes
     *
     *   A bridge method in a derived class may be referred to using the name
     *   of a super class if a method with a matching signature is defined in
     *   that super class.
     *
     *   To build the set of potential matches, we accumulate potential refs in
     *   maybe_refs, and when we find a matching signature in a super class, we
     *   add everything in maybe_refs to the set.
     */
    std::vector<std::pair<MethodRef, DexMethod*>> maybe_refs;
    for (auto super = type_class(type_class(clstype)->get_super_class());
         super != nullptr;
         super = type_class(super->get_super_class())) {
      maybe_refs.emplace_back(
          MethodRef(super->get_type(), name, proto), bridge);
      for (auto vmethod : super->get_vmethods()) {
        if (signature_matches(bridgee, vmethod)) {
          for (auto DEBUG_ONLY refp : maybe_refs) {
            TRACE(BRIDGE,
                  5,
                  "    %s %s %s\n",
                  SHOW(std::get<0>(refp.first)),
                  SHOW(std::get<1>(refp.first)),
                  SHOW(std::get<2>(refp.first)));
          }
          m_potential_bridgee_refs.insert(maybe_refs.begin(), maybe_refs.end());
          maybe_refs.clear();
        }
      }
    }

    /*
     * Search sub classes
     *
     *   Easy.  Any subclass can refer to the bridgee.
     */
    TypeVector subclasses;
    get_all_children(clstype, subclasses);
    for (auto subclass : subclasses) {
      m_potential_bridgee_refs.emplace(MethodRef(subclass, name, proto),
                                       bridge);
      TRACE(BRIDGE,
            5,
            "    %s %s %s\n",
            SHOW(subclass),
            SHOW(name),
            SHOW(proto));
    }
  }