//===-- NativeBreakpointList.cpp --------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/common/NativeBreakpointList.h"

#include "lldb/Core/Log.h"

#include "lldb/Host/common/NativeBreakpoint.h"
#include "lldb/Host/common/SoftwareBreakpoint.h"

using namespace lldb;
using namespace lldb_private;

NativeBreakpointList::NativeBreakpointList () :
    m_mutex (Mutex::eMutexTypeRecursive)
{
}

Error
NativeBreakpointList::AddRef (lldb::addr_t addr, size_t size_hint, bool hardware, CreateBreakpointFunc create_func)
{
    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
    if (log)
        log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false");

    Mutex::Locker locker (m_mutex);

    // Check if the breakpoint is already set.
    auto iter = m_breakpoints.find (addr);
    if (iter != m_breakpoints.end ())
    {
        // Yes - bump up ref count.
        if (log)
            log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- already enabled, upping ref count", __FUNCTION__, addr);

        iter->second->AddRef ();
        return Error ();
    }

    // Create a new breakpoint using the given create func.
    if (log)
        log->Printf ("NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false");

    NativeBreakpointSP breakpoint_sp;
    Error error = create_func (addr, size_hint, hardware, breakpoint_sp);
    if (error.Fail ())
    {
        if (log)
            log->Printf ("NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s -- FAILED: %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false", error.AsCString ());
        return error;
    }

    // Remember the breakpoint.
    assert (breakpoint_sp && "NativeBreakpoint create function succeeded but returned NULL breakpoint");
    m_breakpoints.insert (BreakpointMap::value_type (addr, breakpoint_sp));

    return error;
}

Error
NativeBreakpointList::DecRef (lldb::addr_t addr)
{
    Error error;

    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
    if (log)
        log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);

    Mutex::Locker locker (m_mutex);

    // Check if the breakpoint is already set.
    auto iter = m_breakpoints.find (addr);
    if (iter == m_breakpoints.end ())
    {
        // Not found!
        if (log)
            log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
        error.SetErrorString ("breakpoint not found");
        return error;
    }

    // Decrement ref count.
    const int32_t new_ref_count = iter->second->DecRef ();
    assert (new_ref_count >= 0 && "NativeBreakpoint ref count went negative");

    if (new_ref_count > 0)
    {
        // Still references to this breakpoint.  Leave it alone.
        if (log)
            log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- new breakpoint ref count %" PRIu32, __FUNCTION__, addr, new_ref_count);
        return error;
    }

    // Breakpoint has no more references.  Disable it if it's not
    // already disabled.
    if (log)
        log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removing due to no remaining references", __FUNCTION__, addr);

    // If it's enabled, we need to disable it.
    if (iter->second->IsEnabled ())
    {
        if (log)
            log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- currently enabled, now disabling", __FUNCTION__, addr);
        error = iter->second->Disable ();
        if (error.Fail ())
        {
            if (log)
                log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removal FAILED: %s", __FUNCTION__, addr, error.AsCString ());
            // Continue since we still want to take it out of the breakpoint list.
        }
    }
    else
    {
        if (log)
            log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- already disabled, nothing to do", __FUNCTION__, addr);
    }

    // Take the breakpoint out of the list.
    if (log)
        log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removed from breakpoint map", __FUNCTION__, addr);

    m_breakpoints.erase (iter);
    return error;
}

Error
NativeBreakpointList::EnableBreakpoint (lldb::addr_t addr)
{
    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
    if (log)
        log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);

    Mutex::Locker locker (m_mutex);

    // Ensure we have said breakpoint.
    auto iter = m_breakpoints.find (addr);
    if (iter == m_breakpoints.end ())
    {
        // Not found!
        if (log)
            log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
        return Error ("breakpoint not found");
    }

    // Enable it.
    return iter->second->Enable ();
}

Error
NativeBreakpointList::DisableBreakpoint (lldb::addr_t addr)
{
    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
    if (log)
        log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);

    Mutex::Locker locker (m_mutex);

    // Ensure we have said breakpoint.
    auto iter = m_breakpoints.find (addr);
    if (iter == m_breakpoints.end ())
    {
        // Not found!
        if (log)
            log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
        return Error ("breakpoint not found");
    }

    // Disable it.
    return iter->second->Disable ();
}

Error
NativeBreakpointList::GetBreakpoint (lldb::addr_t addr, NativeBreakpointSP &breakpoint_sp)
{
    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
    if (log)
        log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);

    Mutex::Locker locker (m_mutex);

    // Ensure we have said breakpoint.
    auto iter = m_breakpoints.find (addr);
    if (iter == m_breakpoints.end ())
    {
        // Not found!
        breakpoint_sp.reset ();
        return Error ("breakpoint not found");
    }

    // Disable it.
    breakpoint_sp = iter->second;
    return Error ();
}

Error
NativeBreakpointList::RemoveTrapsFromBuffer(lldb::addr_t addr, void *buf, size_t size) const
{
    for (const auto &map : m_breakpoints)
    {
        lldb::addr_t bp_addr = map.first;
        // Breapoint not in range, ignore
        if (bp_addr < addr || addr + size <= bp_addr)
            continue;
        const auto &bp_sp = map.second;
        // Not software breakpoint, ignore
        if (!bp_sp->IsSoftwareBreakpoint())
            continue;
        auto software_bp_sp = std::static_pointer_cast<SoftwareBreakpoint>(bp_sp);
        auto opcode_addr = static_cast<char *>(buf) + bp_addr - addr;
        auto saved_opcodes = software_bp_sp->m_saved_opcodes;
        auto opcode_size = software_bp_sp->m_opcode_size;
        ::memcpy(opcode_addr, saved_opcodes, opcode_size);
    }
    return Error();
}
