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