diff options
| -rw-r--r-- | tools/veridex/Android.bp | 1 | ||||
| -rw-r--r-- | tools/veridex/hidden_api.cc | 79 | ||||
| -rw-r--r-- | tools/veridex/hidden_api.h | 63 | ||||
| -rw-r--r-- | tools/veridex/resolver.cc | 13 | ||||
| -rw-r--r-- | tools/veridex/resolver.h | 6 | ||||
| -rw-r--r-- | tools/veridex/veridex.cc | 4 |
6 files changed, 160 insertions, 6 deletions
diff --git a/tools/veridex/Android.bp b/tools/veridex/Android.bp index 31ff682828..ff181c89a7 100644 --- a/tools/veridex/Android.bp +++ b/tools/veridex/Android.bp @@ -16,6 +16,7 @@ art_cc_binary { name: "veridex", host_supported: true, srcs: [ + "hidden_api.cc", "resolver.cc", "veridex.cc", ], diff --git a/tools/veridex/hidden_api.cc b/tools/veridex/hidden_api.cc new file mode 100644 index 0000000000..33e499bfc3 --- /dev/null +++ b/tools/veridex/hidden_api.cc @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hidden_api.h" + +#include <fstream> +#include <sstream> + +#include "dex/dex_file-inl.h" + +namespace art { + +std::string HiddenApi::GetApiMethodName(const DexFile& dex_file, uint32_t method_index) { + std::stringstream ss; + const DexFile::MethodId& method_id = dex_file.GetMethodId(method_index); + ss << dex_file.StringByTypeIdx(method_id.class_idx_) + << "->" + << dex_file.GetMethodName(method_id) + << dex_file.GetMethodSignature(method_id).ToString(); + return ss.str(); +} + +std::string HiddenApi::GetApiFieldName(const DexFile& dex_file, uint32_t field_index) { + std::stringstream ss; + const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index); + ss << dex_file.StringByTypeIdx(field_id.class_idx_) + << "->" + << dex_file.GetFieldName(field_id) + << ":" + << dex_file.GetFieldTypeDescriptor(field_id); + return ss.str(); +} + +bool HiddenApi::LogIfIn(const std::string& name, + const std::set<std::string>& list, + const std::string& log, + const std::string& access_kind) { + if (list.find(name) != list.end()) { + LOG(WARNING) << std::string(log) << " usage found " << name << " (" << access_kind << ")"; + return true; + } + return false; +} + +void HiddenApi::FillList(const char* filename, std::set<std::string>& entries) { + if (filename == nullptr) { + return; + } + std::ifstream in(filename); + std::string str; + while (std::getline(in, str)) { + entries.insert(str); + size_t pos = str.find("->"); + if (pos != std::string::npos) { + // Add the class name. + entries.insert(str.substr(0, pos)); + pos = str.find('('); + if (pos != std::string::npos) { + // Add the class->method name (so stripping the signature). + entries.insert(str.substr(0, pos)); + } + } + } +} + +} // namespace art diff --git a/tools/veridex/hidden_api.h b/tools/veridex/hidden_api.h new file mode 100644 index 0000000000..282e7cf8e8 --- /dev/null +++ b/tools/veridex/hidden_api.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_TOOLS_VERIDEX_HIDDEN_API_H_ +#define ART_TOOLS_VERIDEX_HIDDEN_API_H_ + +#include <set> +#include <string> + +namespace art { + +class DexFile; + +/** + * Helper class for logging if a method/field is in a hidden API list. + */ +class HiddenApi { + public: + HiddenApi(const char* blacklist, const char* dark_greylist, const char* light_greylist) { + FillList(light_greylist, light_greylist_); + FillList(dark_greylist, dark_greylist_); + FillList(blacklist, blacklist_); + } + + bool LogIfInList(const std::string& name, const char* access_kind) const { + return LogIfIn(name, blacklist_, "Blacklist", access_kind) || + LogIfIn(name, dark_greylist_, "Dark greylist", access_kind) || + LogIfIn(name, light_greylist_, "Light greylist", access_kind); + } + + static std::string GetApiMethodName(const DexFile& dex_file, uint32_t method_index); + + static std::string GetApiFieldName(const DexFile& dex_file, uint32_t field_index); + + private: + static bool LogIfIn(const std::string& name, + const std::set<std::string>& list, + const std::string& log, + const std::string& access_kind); + + static void FillList(const char* filename, std::set<std::string>& entries); + + std::set<std::string> blacklist_; + std::set<std::string> light_greylist_; + std::set<std::string> dark_greylist_; +}; + +} // namespace art + +#endif // ART_TOOLS_VERIDEX_HIDDEN_API_H_ diff --git a/tools/veridex/resolver.cc b/tools/veridex/resolver.cc index 82978215a6..6ab872ed6f 100644 --- a/tools/veridex/resolver.cc +++ b/tools/veridex/resolver.cc @@ -18,6 +18,7 @@ #include "dex/dex_file-inl.h" #include "dex/primitive.h" +#include "hidden_api.h" #include "veridex.h" namespace art { @@ -276,8 +277,10 @@ VeriField VeridexResolver::GetField(uint32_t field_index) { return field_info; } -void VeridexResolver::ResolveAll() { +void VeridexResolver::ResolveAll(const HiddenApi& hidden_api) { for (uint32_t i = 0; i < dex_file_.NumTypeIds(); ++i) { + // Note: we don't look at HiddenApi for types, as the lists don't contain + // classes. if (GetVeriClass(dex::TypeIndex(i)) == nullptr) { LOG(WARNING) << "Unresolved " << dex_file_.PrettyType(dex::TypeIndex(i)); } @@ -285,13 +288,17 @@ void VeridexResolver::ResolveAll() { for (uint32_t i = 0; i < dex_file_.NumMethodIds(); ++i) { if (GetMethod(i) == nullptr) { - LOG(WARNING) << "Unresolved: " << dex_file_.PrettyMethod(i); + if (!hidden_api.LogIfInList(HiddenApi::GetApiMethodName(dex_file_, i), "Linking")) { + LOG(WARNING) << "Unresolved: " << dex_file_.PrettyMethod(i); + } } } for (uint32_t i = 0; i < dex_file_.NumFieldIds(); ++i) { if (GetField(i) == nullptr) { - LOG(WARNING) << "Unresolved: " << dex_file_.PrettyField(i); + if (!hidden_api.LogIfInList(HiddenApi::GetApiFieldName(dex_file_, i), "Linking")) { + LOG(WARNING) << "Unresolved: " << dex_file_.PrettyField(i); + } } } } diff --git a/tools/veridex/resolver.h b/tools/veridex/resolver.h index ae94dadb28..82f6aaeddd 100644 --- a/tools/veridex/resolver.h +++ b/tools/veridex/resolver.h @@ -22,6 +22,7 @@ namespace art { +class HiddenApi; class VeridexResolver; /** @@ -65,8 +66,9 @@ class VeridexResolver { const char* field_name, const char* field_type); - // Resolve all type_id/method_id/field_id. - void ResolveAll(); + // Resolve all type_id/method_id/field_id. Log for unresolved + // entities, or entities part of a hidden API list. + void ResolveAll(const HiddenApi& hidden_api); private: // Return the resolver where `kls` is from. diff --git a/tools/veridex/veridex.cc b/tools/veridex/veridex.cc index 9287211a3c..c5203fea66 100644 --- a/tools/veridex/veridex.cc +++ b/tools/veridex/veridex.cc @@ -20,6 +20,7 @@ #include "dex/dex_file.h" #include "dex/dex_file_loader.h" +#include "hidden_api.h" #include "resolver.h" #include <sstream> @@ -162,8 +163,9 @@ class Veridex { Resolve(app_dex_files, resolver_map, type_map, &app_resolvers); // Resolve all type_id/method_id/field_id of app dex files. + HiddenApi hidden_api(options.blacklist, options.dark_greylist, options.light_greylist); for (const std::unique_ptr<VeridexResolver>& resolver : app_resolvers) { - resolver->ResolveAll(); + resolver->ResolveAll(hidden_api); } return 0; |