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 "entrypoints/entrypoint_utils.h"
18 
19 #include "art_field-inl.h"
20 #include "art_method-inl.h"
21 #include "base/mutex.h"
22 #include "base/pointer_size.h"
23 #include "base/sdk_version.h"
24 #include "class_linker-inl.h"
25 #include "class_root-inl.h"
26 #include "dex/dex_file-inl.h"
27 #include "dex/method_reference.h"
28 #include "entrypoints/entrypoint_utils-inl.h"
29 #include "entrypoints/quick/callee_save_frame.h"
30 #include "entrypoints/runtime_asm_entrypoints.h"
31 #include "gc/accounting/card_table-inl.h"
32 #include "jni/java_vm_ext.h"
33 #include "mirror/class-inl.h"
34 #include "mirror/method.h"
35 #include "mirror/object-inl.h"
36 #include "mirror/object_array-alloc-inl.h"
37 #include "nth_caller_visitor.h"
38 #include "oat/index_bss_mapping.h"
39 #include "oat/oat_file-inl.h"
40 #include "oat/oat_quick_method_header.h"
41 #include "reflection.h"
42 #include "scoped_thread_state_change-inl.h"
43 #include "well_known_classes-inl.h"
44 
45 namespace art HIDDEN {
46 
CheckReferenceResult(Handle<mirror::Object> o,Thread * self)47 void CheckReferenceResult(Handle<mirror::Object> o, Thread* self) {
48   if (o == nullptr) {
49     return;
50   }
51   // Make sure that the result is an instance of the type this method was expected to return.
52   ArtMethod* method = self->GetCurrentMethod(nullptr);
53   ObjPtr<mirror::Class> return_type = method->ResolveReturnType();
54 
55   if (!o->InstanceOf(return_type)) {
56     Runtime::Current()->GetJavaVM()->JniAbortF(nullptr,
57                                                "attempt to return an instance of %s from %s",
58                                                o->PrettyTypeOf().c_str(),
59                                                method->PrettyMethod().c_str());
60   }
61 }
62 
InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable & soa,const char * shorty,jobject rcvr_jobj,jobject interface_method_jobj,std::vector<jvalue> & args)63 JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa,
64                                     const char* shorty,
65                                     jobject rcvr_jobj,
66                                     jobject interface_method_jobj,
67                                     std::vector<jvalue>& args) {
68   StackHandleScope<4u> hs(soa.Self());
69   DCHECK(rcvr_jobj != nullptr);
70   Handle<mirror::Object> h_receiver = hs.NewHandle(soa.Decode<mirror::Object>(rcvr_jobj));
71   DCHECK(h_receiver->InstanceOf(GetClassRoot(ClassRoot::kJavaLangReflectProxy)));
72   Handle<mirror::Method> h_interface_method =
73       hs.NewHandle(soa.Decode<mirror::Method>(interface_method_jobj));
74 
75   // Build argument array possibly triggering GC.
76   soa.Self()->AssertThreadSuspensionIsAllowable();
77   auto h_args = hs.NewHandle<mirror::ObjectArray<mirror::Object>>(nullptr);
78   const JValue zero;
79   Runtime* runtime = Runtime::Current();
80   uint32_t target_sdk_version = runtime->GetTargetSdkVersion();
81   // Do not create empty arrays unless needed to maintain Dalvik bug compatibility.
82   if (args.size() > 0 || IsSdkVersionSetAndAtMost(target_sdk_version, SdkVersion::kL)) {
83     h_args.Assign(mirror::ObjectArray<mirror::Object>::Alloc(
84         soa.Self(), GetClassRoot<mirror::ObjectArray<mirror::Object>>(), args.size()));
85     if (h_args == nullptr) {
86       CHECK(soa.Self()->IsExceptionPending());
87       return zero;
88     }
89     for (size_t i = 0; i < args.size(); ++i) {
90       ObjPtr<mirror::Object> value;
91       if (shorty[i + 1] == 'L') {
92         value = soa.Decode<mirror::Object>(args[i].l);
93       } else {
94         JValue jv;
95         jv.SetJ(args[i].j);
96         value = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv);
97         if (value == nullptr) {
98           CHECK(soa.Self()->IsExceptionPending());
99           return zero;
100         }
101       }
102       // We do not support `Proxy.invoke()` in a transaction.
103       h_args->SetWithoutChecks</*kActiveTransaction=*/ false>(i, value);
104     }
105   }
106 
107   // Call Proxy.invoke(Proxy proxy, Method method, Object[] args).
108   Handle<mirror::Object> h_result = hs.NewHandle(
109       WellKnownClasses::java_lang_reflect_Proxy_invoke->InvokeStatic<'L', 'L', 'L', 'L'>(
110           soa.Self(), h_receiver.Get(), h_interface_method.Get(), h_args.Get()));
111 
112   // Unbox result and handle error conditions.
113   if (LIKELY(!soa.Self()->IsExceptionPending())) {
114     if (shorty[0] == 'V' || (shorty[0] == 'L' && h_result == nullptr)) {
115       // Do nothing.
116       return zero;
117     } else {
118       ObjPtr<mirror::Class> result_type;
119       if (shorty[0] == 'L') {
120         // This can cause thread suspension.
121         result_type = h_interface_method->GetArtMethod()->ResolveReturnType();
122         if (result_type == nullptr) {
123           DCHECK(soa.Self()->IsExceptionPending());
124           return zero;
125         }
126       } else {
127         result_type = runtime->GetClassLinker()->LookupPrimitiveClass(shorty[0]);
128         DCHECK(result_type != nullptr);
129       }
130       JValue result_unboxed;
131       if (!UnboxPrimitiveForResult(h_result.Get(), result_type, &result_unboxed)) {
132         DCHECK(soa.Self()->IsExceptionPending());
133         return zero;
134       }
135       return result_unboxed;
136     }
137   } else {
138     // In the case of checked exceptions that aren't declared, the exception must be wrapped by
139     // a UndeclaredThrowableException.
140     ObjPtr<mirror::Throwable> exception = soa.Self()->GetException();
141     if (exception->IsCheckedException()) {
142       bool declares_exception = false;
143       {
144         ScopedAssertNoThreadSuspension ants(__FUNCTION__);
145         ObjPtr<mirror::Object> rcvr = soa.Decode<mirror::Object>(rcvr_jobj);
146         ObjPtr<mirror::Class> proxy_class = rcvr->GetClass();
147         ObjPtr<mirror::Method> interface_method = soa.Decode<mirror::Method>(interface_method_jobj);
148         ArtMethod* proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface(
149             interface_method->GetArtMethod(), kRuntimePointerSize);
150         auto virtual_methods = proxy_class->GetVirtualMethodsSlice(kRuntimePointerSize);
151         size_t num_virtuals = proxy_class->NumVirtualMethods();
152         size_t method_size = ArtMethod::Size(kRuntimePointerSize);
153         // Rely on the fact that the methods are contiguous to determine the index of the method in
154         // the slice.
155         int throws_index = (reinterpret_cast<uintptr_t>(proxy_method) -
156             reinterpret_cast<uintptr_t>(&virtual_methods[0])) / method_size;
157         CHECK_LT(throws_index, static_cast<int>(num_virtuals));
158         ObjPtr<mirror::ObjectArray<mirror::Class>> declared_exceptions =
159             proxy_class->GetProxyThrows()->Get(throws_index);
160         ObjPtr<mirror::Class> exception_class = exception->GetClass();
161         for (int32_t i = 0; i < declared_exceptions->GetLength() && !declares_exception; i++) {
162           ObjPtr<mirror::Class> declared_exception = declared_exceptions->Get(i);
163           declares_exception = declared_exception->IsAssignableFrom(exception_class);
164         }
165       }
166       if (!declares_exception) {
167         soa.Self()->ThrowNewWrappedException("Ljava/lang/reflect/UndeclaredThrowableException;",
168                                              nullptr);
169       }
170     }
171     return zero;
172   }
173 }
174 
FillArrayData(ObjPtr<mirror::Object> obj,const Instruction::ArrayDataPayload * payload)175 bool FillArrayData(ObjPtr<mirror::Object> obj, const Instruction::ArrayDataPayload* payload) {
176   DCHECK_EQ(payload->ident, static_cast<uint16_t>(Instruction::kArrayDataSignature));
177   if (UNLIKELY(obj == nullptr)) {
178     ThrowNullPointerException("null array in FILL_ARRAY_DATA");
179     return false;
180   }
181   ObjPtr<mirror::Array> array = obj->AsArray();
182   DCHECK(!array->IsObjectArray());
183   if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
184     Thread* self = Thread::Current();
185     self->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
186                              "failed FILL_ARRAY_DATA; length=%d, index=%d",
187                              array->GetLength(), payload->element_count);
188     return false;
189   }
190   // Copy data from dex file to memory assuming both are little endian.
191   uint32_t size_in_bytes = payload->element_count * payload->element_width;
192   memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes);
193   return true;
194 }
195 
DoGetCalleeSaveMethodOuterCallerAndPc(ArtMethod ** sp,CalleeSaveType type)196 static inline std::pair<ArtMethod*, uintptr_t> DoGetCalleeSaveMethodOuterCallerAndPc(
197     ArtMethod** sp, CalleeSaveType type) REQUIRES_SHARED(Locks::mutator_lock_) {
198   DCHECK_EQ(*sp, Runtime::Current()->GetCalleeSaveMethod(type));
199 
200   const size_t callee_frame_size = RuntimeCalleeSaveFrame::GetFrameSize(type);
201   auto** caller_sp = reinterpret_cast<ArtMethod**>(
202       reinterpret_cast<uintptr_t>(sp) + callee_frame_size);
203   const size_t callee_return_pc_offset = RuntimeCalleeSaveFrame::GetReturnPcOffset(type);
204   uintptr_t caller_pc = *reinterpret_cast<uintptr_t*>(
205       (reinterpret_cast<uint8_t*>(sp) + callee_return_pc_offset));
206   ArtMethod* outer_method = *caller_sp;
207   return std::make_pair(outer_method, caller_pc);
208 }
209 
DoGetCalleeSaveMethodCallerAndDexPc(ArtMethod ** sp,CalleeSaveType type,ArtMethod * outer_method,uintptr_t caller_pc,uint32_t * dex_pc,bool do_caller_check)210 static inline ArtMethod* DoGetCalleeSaveMethodCallerAndDexPc(ArtMethod** sp,
211                                                              CalleeSaveType type,
212                                                              ArtMethod* outer_method,
213                                                              uintptr_t caller_pc,
214                                                              uint32_t* dex_pc,
215                                                              bool do_caller_check)
216     REQUIRES_SHARED(Locks::mutator_lock_) {
217   ArtMethod* caller = outer_method;
218   if (outer_method != nullptr) {
219     const OatQuickMethodHeader* current_code = outer_method->GetOatQuickMethodHeader(caller_pc);
220     DCHECK(current_code != nullptr);
221     if (current_code->IsOptimized() &&
222         CodeInfo::HasInlineInfo(current_code->GetOptimizedCodeInfoPtr())) {
223       uintptr_t native_pc_offset = current_code->NativeQuickPcOffset(caller_pc);
224       CodeInfo code_info = CodeInfo::DecodeInlineInfoOnly(current_code);
225       StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
226       DCHECK(stack_map.IsValid());
227       BitTableRange<InlineInfo> inline_infos = code_info.GetInlineInfosOf(stack_map);
228       if (!inline_infos.empty()) {
229         caller = GetResolvedMethod(outer_method, code_info, inline_infos);
230         *dex_pc = inline_infos.back().GetDexPc();
231       } else {
232         *dex_pc = stack_map.GetDexPc();
233       }
234     } else {
235       size_t callee_frame_size = RuntimeCalleeSaveFrame::GetFrameSize(type);
236       ArtMethod** caller_sp = reinterpret_cast<ArtMethod**>(
237           reinterpret_cast<uintptr_t>(sp) + callee_frame_size);
238       *dex_pc = current_code->ToDexPc(caller_sp, caller_pc);
239     }
240   }
241   if (kIsDebugBuild && do_caller_check) {
242     // Note that do_caller_check is optional, as this method can be called by
243     // stubs, and tests without a proper call stack.
244     NthCallerVisitor visitor(Thread::Current(), 1, true);
245     visitor.WalkStack();
246     CHECK_EQ(caller, visitor.caller);
247   }
248   return caller;
249 }
250 
GetCalleeSaveMethodCallerAndDexPc(ArtMethod ** sp,CalleeSaveType type,uint32_t * dex_pc,bool do_caller_check)251 ArtMethod* GetCalleeSaveMethodCallerAndDexPc(ArtMethod** sp,
252                                              CalleeSaveType type,
253                                              uint32_t* dex_pc,
254                                              bool do_caller_check)
255     REQUIRES_SHARED(Locks::mutator_lock_) {
256   ScopedAssertNoThreadSuspension ants(__FUNCTION__);
257   auto outer_caller_and_pc = DoGetCalleeSaveMethodOuterCallerAndPc(sp, type);
258   ArtMethod* outer_method = outer_caller_and_pc.first;
259   uintptr_t caller_pc = outer_caller_and_pc.second;
260   ArtMethod* caller = DoGetCalleeSaveMethodCallerAndDexPc(sp,
261                                                           type,
262                                                           outer_method,
263                                                           caller_pc,
264                                                           dex_pc,
265                                                           do_caller_check);
266   return caller;
267 }
268 
GetCalleeSaveMethodCallerAndOuterMethod(Thread * self,CalleeSaveType type)269 CallerAndOuterMethod GetCalleeSaveMethodCallerAndOuterMethod(Thread* self, CalleeSaveType type) {
270   CallerAndOuterMethod result;
271   ScopedAssertNoThreadSuspension ants(__FUNCTION__);
272   ArtMethod** sp = self->GetManagedStack()->GetTopQuickFrameKnownNotTagged();
273   auto outer_caller_and_pc = DoGetCalleeSaveMethodOuterCallerAndPc(sp, type);
274   result.outer_method = outer_caller_and_pc.first;
275   uintptr_t caller_pc = outer_caller_and_pc.second;
276   uint32_t dex_pc;
277   result.caller = DoGetCalleeSaveMethodCallerAndDexPc(sp,
278                                                       type,
279                                                       result.outer_method,
280                                                       caller_pc,
281                                                       &dex_pc,
282                                                       /* do_caller_check= */ true);
283   return result;
284 }
285 
GetCalleeSaveOuterMethod(Thread * self,CalleeSaveType type)286 ArtMethod* GetCalleeSaveOuterMethod(Thread* self, CalleeSaveType type) {
287   ScopedAssertNoThreadSuspension ants(__FUNCTION__);
288   ArtMethod** sp = self->GetManagedStack()->GetTopQuickFrameKnownNotTagged();
289   return DoGetCalleeSaveMethodOuterCallerAndPc(sp, type).first;
290 }
291 
ResolveMethodHandleFromCode(ArtMethod * referrer,uint32_t method_handle_idx)292 ObjPtr<mirror::MethodHandle> ResolveMethodHandleFromCode(ArtMethod* referrer,
293                                                          uint32_t method_handle_idx) {
294   Thread::PoisonObjectPointersIfDebug();
295   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
296   return class_linker->ResolveMethodHandle(Thread::Current(), method_handle_idx, referrer);
297 }
298 
ResolveMethodTypeFromCode(ArtMethod * referrer,dex::ProtoIndex proto_idx)299 ObjPtr<mirror::MethodType> ResolveMethodTypeFromCode(ArtMethod* referrer,
300                                                      dex::ProtoIndex proto_idx) {
301   Thread::PoisonObjectPointersIfDebug();
302   ObjPtr<mirror::MethodType> method_type =
303       referrer->GetDexCache()->GetResolvedMethodType(proto_idx);
304   if (UNLIKELY(method_type == nullptr)) {
305     StackHandleScope<2> hs(Thread::Current());
306     Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache()));
307     Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referrer->GetClassLoader()));
308     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
309     method_type = class_linker->ResolveMethodType(hs.Self(), proto_idx, dex_cache, class_loader);
310   }
311   return method_type;
312 }
313 
MaybeUpdateBssMethodEntry(ArtMethod * callee,MethodReference callee_reference,ArtMethod * outer_method)314 void MaybeUpdateBssMethodEntry(ArtMethod* callee,
315                                MethodReference callee_reference,
316                                ArtMethod* outer_method) {
317   DCHECK_NE(callee, nullptr);
318   if (outer_method->GetDexFile()->GetOatDexFile() == nullptr ||
319       outer_method->GetDexFile()->GetOatDexFile()->GetOatFile() == nullptr) {
320     // No OatFile to update.
321     return;
322   }
323   const OatFile* outer_oat_file = outer_method->GetDexFile()->GetOatDexFile()->GetOatFile();
324 
325   const DexFile* dex_file = callee_reference.dex_file;
326   const OatDexFile* oat_dex_file = dex_file->GetOatDexFile();
327   const IndexBssMapping* mapping = nullptr;
328   if (oat_dex_file != nullptr && oat_dex_file->GetOatFile() == outer_oat_file) {
329     // DexFiles compiled together to an oat file case.
330     mapping = oat_dex_file->GetMethodBssMapping();
331   } else {
332     // Try to find the DexFile in the BCP of the outer_method.
333     const OatFile::BssMappingInfo* mapping_info = outer_oat_file->FindBcpMappingInfo(dex_file);
334     if (mapping_info != nullptr) {
335       mapping = mapping_info->method_bss_mapping;
336     }
337   }
338 
339   // Perform the update if we found a mapping.
340   if (mapping != nullptr) {
341     size_t bss_offset =
342         IndexBssMappingLookup::GetBssOffset(mapping,
343                                             callee_reference.index,
344                                             dex_file->NumMethodIds(),
345                                             static_cast<size_t>(kRuntimePointerSize));
346     if (bss_offset != IndexBssMappingLookup::npos) {
347       DCHECK_ALIGNED(bss_offset, static_cast<size_t>(kRuntimePointerSize));
348       DCHECK_NE(outer_oat_file, nullptr);
349       ArtMethod** method_entry = reinterpret_cast<ArtMethod**>(
350           const_cast<uint8_t*>(outer_oat_file->BssBegin() + bss_offset));
351       DCHECK_GE(method_entry, outer_oat_file->GetBssMethods().data());
352       DCHECK_LT(method_entry,
353                 outer_oat_file->GetBssMethods().data() + outer_oat_file->GetBssMethods().size());
354       std::atomic<ArtMethod*>* atomic_entry =
355           reinterpret_cast<std::atomic<ArtMethod*>*>(method_entry);
356       if (kIsDebugBuild) {
357         ArtMethod* existing = atomic_entry->load(std::memory_order_acquire);
358         CHECK(existing->IsRuntimeMethod() || existing == callee);
359       }
360       static_assert(sizeof(*method_entry) == sizeof(*atomic_entry), "Size check.");
361       atomic_entry->store(callee, std::memory_order_release);
362     }
363   }
364 }
365 
366 }  // namespace art
367