summaryrefslogtreecommitdiffstats
path: root/c/src/librdbg/include/rdbg/servrpc.h
blob: 7e82f56ac1a3c2dca14e79f72ea5349b25ad7414 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/*
 * $Id$
 */

#ifndef SERVRPC_H
#define SERVRPC_H


#include <rtems/system.h>
#include <rtems/score/cpu.h>

#include <signal.h>		
#include <stdio.h>		
#include <stdlib.h>		
#include <string.h>		

#include <rpc/types.h>		
#include <rdbg/remdeb.h>	
#include <rpc/rpc.h>		
#include <rpc/svc.h>		

extern int CONN_LIST_INC;
extern int PID_LIST_INC;
extern int TSP_RETRIES;
extern int BackPort;
extern char taskName[];
extern int getId();


#ifdef DDEBUG
int   rdb_debug;		/* True if env var RDB_DEBUG defined */
extern const char* PtraceNames[]; /* list of ptrace requests for debug out */
extern const char* BmsgNames[]; /* list of BMSG_xxx names */
extern const char* PtraceName(int req);

#ifdef i386			/* low-high machine such as 386 */
#define HL_W(w)		(((UINT16)(w)>>8)+((((w)&0xFF)<<8)))
#define HL_D(d)		(((UINT32)(d)>>24)+(((d)&0x00FF0000)>>8) \
		       +(((d)&0xFF00)<<8)+(((d)&0xFF)<<24))
#else
#define HL_W(w)		w
#define HL_D(d)		d
#endif

# define DPRINTF(a)	(rdb_debug ? printk ("%d >>> ", getId()), printk a : 0)
#else
# define DPRINTF(a)		/* suppress */
#endif

  /* Macros for analyzing/creating process status values. Presently do
	not need to be separated per target. Could even use WIF... */

#define STS_SIGNALLED(status)	(((status) & 0xFF) == 0x7F)
#define STS_TERMONSIG(status)	(((status) & 0xFF) && !STS_SIGNALLED(status))
#define STS_TERMGETSIG(status)	((status) & 0x7F)
#define STS_MAKESIG(sig)	(((sig) << 8) | 0x7f)
#define STS_GETSIG(status)	((status) >> 8)
#define STS_GETCODE(status)	((status) >> 8)


/* now define base types */
#ifndef UCHAR_DEFINED
#define UCHAR_DEFINED		/* to handle duplicate typedes */
typedef unsigned char	UCHAR;
typedef unsigned char	UINT8;
typedef char		INT8;
typedef unsigned short	UINT16;
typedef short		INT16;
typedef unsigned long	UINT32;
typedef long		INT32;
#endif				/* UCHAR_DEFINED */

typedef long		PID;	/* generalized process id */

#ifndef True
# define True	1
# define False	0
typedef char Boolean;		
#endif

#define MAX_FILENAME	1024	/* largest filename with path */
#define MAX_SEND	5	/* up to 5 pended outbound messages */

#define SERVER_VERS     1

typedef enum
{				/* message types */
  BMSG_WARM=1,			/* warm test for network connection */
  BMSG_WAIT,			/* wait change (stopped/started) */
  BMSG_BREAK,			/* breakpoint changed */
  BMSG_EXEC_FAIL,		/* exec failed from spawn */
  BMSG_DETACH,			/* process detached from server */
  BMSG_KILLED,			/* killed by server */
  BMSG_NOT_PRIM,		/* no longer the primary owner */
  BMSG_NEW_PID			/* the process was restart with new pid (in
				   context). Same ownership rules.   */
} BACK_MSG;

typedef struct 
{				/* this is the break_list[0] entry of pid */
  UCHAR		clr_step;	/* true if step off break in last_break */
  UCHAR		pad1;		/* Set if STEPEMUL breakpoints exist */
  UINT16	last_break;	/* last breakpoint we stopped on (if break) */
  UINT32	range_start;	/* start address of range */
  UINT32	range_end;	/* end address inclusive */
} BASE_BREAK;

enum 
{				/* last start values */
  LAST_NONE,			/* stopped already */
  LAST_STEP,			/* did a step last - do not send to prim */
  LAST_CONT,			/* did a continue last */
  LAST_RANGE,			/* in the middle of step-in-range */
  LAST_STEPOFF,			/* stepped off break, now need to cont */
  LAST_KILLED,			/* was killed by ptrace */
  LAST_DETACHED			/* was detached by ptrace */
};
#define LAST_START 0x80		/* first execed. This is to handle MiX
				   bug where we need to start again */

typedef struct 
{				/* one per open process */
  PID		pid;		/* process id (or 0 if free) */
  int		state;		/* status from last wait if stopped */
  UCHAR		running;	/* True if running, else stopped/term */
  /* now connection control over process */
  UCHAR		owners;		/* count of owners for notify and term release */
  UCHAR		primary_conn;	/* primary owner connection or 255=none */

  UCHAR		filler;		/* Preserve alignment */

  /* now break control and support */
  UINT8		last_start;	/* LAST_xx start info for wait() */
  UINT8		flags;		/* PIDFLG_xxx flags */
  UINT16	break_alloc;	/* number of entries in break_list */
  xdr_break	*break_list;	/* list of breakpoints ([0] is BASE_BREAK) */
  /* now registers and other save information */
  xdr_regs	regs;		/* saved registers when stopped */
  int		is_step;	/* Was break or step (regs ambiguous often) */
  int		stop_wanted;	/* Don't ignore next stop */
  UINT32	thread;		/* current stopped thread or -1 if none */
  char		*name;		/* full pathname or NULL if not known */
  INT32		child;		/* child pid that manages the pid */
  UINT32	textStart;	/* for relocating breakpoints at restart */
} PID_LIST;
PID_LIST	*pid_list;	/* array of processes being managed */
int		pid_list_cnt;	/* number of entries allocated */
UINT16		last_break;	/* unique handle generator for breaks */
#define NO_PRIMARY ((UCHAR)-1)

typedef union
{				/* an opaque net address */
  unsigned long	l[4];
  unsigned char c[16];		/* corresponds to IP, enough for ChIPC */
} NET_OPAQUE;

typedef struct
{				/* one per connection */
  UCHAR		in_use;		/* True if in use */
  UCHAR		debug_type;	/* type of connection */
  UINT16	flags;		/* flags for connection (CFLG_xxx) */
  NET_OPAQUE 	sender;		/* opaque address for transport compare */
  NET_OPAQUE 	back_port;	/* opaque address for transport event msgs */
  NET_OPAQUE	route;		/* optional route address */
  UINT32	pid_map[10];	/* map of pids owned relative to pid list */
				/* this allows up to 320 pids to be managed */
  UCHAR 	last_msg_num;	/* msg number used last to handle multi-send */
  /* next field associated with UDP send messages */
  UCHAR		retry;		/* count of retries. If 0, ok. If not 0, we
				   are in active wait for reply to an event */
  UCHAR		send_idx;	/* current number of send's pended */
  struct SEND_LIST
  {				/* holds pending msgs */
    UCHAR 	send_type;	/* BMSG_xxx type of message */
    UCHAR	retry;		/* number of times to retry */
    UINT16	spec;		/* spec field */
    PID		pid;		/* pid if applies */
    UINT32	context;	/* additional context if needed */
  }		send_list[MAX_SEND]; /* pended list of messages being sent */
  char		user_name[NAMEMAX]; /* name of user connecting in */
  /* next fields are managed at runtime to handle lists, command upload, and
     command download.							*/
  enum {LST_NONE, LST_SPAWN, LST_INFO, LST_CMD_DOWN} list_type;
  char		*list;		/* curr list we are sending/getting (malloced) */
  UINT16	list_sz;	/* size of current list (string len) */
  UINT16	list_num;	/* number of current list or position */
  UINT16	list_alloc;	/* amount allocated so far */
  UINT16	list_save;	/* used internally */
} CONN_LIST;
CONN_LIST 	*conn_list;	/* an array of connections */
int		conn_list_cnt;	/* number allocated */

    /* Operations over the PID map. Each indexes into long and then bit */
    /* 5 is log2 of 32, the number of bits in an int */
#define PIDMAP_TEST(conn,idx) \
    (conn_list [conn].pid_map [(idx) >> 5] & (1 << ((idx) & 31)))

#define PIDMAP_SET(conn,idx) \
    (conn_list [conn].pid_map [(idx) >> 5] |= 1 << ((idx) & 31))

#define PIDMAP_CLEAR(conn,idx) \
    (conn_list [conn].pid_map [(idx) >> 5] &= ~(1 << ((idx) &31)))

#define PROC_TERMINATED(plst) \
    (!(plst)->running && !STS_SIGNALLED ((plst)->state))


/* first define the Connection routines exported from servcon.c */

int ConnCreate	(struct svc_req *rqstp, open_in *in);
void ConnDelete	(int conn_idx, struct svc_req *rqstp, close_control control);

void 	TspInit	(int rpc_io_channel);
Boolean TspTranslateRpcAddr	(struct svc_req *rqstp, NET_OPAQUE *opaque);
Boolean TspValidateAddr	(NET_OPAQUE *opaque, NET_OPAQUE *sender);
int 	TspConnGetIndex	(struct svc_req *rqstp);

void 	TspSendWaitChange  (int conn_idx, BACK_MSG msg, UINT16 spec, PID pid,
			    UINT32 context, Boolean force);
void 	TspSendMessage	   (int conn_idx, Boolean resend);
void 	TspMessageReceive  (int conn_idx, PID pid);
char* 	TspGetHostName     (int conn_idx);
void 	TgtCreateNew	   (PID pid, int conn_idx, INT32 child,
			    char *name, Boolean spawn);
Boolean TgtAttach	   (int conn_idx, PID pid);
void 	TgtNotifyWaitChange(PID pid, int status, Boolean exclude);
void 	TgtNotifyAll	   (int pid_idx, BACK_MSG msg, UINT16 spec,
			    UINT32 context, int exclude_conn, Boolean force);
void 	TgtDelete	   (PID_LIST*, int conn_idx, BACK_MSG notify);
int 	TgtKillAndDelete   (PID_LIST *plst, struct svc_req *rqstp, Boolean term);
void 	TgtDetachCon	   (int conn_idx, int pid_idx, Boolean delete);
int	TgtThreadList 	   (PID_LIST*, unsigned* buf, unsigned int size);
int	TgtGetThreadName   (PID_LIST*, unsigned thLi, char* name);
int 	TgtPtrace	   (int req, PID pid, char *addr, int data, void *addr2);
int 	TgtRealPtrace      (int req, PID pid, char *addr, int data, void *addr2);
Boolean TgtHandleChildChange(PID pid, int* status, int* unexp,
			     CPU_Exception_frame *ctx);
#ifdef DDEBUG
  /* TgtDbgPtrace is a wrapper for RealPtrace() doing traces */
int 	TgtDbgPtrace       (int req, PID pid, char *addr, int data, void *addr2);
#endif


/* Information stored in "handle" */
#define BKPT_INACTIVE	1	/* bkpt inactive for this execution */
#define BKPT_ACTIVE	0	/* bkpt active for this execution */

int 	BreakOverwrite 	(const PID_LIST* plst,const char* addr,
			 unsigned int size);
int 	BreakSet 	(PID_LIST*, int conn_idx, xdr_break*);
int 	BreakSetAt 	(PID_LIST*, int conn_idx, unsigned long addr,break_type);
int 	BreakClear 	(PID_LIST*, int conn_idx, int handle);
int 	BreakGetIndex	(PID_LIST*, void* addr);
int 	BreakGet 	(const PID_LIST*, int data, xdr_break*);
void 	BreakHide 	(const PID_LIST*, void*, int, void*);
int 	BreakStepOff 	(const PID_LIST*, void** paddr2);
void 	BreakSteppedOff (PID_LIST*);
int 	BreakRespawn 	(PID_LIST*);
int 	BreakIdentify 	(PID_LIST*, int adjust, int thread);
void 	BreakPcChanged 	(PID_LIST*);
int 	BreakStepRange 	(PID_LIST*, void* addr, int len);
void 	BreaksDisable 	(int pid);
void 	BreaksEnable 	(int pid);

int 	TgtBreakRestoreOrig (int pid, void* addr, void* addr2);
void 	TgtBreakCancelStep  (PID_LIST* plst);

Boolean ListAlloc	(char *buff, CONN_LIST *clst);
int 	FindPidEntry 	(int pid);

open_out*    RPCGENSRVNAME(open_connex_2_svc)    (open_in *in,
                                                 struct svc_req *rqstp);
signal_out*  RPCGENSRVNAME(send_signal_2_svc)    (signal_in *in,
                                                 struct svc_req *rqstp);
ptrace_out*  RPCGENSRVNAME(ptrace_2_svc)         (ptrace_in *in,
                                                 struct svc_req *rqstp);
wait_out*    RPCGENSRVNAME(wait_info_2_svc)      (wait_in *in,
                                                 struct svc_req *rqstp);
#endif /* !SERVRPC_H */