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