void RemoveInterfacePass::configure_pass(const JsonWrapper& jw) { std::vector<std::string> interface_roots; jw.get("interface_roots", {}, interface_roots); for (const auto& type_str : interface_roots) { auto type = DexType::get_type(type_str.c_str()); if (type == nullptr) { fprintf(stderr, "No type found for root %s\n", type_str.c_str()); continue; } m_interface_roots.emplace(type); } std::vector<std::string> skip_multiple_targets_roots; jw.get("skip_multiple_targets_roots", {}, skip_multiple_targets_roots); for (const auto& type_str : skip_multiple_targets_roots) { auto type = DexType::get_type(type_str.c_str()); if (type == nullptr) { fprintf(stderr, "No type found for root %s\n", type_str.c_str()); continue; } m_skip_multiple_targets_roots.emplace(type); } jw.get("include_primary_dex", false, m_include_primary_dex); jw.get("keep_debug_info", false, m_keep_debug_info); // Interface dispatch annotation. std::string interface_dispatch_anno_type; jw.get("interface_dispatch_anno", "", interface_dispatch_anno_type); m_interface_dispatch_anno = DexType::get_type(interface_dispatch_anno_type.c_str()); always_assert(m_interface_dispatch_anno != nullptr); }
const Json::Value Event::SerializeJSON(void) const { JsonWrapper jsonWrapper; Json::Value & json = jsonWrapper.GetJsonRoot(); json[Dict::EVENT_ATTR_NAME] = Name; json[Dict::EVENT_ATTR_SEVERITY] = Severity; json[Dict::EVENT_ATTR_TRANSITION] = GetTransitionTypeString(); json[Dict::EVENT_ATTR_TIMESTAMP] = Timestamp; json[Dict::EVENT_ATTR_WHAT] = What; json[Dict::EVENT_ATTR_ACTIVE] = Active; json[Dict::EVENT_ATTR_IGNORED] = Ignored; return json; }
void TypeErasurePass::configure_pass(const JsonWrapper& jw) { jw.get("merged_type_mappings", "", m_merged_type_mapping_file); bool devirtualize_non_virtuals; jw.get("devirtualize", false, devirtualize_non_virtuals); bool process_method_meta; jw.get("process_method_meta", false, process_method_meta); int64_t max_num_dispatch_target; jw.get("max_num_dispatch_target", 0, max_num_dispatch_target); if (max_num_dispatch_target > 0) { m_max_num_dispatch_target = boost::optional<size_t>(static_cast<size_t>(max_num_dispatch_target)); } bool merge_static_methods_within_shape; jw.get("merge_static_methods_within_shape", false, merge_static_methods_within_shape); bool merge_direct_methods_within_shape; jw.get("merge_direct_methods_within_shape", false, merge_direct_methods_within_shape); bool merge_nonvirt_methods_within_shape; jw.get("merge_nonvirt_methods_within_shape", false, merge_nonvirt_methods_within_shape); // load model specifications Json::Value models; jw.get("models", Json::Value(), models); if (models.isNull()) return; if (!models.isArray()) { fprintf(stderr, "[TERA] Wrong specification: \"models\" is not an array\n"); return; } // load each model spec for erasure for (auto it = models.begin(); it != models.end(); ++it) { const auto& value = *it; if (!value.isObject()) { fprintf(stderr, "[TERA] Wrong specification: model in array not an object\n"); m_model_specs.clear(); return; } JsonWrapper model_spec = JsonWrapper(value); ModelSpec model; model_spec.get("enabled", true, model.enabled); std::string type_tag_config; model_spec.get("type_tag_config", "generate", type_tag_config); model.type_tag_config = get_type_tag_config(type_tag_config); size_t min_count; model_spec.get("min_count", 1, min_count); model.min_count = min_count > 0 ? min_count : 0; model_spec.get("name", "", model.name); std::vector<std::string> root_names; model_spec.get("roots", {}, root_names); load_types(root_names, model.roots); std::vector<std::string> excl_names; model_spec.get("exclude", {}, excl_names); load_types(excl_names, model.exclude_types); model_spec.get("class_name_prefix", "", model.class_name_prefix); Json::Value generated; model_spec.get("generated", Json::Value(), generated); if (!generated.isNull()) { if (!generated.isObject()) { fprintf(stderr, "[TERA] Wrong specification: model in array not an object\n"); m_model_specs.clear(); return; } JsonWrapper gen_spec = JsonWrapper(generated); std::vector<std::string> gen_names; gen_spec.get("other_roots", {}, gen_names); load_types(gen_names, model.gen_types); std::vector<std::string> gen_anno_names; gen_spec.get("annos", {}, gen_anno_names); load_types(gen_anno_names, model.gen_annos); } model_spec.get("include_primary_dex", false, model.include_primary_dex); model_spec.get("dex_sharding", false, model.dex_sharding); std::string merge_per_interdex_set; model_spec.get("merge_per_interdex_set", "disabled", merge_per_interdex_set); model.merge_per_interdex_set = get_merge_per_interdex_type(merge_per_interdex_set); always_assert_log(!model.merge_per_interdex_set || (model.type_tag_config != TypeTagConfig::NONE), "Cannot group when type tag is not needed."); always_assert_log(!model.dex_sharding || !model.merge_per_interdex_set, "Cannot have both dex sharding and group sharding " "enabled!"); size_t max_count; model_spec.get("max_count", 0, max_count); Json::Value approximate_shaping; model_spec.get("approximate_shape_merging", Json::Value(), model.approximate_shape_merging); model_spec.get("merge_types_with_static_fields", false, model.merge_types_with_static_fields); model_spec.get("keep_debug_info", false, model.keep_debug_info); model_spec.get("exclude_reference_to_android_sdk", Json::Value(), model.exclude_reference_to_android_sdk); if (max_count > 0) { model.max_count = boost::optional<size_t>(max_count); } model.devirtualize_non_virtuals = devirtualize_non_virtuals; model.process_method_meta = process_method_meta; model.merge_static_methods_within_shape = merge_static_methods_within_shape; model.merge_direct_methods_within_shape = merge_direct_methods_within_shape; model.merge_nonvirt_methods_within_shape = merge_nonvirt_methods_within_shape; if (!verify_model_spec(model)) { continue; } if (model.dex_sharding) { if (!model.enabled) { TRACE(TERA, 3, "Per dex Type Erased model not enabled. Skipping %s\n", model.name.c_str()); } else { m_dex_sharding_model_specs.emplace_back(std::move(model)); } } else { m_model_specs.emplace_back(std::move(model)); } } TRACE(TERA, 1, "[TERA] valid model specs %ld\n", m_model_specs.size()); }