• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 "common_throws.h"
18 
19 #include <sstream>
20 
21 #include <android-base/logging.h>
22 #include <android-base/stringprintf.h>
23 
24 #include "art_field-inl.h"
25 #include "art_method-inl.h"
26 #include "art_method.h"
27 #include "class_linker-inl.h"
28 #include "debug_print.h"
29 #include "dex/dex_file-inl.h"
30 #include "dex/dex_instruction-inl.h"
31 #include "dex/invoke_type.h"
32 #include "mirror/class-alloc-inl.h"
33 #include "mirror/method_type.h"
34 #include "mirror/object-inl.h"
35 #include "mirror/object_array-inl.h"
36 #include "nativehelper/scoped_local_ref.h"
37 #include "obj_ptr-inl.h"
38 #include "thread.h"
39 #include "well_known_classes-inl.h"
40 
41 namespace art HIDDEN {
42 
43 using android::base::StringAppendV;
44 using android::base::StringPrintf;
45 
AddReferrerLocation(std::ostream & os,ObjPtr<mirror::Class> referrer)46 static void AddReferrerLocation(std::ostream& os, ObjPtr<mirror::Class> referrer)
47     REQUIRES_SHARED(Locks::mutator_lock_) {
48   if (referrer != nullptr) {
49     std::string location(referrer->GetLocation());
50     if (!location.empty()) {
51       os << " (declaration of '" << referrer->PrettyDescriptor()
52          << "' appears in " << location << ")";
53     }
54   }
55 }
56 
ThrowException(const char * exception_descriptor)57 static void ThrowException(const char* exception_descriptor) REQUIRES_SHARED(Locks::mutator_lock_) {
58   Thread* self = Thread::Current();
59   self->ThrowNewException(exception_descriptor, nullptr);
60 }
61 
ThrowException(const char * exception_descriptor,ObjPtr<mirror::Class> referrer,const char * fmt,va_list * args=nullptr)62 static void ThrowException(const char* exception_descriptor,
63                            ObjPtr<mirror::Class> referrer,
64                            const char* fmt,
65                            va_list* args = nullptr)
66     REQUIRES_SHARED(Locks::mutator_lock_) {
67   std::ostringstream msg;
68   if (args != nullptr) {
69     std::string vmsg;
70     StringAppendV(&vmsg, fmt, *args);
71     msg << vmsg;
72   } else {
73     msg << fmt;
74   }
75   AddReferrerLocation(msg, referrer);
76   Thread* self = Thread::Current();
77   self->ThrowNewException(exception_descriptor, msg.str().c_str());
78 }
79 
ThrowWrappedException(const char * exception_descriptor,ObjPtr<mirror::Class> referrer,const char * fmt,va_list * args=nullptr)80 static void ThrowWrappedException(const char* exception_descriptor,
81                                   ObjPtr<mirror::Class> referrer,
82                                   const char* fmt,
83                                   va_list* args = nullptr)
84     REQUIRES_SHARED(Locks::mutator_lock_) {
85   std::ostringstream msg;
86   if (args != nullptr) {
87     std::string vmsg;
88     StringAppendV(&vmsg, fmt, *args);
89     msg << vmsg;
90   } else {
91     msg << fmt;
92   }
93   AddReferrerLocation(msg, referrer);
94   Thread* self = Thread::Current();
95   self->ThrowNewWrappedException(exception_descriptor, msg.str().c_str());
96 }
97 
98 // AbstractMethodError
99 
ThrowAbstractMethodError(ArtMethod * method,ObjPtr<mirror::Object> receiver)100 void ThrowAbstractMethodError(ArtMethod* method, ObjPtr<mirror::Object> receiver) {
101   std::string klass = (receiver == nullptr)
102       ? "null"
103       : mirror::Class::PrettyClass(receiver->GetClass());
104   ThrowException("Ljava/lang/AbstractMethodError;", nullptr,
105                  StringPrintf("abstract method \"%s\" on receiver %s",
106                               ArtMethod::PrettyMethod(method).c_str(),
107                               klass.c_str()).c_str());
108 }
109 
ThrowAbstractMethodError(uint32_t method_idx,const DexFile & dex_file,ObjPtr<mirror::Object> receiver)110 void ThrowAbstractMethodError(uint32_t method_idx,
111                               const DexFile& dex_file,
112                               ObjPtr<mirror::Object> receiver) {
113   std::string klass = (receiver == nullptr)
114       ? "null"
115       : mirror::Class::PrettyClass(receiver->GetClass());
116   ThrowException("Ljava/lang/AbstractMethodError;", /* referrer= */ nullptr,
117                  StringPrintf("abstract method \"%s\" on receiver %s",
118                               dex_file.PrettyMethod(method_idx,
119                                                     /* with_signature= */ true).c_str(),
120                               klass.c_str()).c_str());
121 }
122 
123 // ArithmeticException
124 
ThrowArithmeticExceptionDivideByZero()125 void ThrowArithmeticExceptionDivideByZero() {
126   ThrowException("Ljava/lang/ArithmeticException;", nullptr, "divide by zero");
127 }
128 
129 // ArrayIndexOutOfBoundsException
130 
ThrowArrayIndexOutOfBoundsException(int index,int length)131 void ThrowArrayIndexOutOfBoundsException(int index, int length) {
132   ThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", nullptr,
133                  StringPrintf("length=%d; index=%d", length, index).c_str());
134 }
135 
136 // ArrayStoreException
137 
ThrowArrayStoreException(ObjPtr<mirror::Class> element_class,ObjPtr<mirror::Class> array_class)138 void ThrowArrayStoreException(ObjPtr<mirror::Class> element_class,
139                               ObjPtr<mirror::Class> array_class) {
140   ThrowException("Ljava/lang/ArrayStoreException;", nullptr,
141                  StringPrintf("%s cannot be stored in an array of type %s",
142                               mirror::Class::PrettyDescriptor(element_class).c_str(),
143                               mirror::Class::PrettyDescriptor(array_class).c_str()).c_str());
144 }
145 
146 // BootstrapMethodError
147 
ThrowBootstrapMethodError(const char * fmt,...)148 void ThrowBootstrapMethodError(const char* fmt, ...) {
149   va_list args;
150   va_start(args, fmt);
151   ThrowException("Ljava/lang/BootstrapMethodError;", nullptr, fmt, &args);
152   va_end(args);
153 }
154 
ThrowWrappedBootstrapMethodError(const char * fmt,...)155 void ThrowWrappedBootstrapMethodError(const char* fmt, ...) {
156   va_list args;
157   va_start(args, fmt);
158   ThrowWrappedException("Ljava/lang/BootstrapMethodError;", nullptr, fmt, &args);
159   va_end(args);
160 }
161 
162 // ClassCastException
163 
ThrowClassCastException(ObjPtr<mirror::Class> dest_type,ObjPtr<mirror::Class> src_type)164 void ThrowClassCastException(ObjPtr<mirror::Class> dest_type, ObjPtr<mirror::Class> src_type) {
165   ThrowException("Ljava/lang/ClassCastException;", nullptr,
166                  StringPrintf("%s cannot be cast to %s",
167                               mirror::Class::PrettyDescriptor(src_type).c_str(),
168                               mirror::Class::PrettyDescriptor(dest_type).c_str()).c_str());
169 }
170 
ThrowClassCastException(const char * msg)171 void ThrowClassCastException(const char* msg) {
172   ThrowException("Ljava/lang/ClassCastException;", nullptr, msg);
173 }
174 
175 // ClassCircularityError
176 
ThrowClassCircularityError(ObjPtr<mirror::Class> c)177 void ThrowClassCircularityError(ObjPtr<mirror::Class> c) {
178   std::ostringstream msg;
179   msg << mirror::Class::PrettyDescriptor(c);
180   ThrowException("Ljava/lang/ClassCircularityError;", c, msg.str().c_str());
181 }
182 
ThrowClassCircularityError(ObjPtr<mirror::Class> c,const char * fmt,...)183 void ThrowClassCircularityError(ObjPtr<mirror::Class> c, const char* fmt, ...) {
184   va_list args;
185   va_start(args, fmt);
186   ThrowException("Ljava/lang/ClassCircularityError;", c, fmt, &args);
187   va_end(args);
188 }
189 
190 // ClassFormatError
191 
ThrowClassFormatError(ObjPtr<mirror::Class> referrer,const char * fmt,...)192 void ThrowClassFormatError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
193   va_list args;
194   va_start(args, fmt);
195   ThrowException("Ljava/lang/ClassFormatError;", referrer, fmt, &args);
196   va_end(args);
197 }
198 
199 // IllegalAccessError
200 
ThrowIllegalAccessErrorClass(ObjPtr<mirror::Class> referrer,ObjPtr<mirror::Class> accessed)201 void ThrowIllegalAccessErrorClass(ObjPtr<mirror::Class> referrer, ObjPtr<mirror::Class> accessed) {
202   std::ostringstream msg;
203   msg << "Illegal class access: '" << mirror::Class::PrettyDescriptor(referrer)
204       << "' attempting to access '" << mirror::Class::PrettyDescriptor(accessed) << "'";
205   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
206 }
207 
ThrowIllegalAccessErrorClassForMethodDispatch(ObjPtr<mirror::Class> referrer,ObjPtr<mirror::Class> accessed,ArtMethod * called,InvokeType type)208 void ThrowIllegalAccessErrorClassForMethodDispatch(ObjPtr<mirror::Class> referrer,
209                                                    ObjPtr<mirror::Class> accessed,
210                                                    ArtMethod* called,
211                                                    InvokeType type) {
212   std::ostringstream msg;
213   msg << "Illegal class access ('" << mirror::Class::PrettyDescriptor(referrer)
214       << "' attempting to access '"
215       << mirror::Class::PrettyDescriptor(accessed) << "') in attempt to invoke " << type
216       << " method " << ArtMethod::PrettyMethod(called).c_str();
217   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
218 }
219 
ThrowIllegalAccessErrorMethod(ObjPtr<mirror::Class> referrer,ArtMethod * accessed)220 void ThrowIllegalAccessErrorMethod(ObjPtr<mirror::Class> referrer, ArtMethod* accessed) {
221   std::ostringstream msg;
222   msg << "Method '" << ArtMethod::PrettyMethod(accessed) << "' is inaccessible to class '"
223       << mirror::Class::PrettyDescriptor(referrer) << "'";
224   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
225 }
226 
ThrowIllegalAccessErrorField(ObjPtr<mirror::Class> referrer,ArtField * accessed)227 void ThrowIllegalAccessErrorField(ObjPtr<mirror::Class> referrer, ArtField* accessed) {
228   std::ostringstream msg;
229   msg << "Field '" << ArtField::PrettyField(accessed, false) << "' is inaccessible to class '"
230       << mirror::Class::PrettyDescriptor(referrer) << "'";
231   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
232 }
233 
ThrowIllegalAccessErrorFinalField(ArtMethod * referrer,ArtField * accessed)234 void ThrowIllegalAccessErrorFinalField(ArtMethod* referrer, ArtField* accessed) {
235   std::ostringstream msg;
236   msg << "Final field '" << ArtField::PrettyField(accessed, false)
237       << "' cannot be written to by method '" << ArtMethod::PrettyMethod(referrer) << "'";
238   ThrowException("Ljava/lang/IllegalAccessError;",
239                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
240                  msg.str().c_str());
241 }
242 
ThrowIllegalAccessError(ObjPtr<mirror::Class> referrer,const char * fmt,...)243 void ThrowIllegalAccessError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
244   va_list args;
245   va_start(args, fmt);
246   ThrowException("Ljava/lang/IllegalAccessError;", referrer, fmt, &args);
247   va_end(args);
248 }
249 
ThrowIllegalAccessErrorForImplementingMethod(ObjPtr<mirror::Class> klass,ArtMethod * implementation_method,ArtMethod * interface_method)250 void ThrowIllegalAccessErrorForImplementingMethod(ObjPtr<mirror::Class> klass,
251                                                   ArtMethod* implementation_method,
252                                                   ArtMethod* interface_method)
253     REQUIRES_SHARED(Locks::mutator_lock_) {
254   // Note: For a non-public abstract implementing method, both `AbstractMethodError` and
255   // `IllegalAccessError` are reasonable. We now follow the RI behaviour and throw the latter,
256   // so we do not assert here that the implementation method is concrete as we did in the past.
257   DCHECK(!implementation_method->IsPublic());
258   ThrowIllegalAccessError(
259       klass,
260       "Method '%s' implementing interface method '%s' is not public",
261       implementation_method->PrettyMethod().c_str(),
262       interface_method->PrettyMethod().c_str());
263 }
264 
265 // IllegalAccessException
266 
ThrowIllegalAccessException(const char * msg)267 void ThrowIllegalAccessException(const char* msg) {
268   ThrowException("Ljava/lang/IllegalAccessException;", nullptr, msg);
269 }
270 
271 // IllegalArgumentException
272 
ThrowIllegalArgumentException(const char * msg)273 void ThrowIllegalArgumentException(const char* msg) {
274   ThrowException("Ljava/lang/IllegalArgumentException;", nullptr, msg);
275 }
276 
277 // IllegalStateException
278 
ThrowIllegalStateException(const char * msg)279 void ThrowIllegalStateException(const char* msg) {
280   ThrowException("Ljava/lang/IllegalStateException;", nullptr, msg);
281 }
282 
283 // IncompatibleClassChangeError
284 
ThrowIncompatibleClassChangeError(InvokeType expected_type,InvokeType found_type,ArtMethod * method,ArtMethod * referrer)285 void ThrowIncompatibleClassChangeError(InvokeType expected_type,
286                                        InvokeType found_type,
287                                        ArtMethod* method,
288                                        ArtMethod* referrer) {
289   std::ostringstream msg;
290   msg << "The method '" << ArtMethod::PrettyMethod(method) << "' was expected to be of type "
291       << expected_type << " but instead was found to be of type " << found_type;
292   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
293                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
294                  msg.str().c_str());
295 }
296 
ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(ArtMethod * interface_method,ObjPtr<mirror::Object> this_object,ArtMethod * referrer)297 void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(ArtMethod* interface_method,
298                                                                 ObjPtr<mirror::Object> this_object,
299                                                                 ArtMethod* referrer) {
300   // Referrer is calling interface_method on this_object, however, the interface_method isn't
301   // implemented by this_object.
302   CHECK(this_object != nullptr);
303   std::ostringstream msg;
304   msg << "Class '" << mirror::Class::PrettyDescriptor(this_object->GetClass())
305       << "' does not implement interface '"
306       << mirror::Class::PrettyDescriptor(interface_method->GetDeclaringClass())
307       << "' in call to '" << ArtMethod::PrettyMethod(interface_method) << "'";
308   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
309                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
310                  msg.str().c_str());
311 }
312 
ThrowIncompatibleClassChangeErrorField(ArtField * resolved_field,bool is_static,ArtMethod * referrer)313 void ThrowIncompatibleClassChangeErrorField(ArtField* resolved_field,
314                                             bool is_static,
315                                             ArtMethod* referrer) {
316   std::ostringstream msg;
317   msg << "Expected '" << ArtField::PrettyField(resolved_field) << "' to be a "
318       << (is_static ? "static" : "instance") << " field" << " rather than a "
319       << (is_static ? "instance" : "static") << " field";
320   ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer->GetDeclaringClass(),
321                  msg.str().c_str());
322 }
323 
ThrowIncompatibleClassChangeError(ObjPtr<mirror::Class> referrer,const char * fmt,...)324 void ThrowIncompatibleClassChangeError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
325   va_list args;
326   va_start(args, fmt);
327   ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args);
328   va_end(args);
329 }
330 
ThrowIncompatibleClassChangeErrorForMethodConflict(ArtMethod * method)331 void ThrowIncompatibleClassChangeErrorForMethodConflict(ArtMethod* method) {
332   DCHECK(method != nullptr);
333   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
334                  /*referrer=*/nullptr,
335                  StringPrintf("Conflicting default method implementations %s",
336                               ArtMethod::PrettyMethod(method).c_str()).c_str());
337 }
338 
339 // IndexOutOfBoundsException
340 
ThrowIndexOutOfBoundsException(int index,int length)341 void ThrowIndexOutOfBoundsException(int index, int length) {
342   ThrowException("Ljava/lang/IndexOutOfBoundsException;", nullptr,
343                  StringPrintf("length=%d; index=%d", length, index).c_str());
344 }
345 
346 // InternalError
347 
ThrowInternalError(const char * fmt,...)348 void ThrowInternalError(const char* fmt, ...) {
349   va_list args;
350   va_start(args, fmt);
351   ThrowException("Ljava/lang/InternalError;", nullptr, fmt, &args);
352   va_end(args);
353 }
354 
355 // IOException
356 
ThrowIOException(const char * fmt,...)357 void ThrowIOException(const char* fmt, ...) {
358   va_list args;
359   va_start(args, fmt);
360   ThrowException("Ljava/io/IOException;", nullptr, fmt, &args);
361   va_end(args);
362 }
363 
ThrowWrappedIOException(const char * fmt,...)364 void ThrowWrappedIOException(const char* fmt, ...) {
365   va_list args;
366   va_start(args, fmt);
367   ThrowWrappedException("Ljava/io/IOException;", nullptr, fmt, &args);
368   va_end(args);
369 }
370 
371 // LinkageError
372 
ThrowLinkageError(ObjPtr<mirror::Class> referrer,const char * fmt,...)373 void ThrowLinkageError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
374   va_list args;
375   va_start(args, fmt);
376   ThrowException("Ljava/lang/LinkageError;", referrer, fmt, &args);
377   va_end(args);
378 }
379 
ThrowWrappedLinkageError(ObjPtr<mirror::Class> referrer,const char * fmt,...)380 void ThrowWrappedLinkageError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
381   va_list args;
382   va_start(args, fmt);
383   ThrowWrappedException("Ljava/lang/LinkageError;", referrer, fmt, &args);
384   va_end(args);
385 }
386 
387 // NegativeArraySizeException
388 
ThrowNegativeArraySizeException(int size)389 void ThrowNegativeArraySizeException(int size) {
390   ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr,
391                  StringPrintf("%d", size).c_str());
392 }
393 
ThrowNegativeArraySizeException(const char * msg)394 void ThrowNegativeArraySizeException(const char* msg) {
395   ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr, msg);
396 }
397 
398 // NoSuchFieldError
399 
ThrowNoSuchFieldError(std::string_view scope,ObjPtr<mirror::Class> c,std::string_view type,std::string_view name)400 void ThrowNoSuchFieldError(std::string_view scope,
401                            ObjPtr<mirror::Class> c,
402                            std::string_view type,
403                            std::string_view name) {
404   std::ostringstream msg;
405   std::string temp;
406   msg << "No " << scope << "field " << name << " of type " << type
407       << " in class " << c->GetDescriptor(&temp) << " or its superclasses";
408   ThrowException("Ljava/lang/NoSuchFieldError;", c, msg.str().c_str());
409 }
410 
ThrowNoSuchFieldException(ObjPtr<mirror::Class> c,std::string_view name)411 void ThrowNoSuchFieldException(ObjPtr<mirror::Class> c, std::string_view name) {
412   std::ostringstream msg;
413   std::string temp;
414   msg << "No field " << name << " in class " << c->GetDescriptor(&temp);
415   ThrowException("Ljava/lang/NoSuchFieldException;", c, msg.str().c_str());
416 }
417 
418 // NoSuchMethodError
419 
ThrowNoSuchMethodError(InvokeType type,ObjPtr<mirror::Class> c,std::string_view name,const Signature & signature)420 void ThrowNoSuchMethodError(InvokeType type,
421                             ObjPtr<mirror::Class> c,
422                             std::string_view name,
423                             const Signature& signature) {
424   std::ostringstream msg;
425   std::string temp;
426   msg << "No " << type << " method " << name << signature
427       << " in class " << c->GetDescriptor(&temp) << " or its super classes";
428   ThrowException("Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
429 }
430 
ThrowNoSuchMethodError(ObjPtr<mirror::Class> c,std::string_view name,const Signature & signature)431 void ThrowNoSuchMethodError(ObjPtr<mirror::Class> c,
432                             std::string_view name,
433                             const Signature& signature) {
434   std::ostringstream msg;
435   std::string temp;
436   msg << "No method " << name << signature
437       << " in class " << c->GetDescriptor(&temp) << " or its super classes";
438   ThrowException("Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
439 }
440 
441 // NullPointerException
442 
ThrowNullPointerExceptionForFieldAccess(ArtField * field,ArtMethod * method,bool is_read)443 void ThrowNullPointerExceptionForFieldAccess(ArtField* field, ArtMethod* method, bool is_read) {
444   std::ostringstream msg;
445   msg << "Attempt to " << (is_read ? "read from" : "write to") << " field '"
446       << ArtField::PrettyField(field) << "' on a null object reference in method '"
447       << ArtMethod::PrettyMethod(method) << "'";
448   ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str());
449 }
450 
ThrowNullPointerExceptionForMethodAccessImpl(uint32_t method_idx,const DexFile & dex_file,InvokeType type)451 static void ThrowNullPointerExceptionForMethodAccessImpl(uint32_t method_idx,
452                                                          const DexFile& dex_file,
453                                                          InvokeType type)
454     REQUIRES_SHARED(Locks::mutator_lock_) {
455   std::ostringstream msg;
456   msg << "Attempt to invoke " << type << " method '"
457       << dex_file.PrettyMethod(method_idx, true) << "' on a null object reference";
458   ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str());
459 }
460 
ThrowNullPointerExceptionForMethodAccess(uint32_t method_idx,InvokeType type)461 void ThrowNullPointerExceptionForMethodAccess(uint32_t method_idx, InvokeType type) {
462   const DexFile& dex_file = *Thread::Current()->GetCurrentMethod(nullptr)->GetDexFile();
463   ThrowNullPointerExceptionForMethodAccessImpl(method_idx, dex_file, type);
464 }
465 
ThrowNullPointerExceptionForMethodAccess(ArtMethod * method,InvokeType type)466 void ThrowNullPointerExceptionForMethodAccess(ArtMethod* method, InvokeType type) {
467   ThrowNullPointerExceptionForMethodAccessImpl(method->GetDexMethodIndex(),
468                                                *method->GetDexFile(),
469                                                type);
470 }
471 
IsValidReadBarrierImplicitCheck(uintptr_t addr)472 static bool IsValidReadBarrierImplicitCheck(uintptr_t addr) {
473   DCHECK(gUseReadBarrier);
474   uint32_t monitor_offset = mirror::Object::MonitorOffset().Uint32Value();
475   if (kUseBakerReadBarrier &&
476       (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64)) {
477     constexpr uint32_t gray_byte_position = LockWord::kReadBarrierStateShift / kBitsPerByte;
478     monitor_offset += gray_byte_position;
479   }
480   return addr == monitor_offset;
481 }
482 
IsValidImplicitCheck(uintptr_t addr,const Instruction & instr)483 static bool IsValidImplicitCheck(uintptr_t addr, const Instruction& instr)
484     REQUIRES_SHARED(Locks::mutator_lock_) {
485   if (!CanDoImplicitNullCheckOn(addr)) {
486     return false;
487   }
488 
489   switch (instr.Opcode()) {
490     case Instruction::INVOKE_DIRECT:
491     case Instruction::INVOKE_DIRECT_RANGE:
492     case Instruction::INVOKE_VIRTUAL:
493     case Instruction::INVOKE_VIRTUAL_RANGE:
494     case Instruction::INVOKE_INTERFACE:
495     case Instruction::INVOKE_INTERFACE_RANGE:
496     case Instruction::INVOKE_POLYMORPHIC:
497     case Instruction::INVOKE_POLYMORPHIC_RANGE:
498     case Instruction::INVOKE_SUPER:
499     case Instruction::INVOKE_SUPER_RANGE: {
500       // Without inlining, we could just check that the offset is the class offset.
501       // However, when inlining, the compiler can (validly) merge the null check with a field access
502       // on the same object. Note that the stack map at the NPE will reflect the invoke's location,
503       // which is the caller.
504       return true;
505     }
506 
507     case Instruction::IGET_OBJECT:
508       if (gUseReadBarrier && IsValidReadBarrierImplicitCheck(addr)) {
509         return true;
510       }
511       FALLTHROUGH_INTENDED;
512     case Instruction::IGET:
513     case Instruction::IGET_WIDE:
514     case Instruction::IGET_BOOLEAN:
515     case Instruction::IGET_BYTE:
516     case Instruction::IGET_CHAR:
517     case Instruction::IGET_SHORT:
518     case Instruction::IPUT:
519     case Instruction::IPUT_WIDE:
520     case Instruction::IPUT_OBJECT:
521     case Instruction::IPUT_BOOLEAN:
522     case Instruction::IPUT_BYTE:
523     case Instruction::IPUT_CHAR:
524     case Instruction::IPUT_SHORT: {
525       // We might be doing an implicit null check with an offset that doesn't correspond
526       // to the instruction, for example with two field accesses and the first one being
527       // eliminated or re-ordered.
528       return true;
529     }
530 
531     case Instruction::AGET_OBJECT:
532       if (gUseReadBarrier && IsValidReadBarrierImplicitCheck(addr)) {
533         return true;
534       }
535       FALLTHROUGH_INTENDED;
536     case Instruction::AGET:
537     case Instruction::AGET_WIDE:
538     case Instruction::AGET_BOOLEAN:
539     case Instruction::AGET_BYTE:
540     case Instruction::AGET_CHAR:
541     case Instruction::AGET_SHORT:
542     case Instruction::APUT:
543     case Instruction::APUT_WIDE:
544     case Instruction::APUT_OBJECT:
545     case Instruction::APUT_BOOLEAN:
546     case Instruction::APUT_BYTE:
547     case Instruction::APUT_CHAR:
548     case Instruction::APUT_SHORT:
549     case Instruction::FILL_ARRAY_DATA:
550     case Instruction::ARRAY_LENGTH: {
551       // The length access should crash. We currently do not do implicit checks on
552       // the array access itself.
553       return (addr == 0u) || (addr == mirror::Array::LengthOffset().Uint32Value());
554     }
555 
556     default: {
557       // We have covered all the cases where an NPE could occur.
558       // Note that this must be kept in sync with the compiler, and adding
559       // any new way to do implicit checks in the compiler should also update
560       // this code.
561       return false;
562     }
563   }
564 }
565 
ThrowNullPointerExceptionFromDexPC(bool check_address,uintptr_t addr)566 void ThrowNullPointerExceptionFromDexPC(bool check_address, uintptr_t addr) {
567   uint32_t throw_dex_pc;
568   ArtMethod* method = Thread::Current()->GetCurrentMethod(&throw_dex_pc);
569   CodeItemInstructionAccessor accessor(method->DexInstructions());
570   CHECK_LT(throw_dex_pc, accessor.InsnsSizeInCodeUnits());
571   const Instruction& instr = accessor.InstructionAt(throw_dex_pc);
572   if (check_address && !IsValidImplicitCheck(addr, instr)) {
573     const DexFile* dex_file = method->GetDexFile();
574     LOG(FATAL) << "Invalid address for an implicit NullPointerException check: "
575                << "0x" << std::hex << addr << std::dec
576                << ", at "
577                << instr.DumpString(dex_file)
578                << " in "
579                << method->PrettyMethod();
580   }
581 
582   switch (instr.Opcode()) {
583     case Instruction::INVOKE_DIRECT:
584       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kDirect);
585       break;
586     case Instruction::INVOKE_DIRECT_RANGE:
587       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kDirect);
588       break;
589     case Instruction::INVOKE_VIRTUAL:
590       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kVirtual);
591       break;
592     case Instruction::INVOKE_VIRTUAL_RANGE:
593       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kVirtual);
594       break;
595     case Instruction::INVOKE_SUPER:
596       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kSuper);
597       break;
598     case Instruction::INVOKE_SUPER_RANGE:
599       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kSuper);
600       break;
601     case Instruction::INVOKE_INTERFACE:
602       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kInterface);
603       break;
604     case Instruction::INVOKE_INTERFACE_RANGE:
605       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kInterface);
606       break;
607     case Instruction::INVOKE_POLYMORPHIC:
608       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_45cc(), kVirtual);
609       break;
610     case Instruction::INVOKE_POLYMORPHIC_RANGE:
611       ThrowNullPointerExceptionForMethodAccess(instr.VRegB_4rcc(), kVirtual);
612       break;
613     case Instruction::IGET:
614     case Instruction::IGET_WIDE:
615     case Instruction::IGET_OBJECT:
616     case Instruction::IGET_BOOLEAN:
617     case Instruction::IGET_BYTE:
618     case Instruction::IGET_CHAR:
619     case Instruction::IGET_SHORT: {
620       ArtField* field =
621           Runtime::Current()->GetClassLinker()->ResolveField(instr.VRegC_22c(), method, false);
622       Thread::Current()->ClearException();  // Resolution may fail, ignore.
623       ThrowNullPointerExceptionForFieldAccess(field, method, /* is_read= */ true);
624       break;
625     }
626     case Instruction::IPUT:
627     case Instruction::IPUT_WIDE:
628     case Instruction::IPUT_OBJECT:
629     case Instruction::IPUT_BOOLEAN:
630     case Instruction::IPUT_BYTE:
631     case Instruction::IPUT_CHAR:
632     case Instruction::IPUT_SHORT: {
633       ArtField* field = Runtime::Current()->GetClassLinker()->ResolveField(
634           instr.VRegC_22c(), method, /* is_static= */ false);
635       Thread::Current()->ClearException();  // Resolution may fail, ignore.
636       ThrowNullPointerExceptionForFieldAccess(field, method, /* is_read= */ false);
637       break;
638     }
639     case Instruction::AGET:
640     case Instruction::AGET_WIDE:
641     case Instruction::AGET_OBJECT:
642     case Instruction::AGET_BOOLEAN:
643     case Instruction::AGET_BYTE:
644     case Instruction::AGET_CHAR:
645     case Instruction::AGET_SHORT:
646       ThrowException("Ljava/lang/NullPointerException;", nullptr,
647                      "Attempt to read from null array");
648       break;
649     case Instruction::APUT:
650     case Instruction::APUT_WIDE:
651     case Instruction::APUT_OBJECT:
652     case Instruction::APUT_BOOLEAN:
653     case Instruction::APUT_BYTE:
654     case Instruction::APUT_CHAR:
655     case Instruction::APUT_SHORT:
656       ThrowException("Ljava/lang/NullPointerException;", nullptr,
657                      "Attempt to write to null array");
658       break;
659     case Instruction::ARRAY_LENGTH:
660       ThrowException("Ljava/lang/NullPointerException;", nullptr,
661                      "Attempt to get length of null array");
662       break;
663     case Instruction::FILL_ARRAY_DATA: {
664       ThrowException("Ljava/lang/NullPointerException;", nullptr,
665                      "Attempt to write to null array");
666       break;
667     }
668     case Instruction::MONITOR_ENTER:
669     case Instruction::MONITOR_EXIT: {
670       ThrowException("Ljava/lang/NullPointerException;", nullptr,
671                      "Attempt to do a synchronize operation on a null object");
672       break;
673     }
674     default: {
675       const DexFile* dex_file = method->GetDexFile();
676       LOG(FATAL) << "NullPointerException at an unexpected instruction: "
677                  << instr.DumpString(dex_file)
678                  << " in "
679                  << method->PrettyMethod();
680       UNREACHABLE();
681     }
682   }
683 }
684 
ThrowNullPointerException(const char * msg)685 void ThrowNullPointerException(const char* msg) {
686   ThrowException("Ljava/lang/NullPointerException;", nullptr, msg);
687 }
688 
ThrowNullPointerException()689 void ThrowNullPointerException() {
690   ThrowException("Ljava/lang/NullPointerException;");
691 }
692 
693 // ReadOnlyBufferException
694 
ThrowReadOnlyBufferException()695 void ThrowReadOnlyBufferException() {
696   Thread::Current()->ThrowNewException("Ljava/nio/ReadOnlyBufferException;", nullptr);
697 }
698 
699 // RuntimeException
700 
ThrowRuntimeException(const char * fmt,...)701 void ThrowRuntimeException(const char* fmt, ...) {
702   va_list args;
703   va_start(args, fmt);
704   ThrowException("Ljava/lang/RuntimeException;", nullptr, fmt, &args);
705   va_end(args);
706 }
707 
708 // SecurityException
709 
ThrowSecurityException(const char * fmt,...)710 void ThrowSecurityException(const char* fmt, ...) {
711   va_list args;
712   va_start(args, fmt);
713   ThrowException("Ljava/lang/SecurityException;", nullptr, fmt, &args);
714   va_end(args);
715 }
716 
717 // Stack overflow.
718 
719 template <StackType stack_type>
ThrowStackOverflowError(Thread * self)720 void ThrowStackOverflowError(Thread* self) {
721   if (self->IsHandlingStackOverflow<stack_type>()) {
722     LOG(ERROR) << "Recursive stack overflow.";
723     // We don't fail here because SetStackEndForStackOverflow will print better diagnostics.
724   }
725 
726   // Allow space on the stack for constructor to execute.
727   self->SetStackEndForStackOverflow<stack_type>();
728 
729   // Remove the stack overflow protection if it is set up.
730   bool implicit_stack_check = Runtime::Current()->GetImplicitStackOverflowChecks();
731   if (implicit_stack_check) {
732     if (!self->UnprotectStack<stack_type>()) {
733       LOG(ERROR) << "Unable to remove stack protection for stack overflow";
734     }
735   }
736 
737   // Avoid running Java code for exception initialization.
738   // TODO: Checks to make this a bit less brittle.
739   //
740   // Note: This lambda is used to make sure the `StackOverflowError` intitialization code
741   //       does not increase the frame size of `ThrowStackOverflowError()` itself. It runs
742   //       with its own frame in the extended stack, which is especially important for modes
743   //       with larger stack sizes (e.g., ASAN).
744   auto create_and_throw = [self]() REQUIRES_SHARED(Locks::mutator_lock_) NO_INLINE {
745     std::string msg("stack size ");
746     msg += PrettySize(self->GetUsableStackSize<stack_type>());
747 
748     ScopedObjectAccessUnchecked soa(self);
749     StackHandleScope<1u> hs(self);
750 
751     // Allocate an uninitialized object.
752     DCHECK(WellKnownClasses::java_lang_StackOverflowError->IsInitialized());
753     Handle<mirror::Object> exc = hs.NewHandle(
754         WellKnownClasses::java_lang_StackOverflowError->AllocObject(self));
755     if (exc == nullptr) {
756       LOG(WARNING) << "Could not allocate StackOverflowError object.";
757       return;
758     }
759 
760     // "Initialize".
761     // StackOverflowError -> VirtualMachineError -> Error -> Throwable -> Object.
762     // Only Throwable has "custom" fields:
763     //   String detailMessage.
764     //   Throwable cause (= this).
765     //   List<Throwable> suppressedExceptions (= Collections.emptyList()).
766     //   Object stackState;
767     //   StackTraceElement[] stackTrace;
768     // Only Throwable has a non-empty constructor:
769     //   this.stackTrace = EmptyArray.STACK_TRACE_ELEMENT;
770     //   fillInStackTrace();
771 
772     // detailMessage.
773     {
774       ObjPtr<mirror::String> s = mirror::String::AllocFromModifiedUtf8(self, msg.c_str());
775       if (s == nullptr) {
776         LOG(WARNING) << "Could not throw new StackOverflowError because message allocation failed.";
777         return;
778       }
779       WellKnownClasses::java_lang_Throwable_detailMessage
780           ->SetObject</*kTransactionActive=*/ false>(exc.Get(), s);
781     }
782 
783     // cause.
784     WellKnownClasses::java_lang_Throwable_cause
785         ->SetObject</*kTransactionActive=*/ false>(exc.Get(), exc.Get());
786 
787     // suppressedExceptions.
788     {
789       ObjPtr<mirror::Class> j_u_c = WellKnownClasses::java_util_Collections.Get();
790       DCHECK(j_u_c->IsInitialized());
791       ObjPtr<mirror::Object> empty_list =
792           WellKnownClasses::java_util_Collections_EMPTY_LIST->GetObject(j_u_c);
793       CHECK(empty_list != nullptr);
794       WellKnownClasses::java_lang_Throwable_suppressedExceptions
795           ->SetObject</*kTransactionActive=*/ false>(exc.Get(), empty_list);
796     }
797 
798     // stackState is set as result of fillInStackTrace. fillInStackTrace calls
799     // nativeFillInStackTrace.
800     ObjPtr<mirror::Object> stack_state_val = self->CreateInternalStackTrace(soa);
801     if (stack_state_val != nullptr) {
802       WellKnownClasses::java_lang_Throwable_stackState
803           ->SetObject</*kTransactionActive=*/ false>(exc.Get(), stack_state_val);
804 
805       // stackTrace.
806       ObjPtr<mirror::Class> l_u_ea = WellKnownClasses::libcore_util_EmptyArray.Get();
807       DCHECK(l_u_ea->IsInitialized());
808       ObjPtr<mirror::Object> empty_ste =
809           WellKnownClasses::libcore_util_EmptyArray_STACK_TRACE_ELEMENT->GetObject(l_u_ea);
810       CHECK(empty_ste != nullptr);
811       WellKnownClasses::java_lang_Throwable_stackTrace
812           ->SetObject</*kTransactionActive=*/ false>(exc.Get(), empty_ste);
813     } else {
814       LOG(WARNING) << "Could not create stack trace.";
815       // Note: we'll create an exception without stack state, which is valid.
816     }
817 
818     // Throw the exception.
819     self->SetException(exc->AsThrowable());
820   };
821   create_and_throw();
822   CHECK(self->IsExceptionPending());
823 
824   self->ResetDefaultStackEnd<stack_type>();  // Return to default stack size.
825 
826   // And restore protection if implicit checks are on.
827   if (implicit_stack_check) {
828     self->ProtectStack<stack_type>();
829   }
830 }
831 
832 // Explicit instantiations to keep this definition separate to the declaration.
833 template void ThrowStackOverflowError<StackType::kHardware>(Thread* self);
834 
835 // StringIndexOutOfBoundsException
836 
ThrowStringIndexOutOfBoundsException(int index,int length)837 void ThrowStringIndexOutOfBoundsException(int index, int length) {
838   ThrowException("Ljava/lang/StringIndexOutOfBoundsException;", nullptr,
839                  StringPrintf("length=%d; index=%d", length, index).c_str());
840 }
841 
842 // UnsupportedOperationException
843 
ThrowUnsupportedOperationException()844 void ThrowUnsupportedOperationException() {
845   ThrowException("Ljava/lang/UnsupportedOperationException;");
846 }
847 
848 // VerifyError
849 
ThrowVerifyError(ObjPtr<mirror::Class> referrer,const char * fmt,...)850 void ThrowVerifyError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
851   va_list args;
852   va_start(args, fmt);
853   ThrowException("Ljava/lang/VerifyError;", referrer, fmt, &args);
854   va_end(args);
855 }
856 
857 // WrongMethodTypeException
858 
ThrowWrongMethodTypeException(ObjPtr<mirror::MethodType> expected_type,ObjPtr<mirror::MethodType> actual_type)859 void ThrowWrongMethodTypeException(ObjPtr<mirror::MethodType> expected_type,
860                                    ObjPtr<mirror::MethodType> actual_type) {
861   ThrowWrongMethodTypeException(expected_type->PrettyDescriptor(), actual_type->PrettyDescriptor());
862 }
863 
ThrowWrongMethodTypeException(const std::string & expected_descriptor,const std::string & actual_descriptor)864 void ThrowWrongMethodTypeException(const std::string& expected_descriptor,
865                                    const std::string& actual_descriptor) {
866   std::ostringstream msg;
867   msg << "Expected " << expected_descriptor << " but was " << actual_descriptor;
868   ThrowException("Ljava/lang/invoke/WrongMethodTypeException;",  nullptr, msg.str().c_str());
869 }
870 
871 }  // namespace art
872