//===-- DNBBreakpoint.cpp ---------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/29/07.
//
//===----------------------------------------------------------------------===//

#include "DNBBreakpoint.h"
#include "MachProcess.h"
#include <assert.h>
#include <algorithm>
#include <inttypes.h>
#include "DNBLog.h"


#pragma mark -- DNBBreakpoint
DNBBreakpoint::DNBBreakpoint(nub_addr_t addr, nub_size_t byte_size, bool hardware) :
    m_retain_count (1),
    m_byte_size (static_cast<uint32_t>(byte_size)),
    m_opcode(),
    m_addr(addr),
    m_enabled(0),
    m_hw_preferred(hardware),
    m_is_watchpoint(0),
    m_watch_read(0),
    m_watch_write(0),
    m_hw_index(INVALID_NUB_HW_INDEX)
{
}

DNBBreakpoint::~DNBBreakpoint()
{
}

void
DNBBreakpoint::Dump() const
{
    if (IsBreakpoint())
    {
        DNBLog ("DNBBreakpoint addr = 0x%llx  state = %s  type = %s breakpoint  hw_index = %i",
                (uint64_t)m_addr,
                m_enabled ? "enabled " : "disabled",
                IsHardware() ? "hardware" : "software",
                GetHardwareIndex());
    }
    else
    {
        DNBLog ("DNBBreakpoint addr = 0x%llx  size = %llu  state = %s  type = %s watchpoint (%s%s)  hw_index = %i",
                (uint64_t)m_addr,
                (uint64_t)m_byte_size,
                m_enabled ? "enabled " : "disabled",
                IsHardware() ? "hardware" : "software",
                m_watch_read ? "r" : "",
                m_watch_write ? "w" : "",
                GetHardwareIndex());
    }
}

#pragma mark -- DNBBreakpointList

DNBBreakpointList::DNBBreakpointList()
{
}

DNBBreakpointList::~DNBBreakpointList()
{
}


DNBBreakpoint *
DNBBreakpointList::Add(nub_addr_t addr, nub_size_t length, bool hardware)
{
    m_breakpoints.insert(std::make_pair(addr, DNBBreakpoint(addr, length, hardware)));
    iterator pos = m_breakpoints.find (addr);
    return &pos->second;
}

bool
DNBBreakpointList::Remove (nub_addr_t addr)
{
    iterator pos = m_breakpoints.find(addr);
    if (pos != m_breakpoints.end())
    {
        m_breakpoints.erase(pos);
        return true;
    }
    return false;
}

DNBBreakpoint *
DNBBreakpointList::FindByAddress (nub_addr_t addr)
{
    iterator pos = m_breakpoints.find(addr);
    if (pos != m_breakpoints.end())
        return &pos->second;

    return NULL;
}

const DNBBreakpoint *
DNBBreakpointList::FindByAddress (nub_addr_t addr) const
{
    const_iterator pos = m_breakpoints.find(addr);
    if (pos != m_breakpoints.end())
        return &pos->second;
    
    return NULL;
}

// Finds the next breakpoint at an address greater than or equal to "addr"
size_t
DNBBreakpointList::FindBreakpointsThatOverlapRange (nub_addr_t addr,
                                                    nub_addr_t size,
                                                    std::vector<DNBBreakpoint *> &bps)
{
    bps.clear();
    iterator end = m_breakpoints.end();
    // Find the first breakpoint with an address >= to "addr"
    iterator pos = m_breakpoints.lower_bound(addr);
    if (pos != end)
    {
        if (pos != m_breakpoints.begin())
        {
            // Watch out for a breakpoint at an address less than "addr" that might still overlap
            iterator prev_pos = pos;
            --prev_pos;
            if (prev_pos->second.IntersectsRange (addr, size, NULL, NULL, NULL))
                bps.push_back (&pos->second);
            
        }

        while (pos != end)
        {
            // When we hit a breakpoint whose start address is greater than "addr + size" we are done.
            // Do the math in a way that doesn't risk unsigned overflow with bad input.
            if ((pos->second.Address() - addr) >= size)
                break;
                
            // Check if this breakpoint overlaps, and if it does, add it to the list
            if (pos->second.IntersectsRange (addr, size, NULL, NULL, NULL))
            {
                bps.push_back (&pos->second);
                ++pos;
            }
        }
    }
    return bps.size();
}

void
DNBBreakpointList::Dump() const
{
    const_iterator pos;
    const_iterator end = m_breakpoints.end();
    for (pos = m_breakpoints.begin(); pos != end; ++pos)
        pos->second.Dump();
}

void
DNBBreakpointList::DisableAll ()
{
    iterator pos, end = m_breakpoints.end();
    for (pos = m_breakpoints.begin(); pos != end; ++pos)
        pos->second.SetEnabled(false);
}


void
DNBBreakpointList::RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, void *p) const
{
    uint8_t *buf = (uint8_t *)p;
    const_iterator end = m_breakpoints.end();
    const_iterator pos = m_breakpoints.lower_bound(addr);
    while (pos != end && (pos->first < (addr + size)))
    {
        nub_addr_t intersect_addr;
        nub_size_t intersect_size;
        nub_size_t opcode_offset;
        const DNBBreakpoint &bp = pos->second;
        if (bp.IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset))
        {
            assert(addr <= intersect_addr && intersect_addr < addr + size);
            assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
            assert(opcode_offset + intersect_size <= bp.ByteSize());
            nub_size_t buf_offset = intersect_addr - addr;
            ::memcpy(buf + buf_offset, bp.SavedOpcodeBytes() + opcode_offset, intersect_size);
        }
        ++pos;
    }
}

void
DNBBreakpointList::DisableAllBreakpoints(MachProcess *process)
{
    iterator pos, end = m_breakpoints.end();
    for (pos = m_breakpoints.begin(); pos != end; ++pos)
        process->DisableBreakpoint(pos->second.Address(), false);    
}

void
DNBBreakpointList::DisableAllWatchpoints(MachProcess *process)
{
    iterator pos, end = m_breakpoints.end();
    for (pos = m_breakpoints.begin(); pos != end; ++pos)
        process->DisableWatchpoint(pos->second.Address(), false);
}

void
DNBBreakpointList::RemoveDisabled()
{
    iterator pos = m_breakpoints.begin();
    while (pos != m_breakpoints.end())
    {
        if (!pos->second.IsEnabled())
            pos = m_breakpoints.erase(pos);
        else
            ++pos;
    }
}
