130fdc8d8SChris Lattner //===-- BreakpointSite.cpp --------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointSite.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h" 1730fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointSiteList.h" 1830fdc8d8SChris Lattner 1930fdc8d8SChris Lattner using namespace lldb; 2030fdc8d8SChris Lattner using namespace lldb_private; 2130fdc8d8SChris Lattner 2230fdc8d8SChris Lattner BreakpointSite::BreakpointSite 2330fdc8d8SChris Lattner ( 2430fdc8d8SChris Lattner BreakpointSiteList *list, 2530fdc8d8SChris Lattner BreakpointLocationSP& owner, 2630fdc8d8SChris Lattner lldb::addr_t addr, 2730fdc8d8SChris Lattner lldb::tid_t tid, 2830fdc8d8SChris Lattner bool use_hardware 2930fdc8d8SChris Lattner ) : 3030fdc8d8SChris Lattner StoppointLocation(GetNextID(), addr, tid, use_hardware), 3130fdc8d8SChris Lattner m_type (eSoftware), // Process subclasses need to set this correctly using SetType() 3230fdc8d8SChris Lattner m_saved_opcode(), 3330fdc8d8SChris Lattner m_trap_opcode(), 3430fdc8d8SChris Lattner m_enabled(false), // Need to create it disabled, so the first enable turns it on. 3530fdc8d8SChris Lattner m_owners() 3630fdc8d8SChris Lattner { 3730fdc8d8SChris Lattner m_owners.Add(owner); 3830fdc8d8SChris Lattner } 3930fdc8d8SChris Lattner 4030fdc8d8SChris Lattner BreakpointSite::~BreakpointSite() 4130fdc8d8SChris Lattner { 4230fdc8d8SChris Lattner BreakpointLocationSP bp_loc_sp; 4330fdc8d8SChris Lattner for (int i = 0; i < m_owners.GetSize(); i++) 4430fdc8d8SChris Lattner { 4530fdc8d8SChris Lattner m_owners.GetByIndex(i)->ClearBreakpointSite(); 4630fdc8d8SChris Lattner } 4730fdc8d8SChris Lattner } 4830fdc8d8SChris Lattner 4930fdc8d8SChris Lattner break_id_t 5030fdc8d8SChris Lattner BreakpointSite::GetNextID() 5130fdc8d8SChris Lattner { 5230fdc8d8SChris Lattner static break_id_t g_next_id = 0; 5330fdc8d8SChris Lattner return ++g_next_id; 5430fdc8d8SChris Lattner } 5530fdc8d8SChris Lattner 5630fdc8d8SChris Lattner // RETURNS - true if we should stop at this breakpoint, false if we 5730fdc8d8SChris Lattner // should continue. 5830fdc8d8SChris Lattner 5930fdc8d8SChris Lattner bool 6030fdc8d8SChris Lattner BreakpointSite::ShouldStop (StoppointCallbackContext *context) 6130fdc8d8SChris Lattner { 6230fdc8d8SChris Lattner m_hit_count++; 6330fdc8d8SChris Lattner return m_owners.ShouldStop (context); 6430fdc8d8SChris Lattner } 6530fdc8d8SChris Lattner 6630fdc8d8SChris Lattner bool 6730fdc8d8SChris Lattner BreakpointSite::IsBreakpointAtThisSite (lldb::break_id_t bp_id) 6830fdc8d8SChris Lattner { 6930fdc8d8SChris Lattner for (int i = 0; i < m_owners.GetSize(); i++) 7030fdc8d8SChris Lattner { 7130fdc8d8SChris Lattner if (m_owners.GetByIndex(i)->GetBreakpoint().GetID() == bp_id) 7230fdc8d8SChris Lattner return true; 7330fdc8d8SChris Lattner } 7430fdc8d8SChris Lattner return false; 7530fdc8d8SChris Lattner } 7630fdc8d8SChris Lattner 7730fdc8d8SChris Lattner void 7830fdc8d8SChris Lattner BreakpointSite::Dump(Stream *s) const 7930fdc8d8SChris Lattner { 8030fdc8d8SChris Lattner if (s == NULL) 8130fdc8d8SChris Lattner return; 8230fdc8d8SChris Lattner 83*1b54c88cSJim Ingham s->Printf("BreakpointSite %u: addr = 0x%8.8llx type = %s breakpoint hw_index = %i hit_count = %-4u", 8430fdc8d8SChris Lattner GetID(), 8530fdc8d8SChris Lattner (uint64_t)m_addr, 8630fdc8d8SChris Lattner IsHardware() ? "hardware" : "software", 8730fdc8d8SChris Lattner GetHardwareIndex(), 8830fdc8d8SChris Lattner GetHitCount()); 8930fdc8d8SChris Lattner } 9030fdc8d8SChris Lattner 9130fdc8d8SChris Lattner void 9230fdc8d8SChris Lattner BreakpointSite::GetDescription (Stream *s, lldb::DescriptionLevel level) 9330fdc8d8SChris Lattner { 9430fdc8d8SChris Lattner if (level != lldb::eDescriptionLevelBrief) 9530fdc8d8SChris Lattner s->Printf ("breakpoint site: %d ", GetID()); 9630fdc8d8SChris Lattner m_owners.GetDescription (s, level); 9730fdc8d8SChris Lattner } 9830fdc8d8SChris Lattner 9930fdc8d8SChris Lattner uint8_t * 10030fdc8d8SChris Lattner BreakpointSite::GetTrapOpcodeBytes() 10130fdc8d8SChris Lattner { 10230fdc8d8SChris Lattner return &m_trap_opcode[0]; 10330fdc8d8SChris Lattner } 10430fdc8d8SChris Lattner 10530fdc8d8SChris Lattner const uint8_t * 10630fdc8d8SChris Lattner BreakpointSite::GetTrapOpcodeBytes() const 10730fdc8d8SChris Lattner { 10830fdc8d8SChris Lattner return &m_trap_opcode[0]; 10930fdc8d8SChris Lattner } 11030fdc8d8SChris Lattner 11130fdc8d8SChris Lattner size_t 11230fdc8d8SChris Lattner BreakpointSite::GetTrapOpcodeMaxByteSize() const 11330fdc8d8SChris Lattner { 11430fdc8d8SChris Lattner return sizeof(m_trap_opcode); 11530fdc8d8SChris Lattner } 11630fdc8d8SChris Lattner 11730fdc8d8SChris Lattner bool 11830fdc8d8SChris Lattner BreakpointSite::SetTrapOpcode (const uint8_t *trap_opcode, size_t trap_opcode_size) 11930fdc8d8SChris Lattner { 12030fdc8d8SChris Lattner if (trap_opcode_size > 0 && trap_opcode_size <= sizeof(m_trap_opcode)) 12130fdc8d8SChris Lattner { 12230fdc8d8SChris Lattner m_byte_size = trap_opcode_size; 12330fdc8d8SChris Lattner ::memcpy (m_trap_opcode, trap_opcode, trap_opcode_size); 12430fdc8d8SChris Lattner return true; 12530fdc8d8SChris Lattner } 12630fdc8d8SChris Lattner m_byte_size = 0; 12730fdc8d8SChris Lattner return false; 12830fdc8d8SChris Lattner } 12930fdc8d8SChris Lattner 13030fdc8d8SChris Lattner uint8_t * 13130fdc8d8SChris Lattner BreakpointSite::GetSavedOpcodeBytes() 13230fdc8d8SChris Lattner { 13330fdc8d8SChris Lattner return &m_saved_opcode[0]; 13430fdc8d8SChris Lattner } 13530fdc8d8SChris Lattner 13630fdc8d8SChris Lattner const uint8_t * 13730fdc8d8SChris Lattner BreakpointSite::GetSavedOpcodeBytes() const 13830fdc8d8SChris Lattner { 13930fdc8d8SChris Lattner return &m_saved_opcode[0]; 14030fdc8d8SChris Lattner } 14130fdc8d8SChris Lattner 14230fdc8d8SChris Lattner bool 14330fdc8d8SChris Lattner BreakpointSite::IsEnabled () const 14430fdc8d8SChris Lattner { 14530fdc8d8SChris Lattner return m_enabled; 14630fdc8d8SChris Lattner } 14730fdc8d8SChris Lattner 14830fdc8d8SChris Lattner void 14930fdc8d8SChris Lattner BreakpointSite::SetEnabled (bool enabled) 15030fdc8d8SChris Lattner { 15130fdc8d8SChris Lattner m_enabled = enabled; 15230fdc8d8SChris Lattner } 15330fdc8d8SChris Lattner 15430fdc8d8SChris Lattner void 15530fdc8d8SChris Lattner BreakpointSite::AddOwner (BreakpointLocationSP &owner) 15630fdc8d8SChris Lattner { 15730fdc8d8SChris Lattner m_owners.Add(owner); 15830fdc8d8SChris Lattner } 15930fdc8d8SChris Lattner 16030fdc8d8SChris Lattner uint32_t 16130fdc8d8SChris Lattner BreakpointSite::RemoveOwner (lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 16230fdc8d8SChris Lattner { 16330fdc8d8SChris Lattner m_owners.Remove(break_id, break_loc_id); 16430fdc8d8SChris Lattner return m_owners.GetSize(); 16530fdc8d8SChris Lattner } 16630fdc8d8SChris Lattner 16730fdc8d8SChris Lattner uint32_t 16830fdc8d8SChris Lattner BreakpointSite::GetNumberOfOwners () 16930fdc8d8SChris Lattner { 17030fdc8d8SChris Lattner return m_owners.GetSize(); 17130fdc8d8SChris Lattner } 17230fdc8d8SChris Lattner 17330fdc8d8SChris Lattner BreakpointLocationSP 17430fdc8d8SChris Lattner BreakpointSite::GetOwnerAtIndex (uint32_t index) 17530fdc8d8SChris Lattner { 17630fdc8d8SChris Lattner return m_owners.GetByIndex (index); 17730fdc8d8SChris Lattner } 17830fdc8d8SChris Lattner 17930fdc8d8SChris Lattner bool 180*1b54c88cSJim Ingham BreakpointSite::ValidForThisThread (Thread *thread) 181*1b54c88cSJim Ingham { 182*1b54c88cSJim Ingham return m_owners.ValidForThisThread(thread); 183*1b54c88cSJim Ingham } 184*1b54c88cSJim Ingham 185*1b54c88cSJim Ingham bool 18630fdc8d8SChris Lattner BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size, lldb::addr_t *intersect_addr, size_t *intersect_size, size_t *opcode_offset) const 18730fdc8d8SChris Lattner { 18830fdc8d8SChris Lattner // We only use software traps for software breakpoints 18930fdc8d8SChris Lattner if (!IsHardware()) 19030fdc8d8SChris Lattner { 19130fdc8d8SChris Lattner if (m_byte_size > 0) 19230fdc8d8SChris Lattner { 19330fdc8d8SChris Lattner const lldb::addr_t bp_end_addr = m_addr + m_byte_size; 19430fdc8d8SChris Lattner const lldb::addr_t end_addr = addr + size; 19530fdc8d8SChris Lattner // Is the breakpoint end address before the passed in start address? 19630fdc8d8SChris Lattner if (bp_end_addr <= addr) 19730fdc8d8SChris Lattner return false; 19830fdc8d8SChris Lattner // Is the breakpoint start address after passed in end address? 19930fdc8d8SChris Lattner if (end_addr <= m_addr) 20030fdc8d8SChris Lattner return false; 20130fdc8d8SChris Lattner if (intersect_addr || intersect_size || opcode_offset) 20230fdc8d8SChris Lattner { 20330fdc8d8SChris Lattner if (m_addr < addr) 20430fdc8d8SChris Lattner { 20530fdc8d8SChris Lattner if (intersect_addr) 20630fdc8d8SChris Lattner *intersect_addr = addr; 20730fdc8d8SChris Lattner if (intersect_size) 20830fdc8d8SChris Lattner *intersect_size = std::min<lldb::addr_t>(bp_end_addr, end_addr) - addr; 20930fdc8d8SChris Lattner if (opcode_offset) 21030fdc8d8SChris Lattner *opcode_offset = addr - m_addr; 21130fdc8d8SChris Lattner } 21230fdc8d8SChris Lattner else 21330fdc8d8SChris Lattner { 21430fdc8d8SChris Lattner if (intersect_addr) 21530fdc8d8SChris Lattner *intersect_addr = m_addr; 21630fdc8d8SChris Lattner if (intersect_size) 21730fdc8d8SChris Lattner *intersect_size = std::min<lldb::addr_t>(bp_end_addr, end_addr) - m_addr; 21830fdc8d8SChris Lattner if (opcode_offset) 21930fdc8d8SChris Lattner *opcode_offset = 0; 22030fdc8d8SChris Lattner } 22130fdc8d8SChris Lattner } 22230fdc8d8SChris Lattner return true; 22330fdc8d8SChris Lattner } 22430fdc8d8SChris Lattner } 22530fdc8d8SChris Lattner return false; 22630fdc8d8SChris Lattner } 227