//===-- DNBBreakpoint.h -----------------------------------------*- 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.
//
//===----------------------------------------------------------------------===//

#ifndef __DNBBreakpoint_h__
#define __DNBBreakpoint_h__

#include <mach/mach.h>

#include <map>
#include <vector>

#include "DNBDefs.h"

class MachProcess;

class DNBBreakpoint
{
public:
    DNBBreakpoint(nub_addr_t m_addr, nub_size_t byte_size, bool hardware);
    ~DNBBreakpoint();

    nub_size_t  ByteSize() const { return m_byte_size; }
    uint8_t *   SavedOpcodeBytes() { return &m_opcode[0]; }
    const uint8_t *
                SavedOpcodeBytes() const { return &m_opcode[0]; }
    nub_addr_t  Address() const { return m_addr; }
//    nub_thread_t ThreadID() const { return m_tid; }
    bool        IsEnabled() const { return m_enabled; }
    bool        IntersectsRange(nub_addr_t addr,
                                nub_size_t size,
                                nub_addr_t *intersect_addr,
                                nub_size_t *intersect_size,
                                nub_size_t *opcode_offset) const
                {
                    // We only use software traps for software breakpoints
                    if (IsBreakpoint() && IsEnabled() && !IsHardware())
                    {
                        if (m_byte_size > 0)
                        {
                            const nub_addr_t bp_end_addr = m_addr + m_byte_size;
                            const nub_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<nub_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<nub_addr_t>(bp_end_addr, end_addr) - m_addr;
                                    if (opcode_offset)
                                        *opcode_offset = 0;
                                }
                            }
                            return true;
                        }
                    }
                    return false;
                }
    void        SetEnabled(bool enabled)
                {
                    if (!enabled)
                        SetHardwareIndex(INVALID_NUB_HW_INDEX);
                    m_enabled = enabled;
                }
    void        SetIsWatchpoint (uint32_t type)
                {
                    m_is_watchpoint = 1;
                    m_watch_read = (type & WATCH_TYPE_READ) != 0;
                    m_watch_write = (type & WATCH_TYPE_WRITE) != 0;
                }
    bool        IsBreakpoint() const { return m_is_watchpoint == 0; }
    bool        IsWatchpoint() const { return m_is_watchpoint == 1; }
    bool        WatchpointRead() const { return m_watch_read != 0; }
    bool        WatchpointWrite() const { return m_watch_write != 0; }
    bool        HardwarePreferred() const { return m_hw_preferred; }
    bool        IsHardware() const { return m_hw_index != INVALID_NUB_HW_INDEX; }
    uint32_t    GetHardwareIndex() const { return m_hw_index; }
    void        SetHardwareIndex(uint32_t hw_index) { m_hw_index = hw_index; }
    void        Dump() const;
    uint32_t    Retain ()
                {
                    return ++m_retain_count;
                }
    uint32_t    Release ()
                {
                    if (m_retain_count == 0)
                        return 0;
                    return --m_retain_count;
                }

private:
    uint32_t    m_retain_count;     // Each breakpoint is maintained by address and is ref counted in case multiple people set a breakpoint at the same address
    uint32_t    m_byte_size;        // Length in bytes of the breakpoint if set in memory
    uint8_t     m_opcode[8];        // Saved opcode bytes
    nub_addr_t  m_addr;             // Address of this breakpoint
    uint32_t    m_enabled:1,        // Flags for this breakpoint
                m_hw_preferred:1,   // 1 if this point has been requested to be set using hardware (which may fail due to lack of resources)
                m_is_watchpoint:1,  // 1 if this is a watchpoint
                m_watch_read:1,     // 1 if we stop when the watched data is read from
                m_watch_write:1;    // 1 if we stop when the watched data is written to
    uint32_t    m_hw_index;         // The hardware resource index for this breakpoint/watchpoint
};


class DNBBreakpointList
{
public:
                                DNBBreakpointList();
                                ~DNBBreakpointList();

            DNBBreakpoint *     Add (nub_addr_t addr, nub_size_t length, bool hardware);
            bool                Remove (nub_addr_t addr);
            DNBBreakpoint *     FindByAddress (nub_addr_t addr);
    const   DNBBreakpoint *     FindByAddress (nub_addr_t addr) const;

            size_t              FindBreakpointsThatOverlapRange (nub_addr_t addr,
                                                                 nub_addr_t size,
                                                                 std::vector<DNBBreakpoint *> &bps);

            void                Dump () const;

            size_t              Size() const { return m_breakpoints.size(); }
            void                DisableAll ();

            void                RemoveTrapsFromBuffer (nub_addr_t addr,
                                                       nub_size_t size,
                                                       void *buf) const;

            void                DisableAllBreakpoints (MachProcess *process);
            void                DisableAllWatchpoints(MachProcess *process);
            void                RemoveDisabled ();
protected:
    typedef std::map<nub_addr_t, DNBBreakpoint> collection;
    typedef collection::iterator        iterator;
    typedef collection::const_iterator  const_iterator;
            collection                  m_breakpoints;
};

#endif

