DNBBreakpoint.h revision 24943d2ee8bfaa7cf5893e4709143924157a5c1e
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DNBBreakpoint.h -----------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Created by Greg Clayton on 6/29/07. 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef __DNBBreakpoint_h__ 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define __DNBBreakpoint_h__ 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <list> 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DNBDefs.h" 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass DNBBreakpoint 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic: 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DNBBreakpoint(nub_addr_t m_addr, nub_size_t byte_size, nub_thread_t tid, bool hardware); 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ~DNBBreakpoint(); 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_break_t GetID() const { return m_breakID; } 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_size_t ByteSize() const { return m_byte_size; } 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t * SavedOpcodeBytes() { return &m_opcode[0]; } 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const uint8_t * 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SavedOpcodeBytes() const { return &m_opcode[0]; } 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_addr_t Address() const { return m_addr; } 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_thread_t ThreadID() const { return m_tid; } 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool IsEnabled() const { return m_enabled; } 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 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 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // We only use software traps for software breakpoints 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (IsBreakpoint() && IsEnabled() && !IsHardware()) 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_byte_size > 0) 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const nub_addr_t bp_end_addr = m_addr + m_byte_size; 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const nub_addr_t end_addr = addr + size; 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Is the breakpoint end address before the passed in start address? 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (bp_end_addr <= addr) 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Is the breakpoint start address after passed in end address? 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (end_addr <= m_addr) 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (intersect_addr || intersect_size || opcode_offset) 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (m_addr < addr) 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (intersect_addr) 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *intersect_addr = addr; 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (intersect_size) 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *intersect_size = std::min<nub_addr_t>(bp_end_addr, end_addr) - addr; 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (opcode_offset) 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *opcode_offset = addr - m_addr; 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner else 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (intersect_addr) 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *intersect_addr = m_addr; 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (intersect_size) 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *intersect_size = std::min<nub_addr_t>(bp_end_addr, end_addr) - m_addr; 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (opcode_offset) 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner *opcode_offset = 0; 6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void SetEnabled(uint32_t enabled) 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!enabled) 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SetHardwareIndex(INVALID_NUB_HW_INDEX); 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_enabled = enabled; 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void SetIsWatchpoint (uint32_t type) 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_is_watchpoint = 1; 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_watch_read = (type & WATCH_TYPE_READ) != 0; 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_watch_write = (type & WATCH_TYPE_WRITE) != 0; 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool IsBreakpoint() const { return m_is_watchpoint == 0; } 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool IsWatchpoint() const { return m_is_watchpoint == 1; } 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool WatchpointRead() const { return m_watch_read != 0; } 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool WatchpointWrite() const { return m_watch_write != 0; } 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool HardwarePreferred() const { return m_hw_preferred; } 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool IsHardware() const { return m_hw_index != INVALID_NUB_HW_INDEX; } 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t GetHardwareIndex() const { return m_hw_index; } 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void SetHardwareIndex(uint32_t hw_index) { m_hw_index = hw_index; } 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// StateType GetState() const { return m_state; } 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// void SetState(StateType newState) { m_state = newState; } 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int32_t GetHitCount() const { return m_hit_count; } 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int32_t GetIgnoreCount() const { return m_ignore_count; } 10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void SetIgnoreCount(int32_t n) { m_ignore_count = n; } 10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool BreakpointHit(nub_process_t pid, nub_thread_t tid); 10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void SetCallback(DNBCallbackBreakpointHit callback, void *callback_baton); 10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void Dump() const; 10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate: 10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_break_t m_breakID; // The unique identifier for this breakpoint 10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_thread_t m_tid; // Thread ID for the breakpoint (can be INVALID_NUB_THREAD for all threads) 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_size_t m_byte_size; // Length in bytes of the breakpoint if set in memory 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint8_t m_opcode[8]; // Saved opcode bytes 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_addr_t m_addr; // Address of this breakpoint 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t m_enabled:1, // Flags for this breakpoint 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_hw_preferred:1, // 1 if this point has been requested to be set using hardware (which may fail due to lack of resources) 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_is_watchpoint:1, // 1 if this is a watchpoint 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_watch_read:1, // 1 if we stop when the watched data is read from 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_watch_write:1; // 1 if we stop when the watched data is written to 11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t m_hw_index; // The hardware resource index for this breakpoint/watchpoint 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int32_t m_hit_count; // Number of times this breakpoint has been hit 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int32_t m_ignore_count; // Number of times to ignore this breakpoint 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DNBCallbackBreakpointHit 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_callback; // Callback to call when this breakpoint gets hit 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void * m_callback_baton; // Callback user data to pass to callback 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner static nub_break_t GetNextID(); 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}; 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass DNBBreakpointList 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic: 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DNBBreakpointList(); 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ~DNBBreakpointList(); 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_break_t Add (const DNBBreakpoint& bp); 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner nub_break_t FindIDByAddress (nub_addr_t addr); 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool ShouldStop (nub_process_t pid, nub_thread_t tid, nub_break_t breakID); 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool Remove (nub_break_t breakID); 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool SetCallback (nub_break_t breakID, DNBCallbackBreakpointHit callback, void *callback_baton); 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DNBBreakpoint * FindByAddress (nub_addr_t addr); 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const DNBBreakpoint * FindByAddress (nub_addr_t addr) const; 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DNBBreakpoint * FindByID (nub_break_t breakID); 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const DNBBreakpoint * FindByID (nub_break_t breakID) const; 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void Dump () const; 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner size_t Size() const { return m_breakpoints.size(); } 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DNBBreakpoint * GetByIndex (uint32_t i); 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const DNBBreakpoint * GetByIndex (uint32_t i) const; 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprotected: 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner typedef std::list<DNBBreakpoint> collection; 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner typedef collection::iterator iterator; 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner typedef collection::const_iterator const_iterator; 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner iterator GetBreakIDIterator(nub_break_t breakID); 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const_iterator GetBreakIDConstIterator(nub_break_t breakID) const; 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner collection m_breakpoints; 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}; 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 160