blob: a65e82b3df41c1be4bb9cb96f0af3b0dca998c83 [file] [log] [blame]
David Brazdilca3c8c32016-09-06 14:04:48 +01001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "verifier_deps.h"
18
Mathieu Chartier32b50302016-11-17 13:08:35 -080019#include <cstring>
20
David Brazdilca3c8c32016-09-06 14:04:48 +010021#include "compiler_callbacks.h"
David Brazdil6f82fbd2016-09-14 11:55:26 +010022#include "leb128.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010023#include "mirror/class-inl.h"
Mathieu Chartier3398c782016-09-30 10:27:43 -070024#include "obj_ptr-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010025#include "runtime.h"
26
27namespace art {
28namespace verifier {
29
30VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files) {
31 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
32 for (const DexFile* dex_file : dex_files) {
33 DCHECK(GetDexFileDeps(*dex_file) == nullptr);
34 std::unique_ptr<DexFileDeps> deps(new DexFileDeps());
35 dex_deps_.emplace(dex_file, std::move(deps));
36 }
37}
38
39VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) {
40 auto it = dex_deps_.find(&dex_file);
41 return (it == dex_deps_.end()) ? nullptr : it->second.get();
42}
43
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +010044const VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) const {
45 auto it = dex_deps_.find(&dex_file);
46 return (it == dex_deps_.end()) ? nullptr : it->second.get();
47}
48
David Brazdilca3c8c32016-09-06 14:04:48 +010049template <typename T>
50uint16_t VerifierDeps::GetAccessFlags(T* element) {
51 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
52 if (element == nullptr) {
53 return VerifierDeps::kUnresolvedMarker;
54 } else {
55 uint16_t access_flags = Low16Bits(element->GetAccessFlags());
56 CHECK_NE(access_flags, VerifierDeps::kUnresolvedMarker);
57 return access_flags;
58 }
59}
60
Mathieu Chartier32b50302016-11-17 13:08:35 -080061uint32_t VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
62 ObjPtr<mirror::Class> klass) {
63 DCHECK(klass != nullptr);
64 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
65 // Array classes do not have a dex cache.
66 if (!klass->IsArrayClass() && !klass->IsProxyClass()) {
67 DCHECK(dex_cache != nullptr) << klass->PrettyClass();
68 if (dex_cache->GetDexFile() == &dex_file) {
69 // FindStringId is slow, try to go through the class def if we have one.
70 const DexFile::ClassDef* class_def = klass->GetClassDef();
71 DCHECK(class_def != nullptr) << klass->PrettyClass();
72 std::string temp;
73 const DexFile::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_);
74 DCHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_);
75 return type_id.descriptor_idx_;
76 }
77 }
78 std::string temp;
79 return GetIdFromString(dex_file, klass->GetDescriptor(&temp));
80}
81
82// Try to find the string descriptor of the class. type_idx is a best guess of a matching string id.
83static uint32_t TryGetClassDescriptorStringId(const DexFile& dex_file,
84 dex::TypeIndex type_idx,
85 ObjPtr<mirror::Class> klass)
86 REQUIRES_SHARED(Locks::mutator_lock_) {
87 if (!klass->IsArrayClass()) {
88 const DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx);
89 const DexFile& klass_dex = klass->GetDexFile();
90 const DexFile::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_);
91 if (strcmp(dex_file.GetTypeDescriptor(type_id),
92 klass_dex.GetTypeDescriptor(klass_type_id)) == 0) {
93 return type_id.descriptor_idx_;
94 }
95 }
96 return DexFile::kDexNoIndex;
97}
98
99uint32_t VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
100 uint32_t dex_method_index,
101 ArtMethod* method) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100102 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
Mathieu Chartier32b50302016-11-17 13:08:35 -0800103 if (method == nullptr) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100104 return VerifierDeps::kUnresolvedMarker;
Mathieu Chartier32b50302016-11-17 13:08:35 -0800105 }
106 const uint32_t string_id = TryGetClassDescriptorStringId(
107 dex_file,
108 dex_file.GetMethodId(dex_method_index).class_idx_,
109 method->GetDeclaringClass());
110 if (string_id != DexFile::kDexNoIndex) {
111 // Got lucky using the original dex file, return based on the input dex file.
112 DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id);
David Brazdilca3c8c32016-09-06 14:04:48 +0100113 return string_id;
114 }
Mathieu Chartier32b50302016-11-17 13:08:35 -0800115 return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass());
116}
117
118uint32_t VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
119 uint32_t dex_field_idx,
120 ArtField* field) {
121 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
122 if (field == nullptr) {
123 return VerifierDeps::kUnresolvedMarker;
124 }
125 const uint32_t string_id = TryGetClassDescriptorStringId(
126 dex_file,
127 dex_file.GetFieldId(dex_field_idx).class_idx_,
128 field->GetDeclaringClass());
129 if (string_id != DexFile::kDexNoIndex) {
130 // Got lucky using the original dex file, return based on the input dex file.
131 DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id);
132 return string_id;
133 }
134 return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass());
David Brazdilca3c8c32016-09-06 14:04:48 +0100135}
136
137uint32_t VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
138 const DexFile::StringId* string_id = dex_file.FindStringId(str.c_str());
139 if (string_id != nullptr) {
140 // String is in the DEX file. Return its ID.
141 return dex_file.GetIndexForStringId(*string_id);
142 }
143
144 // String is not in the DEX file. Assign a new ID to it which is higher than
145 // the number of strings in the DEX file.
146
147 DexFileDeps* deps = GetDexFileDeps(dex_file);
148 DCHECK(deps != nullptr);
149
150 uint32_t num_ids_in_dex = dex_file.NumStringIds();
151 uint32_t num_extra_ids = deps->strings_.size();
152
153 for (size_t i = 0; i < num_extra_ids; ++i) {
154 if (deps->strings_[i] == str) {
155 return num_ids_in_dex + i;
156 }
157 }
158
159 deps->strings_.push_back(str);
160
161 uint32_t new_id = num_ids_in_dex + num_extra_ids;
162 CHECK_GE(new_id, num_ids_in_dex); // check for overflows
163 DCHECK_EQ(str, GetStringFromId(dex_file, new_id));
164
165 return new_id;
166}
167
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100168std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, uint32_t string_id) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100169 uint32_t num_ids_in_dex = dex_file.NumStringIds();
170 if (string_id < num_ids_in_dex) {
171 return std::string(dex_file.StringDataByIdx(string_id));
172 } else {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100173 const DexFileDeps* deps = GetDexFileDeps(dex_file);
David Brazdilca3c8c32016-09-06 14:04:48 +0100174 DCHECK(deps != nullptr);
175 string_id -= num_ids_in_dex;
176 CHECK_LT(string_id, deps->strings_.size());
177 return deps->strings_[string_id];
178 }
179}
180
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100181bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100182 DCHECK(klass != nullptr);
183
Mathieu Chartier3398c782016-09-30 10:27:43 -0700184 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
David Brazdilca3c8c32016-09-06 14:04:48 +0100185 if (dex_cache == nullptr) {
186 // This is a synthesized class, in this case always an array. They are not
187 // defined in the compiled DEX files and therefore are part of the classpath.
188 // We could avoid recording dependencies on arrays with component types in
189 // the compiled DEX files but we choose to record them anyway so as to
190 // record the access flags VM sets for array classes.
David Sehr709b0702016-10-13 09:12:37 -0700191 DCHECK(klass->IsArrayClass()) << klass->PrettyDescriptor();
David Brazdilca3c8c32016-09-06 14:04:48 +0100192 return true;
193 }
194
195 const DexFile* dex_file = dex_cache->GetDexFile();
196 DCHECK(dex_file != nullptr);
197
198 // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex
199 // file was not registered as being compiled and we assume `klass` is in the
200 // classpath.
201 return (GetDexFileDeps(*dex_file) == nullptr);
202}
203
204void VerifierDeps::AddClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800205 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100206 mirror::Class* klass) {
207 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
208 if (dex_deps == nullptr) {
209 // This invocation is from verification of a dex file which is not being compiled.
210 return;
211 }
212
213 if (klass != nullptr && !IsInClassPath(klass)) {
214 // Class resolved into one of the DEX files which are being compiled.
215 // This is not a classpath dependency.
216 return;
217 }
218
219 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
220 dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass)));
221}
222
223void VerifierDeps::AddFieldResolution(const DexFile& dex_file,
224 uint32_t field_idx,
225 ArtField* field) {
226 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
227 if (dex_deps == nullptr) {
228 // This invocation is from verification of a dex file which is not being compiled.
229 return;
230 }
231
232 if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) {
233 // Field resolved into one of the DEX files which are being compiled.
234 // This is not a classpath dependency.
235 return;
236 }
237
238 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
Mathieu Chartier32b50302016-11-17 13:08:35 -0800239 dex_deps->fields_.emplace(FieldResolution(field_idx,
240 GetAccessFlags(field),
241 GetFieldDeclaringClassStringId(dex_file,
242 field_idx,
243 field)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100244}
245
246void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
247 uint32_t method_idx,
248 MethodResolutionKind resolution_kind,
249 ArtMethod* method) {
250 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
251 if (dex_deps == nullptr) {
252 // This invocation is from verification of a dex file which is not being compiled.
253 return;
254 }
255
256 if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) {
257 // Method resolved into one of the DEX files which are being compiled.
258 // This is not a classpath dependency.
259 return;
260 }
261
262 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
263 MethodResolution method_tuple(method_idx,
264 GetAccessFlags(method),
Mathieu Chartier32b50302016-11-17 13:08:35 -0800265 GetMethodDeclaringClassStringId(dex_file, method_idx, method));
David Brazdilca3c8c32016-09-06 14:04:48 +0100266 if (resolution_kind == kDirectMethodResolution) {
267 dex_deps->direct_methods_.emplace(method_tuple);
268 } else if (resolution_kind == kVirtualMethodResolution) {
269 dex_deps->virtual_methods_.emplace(method_tuple);
270 } else {
271 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
272 dex_deps->interface_methods_.emplace(method_tuple);
273 }
274}
275
276void VerifierDeps::AddAssignability(const DexFile& dex_file,
277 mirror::Class* destination,
278 mirror::Class* source,
279 bool is_strict,
280 bool is_assignable) {
281 // Test that the method is only called on reference types.
282 // Note that concurrent verification of `destination` and `source` may have
283 // set their status to erroneous. However, the tests performed below rely
284 // merely on no issues with linking (valid access flags, superclass and
285 // implemented interfaces). If the class at any point reached the IsResolved
286 // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass.
287 DCHECK(destination != nullptr && !destination->IsPrimitive());
288 DCHECK(source != nullptr && !source->IsPrimitive());
289
290 if (destination == source ||
291 destination->IsObjectClass() ||
292 (!is_strict && destination->IsInterface())) {
293 // Cases when `destination` is trivially assignable from `source`.
294 DCHECK(is_assignable);
295 return;
296 }
297
298 DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
299
300 if (destination->IsArrayClass() && source->IsArrayClass()) {
301 // Both types are arrays. Break down to component types and add recursively.
302 // This helps filter out destinations from compiled DEX files (see below)
303 // and deduplicate entries with the same canonical component type.
304 mirror::Class* destination_component = destination->GetComponentType();
305 mirror::Class* source_component = source->GetComponentType();
306
307 // Only perform the optimization if both types are resolved which guarantees
308 // that they linked successfully, as required at the top of this method.
309 if (destination_component->IsResolved() && source_component->IsResolved()) {
310 AddAssignability(dex_file,
311 destination_component,
312 source_component,
313 /* is_strict */ true,
314 is_assignable);
315 return;
316 }
317 }
318
319 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
320 if (dex_deps == nullptr) {
321 // This invocation is from verification of a DEX file which is not being compiled.
322 return;
323 }
324
325 if (!IsInClassPath(destination) && !IsInClassPath(source)) {
326 // Both `destination` and `source` are defined in the compiled DEX files.
327 // No need to record a dependency.
328 return;
329 }
330
331 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
332
333 // Get string IDs for both descriptors and store in the appropriate set.
Mathieu Chartier32b50302016-11-17 13:08:35 -0800334 uint32_t destination_id = GetClassDescriptorStringId(dex_file, destination);
335 uint32_t source_id = GetClassDescriptorStringId(dex_file, source);
David Brazdilca3c8c32016-09-06 14:04:48 +0100336
337 if (is_assignable) {
338 dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
339 } else {
340 dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
341 }
342}
343
344static inline VerifierDeps* GetVerifierDepsSingleton() {
345 CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks();
346 if (callbacks == nullptr) {
347 return nullptr;
348 }
349 return callbacks->GetVerifierDeps();
350}
351
Nicolas Geoffray08025182016-10-25 17:20:18 +0100352void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800353 dex::TypeIndex type_idx,
Nicolas Geoffray08025182016-10-25 17:20:18 +0100354 MethodVerifier::FailureKind failure_kind) {
355 if (failure_kind == MethodVerifier::kNoFailure) {
356 // We only record classes that did not fully verify at compile time.
357 return;
358 }
359
360 VerifierDeps* singleton = GetVerifierDepsSingleton();
361 if (singleton != nullptr) {
362 DexFileDeps* dex_deps = singleton->GetDexFileDeps(dex_file);
363 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
364 dex_deps->unverified_classes_.push_back(type_idx);
365 }
366}
367
David Brazdilca3c8c32016-09-06 14:04:48 +0100368void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800369 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100370 mirror::Class* klass) {
371 VerifierDeps* singleton = GetVerifierDepsSingleton();
372 if (singleton != nullptr) {
373 singleton->AddClassResolution(dex_file, type_idx, klass);
374 }
375}
376
377void VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file,
378 uint32_t field_idx,
379 ArtField* field) {
380 VerifierDeps* singleton = GetVerifierDepsSingleton();
381 if (singleton != nullptr) {
382 singleton->AddFieldResolution(dex_file, field_idx, field);
383 }
384}
385
386void VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file,
387 uint32_t method_idx,
388 MethodResolutionKind resolution_kind,
389 ArtMethod* method) {
390 VerifierDeps* singleton = GetVerifierDepsSingleton();
391 if (singleton != nullptr) {
392 singleton->AddMethodResolution(dex_file, method_idx, resolution_kind, method);
393 }
394}
395
396void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
397 mirror::Class* destination,
398 mirror::Class* source,
399 bool is_strict,
400 bool is_assignable) {
401 VerifierDeps* singleton = GetVerifierDepsSingleton();
402 if (singleton != nullptr) {
403 singleton->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
404 }
405}
406
Andreas Gampea5b09a62016-11-17 15:21:22 -0800407namespace {
408
David Brazdil6f82fbd2016-09-14 11:55:26 +0100409static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) {
410 CHECK_LT(*in, end);
411 return DecodeUnsignedLeb128(in);
412}
413
Andreas Gampea5b09a62016-11-17 15:21:22 -0800414template<typename T> inline uint32_t Encode(T in);
415
416template<> inline uint32_t Encode<uint16_t>(uint16_t in) {
417 return in;
418}
419template<> inline uint32_t Encode<uint32_t>(uint32_t in) {
420 return in;
421}
422template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
423 return in.index_;
424}
425
426template<typename T> inline T Decode(uint32_t in);
427
428template<> inline uint16_t Decode<uint16_t>(uint32_t in) {
429 return dchecked_integral_cast<uint16_t>(in);
430}
431template<> inline uint32_t Decode<uint32_t>(uint32_t in) {
432 return in;
433}
434template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
435 return dex::TypeIndex(in);
436}
437
David Brazdil6f82fbd2016-09-14 11:55:26 +0100438template<typename T1, typename T2>
439static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800440 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
441 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100442}
443
444template<typename T1, typename T2>
445static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800446 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
447 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100448 *t = std::make_tuple(v1, v2);
449}
450
451template<typename T1, typename T2, typename T3>
452static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800453 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
454 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
455 EncodeUnsignedLeb128(out, Encode(std::get<2>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100456}
457
458template<typename T1, typename T2, typename T3>
459static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800460 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
461 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
462 T3 v3 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100463 *t = std::make_tuple(v1, v2, v3);
464}
465
466template<typename T>
467static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) {
468 EncodeUnsignedLeb128(out, set.size());
469 for (const T& entry : set) {
470 EncodeTuple(out, entry);
471 }
472}
473
Andreas Gampea5b09a62016-11-17 15:21:22 -0800474template <typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100475static inline void EncodeUint16Vector(std::vector<uint8_t>* out,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800476 const std::vector<T>& vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100477 EncodeUnsignedLeb128(out, vector.size());
Andreas Gampea5b09a62016-11-17 15:21:22 -0800478 for (const T& entry : vector) {
479 EncodeUnsignedLeb128(out, Encode(entry));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100480 }
481}
482
David Brazdil6f82fbd2016-09-14 11:55:26 +0100483template<typename T>
484static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) {
485 DCHECK(set->empty());
486 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
487 for (size_t i = 0; i < num_entries; ++i) {
488 T tuple;
489 DecodeTuple(in, end, &tuple);
490 set->emplace(tuple);
491 }
492}
493
Andreas Gampea5b09a62016-11-17 15:21:22 -0800494template<typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100495static inline void DecodeUint16Vector(const uint8_t** in,
496 const uint8_t* end,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800497 std::vector<T>* vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100498 DCHECK(vector->empty());
499 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
500 vector->reserve(num_entries);
501 for (size_t i = 0; i < num_entries; ++i) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800502 vector->push_back(
503 Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100504 }
505}
506
David Brazdil6f82fbd2016-09-14 11:55:26 +0100507static inline void EncodeStringVector(std::vector<uint8_t>* out,
508 const std::vector<std::string>& strings) {
509 EncodeUnsignedLeb128(out, strings.size());
510 for (const std::string& str : strings) {
511 const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str());
512 size_t length = str.length() + 1;
513 out->insert(out->end(), data, data + length);
514 DCHECK_EQ(0u, out->back());
515 }
516}
517
518static inline void DecodeStringVector(const uint8_t** in,
519 const uint8_t* end,
520 std::vector<std::string>* strings) {
521 DCHECK(strings->empty());
522 size_t num_strings = DecodeUint32WithOverflowCheck(in, end);
523 strings->reserve(num_strings);
524 for (size_t i = 0; i < num_strings; ++i) {
525 CHECK_LT(*in, end);
526 const char* string_start = reinterpret_cast<const char*>(*in);
527 strings->emplace_back(std::string(string_start));
528 *in += strings->back().length() + 1;
529 }
530}
531
Andreas Gampea5b09a62016-11-17 15:21:22 -0800532} // namespace
533
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100534void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
535 std::vector<uint8_t>* buffer) const {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100536 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100537 for (const DexFile* dex_file : dex_files) {
538 const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
539 EncodeStringVector(buffer, deps.strings_);
540 EncodeSet(buffer, deps.assignable_types_);
541 EncodeSet(buffer, deps.unassignable_types_);
542 EncodeSet(buffer, deps.classes_);
543 EncodeSet(buffer, deps.fields_);
544 EncodeSet(buffer, deps.direct_methods_);
545 EncodeSet(buffer, deps.virtual_methods_);
546 EncodeSet(buffer, deps.interface_methods_);
547 EncodeUint16Vector(buffer, deps.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100548 }
549}
550
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000551VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
552 ArrayRef<const uint8_t> data)
David Brazdil6f82fbd2016-09-14 11:55:26 +0100553 : VerifierDeps(dex_files) {
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000554 if (data.empty()) {
555 // Return eagerly, as the first thing we expect from VerifierDeps data is
556 // the number of created strings, even if there is no dependency.
557 // Currently, only the boot image does not have any VerifierDeps data.
558 return;
559 }
David Brazdil6f82fbd2016-09-14 11:55:26 +0100560 const uint8_t* data_start = data.data();
561 const uint8_t* data_end = data_start + data.size();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100562 for (const DexFile* dex_file : dex_files) {
563 DexFileDeps* deps = GetDexFileDeps(*dex_file);
564 DecodeStringVector(&data_start, data_end, &deps->strings_);
565 DecodeSet(&data_start, data_end, &deps->assignable_types_);
566 DecodeSet(&data_start, data_end, &deps->unassignable_types_);
567 DecodeSet(&data_start, data_end, &deps->classes_);
568 DecodeSet(&data_start, data_end, &deps->fields_);
569 DecodeSet(&data_start, data_end, &deps->direct_methods_);
570 DecodeSet(&data_start, data_end, &deps->virtual_methods_);
571 DecodeSet(&data_start, data_end, &deps->interface_methods_);
572 DecodeUint16Vector(&data_start, data_end, &deps->unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100573 }
574 CHECK_LE(data_start, data_end);
575}
576
577bool VerifierDeps::Equals(const VerifierDeps& rhs) const {
578 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
579
580 if (dex_deps_.size() != rhs.dex_deps_.size()) {
581 return false;
582 }
583
584 auto lhs_it = dex_deps_.begin();
585 auto rhs_it = rhs.dex_deps_.begin();
586
587 for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) {
588 const DexFile* lhs_dex_file = lhs_it->first;
589 const DexFile* rhs_dex_file = rhs_it->first;
590 if (lhs_dex_file != rhs_dex_file) {
591 return false;
592 }
593
594 DexFileDeps* lhs_deps = lhs_it->second.get();
595 DexFileDeps* rhs_deps = rhs_it->second.get();
596 if (!lhs_deps->Equals(*rhs_deps)) {
597 return false;
598 }
599 }
600
601 DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end()));
602 return true;
603}
604
605bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
606 return (strings_ == rhs.strings_) &&
607 (assignable_types_ == rhs.assignable_types_) &&
608 (unassignable_types_ == rhs.unassignable_types_) &&
609 (classes_ == rhs.classes_) &&
610 (fields_ == rhs.fields_) &&
611 (direct_methods_ == rhs.direct_methods_) &&
612 (virtual_methods_ == rhs.virtual_methods_) &&
Nicolas Geoffray08025182016-10-25 17:20:18 +0100613 (interface_methods_ == rhs.interface_methods_) &&
614 (unverified_classes_ == rhs.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100615}
616
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100617void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
618 for (const auto& dep : dex_deps_) {
619 const DexFile& dex_file = *dep.first;
620 vios->Stream()
621 << "Dependencies of "
622 << dex_file.GetLocation()
623 << ":\n";
624
625 ScopedIndentation indent(vios);
626
627 for (const std::string& str : dep.second->strings_) {
628 vios->Stream() << "Extra string: " << str << "\n";
629 }
630
631 for (const TypeAssignability& entry : dep.second->assignable_types_) {
632 vios->Stream()
633 << GetStringFromId(dex_file, entry.GetSource())
634 << " must be assignable to "
635 << GetStringFromId(dex_file, entry.GetDestination())
636 << "\n";
637 }
638
639 for (const TypeAssignability& entry : dep.second->unassignable_types_) {
640 vios->Stream()
641 << GetStringFromId(dex_file, entry.GetSource())
642 << " must not be assignable to "
643 << GetStringFromId(dex_file, entry.GetDestination())
644 << "\n";
645 }
646
647 for (const ClassResolution& entry : dep.second->classes_) {
648 vios->Stream()
649 << dex_file.StringByTypeIdx(entry.GetDexTypeIndex())
650 << (entry.IsResolved() ? " must be resolved " : "must not be resolved ")
651 << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec
652 << "\n";
653 }
654
655 for (const FieldResolution& entry : dep.second->fields_) {
656 const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
657 vios->Stream()
658 << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->"
659 << dex_file.GetFieldName(field_id) << ":"
660 << dex_file.GetFieldTypeDescriptor(field_id)
661 << " is expected to be ";
662 if (!entry.IsResolved()) {
663 vios->Stream() << "unresolved\n";
664 } else {
665 vios->Stream()
666 << "in class "
667 << GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
668 << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec
669 << "\n";
670 }
671 }
672
673 for (const auto& entry :
674 { std::make_pair(kDirectMethodResolution, dep.second->direct_methods_),
675 std::make_pair(kVirtualMethodResolution, dep.second->virtual_methods_),
676 std::make_pair(kInterfaceMethodResolution, dep.second->interface_methods_) }) {
677 for (const MethodResolution& method : entry.second) {
678 const DexFile::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
679 vios->Stream()
680 << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->"
681 << dex_file.GetMethodName(method_id)
682 << dex_file.GetMethodSignature(method_id).ToString()
683 << " is expected to be ";
684 if (!method.IsResolved()) {
685 vios->Stream() << "unresolved\n";
686 } else {
687 vios->Stream()
688 << "in class "
689 << GetStringFromId(dex_file, method.GetDeclaringClassIndex())
690 << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec
691 << ", and be of kind " << entry.first
692 << "\n";
693 }
694 }
695 }
696
Andreas Gampea5b09a62016-11-17 15:21:22 -0800697 for (dex::TypeIndex type_index : dep.second->unverified_classes_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100698 vios->Stream()
699 << dex_file.StringByTypeIdx(type_index)
700 << " is expected to be verified at runtime\n";
701 }
702 }
703}
704
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000705bool VerifierDeps::ValidateDependencies(Handle<mirror::ClassLoader> class_loader,
706 Thread* self) const {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100707 for (const auto& entry : dex_deps_) {
708 if (!VerifyDexFile(class_loader, *entry.first, *entry.second, self)) {
709 return false;
710 }
711 }
712 return true;
713}
714
715// TODO: share that helper with other parts of the compiler that have
716// the same lookup pattern.
717static mirror::Class* FindClassAndClearException(ClassLinker* class_linker,
718 Thread* self,
719 const char* name,
720 Handle<mirror::ClassLoader> class_loader)
721 REQUIRES_SHARED(Locks::mutator_lock_) {
722 mirror::Class* result = class_linker->FindClass(self, name, class_loader);
723 if (result == nullptr) {
724 DCHECK(self->IsExceptionPending());
725 self->ClearException();
726 }
727 return result;
728}
729
730bool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
731 const DexFile& dex_file,
732 const std::set<TypeAssignability>& assignables,
733 bool expected_assignability,
734 Thread* self) const {
735 StackHandleScope<2> hs(self);
736 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
737 MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
738 MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
739
740 for (const auto& entry : assignables) {
741 const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
742 destination.Assign(
743 FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader));
744 const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
745 source.Assign(
746 FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader));
747
748 if (destination.Get() == nullptr) {
749 LOG(INFO) << "VerifiersDeps: Could not resolve class " << destination_desc;
750 return false;
751 }
752
753 if (source.Get() == nullptr) {
754 LOG(INFO) << "VerifierDeps: Could not resolve class " << source_desc;
755 return false;
756 }
757
758 DCHECK(destination->IsResolved() && source->IsResolved());
759 if (destination->IsAssignableFrom(source.Get()) != expected_assignability) {
760 LOG(INFO) << "VerifierDeps: Class "
761 << destination_desc
762 << (expected_assignability ? " not " : " ")
763 << "assignable from "
764 << source_desc;
765 return false;
766 }
767 }
768 return true;
769}
770
771bool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader,
772 const DexFile& dex_file,
773 const std::set<ClassResolution>& classes,
774 Thread* self) const {
775 StackHandleScope<1> hs(self);
776 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
777 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
778 for (const auto& entry : classes) {
779 const char* descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex());
780 cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader));
781
782 if (entry.IsResolved()) {
783 if (cls.Get() == nullptr) {
784 LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
785 return false;
786 } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) {
787 LOG(INFO) << "VerifierDeps: Unexpected access flags on class "
788 << descriptor
789 << std::hex
790 << " (expected="
791 << entry.GetAccessFlags()
792 << ", actual="
793 << GetAccessFlags(cls.Get()) << ")"
794 << std::dec;
795 return false;
796 }
797 } else if (cls.Get() != nullptr) {
798 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of class " << descriptor;
799 return false;
800 }
801 }
802 return true;
803}
804
805static std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) {
806 const DexFile::FieldId& field_id = dex_file.GetFieldId(index);
807 return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id))
808 + "->"
809 + dex_file.GetFieldName(field_id)
810 + ":"
811 + dex_file.GetFieldTypeDescriptor(field_id);
812}
813
814bool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader,
815 const DexFile& dex_file,
816 const std::set<FieldResolution>& fields,
817 Thread* self) const {
818 // Check recorded fields are resolved the same way, have the same recorded class,
819 // and have the same recorded flags.
820 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
821 StackHandleScope<1> hs(self);
822 Handle<mirror::DexCache> dex_cache(
823 hs.NewHandle(class_linker->FindDexCache(self, dex_file, /* allow_failure */ false)));
824 for (const auto& entry : fields) {
825 ArtField* field = class_linker->ResolveFieldJLS(
826 dex_file, entry.GetDexFieldIndex(), dex_cache, class_loader);
827
828 if (field == nullptr) {
829 DCHECK(self->IsExceptionPending());
830 self->ClearException();
831 }
832
833 if (entry.IsResolved()) {
834 std::string expected_decl_klass = GetStringFromId(dex_file, entry.GetDeclaringClassIndex());
835 std::string temp;
836 if (field == nullptr) {
837 LOG(INFO) << "VerifierDeps: Could not resolve field "
838 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
839 return false;
840 } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) {
841 LOG(INFO) << "VerifierDeps: Unexpected declaring class for field resolution "
842 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
843 << " (expected=" << expected_decl_klass
844 << ", actual=" << field->GetDeclaringClass()->GetDescriptor(&temp) << ")";
845 return false;
846 } else if (entry.GetAccessFlags() != GetAccessFlags(field)) {
847 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved field "
848 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
849 << std::hex << " (expected=" << entry.GetAccessFlags()
850 << ", actual=" << GetAccessFlags(field) << ")" << std::dec;
851 return false;
852 }
853 } else if (field != nullptr) {
854 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of field "
855 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
856 return false;
857 }
858 }
859 return true;
860}
861
862static std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) {
863 const DexFile::MethodId& method_id = dex_file.GetMethodId(index);
864 return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id))
865 + "->"
866 + dex_file.GetMethodName(method_id)
867 + dex_file.GetMethodSignature(method_id).ToString();
868}
869
870bool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader,
871 const DexFile& dex_file,
872 const std::set<MethodResolution>& methods,
873 MethodResolutionKind kind,
874 Thread* self) const {
875 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
876 PointerSize pointer_size = class_linker->GetImagePointerSize();
877
878 for (const auto& entry : methods) {
879 const DexFile::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex());
880
881 const char* name = dex_file.GetMethodName(method_id);
882 const Signature signature = dex_file.GetMethodSignature(method_id);
883 const char* descriptor = dex_file.GetMethodDeclaringClassDescriptor(method_id);
884
885 mirror::Class* cls = FindClassAndClearException(class_linker, self, descriptor, class_loader);
886 if (cls == nullptr) {
887 LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
888 return false;
889 }
890 DCHECK(cls->IsResolved());
891 ArtMethod* method = nullptr;
892 if (kind == kDirectMethodResolution) {
893 method = cls->FindDirectMethod(name, signature, pointer_size);
894 } else if (kind == kVirtualMethodResolution) {
895 method = cls->FindVirtualMethod(name, signature, pointer_size);
896 } else {
897 DCHECK_EQ(kind, kInterfaceMethodResolution);
898 method = cls->FindInterfaceMethod(name, signature, pointer_size);
899 }
900
901 if (entry.IsResolved()) {
902 std::string temp;
903 std::string expected_decl_klass = GetStringFromId(dex_file, entry.GetDeclaringClassIndex());
904 if (method == nullptr) {
905 LOG(INFO) << "VerifierDeps: Could not resolve "
906 << kind
907 << " method "
908 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
909 return false;
910 } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) {
911 LOG(INFO) << "VerifierDeps: Unexpected declaring class for "
912 << kind
913 << " method resolution "
914 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
915 << " (expected="
916 << expected_decl_klass
917 << ", actual="
918 << method->GetDeclaringClass()->GetDescriptor(&temp)
919 << ")";
920 return false;
921 } else if (entry.GetAccessFlags() != GetAccessFlags(method)) {
922 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved "
923 << kind
924 << " method resolution "
925 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
926 << std::hex
927 << " (expected="
928 << entry.GetAccessFlags()
929 << ", actual="
930 << GetAccessFlags(method) << ")"
931 << std::dec;
932 return false;
933 }
934 } else if (method != nullptr) {
935 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of "
936 << kind
937 << " method "
938 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
939 return false;
940 }
941 }
942 return true;
943}
944
945bool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
946 const DexFile& dex_file,
947 const DexFileDeps& deps,
948 Thread* self) const {
949 bool result = VerifyAssignability(
950 class_loader, dex_file, deps.assignable_types_, /* expected_assignability */ true, self);
951 result = result && VerifyAssignability(
952 class_loader, dex_file, deps.unassignable_types_, /* expected_assignability */ false, self);
953
954 result = result && VerifyClasses(class_loader, dex_file, deps.classes_, self);
955 result = result && VerifyFields(class_loader, dex_file, deps.fields_, self);
956
957 result = result && VerifyMethods(
958 class_loader, dex_file, deps.direct_methods_, kDirectMethodResolution, self);
959 result = result && VerifyMethods(
960 class_loader, dex_file, deps.virtual_methods_, kVirtualMethodResolution, self);
961 result = result && VerifyMethods(
962 class_loader, dex_file, deps.interface_methods_, kInterfaceMethodResolution, self);
963
964 return result;
965}
966
David Brazdilca3c8c32016-09-06 14:04:48 +0100967} // namespace verifier
968} // namespace art