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