//===-- 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()
{
}

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");

    std::lock_guard<std::recursive_mutex> guard(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);

    std::lock_guard<std::recursive_mutex> guard(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);

    std::lock_guard<std::recursive_mutex> guard(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);

    std::lock_guard<std::recursive_mutex> guard(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);

    std::lock_guard<std::recursive_mutex> guard(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();
}
