// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/code_patcher.h"
#if defined(DART_DYNAMIC_MODULES)
#include "vm/constants_kbc.h"
#endif
#include "vm/cpu.h"
#include "vm/instructions.h"
#include "vm/object.h"
#include "vm/virtual_memory.h"

namespace dart {

#if defined(DART_HOST_OS_MACOS) || defined(DART_HOST_OS_MACOS_IOS)
// On iOS even with debugger attached we must still guarantee that memory
// is never executable and writable at the same time. On Mac OS X
// com.apple.security.cs.allow-jit entitlement allows WX memory regions to be
// created - but we should not rely on this entitlement to be present.
static constexpr bool kShouldWriteProtectCodeByDefault = true;
#else
static constexpr bool kShouldWriteProtectCodeByDefault = false;
#endif

DEFINE_FLAG(bool,
            write_protect_code,
            kShouldWriteProtectCodeByDefault,
            "Write protect jitted code");

#if defined(TARGET_ARCH_IA32)
WritableInstructionsScope::WritableInstructionsScope(uword address,
                                                     intptr_t size)
    : address_(address), size_(size) {
  if (FLAG_write_protect_code) {
    VirtualMemory::Protect(reinterpret_cast<void*>(address), size,
                           VirtualMemory::kReadWrite);
  }
}

WritableInstructionsScope::~WritableInstructionsScope() {
  if (FLAG_write_protect_code) {
    VirtualMemory::WriteProtectCode(reinterpret_cast<void*>(address_), size_);
  }
}
#endif  // defined(TARGET_ARCH_IA32)

bool MatchesPattern(uword end, const int16_t* pattern, intptr_t size) {
  // When breaking within generated code in GDB, it may overwrite individual
  // instructions with trap instructions, which can cause this test to fail.
  //
  // Ignoring trap instructions would work well enough within GDB alone, but it
  // doesn't work in RR, because the check for the trap instruction itself will
  // cause replay to diverge from the original record.
  if (FLAG_support_rr) return true;

  uint8_t* bytes = reinterpret_cast<uint8_t*>(end - size);
  for (intptr_t i = 0; i < size; i++) {
    int16_t val = pattern[i];
    if ((val >= 0) && (val != bytes[i])) {
      return false;
    }
  }
  return true;
}

#if !defined(PRODUCT) && defined(DART_DYNAMIC_MODULES)

uint32_t BytecodePatcher::AddBreakpointAt(uword return_address,
                                          const Bytecode& bytecode) {
  auto thread = Thread::Current();
  uint32_t old_opcode;
  thread->isolate_group()->RunWithStoppedMutators([&]() {
    old_opcode =
        AddBreakpointAtWithMutatorsStopped(thread, return_address, bytecode);
  });
  return old_opcode;
}

void BytecodePatcher::RemoveBreakpointAt(uword return_address,
                                         const Bytecode& bytecode,
                                         uint32_t opcode) {
  auto thread = Thread::Current();
  thread->isolate_group()->RunWithStoppedMutators([&]() {
    RemoveBreakpointAtWithMutatorsStopped(thread, return_address, bytecode,
                                          opcode);
  });
}

uint32_t BytecodePatcher::AddBreakpointAtWithMutatorsStopped(
    Thread* thread,
    uword return_address,
    const Bytecode& bytecode) {
  auto* const instr = reinterpret_cast<KBCInstr*>(
      bytecode.GetInstructionBefore(return_address));
  uint32_t old_opcode = *instr;
  *instr = KernelBytecode::BreakpointOpcode(instr);
  return old_opcode;
}

void BytecodePatcher::RemoveBreakpointAtWithMutatorsStopped(
    Thread* thread,
    uword return_address,
    const Bytecode& bytecode,
    uint32_t opcode) {
  auto* const instr = reinterpret_cast<KBCInstr*>(
      bytecode.GetInstructionBefore(return_address));
  // Must be previously enabled and not yet removed.
  ASSERT(*instr == KernelBytecode::BreakpointOpcode(
                       static_cast<KernelBytecode::Opcode>(opcode)));
  *instr = opcode;
}
#endif  // !defined(PRODUCT) && defined(DART_DYNAMIC_MODULES)

}  // namespace dart
