1/* 2 * Copyright (C) 2024 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 "asm_support_x86.S" 18#include "interpreter/cfi_asm_support.h" 19 20/* 21 * This file contains all native entrypoints that are called using the native ABI and do not 22 * transition to the quick ABI. For example: the switch interpreter (using the native ABI) directly 23 * calls ExecuteSwitchImplAsm and this code will always return back to the switch interpreter, 24 * again using the native ABI. Because of this behaviour ExecuteSwitchImplAsm should be included in 25 * this file. This is done so these native entrypoints can be compiled independently to quick 26 * entrypoints for cases when the kRuntimeISA and kRuntimeQuickCodeISA do not match. 27 * 28 * See comment on StackType (thread.h) for definitions and examples of quick ABI/code and 29 * native ABI/code. 30 */ 31 32// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding. 33// Argument 0: ESP+4: The context pointer for ExecuteSwitchImpl. 34// Argument 1: ESP+8: Pointer to the templated ExecuteSwitchImpl to call. 35// Argument 2: ESP+12: The value of DEX PC (memory address of the methods bytecode). 36DEFINE_FUNCTION ExecuteSwitchImplAsm 37 PUSH ebx // Spill EBX; Increments ESP, so arg0 is at ESP+8 now. 38 mov 12(%esp), %eax // EAX = C++ templated interpreter function 39 mov 16(%esp), %ebx // EBX = DEX PC (callee save register) 40 mov 8(%esp), %ecx // ECX = Context argument for the function 41 CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* EAX */, 3 /* EBX */, 0) 42 43 sub LITERAL(4), %esp // Alignment padding 44 CFI_ADJUST_CFA_OFFSET(4) 45 push %ecx // Push argument 46 CFI_ADJUST_CFA_OFFSET(4) 47 call *%eax // Call the wrapped function 48 addl LITERAL(8), %esp 49 CFI_ADJUST_CFA_OFFSET(-8) 50 51 POP ebx // Restore EBX 52 ret 53END_FUNCTION ExecuteSwitchImplAsm 54 55 /* 56 * Jni dlsym lookup stub. 57 */ 58DEFINE_FUNCTION art_jni_dlsym_lookup_stub 59 INCREASE_FRAME 8 // Align stack. 60 pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current(). 61 CFI_ADJUST_CFA_OFFSET(4) 62 // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable() 63 // for @FastNative or @CriticalNative. 64 movl (%esp), %eax // Thread* self 65 movl THREAD_TOP_QUICK_FRAME_OFFSET(%eax), %eax // uintptr_t tagged_quick_frame 66 andl LITERAL(TAGGED_JNI_SP_MASK_TOGGLED32), %eax // ArtMethod** sp 67 movl (%eax), %eax // ArtMethod* method 68 testl LITERAL(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE), \ 69 ART_METHOD_ACCESS_FLAGS_OFFSET(%eax) 70 jne .Llookup_stub_fast_or_critical_native 71 call SYMBOL(artFindNativeMethod) // (Thread*) 72 jmp .Llookup_stub_continue 73.Llookup_stub_fast_or_critical_native: 74 call SYMBOL(artFindNativeMethodRunnable) // (Thread*) 75.Llookup_stub_continue: 76 DECREASE_FRAME 12 // Remove argument & padding. 77 testl %eax, %eax // Check if returned method code is null. 78 jz .Lno_native_code_found // If null, jump to return to handle. 79 jmp *%eax // Otherwise, tail call to intended method. 80.Lno_native_code_found: 81 ret 82END_FUNCTION art_jni_dlsym_lookup_stub 83