2010-06-09 00:52:24 +08:00
|
|
|
//===-- ThreadPlanRunToAddress.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/Target/ThreadPlanRunToAddress.h"
|
|
|
|
|
|
|
|
// C Includes
|
|
|
|
// C++ Includes
|
|
|
|
// Other libraries and framework includes
|
|
|
|
// Project includes
|
|
|
|
#include "lldb/lldb-private-log.h"
|
|
|
|
#include "lldb/Core/Log.h"
|
|
|
|
#include "lldb/Core/Stream.h"
|
|
|
|
#include "lldb/Target/Target.h"
|
|
|
|
#include "lldb/Target/Process.h"
|
|
|
|
#include "lldb/Target/Thread.h"
|
|
|
|
#include "lldb/Target/RegisterContext.h"
|
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// ThreadPlanRunToAddress: Continue plan
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ThreadPlanRunToAddress::ThreadPlanRunToAddress
|
|
|
|
(
|
|
|
|
Thread &thread,
|
|
|
|
Address &address,
|
|
|
|
bool stop_others
|
|
|
|
) :
|
2010-09-15 06:03:00 +08:00
|
|
|
ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
|
2010-06-09 00:52:24 +08:00
|
|
|
m_stop_others (stop_others),
|
2010-09-15 06:03:00 +08:00
|
|
|
m_addresses (),
|
|
|
|
m_break_ids ()
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2012-02-21 08:09:25 +08:00
|
|
|
m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get()));
|
2010-09-15 06:03:00 +08:00
|
|
|
SetInitialBreakpoints();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ThreadPlanRunToAddress::ThreadPlanRunToAddress
|
|
|
|
(
|
|
|
|
Thread &thread,
|
|
|
|
lldb::addr_t address,
|
|
|
|
bool stop_others
|
|
|
|
) :
|
2010-09-15 06:03:00 +08:00
|
|
|
ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
|
2010-06-09 00:52:24 +08:00
|
|
|
m_stop_others (stop_others),
|
2010-09-15 06:03:00 +08:00
|
|
|
m_addresses (),
|
|
|
|
m_break_ids ()
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2012-02-21 08:09:25 +08:00
|
|
|
m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
|
2010-09-15 06:03:00 +08:00
|
|
|
SetInitialBreakpoints();
|
|
|
|
}
|
|
|
|
|
|
|
|
ThreadPlanRunToAddress::ThreadPlanRunToAddress
|
|
|
|
(
|
|
|
|
Thread &thread,
|
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
|
|
|
const std::vector<lldb::addr_t> &addresses,
|
2010-09-15 06:03:00 +08:00
|
|
|
bool stop_others
|
|
|
|
) :
|
|
|
|
ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
|
|
|
|
m_stop_others (stop_others),
|
|
|
|
m_addresses (addresses),
|
|
|
|
m_break_ids ()
|
|
|
|
{
|
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
|
|
|
// Convert all addressses into opcode addresses to make sure we set
|
|
|
|
// breakpoints at the correct address.
|
2012-02-21 08:09:25 +08:00
|
|
|
Target &target = thread.GetProcess()->GetTarget();
|
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
|
|
|
std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
|
|
|
|
for (pos = m_addresses.begin(); pos != end; ++pos)
|
|
|
|
*pos = target.GetOpcodeLoadAddress (*pos);
|
|
|
|
|
2010-09-15 06:03:00 +08:00
|
|
|
SetInitialBreakpoints();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-09-15 06:03:00 +08:00
|
|
|
ThreadPlanRunToAddress::SetInitialBreakpoints ()
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-09-15 06:03:00 +08:00
|
|
|
size_t num_addresses = m_addresses.size();
|
|
|
|
m_break_ids.resize(num_addresses);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < num_addresses; i++)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-09-15 06:03:00 +08:00
|
|
|
Breakpoint *breakpoint;
|
2012-02-21 08:09:25 +08:00
|
|
|
breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true).get();
|
2010-09-15 06:03:00 +08:00
|
|
|
if (breakpoint != NULL)
|
|
|
|
{
|
|
|
|
m_break_ids[i] = breakpoint->GetID();
|
|
|
|
breakpoint->SetThreadID(m_thread.GetID());
|
2013-01-26 10:19:28 +08:00
|
|
|
breakpoint->SetBreakpointKind("run-to-address");
|
2010-09-15 06:03:00 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
|
|
|
|
{
|
2010-09-15 06:03:00 +08:00
|
|
|
size_t num_break_ids = m_break_ids.size();
|
|
|
|
for (size_t i = 0; i < num_break_ids; i++)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2012-02-21 08:09:25 +08:00
|
|
|
m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
|
|
|
{
|
2010-09-15 06:03:00 +08:00
|
|
|
size_t num_addresses = m_addresses.size();
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (level == lldb::eDescriptionLevelBrief)
|
|
|
|
{
|
2010-09-15 06:03:00 +08:00
|
|
|
if (num_addresses == 0)
|
|
|
|
{
|
|
|
|
s->Printf ("run to address with no addresses given.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (num_addresses == 1)
|
|
|
|
s->Printf ("run to address: ");
|
|
|
|
else
|
|
|
|
s->Printf ("run to addresses: ");
|
|
|
|
|
|
|
|
for (size_t i = 0; i < num_addresses; i++)
|
|
|
|
{
|
|
|
|
s->Address (m_addresses[i], sizeof (addr_t));
|
|
|
|
s->Printf(" ");
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-09-15 06:03:00 +08:00
|
|
|
if (num_addresses == 0)
|
|
|
|
{
|
|
|
|
s->Printf ("run to address with no addresses given.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (num_addresses == 1)
|
|
|
|
s->Printf ("Run to address: ");
|
2010-06-09 00:52:24 +08:00
|
|
|
else
|
2010-09-15 06:03:00 +08:00
|
|
|
{
|
|
|
|
s->Printf ("Run to addresses: ");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t i = 0; i < num_addresses; i++)
|
|
|
|
{
|
|
|
|
if (num_addresses > 1)
|
|
|
|
{
|
|
|
|
s->Printf("\n");
|
|
|
|
s->Indent();
|
|
|
|
}
|
|
|
|
|
|
|
|
s->Address(m_addresses[i], sizeof (addr_t));
|
2011-11-10 09:12:26 +08:00
|
|
|
s->Printf (" using breakpoint: %d - ", m_break_ids[i]);
|
2012-02-21 08:09:25 +08:00
|
|
|
Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get();
|
2010-09-15 06:03:00 +08:00
|
|
|
if (breakpoint)
|
|
|
|
breakpoint->Dump (s);
|
|
|
|
else
|
|
|
|
s->Printf ("but the breakpoint has been deleted.");
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ThreadPlanRunToAddress::ValidatePlan (Stream *error)
|
|
|
|
{
|
|
|
|
// If we couldn't set the breakpoint for some reason, then this won't
|
|
|
|
// work.
|
2010-09-15 06:03:00 +08:00
|
|
|
bool all_bps_good = true;
|
|
|
|
size_t num_break_ids = m_break_ids.size();
|
|
|
|
|
|
|
|
for (size_t i = 0; i < num_break_ids; i++)
|
|
|
|
{
|
|
|
|
if (m_break_ids[i] == LLDB_INVALID_BREAK_ID)
|
|
|
|
{
|
|
|
|
all_bps_good = false;
|
2010-11-30 10:22:11 +08:00
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
error->Printf ("Could not set breakpoint for address: ");
|
|
|
|
error->Address (m_addresses[i], sizeof (addr_t));
|
|
|
|
error->Printf ("\n");
|
|
|
|
}
|
2010-09-15 06:03:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return all_bps_good;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2013-02-09 09:29:05 +08:00
|
|
|
ThreadPlanRunToAddress::PlanExplainsStop (Event *event_ptr)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
return AtOurAddress();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ThreadPlanRunToAddress::StopOthers ()
|
|
|
|
{
|
|
|
|
return m_stop_others;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ThreadPlanRunToAddress::SetStopOthers (bool new_value)
|
|
|
|
{
|
|
|
|
m_stop_others = new_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
StateType
|
2010-11-12 03:26:09 +08:00
|
|
|
ThreadPlanRunToAddress::GetPlanRunState ()
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
return eStateRunning;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ThreadPlanRunToAddress::WillStop ()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ThreadPlanRunToAddress::MischiefManaged ()
|
|
|
|
{
|
2013-03-28 07:08:40 +08:00
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
if (AtOurAddress())
|
|
|
|
{
|
|
|
|
// Remove the breakpoint
|
2010-09-15 06:03:00 +08:00
|
|
|
size_t num_break_ids = m_break_ids.size();
|
|
|
|
|
|
|
|
for (size_t i = 0; i < num_break_ids; i++)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-09-15 06:03:00 +08:00
|
|
|
if (m_break_ids[i] != LLDB_INVALID_BREAK_ID)
|
|
|
|
{
|
2012-02-21 08:09:25 +08:00
|
|
|
m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
|
2010-09-15 06:03:00 +08:00
|
|
|
m_break_ids[i] = LLDB_INVALID_BREAK_ID;
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
if (log)
|
|
|
|
log->Printf("Completed run to address plan.");
|
|
|
|
ThreadPlan::MischiefManaged ();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ThreadPlanRunToAddress::AtOurAddress ()
|
|
|
|
{
|
|
|
|
lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
|
2010-09-15 06:03:00 +08:00
|
|
|
bool found_it = false;
|
2011-01-27 03:10:34 +08:00
|
|
|
size_t num_addresses = m_addresses.size();
|
|
|
|
for (size_t i = 0; i < num_addresses; i++)
|
2010-09-15 06:03:00 +08:00
|
|
|
{
|
|
|
|
if (m_addresses[i] == current_address)
|
|
|
|
{
|
|
|
|
found_it = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return found_it;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|