summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2018-03-28 13:10:44 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-03-28 13:10:44 +0000
commit2da18ff17940b721fcc00acf53aed238db7f1887 (patch)
tree608ab03eb2dc120d38ea6e44eb6d3b8c95aad31b
parent9d8aff086fe39f9f2371e35a7abc985e01380348 (diff)
parentc3f88993bfac4606bc25e5c68a5a7330cd0d815f (diff)
Merge "[veridex] Log when linking against private APIs." into pi-dev
-rw-r--r--tools/veridex/Android.bp1
-rw-r--r--tools/veridex/hidden_api.cc79
-rw-r--r--tools/veridex/hidden_api.h63
-rw-r--r--tools/veridex/resolver.cc13
-rw-r--r--tools/veridex/resolver.h6
-rw-r--r--tools/veridex/veridex.cc4
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;