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