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_64.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: RDI: The context pointer for ExecuteSwitchImpl. 34// Argument 1: RSI: Pointer to the templated ExecuteSwitchImpl to call. 35// Argument 2: RDX: The value of DEX PC (memory address of the methods bytecode). 36DEFINE_FUNCTION ExecuteSwitchImplAsm 37 PUSH rbx // Spill RBX 38 movq %rdx, %rbx // RBX = DEX PC (callee save register) 39 CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* RAX */, 3 /* RBX */, 0) 40 41 call *%rsi // Call the wrapped function 42 43 POP rbx // Restore RBX 44 ret 45END_FUNCTION ExecuteSwitchImplAsm 46 47 /* 48 * Jni dlsym lookup stub. 49 */ 50DEFINE_FUNCTION art_jni_dlsym_lookup_stub 51 // Save callee and GPR args. 52 PUSH_ARG r9 // Arg. 53 PUSH_ARG r8 // Arg. 54 PUSH_ARG rdi // Arg. (JniEnv for normal and @FastNative) 55 PUSH_ARG rsi // Arg. 56 PUSH_ARG rdx // Arg. 57 PUSH_ARG rcx // Arg. 58 // Create space for FPR args, plus padding for alignment 59 INCREASE_FRAME 72 60 // Save FPRs. 61 movq %xmm0, 0(%rsp) 62 movq %xmm1, 8(%rsp) 63 movq %xmm2, 16(%rsp) 64 movq %xmm3, 24(%rsp) 65 movq %xmm4, 32(%rsp) 66 movq %xmm5, 40(%rsp) 67 movq %xmm6, 48(%rsp) 68 movq %xmm7, 56(%rsp) 69 // prepare call 70 movq %gs:THREAD_SELF_OFFSET, %rdi // RDI := Thread::Current() 71 // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable() 72 // for @FastNative or @CriticalNative. 73 movq THREAD_TOP_QUICK_FRAME_OFFSET(%rdi), %rax // uintptr_t tagged_quick_frame 74 andq LITERAL(TAGGED_JNI_SP_MASK_TOGGLED64), %rax // ArtMethod** sp 75 movq (%rax), %rax // ArtMethod* method 76 testl LITERAL(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE), \ 77 ART_METHOD_ACCESS_FLAGS_OFFSET(%rax) 78 jne .Llookup_stub_fast_or_critical_native 79 call SYMBOL(artFindNativeMethod) // (Thread*) 80 jmp .Llookup_stub_continue 81.Llookup_stub_fast_or_critical_native: 82 call SYMBOL(artFindNativeMethodRunnable) // (Thread*) 83.Llookup_stub_continue: 84 // restore arguments 85 movq 0(%rsp), %xmm0 86 movq 8(%rsp), %xmm1 87 movq 16(%rsp), %xmm2 88 movq 24(%rsp), %xmm3 89 movq 32(%rsp), %xmm4 90 movq 40(%rsp), %xmm5 91 movq 48(%rsp), %xmm6 92 movq 56(%rsp), %xmm7 93 DECREASE_FRAME 72 94 POP_ARG rcx // Arg. 95 POP_ARG rdx // Arg. 96 POP_ARG rsi // Arg. 97 POP_ARG rdi // Arg. (JniEnv for normal and @FastNative) 98 POP_ARG r8 // Arg. 99 POP_ARG r9 // Arg. 100 testq %rax, %rax // check if returned method code is null 101 jz .Lno_native_code_found // if null, jump to return to handle 102 jmp *%rax // otherwise, tail call to intended method 103.Lno_native_code_found: 104 ret 105END_FUNCTION art_jni_dlsym_lookup_stub 106