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