//===-- 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
#include <inttypes.h>

// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSiteList.h"
#include "lldb/Core/Stream.h"

using namespace lldb;
using namespace lldb_private;

BreakpointSite::BreakpointSite
(
    BreakpointSiteList *list,
    const BreakpointLocationSP& owner,
    lldb::addr_t addr,
    bool use_hardware
) :
    StoppointLocation(GetNextID(), addr, 0, 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_mutex(Mutex::eMutexTypeRecursive)
{
    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)
{
    Mutex::Locker locker(m_owners_mutex);
    IncrementHitCount();
    return m_owners.ShouldStop (context);
}

bool
BreakpointSite::IsBreakpointAtThisSite (lldb::break_id_t bp_id)
{
    Mutex::Locker locker(m_owners_mutex);
    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)
{
    Mutex::Locker locker(m_owners_mutex);
    if (level != lldb::eDescriptionLevelBrief)
        s->Printf ("breakpoint site: %d at 0x%8.8" PRIx64, GetID(), GetLoadAddress());
    m_owners.GetDescription (s, level);
}

bool
BreakpointSite::IsInternal() const
{
    return m_owners.IsInternal();
}

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, uint32_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)
{
    Mutex::Locker locker(m_owners_mutex);
    m_owners.Add(owner);
}

size_t
BreakpointSite::RemoveOwner (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
{
    Mutex::Locker locker(m_owners_mutex);
    m_owners.Remove(break_id, break_loc_id);
    return m_owners.GetSize();
}

size_t
BreakpointSite::GetNumberOfOwners ()
{
    Mutex::Locker locker(m_owners_mutex);
    return m_owners.GetSize();
}

BreakpointLocationSP
BreakpointSite::GetOwnerAtIndex (size_t index)
{
    Mutex::Locker locker(m_owners_mutex);
    return m_owners.GetByIndex (index);
}

bool
BreakpointSite::ValidForThisThread (Thread *thread)
{
    Mutex::Locker locker(m_owners_mutex);
    return m_owners.ValidForThisThread(thread);
}

void
BreakpointSite::BumpHitCounts()
{
    for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations())
    {
        loc_sp->BumpHitCount();
    }
}

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;
}
