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


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

#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"


using namespace lldb;
using namespace lldb_private;

BreakpointLocationList::BreakpointLocationList(Breakpoint &owner) :
    m_owner (owner),
    m_locations(),
    m_address_to_location (),
    m_mutex (Mutex::eMutexTypeRecursive),
    m_next_id (0),
    m_new_location_recorder (NULL)
{
}

BreakpointLocationList::~BreakpointLocationList()
{
}

BreakpointLocationSP
BreakpointLocationList::Create (const Address &addr, bool resolve_indirect_symbols)
{
    Mutex::Locker locker (m_mutex);
    // The location ID is just the size of the location list + 1
    lldb::break_id_t bp_loc_id = ++m_next_id;
    BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID, m_owner.IsHardware(), resolve_indirect_symbols));
    m_locations.push_back (bp_loc_sp);
    m_address_to_location[addr] = bp_loc_sp;
    return bp_loc_sp;
}

bool
BreakpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::break_id_t break_id)
{
    BreakpointLocationSP bp = FindByID (break_id);
    if (bp)
    {
        // Let the BreakpointLocation decide if it should stop here (could not have
        // reached it's target hit count yet, or it could have a callback
        // that decided it shouldn't stop (shared library loads/unloads).
        return bp->ShouldStop (context);
    }
    // We should stop here since this BreakpointLocation isn't valid anymore or it
    // doesn't exist.
    return true;
}

lldb::break_id_t
BreakpointLocationList::FindIDByAddress (const Address &addr)
{
    BreakpointLocationSP bp_loc_sp = FindByAddress (addr);
    if (bp_loc_sp)
    {
        return bp_loc_sp->GetID();
    }
    return LLDB_INVALID_BREAK_ID;
}

static bool
Compare (BreakpointLocationSP lhs, lldb::break_id_t val)
{
    return lhs->GetID() < val;
}

BreakpointLocationSP
BreakpointLocationList::FindByID (lldb::break_id_t break_id) const
{
    Mutex::Locker locker (m_mutex);
    collection::const_iterator end = m_locations.end();
    collection::const_iterator pos = std::lower_bound(m_locations.begin(), end, break_id, Compare);
    if (pos != end && (*pos)->GetID() == break_id)
        return *(pos);
    else
        return BreakpointLocationSP();
}

size_t
BreakpointLocationList::FindInModule (Module *module,
                                      BreakpointLocationCollection& bp_loc_list)
{
    Mutex::Locker locker (m_mutex);
    const size_t orig_size = bp_loc_list.GetSize();
    collection::iterator pos, end = m_locations.end();

    for (pos = m_locations.begin(); pos != end; ++pos)
    {
        BreakpointLocationSP break_loc = (*pos);
        SectionSP section_sp (break_loc->GetAddress().GetSection());
        if (section_sp && section_sp->GetModule().get() == module)
        {
            bp_loc_list.Add (break_loc);
        }
    }
    return bp_loc_list.GetSize() - orig_size;
}

const BreakpointLocationSP
BreakpointLocationList::FindByAddress (const Address &addr) const
{
    Mutex::Locker locker (m_mutex);
    BreakpointLocationSP bp_loc_sp;
    if (!m_locations.empty())
    {
        Address so_addr;

        if (addr.IsSectionOffset())
        {
            so_addr = addr;
        }
        else
        {
            // Try and resolve as a load address if possible.
            m_owner.GetTarget().GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), so_addr);
            if (!so_addr.IsValid())
            {    
                // The address didn't resolve, so just set to passed in addr.
                so_addr = addr;
            }
        }

        addr_map::const_iterator pos = m_address_to_location.find (so_addr);
        if (pos != m_address_to_location.end())
            bp_loc_sp = pos->second;
    }

    return bp_loc_sp;
}

void
BreakpointLocationList::Dump (Stream *s) const
{
    s->Printf("%p: ", static_cast<const void*>(this));
    //s->Indent();
    Mutex::Locker locker (m_mutex);
    s->Printf("BreakpointLocationList with %" PRIu64 " BreakpointLocations:\n", (uint64_t)m_locations.size());
    s->IndentMore();
    collection::const_iterator pos, end = m_locations.end();
    for (pos = m_locations.begin(); pos != end; ++pos)
        (*pos).get()->Dump(s);
    s->IndentLess();
}


BreakpointLocationSP
BreakpointLocationList::GetByIndex (size_t i)
{
    Mutex::Locker locker (m_mutex);
    BreakpointLocationSP bp_loc_sp;
    if (i < m_locations.size())
        bp_loc_sp = m_locations[i];

    return bp_loc_sp;
}

const BreakpointLocationSP
BreakpointLocationList::GetByIndex (size_t i) const
{
    Mutex::Locker locker (m_mutex);
    BreakpointLocationSP bp_loc_sp;
    if (i < m_locations.size())
        bp_loc_sp = m_locations[i];

    return bp_loc_sp;
}

void
BreakpointLocationList::ClearAllBreakpointSites ()
{
    Mutex::Locker locker (m_mutex);
    collection::iterator pos, end = m_locations.end();
    for (pos = m_locations.begin(); pos != end; ++pos)
        (*pos)->ClearBreakpointSite();
}

void
BreakpointLocationList::ResolveAllBreakpointSites ()
{
    Mutex::Locker locker (m_mutex);
    collection::iterator pos, end = m_locations.end();

    for (pos = m_locations.begin(); pos != end; ++pos)
    {
        if ((*pos)->IsEnabled())
            (*pos)->ResolveBreakpointSite();
    }
}

uint32_t
BreakpointLocationList::GetHitCount () const
{
    uint32_t hit_count = 0;
    Mutex::Locker locker (m_mutex);
    collection::const_iterator pos, end = m_locations.end();
    for (pos = m_locations.begin(); pos != end; ++pos)
        hit_count += (*pos)->GetHitCount();
    return hit_count;
}

size_t
BreakpointLocationList::GetNumResolvedLocations() const
{
    Mutex::Locker locker (m_mutex);
    size_t resolve_count = 0;
    collection::const_iterator pos, end = m_locations.end();
    for (pos = m_locations.begin(); pos != end; ++pos)
    {
        if ((*pos)->IsResolved())
            ++resolve_count;
    }
    return resolve_count;
}

void
BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    Mutex::Locker locker (m_mutex);
    collection::iterator pos, end = m_locations.end();

    for (pos = m_locations.begin(); pos != end; ++pos)
    {
        s->Printf(" ");
        (*pos)->GetDescription(s, level);
    }
}

BreakpointLocationSP
BreakpointLocationList::AddLocation (const Address &addr, bool resolve_indirect_symbols, bool *new_location)
{
    Mutex::Locker locker (m_mutex);

    if (new_location)
        *new_location = false;
    BreakpointLocationSP bp_loc_sp (FindByAddress(addr));
    if (!bp_loc_sp)
	{
		bp_loc_sp = Create (addr, resolve_indirect_symbols);
		if (bp_loc_sp)
		{
	    	bp_loc_sp->ResolveBreakpointSite();

		    if (new_location)
	    	    *new_location = true;
            if(m_new_location_recorder)
            {
                m_new_location_recorder->Add(bp_loc_sp);
            }
		}
	}
    return bp_loc_sp;
}

void
BreakpointLocationList::SwapLocation (BreakpointLocationSP to_location_sp, BreakpointLocationSP from_location_sp)
{
    if (!from_location_sp || !to_location_sp)
        return;
    
    m_address_to_location.erase(to_location_sp->GetAddress());
    to_location_sp->SwapLocation(from_location_sp);
    RemoveLocation(from_location_sp);
    m_address_to_location[to_location_sp->GetAddress()] = to_location_sp;
    to_location_sp->ResolveBreakpointSite();
}


bool
BreakpointLocationList::RemoveLocation (const lldb::BreakpointLocationSP &bp_loc_sp)
{
    if (bp_loc_sp)
    {
        Mutex::Locker locker (m_mutex);
        
        m_address_to_location.erase (bp_loc_sp->GetAddress());

        collection::iterator pos, end = m_locations.end();
        for (pos = m_locations.begin(); pos != end; ++pos)
        {
            if ((*pos).get() == bp_loc_sp.get())
            {
                m_locations.erase (pos);
                return true;
            }
        }
	}
    return false;
}

void
BreakpointLocationList::RemoveInvalidLocations (const ArchSpec &arch)
{
    Mutex::Locker locker (m_mutex);
    size_t idx = 0;
    // Don't cache m_location.size() as it will change since we might
    // remove locations from our vector...
    while (idx < m_locations.size())
    {
        BreakpointLocation *bp_loc = m_locations[idx].get();
        if (bp_loc->GetAddress().SectionWasDeleted())
        {
            // Section was deleted which means this breakpoint comes from a module
            // that is no longer valid, so we should remove it.
            m_locations.erase(m_locations.begin() + idx);
            continue;
        }
        if (arch.IsValid())
        {
            ModuleSP module_sp (bp_loc->GetAddress().GetModule());
            if (module_sp)
            {
                if (!arch.IsCompatibleMatch(module_sp->GetArchitecture()))
                {
                    // The breakpoint was in a module whose architecture is no longer
                    // compatible with "arch", so we need to remove it
                    m_locations.erase(m_locations.begin() + idx);
                    continue;
                }
            }
        }
        // Only increment the index if we didn't remove the locations at index "idx"
        ++idx;
    }
}

void
BreakpointLocationList::StartRecordingNewLocations (BreakpointLocationCollection &new_locations)
{
    Mutex::Locker locker (m_mutex);
    assert (m_new_location_recorder == NULL);
    m_new_location_recorder = &new_locations;
}

void
BreakpointLocationList::StopRecordingNewLocations ()
{
    Mutex::Locker locker (m_mutex);
    m_new_location_recorder = NULL;
}

void
BreakpointLocationList::Compact()
{
    lldb::break_id_t highest_id = 0;
    
    for (BreakpointLocationSP loc_sp : m_locations)
    {
        lldb::break_id_t cur_id = loc_sp->GetID();
        if (cur_id > highest_id)
            highest_id = cur_id;
    }
    m_next_id = highest_id;
}
