/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <android-base/logging.h>

#include "arch/arm/jni_frame_arm.h"
#include "arch/arm64/jni_frame_arm64.h"
#include "arch/instruction_set.h"
#include "arch/riscv64/jni_frame_riscv64.h"
#include "arch/x86/jni_frame_x86.h"
#include "arch/x86_64/jni_frame_x86_64.h"
#include "art_method-inl.h"
#include "dex/dex_instruction-inl.h"
#include "dex/method_reference.h"
#include "entrypoints/entrypoint_utils-inl.h"
#include "jni/java_vm_ext.h"
#include "mirror/object-inl.h"
#include "oat/oat_quick_method_header.h"
#include "oat/stack_map.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"

namespace art HIDDEN {

static inline uint32_t GetInvokeStaticMethodIndex(ArtMethod* caller, uint32_t dex_pc)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  // Get the DexFile and method index.
  const Instruction& instruction = caller->DexInstructions().InstructionAt(dex_pc);
  DCHECK(instruction.Opcode() == Instruction::INVOKE_STATIC ||
         instruction.Opcode() == Instruction::INVOKE_STATIC_RANGE);
  uint32_t method_idx = (instruction.Opcode() == Instruction::INVOKE_STATIC)
      ? instruction.VRegB_35c()
      : instruction.VRegB_3rc();
  return method_idx;
}

// Used by the JNI dlsym stub to find the native method to invoke if none is registered.
extern "C" const void* artFindNativeMethodRunnable(Thread* self)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  Locks::mutator_lock_->AssertSharedHeld(self);  // We come here as Runnable.
  uint32_t dex_pc;
  ArtMethod* method = self->GetCurrentMethod(&dex_pc);
  DCHECK(method != nullptr);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();

  if (!method->IsNative()) {
    // We're coming from compiled managed code and the `method` we see here is the caller.
    // Resolve target @CriticalNative method for a direct call from compiled managed code.
    uint32_t method_idx = GetInvokeStaticMethodIndex(method, dex_pc);
    ArtMethod* target_method = class_linker->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
        self, method_idx, method, kStatic);
    if (target_method == nullptr) {
      self->AssertPendingException();
      return nullptr;
    }
    DCHECK(target_method->IsCriticalNative());
    // Note that the BSS also contains entries used for super calls. Given we
    // only deal with invokestatic in this code path, we don't need to adjust
    // the method index.
    MaybeUpdateBssMethodEntry(target_method,
                              MethodReference(method->GetDexFile(), method_idx),
                              GetCalleeSaveOuterMethod(self, CalleeSaveType::kSaveRefsAndArgs));

    // These calls do not have an explicit class initialization check, so do the check now.
    // (When going through the stub or GenericJNI, the check was already done.)
    DCHECK(target_method->NeedsClinitCheckBeforeCall());
    ObjPtr<mirror::Class> declaring_class = target_method->GetDeclaringClass();
    if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) {
      StackHandleScope<1> hs(self);
      Handle<mirror::Class> h_class(hs.NewHandle(declaring_class));
      if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
        DCHECK(self->IsExceptionPending()) << method->PrettyMethod();
        return nullptr;
      }
    }

    // Replace the runtime method on the stack with the target method.
    DCHECK(!self->GetManagedStack()->GetTopQuickFrameGenericJniTag());
    ArtMethod** sp = self->GetManagedStack()->GetTopQuickFrameKnownNotTagged();
    DCHECK(*sp == Runtime::Current()->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs));
    *sp = target_method;
    self->SetTopOfStackGenericJniTagged(sp);  // Fake GenericJNI frame.

    // Continue with the target method.
    method = target_method;
  }
  DCHECK(method == self->GetCurrentMethod(/*dex_pc=*/ nullptr));

  // Check whether we already have a registered native code.
  // For @CriticalNative it may not be stored in the ArtMethod as a JNI entrypoint if the class
  // was not visibly initialized yet. Do this check also for @FastNative and normal native for
  // consistency; though success would mean that another thread raced to do this lookup.
  const void* native_code = class_linker->GetRegisteredNative(self, method);
  if (native_code != nullptr) {
    return native_code;
  }

  // Lookup symbol address for method, on failure we'll return null with an exception set,
  // otherwise we return the address of the method we found.
  JavaVMExt* vm = down_cast<JNIEnvExt*>(self->GetJniEnv())->GetVm();
  std::string error_msg;
  native_code = vm->FindCodeForNativeMethod(method, &error_msg, /*can_suspend=*/ true);
  if (native_code == nullptr) {
    LOG(ERROR) << error_msg;
    self->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;", error_msg.c_str());
    return nullptr;
  }

  // Register the code. This usually prevents future calls from coming to this function again.
  // We can still come here if the ClassLinker cannot set the entrypoint in the ArtMethod,
  // i.e. for @CriticalNative methods with the declaring class not visibly initialized.
  return class_linker->RegisterNative(self, method, native_code);
}

// Used by the JNI dlsym stub to find the native method to invoke if none is registered.
extern "C" const void* artFindNativeMethod(Thread* self) {
  DCHECK_EQ(self, Thread::Current());
  Locks::mutator_lock_->AssertNotHeld(self);  // We come here as Native.
  ScopedObjectAccess soa(self);
  return artFindNativeMethodRunnable(self);
}

extern "C" size_t artCriticalNativeFrameSize(ArtMethod* method, uintptr_t caller_pc)
    REQUIRES_SHARED(Locks::mutator_lock_)  {
  if (method->IsNative()) {
    // Get the method's shorty.
    DCHECK(method->IsCriticalNative());
    uint32_t shorty_len;
    const char* shorty = method->GetShorty(&shorty_len);

    // Return the platform-dependent stub frame size.
    switch (kRuntimeISA) {
      case InstructionSet::kArm:
      case InstructionSet::kThumb2:
        return arm::GetCriticalNativeStubFrameSize(shorty, shorty_len);
      case InstructionSet::kArm64:
        return arm64::GetCriticalNativeStubFrameSize(shorty, shorty_len);
      case InstructionSet::kRiscv64:
        return riscv64::GetCriticalNativeStubFrameSize(shorty, shorty_len);
      case InstructionSet::kX86:
        return x86::GetCriticalNativeStubFrameSize(shorty, shorty_len);
      case InstructionSet::kX86_64:
        return x86_64::GetCriticalNativeStubFrameSize(shorty, shorty_len);
      default:
        UNIMPLEMENTED(FATAL) << kRuntimeISA;
        UNREACHABLE();
    }
  } else {
    // We're coming from compiled managed code and the `method` we see here is the compiled
    // method that made the call. Get the actual caller (may be inlined) and dex pc.
    const OatQuickMethodHeader* current_code = method->GetOatQuickMethodHeader(caller_pc);
    DCHECK(current_code != nullptr);
    DCHECK(current_code->IsOptimized());
    uintptr_t native_pc_offset = current_code->NativeQuickPcOffset(caller_pc);
    CodeInfo code_info = CodeInfo::DecodeInlineInfoOnly(current_code);
    StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
    DCHECK(stack_map.IsValid());
    BitTableRange<InlineInfo> inline_infos = code_info.GetInlineInfosOf(stack_map);
    ArtMethod* caller =
        inline_infos.empty() ? method : GetResolvedMethod(method, code_info, inline_infos);
    uint32_t dex_pc = inline_infos.empty() ? stack_map.GetDexPc() : inline_infos.back().GetDexPc();

    // Get the callee shorty.
    const DexFile* dex_file = caller->GetDexFile();
    uint32_t method_idx = GetInvokeStaticMethodIndex(caller, dex_pc);
    uint32_t shorty_len;
    const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx), &shorty_len);

    // Return the platform-dependent direct call frame size.
    switch (kRuntimeISA) {
      case InstructionSet::kArm:
      case InstructionSet::kThumb2:
        return arm::GetCriticalNativeDirectCallFrameSize(shorty, shorty_len);
      case InstructionSet::kArm64:
        return arm64::GetCriticalNativeDirectCallFrameSize(shorty, shorty_len);
      case InstructionSet::kRiscv64:
        return riscv64::GetCriticalNativeDirectCallFrameSize(shorty, shorty_len);
      case InstructionSet::kX86:
        return x86::GetCriticalNativeDirectCallFrameSize(shorty, shorty_len);
      case InstructionSet::kX86_64:
        return x86_64::GetCriticalNativeDirectCallFrameSize(shorty, shorty_len);
      default:
        UNIMPLEMENTED(FATAL) << kRuntimeISA;
        UNREACHABLE();
    }
  }
}

}  // namespace art
