#ifndef __RNBRemote_h__
#define __RNBRemote_h__
#include "RNBDefs.h"
#include "DNB.h"
#include "RNBContext.h"
#include "RNBSocket.h"
#include "PThreadMutex.h"
#include <string>
#include <vector>
#include <deque>
#include <map>
class RNBSocket;
class RNBContext;
class PThreadEvents;
enum event_loop_mode { debug_nub, gdb_remote_protocol, done };
class RNBRemote
{
public:
typedef enum {
invalid_packet = 0,
ack, nack, halt, use_extended_mode, why_halted, set_argv, set_bp, cont, continue_with_sig, detach, read_general_regs, write_general_regs, set_thread, step_inferior_one_cycle, signal_and_step_inf_one_cycle, kill, read_memory, write_memory, read_register, write_register, restart, single_step, single_step_with_sig, search_mem_backwards, thread_alive_p, vattach, vattachwait, vattachorwait, vattachname, vcont, vcont_list_actions, write_data_to_memory, insert_mem_bp, remove_mem_bp, insert_hardware_bp, remove_hardware_bp, insert_write_watch_bp, remove_write_watch_bp, insert_read_watch_bp, remove_read_watch_bp, insert_access_watch_bp, remove_access_watch_bp,
query_monitor, query_current_thread_id, query_get_pid, query_thread_ids_first, query_thread_ids_subsequent, query_thread_extra_info, query_thread_stop_info, query_image_offsets, query_symbol_lookup, query_launch_success, query_register_info, query_shlib_notify_info_addr, query_step_packet_supported, query_vattachorwait_supported, query_sync_thread_state_supported, query_host_info, query_gdb_server_version, query_process_info, pass_signals_to_inferior, start_noack_mode, prefix_reg_packets_with_tid, set_logging_mode, set_max_packet_size, set_max_payload_size, set_environment_variable, set_environment_variable_hex, set_launch_arch, set_disable_aslr, set_stdin, set_stdout, set_stderr, set_working_dir, set_list_threads_in_stop_reply, sync_thread_state, memory_region_info, get_profile_data, set_enable_profiling, watchpoint_support_info, allocate_memory, deallocate_memory, set_process_event, save_register_state, restore_register_state,
unknown_type
} PacketEnum;
typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p);
RNBRemote ();
~RNBRemote ();
void Initialize();
bool InitializeRegisters (bool force = false);
rnb_err_t HandleAsyncPacket(PacketEnum *type = NULL);
rnb_err_t HandleReceivedPacket(PacketEnum *type = NULL);
nub_thread_t GetContinueThread () const
{
return m_continue_thread;
}
void SetContinueThread (nub_thread_t tid)
{
m_continue_thread = tid;
}
nub_thread_t GetCurrentThread () const
{
if (m_thread == 0 || m_thread == -1)
return DNBProcessGetCurrentThread (m_ctx.ProcessID());
return m_thread;
}
void SetCurrentThread (nub_thread_t tid)
{
DNBProcessSetCurrentThread (m_ctx.ProcessID(), tid);
m_thread = tid;
}
static void* ThreadFunctionReadRemoteData(void *arg);
void StartReadRemoteDataThread ();
void StopReadRemoteDataThread ();
void NotifyThatProcessStopped (void);
rnb_err_t HandlePacket_A (const char *p);
rnb_err_t HandlePacket_H (const char *p);
rnb_err_t HandlePacket_qC (const char *p);
rnb_err_t HandlePacket_qRcmd (const char *p);
rnb_err_t HandlePacket_qGetPid (const char *p);
rnb_err_t HandlePacket_qLaunchSuccess (const char *p);
rnb_err_t HandlePacket_qRegisterInfo (const char *p);
rnb_err_t HandlePacket_qShlibInfoAddr (const char *p);
rnb_err_t HandlePacket_qStepPacketSupported (const char *p);
rnb_err_t HandlePacket_qVAttachOrWaitSupported (const char *p);
rnb_err_t HandlePacket_qSyncThreadStateSupported (const char *p);
rnb_err_t HandlePacket_qThreadInfo (const char *p);
rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
rnb_err_t HandlePacket_qHostInfo (const char *p);
rnb_err_t HandlePacket_qGDBServerVersion (const char *p);
rnb_err_t HandlePacket_qProcessInfo (const char *p);
rnb_err_t HandlePacket_QStartNoAckMode (const char *p);
rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p);
rnb_err_t HandlePacket_QSetLogging (const char *p);
rnb_err_t HandlePacket_QSetDisableASLR (const char *p);
rnb_err_t HandlePacket_QSetSTDIO (const char *p);
rnb_err_t HandlePacket_QSetWorkingDir (const char *p);
rnb_err_t HandlePacket_QSetMaxPayloadSize (const char *p);
rnb_err_t HandlePacket_QSetMaxPacketSize (const char *p);
rnb_err_t HandlePacket_QEnvironment (const char *p);
rnb_err_t HandlePacket_QEnvironmentHexEncoded (const char *p);
rnb_err_t HandlePacket_QLaunchArch (const char *p);
rnb_err_t HandlePacket_QListThreadsInStopReply (const char *p);
rnb_err_t HandlePacket_QSyncThreadState (const char *p);
rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p);
rnb_err_t HandlePacket_QSetProcessEvent (const char *p);
rnb_err_t HandlePacket_last_signal (const char *p);
rnb_err_t HandlePacket_m (const char *p);
rnb_err_t HandlePacket_M (const char *p);
rnb_err_t HandlePacket_X (const char *p);
rnb_err_t HandlePacket_g (const char *p);
rnb_err_t HandlePacket_G (const char *p);
rnb_err_t HandlePacket_z (const char *p);
rnb_err_t HandlePacket_T (const char *p);
rnb_err_t HandlePacket_p (const char *p);
rnb_err_t HandlePacket_P (const char *p);
rnb_err_t HandlePacket_c (const char *p);
rnb_err_t HandlePacket_C (const char *p);
rnb_err_t HandlePacket_D (const char *p);
rnb_err_t HandlePacket_k (const char *p);
rnb_err_t HandlePacket_s (const char *p);
rnb_err_t HandlePacket_S (const char *p);
rnb_err_t HandlePacket_v (const char *p);
rnb_err_t HandlePacket_UNIMPLEMENTED (const char *p);
rnb_err_t HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description);
rnb_err_t HandlePacket_AllocateMemory (const char *p);
rnb_err_t HandlePacket_DeallocateMemory (const char *p);
rnb_err_t HandlePacket_SaveRegisterState (const char *p);
rnb_err_t HandlePacket_RestoreRegisterState (const char *p);
rnb_err_t HandlePacket_MemoryRegionInfo (const char *p);
rnb_err_t HandlePacket_GetProfileData(const char *p);
rnb_err_t HandlePacket_SetEnableAsyncProfiling(const char *p);
rnb_err_t HandlePacket_WatchpointSupportInfo (const char *p);
rnb_err_t HandlePacket_stop_process (const char *p);
rnb_err_t SendStopReplyPacketForThread (nub_thread_t tid);
rnb_err_t SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer);
rnb_err_t SendSTDOUTPacket (char *buf, nub_size_t buf_size);
rnb_err_t SendSTDERRPacket (char *buf, nub_size_t buf_size);
void FlushSTDIO ();
void SendAsyncProfileData ();
rnb_err_t SendAsyncProfileDataPacket (char *buf, nub_size_t buf_size);
RNBContext& Context() { return m_ctx; }
RNBSocket& Comm() { return m_comm; }
private:
RNBRemote (const RNBRemote &);
protected:
rnb_err_t GetCommData ();
void CommDataReceived(const std::string& data);
struct Packet
{
typedef std::vector<Packet> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
PacketEnum type;
HandlePacketCallback normal; HandlePacketCallback async; std::string abbrev;
std::string printable_name;
bool
IsPlatformPacket () const
{
switch (type)
{
case set_logging_mode:
case query_host_info:
return true;
default:
break;
}
return false;
}
Packet() :
type(invalid_packet),
normal (NULL),
async (NULL),
abbrev (),
printable_name ()
{
}
Packet( PacketEnum in_type,
HandlePacketCallback in_normal,
HandlePacketCallback in_async,
const char *in_abbrev,
const char *in_printable_name) :
type (in_type),
normal (in_normal),
async (in_async),
abbrev (in_abbrev),
printable_name (in_printable_name)
{
}
};
rnb_err_t GetPacket (std::string &packet_data, RNBRemote::Packet& packet_info, bool wait);
rnb_err_t SendPacket (const std::string &);
void CreatePacketTable ();
rnb_err_t GetPacketPayload (std::string &);
nub_thread_t
ExtractThreadIDFromThreadSuffix (const char *p);
RNBContext m_ctx; RNBSocket m_comm; std::string m_arch;
nub_thread_t m_continue_thread; nub_thread_t m_thread; PThreadMutex m_mutex; uint32_t m_packets_recvd;
Packet::collection m_packets;
std::deque<std::string> m_rx_packets;
std::string m_rx_partial_data; pthread_t m_rx_pthread;
uint32_t m_max_payload_size; bool m_extended_mode; bool m_noack_mode; bool m_thread_suffix_supported; bool m_list_threads_in_stop_reply;
};
#define TARGET_EXC_BAD_ACCESS 0x91
#define TARGET_EXC_BAD_INSTRUCTION 0x92
#define TARGET_EXC_ARITHMETIC 0x93
#define TARGET_EXC_EMULATION 0x94
#define TARGET_EXC_SOFTWARE 0x95
#define TARGET_EXC_BREAKPOINT 0x96
#define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399
#endif // #ifndef __RNBRemote_h__