230 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- 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
 | 
						|
// Other libraries and framework includes
 | 
						|
// Project includes
 | 
						|
#include "lldb/Breakpoint/Breakpoint.h"
 | 
						|
#include "lldb/Breakpoint/BreakpointLocation.h"
 | 
						|
#include "lldb/Breakpoint/BreakpointSiteList.h"
 | 
						|
 | 
						|
using namespace lldb;
 | 
						|
using namespace lldb_private;
 | 
						|
 | 
						|
BreakpointSite::BreakpointSite
 | 
						|
(
 | 
						|
    BreakpointSiteList *list,
 | 
						|
    BreakpointLocationSP& owner,
 | 
						|
    lldb::addr_t addr,
 | 
						|
    lldb::tid_t tid,
 | 
						|
    bool use_hardware
 | 
						|
) :
 | 
						|
    StoppointLocation(GetNextID(), addr, tid, 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.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)
 | 
						|
{
 | 
						|
    m_hit_count++;
 | 
						|
    return m_owners.ShouldStop (context);
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
BreakpointSite::IsBreakpointAtThisSite (lldb::break_id_t bp_id)
 | 
						|
{
 | 
						|
    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.8llx  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)
 | 
						|
{
 | 
						|
    if (level != lldb::eDescriptionLevelBrief)
 | 
						|
        s->Printf ("breakpoint site: %d ", GetID());
 | 
						|
    m_owners.GetDescription (s, level);
 | 
						|
}
 | 
						|
 | 
						|
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, size_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 (BreakpointLocationSP &owner)
 | 
						|
{
 | 
						|
    m_owners.Add(owner);
 | 
						|
}
 | 
						|
 | 
						|
uint32_t
 | 
						|
BreakpointSite::RemoveOwner (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
 | 
						|
{
 | 
						|
    m_owners.Remove(break_id, break_loc_id);
 | 
						|
    return m_owners.GetSize();
 | 
						|
}
 | 
						|
 | 
						|
uint32_t
 | 
						|
BreakpointSite::GetNumberOfOwners ()
 | 
						|
{
 | 
						|
    return m_owners.GetSize();
 | 
						|
}
 | 
						|
 | 
						|
BreakpointLocationSP
 | 
						|
BreakpointSite::GetOwnerAtIndex (uint32_t index)
 | 
						|
{
 | 
						|
    return m_owners.GetByIndex (index);
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
BreakpointSite::ValidForThisThread (Thread *thread)
 | 
						|
{
 | 
						|
    return m_owners.ValidForThisThread(thread);
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
}
 |