//===-- BreakpointSite.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/Breakpoint/BreakpointSite.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSiteList.h"

using namespace lldb;
using namespace lldb_private;

BreakpointSite::BreakpointSite
(
    BreakpointSiteList *list,
    const BreakpointLocationSP& owner,
    lldb::addr_t addr,
    lldb::tid_t tid,
    bool use_hardware
) :
    StoppointLocation(GetNextID(), addr, tid, use_hardware),
    m_type (eSoftware), // Process subclasses need to set this correctly using SetType()
    m_saved_opcode(),
    m_trap_opcode(),
    m_enabled(false), // Need to create it disabled, so the first enable turns it on.
    m_owners()
{
    m_owners.Add(owner);
}

BreakpointSite::~BreakpointSite()
{
    BreakpointLocationSP bp_loc_sp;
    const size_t owner_count = m_owners.GetSize();
    for (size_t i = 0; i < owner_count; i++)
    {
        m_owners.GetByIndex(i)->ClearBreakpointSite();
    }
}

break_id_t
BreakpointSite::GetNextID()
{
    static break_id_t g_next_id = 0;
    return ++g_next_id;
}

// RETURNS - true if we should stop at this breakpoint, false if we
// should continue.

bool
BreakpointSite::ShouldStop (StoppointCallbackContext *context)
{
    IncrementHitCount();
    return m_owners.ShouldStop (context);
}

bool
BreakpointSite::IsBreakpointAtThisSite (lldb::break_id_t bp_id)
{
    const size_t owner_count = m_owners.GetSize();
    for (size_t i = 0; i < owner_count; i++)
    {
        if (m_owners.GetByIndex(i)->GetBreakpoint().GetID() == bp_id)
            return true;
    }
    return false;
}

void
BreakpointSite::Dump(Stream *s) const
{
    if (s == NULL)
        return;

    s->Printf("BreakpointSite %u: addr = 0x%8.8" PRIx64 "  type = %s breakpoint  hw_index = %i  hit_count = %-4u",
            GetID(),
            (uint64_t)m_addr,
            IsHardware() ? "hardware" : "software",
            GetHardwareIndex(),
            GetHitCount());
}

void
BreakpointSite::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    if (level != lldb::eDescriptionLevelBrief)
        s->Printf ("breakpoint site: %d at 0x%8.8" PRIx64, GetID(), GetLoadAddress());
    m_owners.GetDescription (s, level);
}

uint8_t *
BreakpointSite::GetTrapOpcodeBytes()
{
    return &m_trap_opcode[0];
}

const uint8_t *
BreakpointSite::GetTrapOpcodeBytes() const
{
    return &m_trap_opcode[0];
}

size_t
BreakpointSite::GetTrapOpcodeMaxByteSize() const
{
    return sizeof(m_trap_opcode);
}

bool
BreakpointSite::SetTrapOpcode (const uint8_t *trap_opcode, size_t trap_opcode_size)
{
    if (trap_opcode_size > 0 && trap_opcode_size <= sizeof(m_trap_opcode))
    {
        m_byte_size = trap_opcode_size;
        ::memcpy (m_trap_opcode, trap_opcode, trap_opcode_size);
        return true;
    }
    m_byte_size = 0;
    return false;
}

uint8_t *
BreakpointSite::GetSavedOpcodeBytes()
{
    return &m_saved_opcode[0];
}

const uint8_t *
BreakpointSite::GetSavedOpcodeBytes() const
{
    return &m_saved_opcode[0];
}

bool
BreakpointSite::IsEnabled () const
{
    return m_enabled;
}

void
BreakpointSite::SetEnabled (bool enabled)
{
    m_enabled = enabled;
}

void
BreakpointSite::AddOwner (const BreakpointLocationSP &owner)
{
    m_owners.Add(owner);
}

uint32_t
BreakpointSite::RemoveOwner (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
{
    m_owners.Remove(break_id, break_loc_id);
    return m_owners.GetSize();
}

uint32_t
BreakpointSite::GetNumberOfOwners ()
{
    return m_owners.GetSize();
}

BreakpointLocationSP
BreakpointSite::GetOwnerAtIndex (uint32_t index)
{
    return m_owners.GetByIndex (index);
}

bool
BreakpointSite::ValidForThisThread (Thread *thread)
{
    return m_owners.ValidForThisThread(thread);
}

bool
BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size, lldb::addr_t *intersect_addr, size_t *intersect_size, size_t *opcode_offset) const
{
    // We only use software traps for software breakpoints
    if (!IsHardware())
    {
        if (m_byte_size > 0)
        {
            const lldb::addr_t bp_end_addr = m_addr + m_byte_size;
            const lldb::addr_t end_addr = addr + size;
            // Is the breakpoint end address before the passed in start address?
            if (bp_end_addr <= addr)
                return false;
            // Is the breakpoint start address after passed in end address?
            if (end_addr <= m_addr)
                return false;
            if (intersect_addr || intersect_size || opcode_offset)
            {
                if (m_addr < addr)
                {
                    if (intersect_addr)
                        *intersect_addr = addr;
                    if (intersect_size)
                        *intersect_size = std::min<lldb::addr_t>(bp_end_addr, end_addr) - addr;
                    if (opcode_offset)
                        *opcode_offset = addr - m_addr;
                }
                else
                {
                    if (intersect_addr)
                        *intersect_addr = m_addr;
                    if (intersect_size)
                        *intersect_size = std::min<lldb::addr_t>(bp_end_addr, end_addr) - m_addr;
                    if (opcode_offset)
                        *opcode_offset = 0;
                }
            }
            return true;
        }
    }
    return false;
}
