2010-06-09 00:52:24 +08:00
|
|
|
//===-- SBTarget.cpp --------------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-06-09 15:44:37 +08:00
|
|
|
#include "lldb/API/SBTarget.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
#include "lldb/lldb-include.h"
|
|
|
|
|
|
|
|
#include "lldb/API/SBFileSpec.h"
|
|
|
|
#include "lldb/API/SBModule.h"
|
2010-09-20 13:20:02 +08:00
|
|
|
#include "lldb/API/SBStream.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Breakpoint/BreakpointID.h"
|
|
|
|
#include "lldb/Breakpoint/BreakpointIDList.h"
|
|
|
|
#include "lldb/Breakpoint/BreakpointList.h"
|
|
|
|
#include "lldb/Breakpoint/BreakpointLocation.h"
|
|
|
|
#include "lldb/Core/Address.h"
|
|
|
|
#include "lldb/Core/AddressResolver.h"
|
|
|
|
#include "lldb/Core/AddressResolverName.h"
|
2010-06-16 03:49:27 +08:00
|
|
|
#include "lldb/Interpreter/Args.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Core/ArchSpec.h"
|
|
|
|
#include "lldb/Core/Debugger.h"
|
|
|
|
#include "lldb/Core/Disassembler.h"
|
|
|
|
#include "lldb/Core/FileSpec.h"
|
|
|
|
#include "lldb/Core/RegularExpression.h"
|
|
|
|
#include "lldb/Core/SearchFilter.h"
|
|
|
|
#include "lldb/Core/STLUtils.h"
|
|
|
|
#include "lldb/Target/Process.h"
|
|
|
|
#include "lldb/Target/Target.h"
|
|
|
|
#include "lldb/Target/TargetList.h"
|
|
|
|
|
|
|
|
#include "lldb/Interpreter/CommandReturnObject.h"
|
|
|
|
#include "../source/Commands/CommandObjectBreakpoint.h"
|
|
|
|
|
2010-06-09 15:44:37 +08:00
|
|
|
#include "lldb/API/SBDebugger.h"
|
|
|
|
#include "lldb/API/SBProcess.h"
|
|
|
|
#include "lldb/API/SBListener.h"
|
|
|
|
#include "lldb/API/SBBreakpoint.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
#define DEFAULT_DISASM_BYTE_SIZE 32
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// SBTarget constructor
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
SBTarget::SBTarget ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SBTarget::SBTarget (const SBTarget& rhs) :
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp (rhs.m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SBTarget::SBTarget(const TargetSP& target_sp) :
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp (target_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
const SBTarget&
|
|
|
|
SBTarget::Assign (const SBTarget& rhs)
|
|
|
|
{
|
|
|
|
if (this != &rhs)
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp = rhs.m_opaque_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Destructor
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
SBTarget::~SBTarget()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBTarget::IsValid () const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp.get() != NULL;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SBProcess
|
|
|
|
SBTarget::GetProcess ()
|
|
|
|
{
|
|
|
|
SBProcess sb_process;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
|
|
|
sb_process.SetProcess (m_opaque_sp->GetProcessSP());
|
2010-06-09 00:52:24 +08:00
|
|
|
return sb_process;
|
|
|
|
}
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
SBDebugger
|
|
|
|
SBTarget::GetDebugger () const
|
|
|
|
{
|
|
|
|
SBDebugger debugger;
|
|
|
|
if (m_opaque_sp)
|
|
|
|
debugger.reset (m_opaque_sp->GetDebugger().GetSP());
|
|
|
|
return debugger;
|
|
|
|
}
|
|
|
|
|
2010-10-07 02:44:26 +08:00
|
|
|
|
|
|
|
// DEPRECATED
|
|
|
|
SBProcess
|
|
|
|
SBTarget::CreateProcess ()
|
|
|
|
{
|
|
|
|
SBProcess sb_process;
|
|
|
|
|
|
|
|
if (m_opaque_sp)
|
|
|
|
sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
|
|
|
|
|
|
|
|
return sb_process;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-07 06:10:17 +08:00
|
|
|
SBProcess
|
|
|
|
SBTarget::LaunchProcess
|
2010-10-07 12:19:01 +08:00
|
|
|
(
|
|
|
|
char const **argv,
|
|
|
|
char const **envp,
|
|
|
|
const char *tty,
|
|
|
|
uint32_t launch_flags,
|
|
|
|
bool stop_at_entry
|
|
|
|
)
|
|
|
|
{
|
|
|
|
SBError sb_error;
|
|
|
|
return Launch (argv, envp, tty, launch_flags, stop_at_entry, sb_error);
|
|
|
|
}
|
|
|
|
|
|
|
|
SBProcess
|
|
|
|
SBTarget::Launch
|
2010-10-07 06:10:17 +08:00
|
|
|
(
|
|
|
|
char const **argv,
|
|
|
|
char const **envp,
|
|
|
|
const char *tty,
|
|
|
|
uint32_t launch_flags,
|
|
|
|
bool stop_at_entry,
|
|
|
|
SBError &error
|
|
|
|
)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-10-06 11:53:16 +08:00
|
|
|
SBProcess sb_process;
|
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-10-07 02:44:26 +08:00
|
|
|
// DEPRECATED, this will change when CreateProcess is removed...
|
|
|
|
if (m_opaque_sp->GetProcessSP())
|
|
|
|
{
|
|
|
|
sb_process.SetProcess(m_opaque_sp->GetProcessSP());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// When launching, we always want to create a new process When
|
|
|
|
// SBTarget::CreateProcess is removed, this will always happen.
|
|
|
|
sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
|
|
|
|
}
|
2010-10-06 11:53:16 +08:00
|
|
|
|
|
|
|
if (sb_process.IsValid())
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-10-07 06:10:17 +08:00
|
|
|
error.SetError (sb_process->Launch (argv, envp, launch_flags, tty, tty, tty));
|
2010-10-06 11:53:16 +08:00
|
|
|
if (error.Success())
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-10-06 11:53:16 +08:00
|
|
|
// Make sure we are stopped at the entry
|
|
|
|
StateType state = sb_process->WaitForProcessToStop (NULL);
|
2010-06-09 00:52:24 +08:00
|
|
|
if (state == eStateStopped)
|
2010-10-06 11:53:16 +08:00
|
|
|
{
|
2010-10-07 12:19:01 +08:00
|
|
|
// We we are stopping at the entry point, we can return now!
|
|
|
|
if (stop_at_entry)
|
|
|
|
return sb_process;
|
|
|
|
|
2010-10-06 11:53:16 +08:00
|
|
|
// resume the process to skip the entry point
|
2010-10-07 06:10:17 +08:00
|
|
|
error.SetError (sb_process->Resume());
|
2010-10-06 11:53:16 +08:00
|
|
|
if (error.Success())
|
|
|
|
{
|
|
|
|
// If we are doing synchronous mode, then wait for the
|
|
|
|
// process to stop yet again!
|
|
|
|
if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
|
|
|
|
sb_process->WaitForProcessToStop (NULL);
|
|
|
|
}
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
2010-10-07 06:10:17 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
error.SetErrorString ("unable to create lldb_private::Process");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error.SetErrorString ("SBTarget is invalid");
|
|
|
|
}
|
|
|
|
return sb_process;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lldb::SBProcess
|
2010-10-07 12:19:01 +08:00
|
|
|
SBTarget::AttachToProcessWithID
|
2010-10-07 06:10:17 +08:00
|
|
|
(
|
|
|
|
lldb::pid_t pid,// The process ID to attach to
|
|
|
|
SBError& error // An error explaining what went wrong if attach fails
|
|
|
|
)
|
|
|
|
{
|
|
|
|
SBProcess sb_process;
|
|
|
|
if (m_opaque_sp)
|
|
|
|
{
|
|
|
|
// DEPRECATED, this will change when CreateProcess is removed...
|
|
|
|
if (m_opaque_sp->GetProcessSP())
|
|
|
|
{
|
|
|
|
sb_process.SetProcess(m_opaque_sp->GetProcessSP());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// When launching, we always want to create a new process When
|
|
|
|
// SBTarget::CreateProcess is removed, this will always happen.
|
|
|
|
sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sb_process.IsValid())
|
|
|
|
{
|
|
|
|
error.SetError (sb_process->Attach (pid));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error.SetErrorString ("unable to create lldb_private::Process");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error.SetErrorString ("SBTarget is invalid");
|
|
|
|
}
|
|
|
|
return sb_process;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
lldb::SBProcess
|
2010-10-07 12:19:01 +08:00
|
|
|
SBTarget::AttachToProcessWithName
|
2010-10-07 06:10:17 +08:00
|
|
|
(
|
|
|
|
const char *name, // basename of process to attach to
|
|
|
|
bool wait_for, // if true wait for a new instance of "name" to be launched
|
|
|
|
SBError& error // An error explaining what went wrong if attach fails
|
|
|
|
)
|
|
|
|
{
|
|
|
|
SBProcess sb_process;
|
|
|
|
if (m_opaque_sp)
|
|
|
|
{
|
|
|
|
// DEPRECATED, this will change when CreateProcess is removed...
|
|
|
|
if (m_opaque_sp->GetProcessSP())
|
|
|
|
{
|
|
|
|
sb_process.SetProcess(m_opaque_sp->GetProcessSP());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// When launching, we always want to create a new process When
|
|
|
|
// SBTarget::CreateProcess is removed, this will always happen.
|
|
|
|
sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sb_process.IsValid())
|
|
|
|
{
|
|
|
|
error.SetError (sb_process->Attach (name, wait_for));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error.SetErrorString ("unable to create lldb_private::Process");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error.SetErrorString ("SBTarget is invalid");
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2010-10-06 11:53:16 +08:00
|
|
|
return sb_process;
|
2010-10-07 06:10:17 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SBFileSpec
|
|
|
|
SBTarget::GetExecutable ()
|
|
|
|
{
|
|
|
|
SBFileSpec exe_file_spec;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
ModuleSP exe_module_sp (m_opaque_sp->GetExecutableModule ());
|
2010-06-09 00:52:24 +08:00
|
|
|
if (exe_module_sp)
|
|
|
|
exe_file_spec.SetFileSpec (exe_module_sp->GetFileSpec());
|
|
|
|
}
|
|
|
|
return exe_file_spec;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBTarget::DeleteTargetFromList (TargetList *list)
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
|
|
|
return list->DeleteTarget (m_opaque_sp);
|
2010-06-09 00:52:24 +08:00
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBTarget::operator == (const SBTarget &rhs) const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp.get() == rhs.m_opaque_sp.get();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBTarget::operator != (const SBTarget &rhs) const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp.get() != rhs.m_opaque_sp.get();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
lldb_private::Target *
|
2010-06-23 09:19:29 +08:00
|
|
|
SBTarget::operator ->() const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
return m_opaque_sp.get();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2010-06-23 09:19:29 +08:00
|
|
|
|
|
|
|
lldb_private::Target *
|
|
|
|
SBTarget::get() const
|
|
|
|
{
|
|
|
|
return m_opaque_sp.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SBTarget::reset (const lldb::TargetSP& target_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp = target_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SBBreakpoint
|
|
|
|
SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line)
|
|
|
|
{
|
|
|
|
SBBreakpoint sb_bp;
|
|
|
|
if (file != NULL && line != 0)
|
|
|
|
sb_bp = BreakpointCreateByLocation (SBFileSpec (file), line);
|
|
|
|
return sb_bp;
|
|
|
|
}
|
|
|
|
|
|
|
|
SBBreakpoint
|
|
|
|
SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line)
|
|
|
|
{
|
|
|
|
SBBreakpoint sb_bp;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp.get() && line != 0)
|
|
|
|
*sb_bp = m_opaque_sp->CreateBreakpoint (NULL, *sb_file_spec, line, true, false);
|
2010-06-09 00:52:24 +08:00
|
|
|
return sb_bp;
|
|
|
|
}
|
|
|
|
|
|
|
|
SBBreakpoint
|
|
|
|
SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name)
|
|
|
|
{
|
|
|
|
SBBreakpoint sb_bp;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp.get() && symbol_name && symbol_name[0])
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
if (module_name && module_name[0])
|
|
|
|
{
|
|
|
|
FileSpec module_file_spec(module_name);
|
2010-10-01 05:21:43 +08:00
|
|
|
*sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-01 05:21:43 +08:00
|
|
|
*sb_bp = m_opaque_sp->CreateBreakpoint (NULL, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return sb_bp;
|
|
|
|
}
|
|
|
|
|
|
|
|
SBBreakpoint
|
|
|
|
SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
|
|
|
|
{
|
|
|
|
SBBreakpoint sb_bp;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp.get() && symbol_name_regex && symbol_name_regex[0])
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
RegularExpression regexp(symbol_name_regex);
|
|
|
|
|
|
|
|
if (module_name && module_name[0])
|
|
|
|
{
|
|
|
|
FileSpec module_file_spec(module_name);
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
*sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, regexp, false);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
*sb_bp = m_opaque_sp->CreateBreakpoint (NULL, regexp, false);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return sb_bp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SBBreakpoint
|
|
|
|
SBTarget::BreakpointCreateByAddress (addr_t address)
|
|
|
|
{
|
|
|
|
SBBreakpoint sb_bp;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp.get())
|
|
|
|
*sb_bp = m_opaque_sp->CreateBreakpoint (address, false);
|
2010-06-09 00:52:24 +08:00
|
|
|
return sb_bp;
|
|
|
|
}
|
|
|
|
|
2010-07-24 07:33:17 +08:00
|
|
|
SBBreakpoint
|
|
|
|
SBTarget::FindBreakpointByID (break_id_t bp_id)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-07-24 07:33:17 +08:00
|
|
|
SBBreakpoint sb_breakpoint;
|
|
|
|
if (m_opaque_sp && bp_id != LLDB_INVALID_BREAK_ID)
|
|
|
|
*sb_breakpoint = m_opaque_sp->GetBreakpointByID (bp_id);
|
|
|
|
return sb_breakpoint;
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-07-24 07:33:17 +08:00
|
|
|
uint32_t
|
|
|
|
SBTarget::GetNumBreakpoints () const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-07-24 07:33:17 +08:00
|
|
|
return m_opaque_sp->GetBreakpointList().GetSize();
|
|
|
|
return 0;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SBBreakpoint
|
2010-07-24 07:33:17 +08:00
|
|
|
SBTarget::GetBreakpointAtIndex (uint32_t idx) const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
SBBreakpoint sb_breakpoint;
|
2010-07-24 07:33:17 +08:00
|
|
|
if (m_opaque_sp)
|
|
|
|
*sb_breakpoint = m_opaque_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
|
2010-06-09 00:52:24 +08:00
|
|
|
return sb_breakpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBTarget::BreakpointDelete (break_id_t bp_id)
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
|
|
|
return m_opaque_sp->RemoveBreakpointByID (bp_id);
|
2010-06-09 00:52:24 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBTarget::EnableAllBreakpoints ()
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->EnableAllBreakpoints ();
|
2010-06-09 00:52:24 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBTarget::DisableAllBreakpoints ()
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->DisableAllBreakpoints ();
|
2010-06-09 00:52:24 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SBTarget::DeleteAllBreakpoints ()
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
m_opaque_sp->RemoveAllBreakpoints ();
|
2010-06-09 00:52:24 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
SBTarget::GetNumModules () const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
|
|
|
return m_opaque_sp->GetImages().GetSize();
|
2010-06-09 00:52:24 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-07-31 04:12:55 +08:00
|
|
|
void
|
|
|
|
SBTarget::Clear ()
|
|
|
|
{
|
|
|
|
m_opaque_sp.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
SBModule
|
|
|
|
SBTarget::FindModule (const SBFileSpec &sb_file_spec)
|
|
|
|
{
|
|
|
|
SBModule sb_module;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp && sb_file_spec.IsValid())
|
|
|
|
sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL));
|
2010-06-09 00:52:24 +08:00
|
|
|
return sb_module;
|
|
|
|
}
|
|
|
|
|
|
|
|
SBModule
|
|
|
|
SBTarget::GetModuleAtIndex (uint32_t idx)
|
|
|
|
{
|
|
|
|
SBModule sb_module;
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
|
|
|
sb_module.SetModule(m_opaque_sp->GetImages().GetModuleAtIndex(idx));
|
2010-06-09 00:52:24 +08:00
|
|
|
return sb_module;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SBBroadcaster
|
|
|
|
SBTarget::GetBroadcaster () const
|
|
|
|
{
|
2010-06-23 09:19:29 +08:00
|
|
|
SBBroadcaster broadcaster(m_opaque_sp.get(), false);
|
2010-06-09 00:52:24 +08:00
|
|
|
return broadcaster;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-07-01 07:03:03 +08:00
|
|
|
SBTarget::Disassemble (lldb::addr_t start_addr, lldb::addr_t end_addr, const char *module_name)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-07-01 07:03:03 +08:00
|
|
|
if (start_addr == LLDB_INVALID_ADDRESS)
|
2010-06-09 00:52:24 +08:00
|
|
|
return;
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
|
2010-06-09 00:52:24 +08:00
|
|
|
if (out == NULL)
|
|
|
|
return;
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-07-01 07:03:03 +08:00
|
|
|
ModuleSP module_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
if (module_name != NULL)
|
|
|
|
{
|
2010-07-01 07:03:03 +08:00
|
|
|
FileSpec module_file_spec (module_name);
|
|
|
|
module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
AddressRange range;
|
|
|
|
|
|
|
|
// Make sure the process object is alive if we have one (it might be
|
|
|
|
// created but we might not be launched yet).
|
2010-09-15 07:36:40 +08:00
|
|
|
|
2010-10-06 11:53:16 +08:00
|
|
|
Process *sb_process = m_opaque_sp->GetProcessSP().get();
|
|
|
|
if (sb_process && !sb_process->IsAlive())
|
|
|
|
sb_process = NULL;
|
2010-07-01 07:03:03 +08:00
|
|
|
|
|
|
|
// If we are given a module, then "start_addr" is a file address in
|
|
|
|
// that module.
|
|
|
|
if (module_sp)
|
|
|
|
{
|
|
|
|
if (!module_sp->ResolveFileAddress (start_addr, range.GetBaseAddress()))
|
|
|
|
range.GetBaseAddress().SetOffset(start_addr);
|
|
|
|
}
|
2010-09-15 07:36:40 +08:00
|
|
|
else if (m_opaque_sp->GetSectionLoadList().IsEmpty() == false)
|
2010-07-01 07:03:03 +08:00
|
|
|
{
|
|
|
|
// We don't have a module, se we need to figure out if "start_addr"
|
|
|
|
// resolves to anything in a running process.
|
2010-09-15 07:36:40 +08:00
|
|
|
if (!m_opaque_sp->GetSectionLoadList().ResolveLoadAddress (start_addr, range.GetBaseAddress()))
|
2010-07-01 07:03:03 +08:00
|
|
|
range.GetBaseAddress().SetOffset(start_addr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (m_opaque_sp->GetImages().ResolveFileAddress (start_addr, range.GetBaseAddress()))
|
|
|
|
range.GetBaseAddress().SetOffset(start_addr);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// For now, we need a process; the disassembly functions insist. If we don't have one already,
|
|
|
|
// make one.
|
|
|
|
|
2010-07-01 07:03:03 +08:00
|
|
|
ExecutionContext exe_ctx;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-10-06 11:53:16 +08:00
|
|
|
if (sb_process)
|
|
|
|
sb_process->CalculateExecutionContext(exe_ctx);
|
2010-07-01 07:03:03 +08:00
|
|
|
else
|
2010-10-04 09:05:56 +08:00
|
|
|
m_opaque_sp->CalculateExecutionContext(exe_ctx);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-07-01 07:03:03 +08:00
|
|
|
if (end_addr == LLDB_INVALID_ADDRESS || end_addr < start_addr)
|
|
|
|
range.SetByteSize( DEFAULT_DISASM_BYTE_SIZE);
|
|
|
|
else
|
|
|
|
range.SetByteSize(end_addr - start_addr);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-07-01 07:03:03 +08:00
|
|
|
StreamFile out_stream (out);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-07-01 07:03:03 +08:00
|
|
|
Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
|
|
|
|
m_opaque_sp->GetArchitecture(),
|
|
|
|
exe_ctx,
|
|
|
|
range,
|
|
|
|
3,
|
|
|
|
false,
|
|
|
|
out_stream);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SBTarget::Disassemble (const char *function_name, const char *module_name)
|
|
|
|
{
|
|
|
|
if (function_name == NULL)
|
|
|
|
return;
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
|
2010-06-09 00:52:24 +08:00
|
|
|
if (out == NULL)
|
|
|
|
return;
|
|
|
|
|
2010-06-23 09:19:29 +08:00
|
|
|
if (m_opaque_sp)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-07-01 07:03:03 +08:00
|
|
|
Disassembler *disassembler = Disassembler::FindPlugin (m_opaque_sp->GetArchitecture());
|
2010-06-09 00:52:24 +08:00
|
|
|
if (disassembler == NULL)
|
|
|
|
return;
|
|
|
|
|
2010-07-01 07:03:03 +08:00
|
|
|
ModuleSP module_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
if (module_name != NULL)
|
|
|
|
{
|
2010-07-01 07:03:03 +08:00
|
|
|
FileSpec module_file_spec (module_name);
|
|
|
|
module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2010-07-01 07:03:03 +08:00
|
|
|
|
|
|
|
ExecutionContext exe_ctx;
|
|
|
|
|
|
|
|
// Make sure the process object is alive if we have one (it might be
|
|
|
|
// created but we might not be launched yet).
|
2010-10-06 11:53:16 +08:00
|
|
|
Process *sb_process = m_opaque_sp->GetProcessSP().get();
|
|
|
|
if (sb_process && !sb_process->IsAlive())
|
|
|
|
sb_process = NULL;
|
2010-07-01 07:03:03 +08:00
|
|
|
|
2010-10-06 11:53:16 +08:00
|
|
|
if (sb_process)
|
|
|
|
sb_process->CalculateExecutionContext(exe_ctx);
|
2010-07-01 07:03:03 +08:00
|
|
|
else
|
2010-10-04 09:05:56 +08:00
|
|
|
m_opaque_sp->CalculateExecutionContext(exe_ctx);
|
2010-07-01 07:03:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
StreamFile out_stream (out);
|
|
|
|
|
|
|
|
Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
|
|
|
|
m_opaque_sp->GetArchitecture(),
|
|
|
|
exe_ctx,
|
|
|
|
ConstString (function_name),
|
|
|
|
module_sp.get(),
|
|
|
|
3,
|
|
|
|
false,
|
|
|
|
out_stream);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
2010-09-20 13:20:02 +08:00
|
|
|
|
|
|
|
bool
|
|
|
|
SBTarget::GetDescription (SBStream &description)
|
|
|
|
{
|
|
|
|
if (m_opaque_sp)
|
2010-09-21 00:21:41 +08:00
|
|
|
{
|
2010-09-23 07:01:29 +08:00
|
|
|
description.ref();
|
2010-09-20 13:20:02 +08:00
|
|
|
m_opaque_sp->Dump (description.get());
|
2010-09-21 00:21:41 +08:00
|
|
|
}
|
2010-09-20 13:20:02 +08:00
|
|
|
else
|
|
|
|
description.Printf ("No value");
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|