//===-- WatchpointAlgorithms.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Breakpoint/WatchpointAlgorithms.h"
#include "lldb/Breakpoint/WatchpointResource.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#include <algorithm>
#include <utility>
#include <vector>

using namespace lldb;
using namespace lldb_private;

std::vector<WatchpointResourceSP>
WatchpointAlgorithms::AtomizeWatchpointRequest(
    addr_t addr, size_t size, bool read, bool write,
    WatchpointHardwareFeature supported_features, ArchSpec &arch) {

  std::vector<Region> entries;

  if (supported_features & eWatchpointHardwareArmMASK) {
    entries =
        PowerOf2Watchpoints(addr, size,
                            /*min_byte_size*/ 1,
                            /*max_byte_size*/ INT32_MAX,
                            /*address_byte_size*/ arch.GetAddressByteSize());
  } else {
    // As a fallback, assume we can watch any power-of-2
    // number of bytes up through the size of an address in the target.
    entries =
        PowerOf2Watchpoints(addr, size,
                            /*min_byte_size*/ 1,
                            /*max_byte_size*/ arch.GetAddressByteSize(),
                            /*address_byte_size*/ arch.GetAddressByteSize());
  }

  Log *log = GetLog(LLDBLog::Watchpoints);
  LLDB_LOGV(log, "AtomizeWatchpointRequest user request addr {0:x} size {1}",
            addr, size);
  std::vector<WatchpointResourceSP> resources;
  for (Region &ent : entries) {
    LLDB_LOGV(log, "AtomizeWatchpointRequest creating resource {0:x} size {1}",
              ent.addr, ent.size);
    WatchpointResourceSP wp_res_sp =
        std::make_shared<WatchpointResource>(ent.addr, ent.size, read, write);
    resources.push_back(wp_res_sp);
  }

  return resources;
}

/// Convert a user's watchpoint request (\a user_addr and \a user_size)
/// into hardware watchpoints, for a target that can watch a power-of-2
/// region of memory (1, 2, 4, 8, etc), aligned to that same power-of-2
/// memory address.
///
/// If a user asks to watch 4 bytes at address 0x1002 (0x1002-0x1005
/// inclusive) we can implement this with two 2-byte watchpoints
/// (0x1002 and 0x1004) or with an 8-byte watchpoint at 0x1000.
/// A 4-byte watchpoint at 0x1002 would not be properly 4 byte aligned.
///
/// If a user asks to watch 16 bytes at 0x1000, and this target supports
/// 8-byte watchpoints, we can implement this with two 8-byte watchpoints
/// at 0x1000 and 0x1008.
std::vector<WatchpointAlgorithms::Region>
WatchpointAlgorithms::PowerOf2Watchpoints(addr_t user_addr, size_t user_size,
                                          size_t min_byte_size,
                                          size_t max_byte_size,
                                          uint32_t address_byte_size) {

  Log *log = GetLog(LLDBLog::Watchpoints);
  LLDB_LOGV(log,
            "AtomizeWatchpointRequest user request addr {0:x} size {1} "
            "min_byte_size {2}, max_byte_size {3}, address_byte_size {4}",
            user_addr, user_size, min_byte_size, max_byte_size,
            address_byte_size);

  // Can't watch zero bytes.
  if (user_size == 0)
    return {};

  size_t aligned_size = std::max(user_size, min_byte_size);
  /// Round up \a user_size to the next power-of-2 size
  /// user_size == 8   -> aligned_size == 8
  /// user_size == 9   -> aligned_size == 16
  aligned_size = llvm::bit_ceil(aligned_size);

  addr_t aligned_start = user_addr & ~(aligned_size - 1);

  // Does this power-of-2 memory range, aligned to power-of-2 that the
  // hardware can watch, completely cover the requested region.
  if (aligned_size <= max_byte_size &&
      aligned_start + aligned_size >= user_addr + user_size)
    return {{aligned_start, aligned_size}};

  // If the maximum region we can watch is larger than the aligned
  // size, try increasing the region size by one power of 2 and see
  // if aligning to that amount can cover the requested region.
  //
  // Increasing the aligned_size repeatedly instead of splitting the
  // watchpoint can result in us watching large regions of memory
  // unintentionally when we could use small two watchpoints.  e.g.
  //    user_addr 0x3ff8 user_size 32
  // can be watched with four 8-byte watchpoints or if it's done with one
  // MASK watchpoint, it would need to be a 32KB watchpoint (a 16KB
  // watchpoint at 0x0 only covers 0x0000-0x4000).  A user request
  // at the end of a power-of-2 region can lead to these undesirably
  // large watchpoints and many false positive hits to ignore.
  if (max_byte_size >= (aligned_size << 1)) {
    aligned_size <<= 1;
    aligned_start = user_addr & ~(aligned_size - 1);
    if (aligned_size <= max_byte_size &&
        aligned_start + aligned_size >= user_addr + user_size)
      return {{aligned_start, aligned_size}};

    // Go back to our original aligned size, to try the multiple
    // watchpoint approach.
    aligned_size >>= 1;
  }

  // We need to split the user's watchpoint into two or more watchpoints
  // that can be monitored by hardware, because of alignment and/or size
  // reasons.
  aligned_size = std::min(aligned_size, max_byte_size);
  aligned_start = user_addr & ~(aligned_size - 1);

  std::vector<Region> result;
  addr_t current_address = aligned_start;
  const addr_t user_end_address = user_addr + user_size;
  while (current_address + aligned_size < user_end_address) {
    result.push_back({current_address, aligned_size});
    current_address += aligned_size;
  }

  if (current_address < user_end_address)
    result.push_back({current_address, aligned_size});

  return result;
}
