#ifndef __MachThread_h__
#define __MachThread_h__
#include <string>
#include <vector>
#include <tr1/memory> // for std::tr1::shared_ptr
#include <libproc.h>
#include <mach/mach.h>
#include <pthread.h>
#include <sys/signal.h>
#include "PThreadCondition.h"
#include "PThreadMutex.h"
#include "MachException.h"
#include "DNBArch.h"
#include "DNBRegisterInfo.h"
class DNBBreakpoint;
class MachProcess;
class MachThreadList;
class MachThread
{
public:
MachThread (MachProcess *process, thread_t thread = 0);
~MachThread ();
MachProcess * Process() { return m_process; }
const MachProcess *
Process() const { return m_process; }
nub_process_t ProcessID() const;
void Dump(uint32_t index);
thread_t ThreadID() const { return m_tid; }
thread_t InferiorThreadID() const;
uint32_t SequenceID() const { return m_seq_id; }
static bool ThreadIDIsValid(thread_t thread);
void Resume(bool others_stopped);
void Suspend();
bool SetSuspendCountBeforeResume(bool others_stopped);
bool RestoreSuspendCountAfterStop();
bool GetRegisterState(int flavor, bool force);
bool SetRegisterState(int flavor);
uint64_t GetPC(uint64_t failValue = INVALID_NUB_ADDRESS); bool SetPC(uint64_t value); uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS);
nub_break_t CurrentBreakpoint();
uint32_t EnableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
uint32_t EnableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
bool DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
bool DisableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
nub_state_t GetState();
void SetState(nub_state_t state);
void ThreadWillResume (const DNBThreadResumeAction *thread_action, bool others_stopped = false);
bool ShouldStop(bool &step_more);
bool IsStepping();
bool ThreadDidStop();
bool NotifyException(MachException::Data& exc);
const MachException::Data& GetStopException() { return m_stop_exception; }
uint32_t GetNumRegistersInSet(int regSet) const;
const char * GetRegisterSetName(int regSet) const;
const DNBRegisterInfo *
GetRegisterInfo(int regSet, int regIndex) const;
void DumpRegisterState(int regSet);
const DNBRegisterSetInfo *
GetRegisterSetInfo(nub_size_t *num_reg_sets ) const;
bool GetRegisterValue ( uint32_t reg_set_idx, uint32_t reg_idx, DNBRegisterValue *reg_value );
bool SetRegisterValue ( uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value );
nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len);
nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len);
void NotifyBreakpointChanged (const DNBBreakpoint *bp)
{
}
bool IsUserReady();
struct thread_basic_info *
GetBasicInfo ();
const char * GetBasicInfoAsString () const;
const char * GetName ();
DNBArchProtocol*
GetArchProtocol()
{
return m_arch_ap.get();
}
protected:
static bool GetBasicInfo(thread_t threadID, struct thread_basic_info *basic_info);
bool
GetIdentifierInfo ();
MachProcess * m_process; thread_t m_tid; uint32_t m_seq_id; nub_state_t m_state; PThreadMutex m_state_mutex; nub_break_t m_break_id; struct thread_basic_info m_basic_info; int32_t m_suspend_count; MachException::Data m_stop_exception; std::auto_ptr<DNBArchProtocol> m_arch_ap; const DNBRegisterSetInfo * m_reg_sets; nub_size_t m_num_reg_sets;
#ifdef THREAD_IDENTIFIER_INFO_COUNT
thread_identifier_info_data_t m_ident_info;
struct proc_threadinfo m_proc_threadinfo;
std::string m_dispatch_queue_name;
#endif
private:
friend class MachThreadList;
void HardwareWatchpointStateChanged(); };
typedef std::tr1::shared_ptr<MachThread> MachThreadSP;
#endif