1 | /* |
---|
2 | * $Id$ |
---|
3 | */ |
---|
4 | |
---|
5 | #ifndef SERVRPC_H |
---|
6 | #define SERVRPC_H |
---|
7 | |
---|
8 | |
---|
9 | #include <rtems/system.h> |
---|
10 | #include <rtems/score/cpu.h> |
---|
11 | |
---|
12 | #include <signal.h> |
---|
13 | #include <stdio.h> |
---|
14 | #include <stdlib.h> |
---|
15 | #include <string.h> |
---|
16 | |
---|
17 | #include <rpc/types.h> |
---|
18 | #include <rdbg/remdeb.h> |
---|
19 | #include <rpc/rpc.h> |
---|
20 | #include <rpc/svc.h> |
---|
21 | |
---|
22 | extern int CONN_LIST_INC; |
---|
23 | extern int PID_LIST_INC; |
---|
24 | extern int TSP_RETRIES; |
---|
25 | extern int BackPort; |
---|
26 | extern char ActName[]; |
---|
27 | extern int getId(); |
---|
28 | |
---|
29 | |
---|
30 | #ifdef DDEBUG |
---|
31 | int rdb_debug; /* True if env var RDB_DEBUG defined */ |
---|
32 | extern const char* PtraceNames[]; /* list of ptrace requests for debug out */ |
---|
33 | extern const char* BmsgNames[]; /* list of BMSG_xxx names */ |
---|
34 | extern const char* PtraceName(int req); |
---|
35 | |
---|
36 | #ifdef i386 /* low-high machine such as 386 */ |
---|
37 | #define HL_W(w) (((UINT16)(w)>>8)+((((w)&0xFF)<<8))) |
---|
38 | #define HL_D(d) (((UINT32)(d)>>24)+(((d)&0x00FF0000)>>8) \ |
---|
39 | +(((d)&0xFF00)<<8)+(((d)&0xFF)<<24)) |
---|
40 | #else |
---|
41 | #define HL_W(w) w |
---|
42 | #define HL_D(d) d |
---|
43 | #endif |
---|
44 | |
---|
45 | # define DPRINTF(a) (rdb_debug ? printk ("%d >>> ", getId()), printk a : 0) |
---|
46 | #else |
---|
47 | # define DPRINTF(a) /* suppress */ |
---|
48 | #endif |
---|
49 | |
---|
50 | /* Macros for analyzing/creating process status values. Presently do |
---|
51 | not need to be separated per target. Could even use WIF... */ |
---|
52 | |
---|
53 | #define STS_SIGNALLED(status) (((status) & 0xFF) == 0x7F) |
---|
54 | #define STS_TERMONSIG(status) (((status) & 0xFF) && !STS_SIGNALLED(status)) |
---|
55 | #define STS_TERMGETSIG(status) ((status) & 0x7F) |
---|
56 | #define STS_MAKESIG(sig) (((sig) << 8) | 0x7f) |
---|
57 | #define STS_GETSIG(status) ((status) >> 8) |
---|
58 | #define STS_GETCODE(status) ((status) >> 8) |
---|
59 | |
---|
60 | |
---|
61 | /* now define base types */ |
---|
62 | #ifndef UCHAR_DEFINED |
---|
63 | #define UCHAR_DEFINED /* to handle duplicate typedes */ |
---|
64 | typedef unsigned char UCHAR; |
---|
65 | typedef unsigned char UINT8; |
---|
66 | typedef char INT8; |
---|
67 | typedef unsigned short UINT16; |
---|
68 | typedef short INT16; |
---|
69 | typedef unsigned long UINT32; |
---|
70 | typedef long INT32; |
---|
71 | #endif /* UCHAR_DEFINED */ |
---|
72 | |
---|
73 | typedef long PID; /* generalized process id */ |
---|
74 | |
---|
75 | #ifndef True |
---|
76 | # define True 1 |
---|
77 | # define False 0 |
---|
78 | typedef char Boolean; |
---|
79 | #endif |
---|
80 | |
---|
81 | #define MAX_FILENAME 1024 /* largest filename with path */ |
---|
82 | #define MAX_SEND 5 /* up to 5 pended outbound messages */ |
---|
83 | |
---|
84 | #define SERVER_VERS 1 |
---|
85 | |
---|
86 | typedef enum |
---|
87 | { /* message types */ |
---|
88 | BMSG_WARM=1, /* warm test for network connection */ |
---|
89 | BMSG_WAIT, /* wait change (stopped/started) */ |
---|
90 | BMSG_BREAK, /* breakpoint changed */ |
---|
91 | BMSG_EXEC_FAIL, /* exec failed from spawn */ |
---|
92 | BMSG_DETACH, /* process detached from server */ |
---|
93 | BMSG_KILLED, /* killed by server */ |
---|
94 | BMSG_NOT_PRIM, /* no longer the primary owner */ |
---|
95 | BMSG_NEW_PID /* the process was restart with new pid (in |
---|
96 | context). Same ownership rules. */ |
---|
97 | } BACK_MSG; |
---|
98 | |
---|
99 | typedef struct |
---|
100 | { /* this is the break_list[0] entry of pid */ |
---|
101 | UCHAR clr_step; /* true if step off break in last_break */ |
---|
102 | UCHAR pad1; /* Set if STEPEMUL breakpoints exist */ |
---|
103 | UINT16 last_break; /* last breakpoint we stopped on (if break) */ |
---|
104 | UINT32 range_start; /* start address of range */ |
---|
105 | UINT32 range_end; /* end address inclusive */ |
---|
106 | } BASE_BREAK; |
---|
107 | |
---|
108 | enum |
---|
109 | { /* last start values */ |
---|
110 | LAST_NONE, /* stopped already */ |
---|
111 | LAST_STEP, /* did a step last - do not send to prim */ |
---|
112 | LAST_CONT, /* did a continue last */ |
---|
113 | LAST_RANGE, /* in the middle of step-in-range */ |
---|
114 | LAST_STEPOFF, /* stepped off break, now need to cont */ |
---|
115 | LAST_KILLED, /* was killed by ptrace */ |
---|
116 | LAST_DETACHED /* was detached by ptrace */ |
---|
117 | }; |
---|
118 | #define LAST_START 0x80 /* first execed. This is to handle MiX |
---|
119 | bug where we need to start again */ |
---|
120 | |
---|
121 | typedef struct |
---|
122 | { /* one per open process */ |
---|
123 | PID pid; /* process id (or 0 if free) */ |
---|
124 | int state; /* status from last wait if stopped */ |
---|
125 | UCHAR running; /* True if running, else stopped/term */ |
---|
126 | /* now connection control over process */ |
---|
127 | UCHAR owners; /* count of owners for notify and term release */ |
---|
128 | UCHAR primary_conn; /* primary owner connection or 255=none */ |
---|
129 | |
---|
130 | UCHAR filler; /* Preserve alignment */ |
---|
131 | |
---|
132 | /* now break control and support */ |
---|
133 | UINT8 last_start; /* LAST_xx start info for wait() */ |
---|
134 | UINT8 flags; /* PIDFLG_xxx flags */ |
---|
135 | UINT16 break_alloc; /* number of entries in break_list */ |
---|
136 | xdr_break *break_list; /* list of breakpoints ([0] is BASE_BREAK) */ |
---|
137 | /* now registers and other save information */ |
---|
138 | xdr_regs regs; /* saved registers when stopped */ |
---|
139 | int is_step; /* Was break or step (regs ambiguous often) */ |
---|
140 | int stop_wanted; /* Don't ignore next stop */ |
---|
141 | UINT32 thread; /* current stopped thread or -1 if none */ |
---|
142 | char *name; /* full pathname or NULL if not known */ |
---|
143 | INT32 child; /* child pid that manages the pid */ |
---|
144 | UINT32 textStart; /* for relocating breakpoints at restart */ |
---|
145 | } PID_LIST; |
---|
146 | PID_LIST *pid_list; /* array of processes being managed */ |
---|
147 | int pid_list_cnt; /* number of entries allocated */ |
---|
148 | UINT16 last_break; /* unique handle generator for breaks */ |
---|
149 | #define NO_PRIMARY ((UCHAR)-1) |
---|
150 | |
---|
151 | typedef union |
---|
152 | { /* an opaque net address */ |
---|
153 | unsigned long l[4]; |
---|
154 | unsigned char c[16]; /* corresponds to IP, enough for ChIPC */ |
---|
155 | } NET_OPAQUE; |
---|
156 | |
---|
157 | typedef struct |
---|
158 | { /* one per connection */ |
---|
159 | UCHAR in_use; /* True if in use */ |
---|
160 | UCHAR debug_type; /* type of connection */ |
---|
161 | UINT16 flags; /* flags for connection (CFLG_xxx) */ |
---|
162 | NET_OPAQUE sender; /* opaque address for transport compare */ |
---|
163 | NET_OPAQUE back_port; /* opaque address for transport event msgs */ |
---|
164 | NET_OPAQUE route; /* optional route address */ |
---|
165 | UINT32 pid_map[10]; /* map of pids owned relative to pid list */ |
---|
166 | /* this allows up to 320 pids to be managed */ |
---|
167 | UCHAR last_msg_num; /* msg number used last to handle multi-send */ |
---|
168 | /* next field associated with UDP send messages */ |
---|
169 | UCHAR retry; /* count of retries. If 0, ok. If not 0, we |
---|
170 | are in active wait for reply to an event */ |
---|
171 | UCHAR send_idx; /* current number of send's pended */ |
---|
172 | struct SEND_LIST |
---|
173 | { /* holds pending msgs */ |
---|
174 | UCHAR send_type; /* BMSG_xxx type of message */ |
---|
175 | UCHAR retry; /* number of times to retry */ |
---|
176 | UINT16 spec; /* spec field */ |
---|
177 | PID pid; /* pid if applies */ |
---|
178 | UINT32 context; /* additional context if needed */ |
---|
179 | } send_list[MAX_SEND]; /* pended list of messages being sent */ |
---|
180 | char user_name[NAMEMAX]; /* name of user connecting in */ |
---|
181 | /* next fields are managed at runtime to handle lists, command upload, and |
---|
182 | command download. */ |
---|
183 | enum {LST_NONE, LST_SPAWN, LST_INFO, LST_CMD_DOWN} list_type; |
---|
184 | char *list; /* curr list we are sending/getting (malloced) */ |
---|
185 | UINT16 list_sz; /* size of current list (string len) */ |
---|
186 | UINT16 list_num; /* number of current list or position */ |
---|
187 | UINT16 list_alloc; /* amount allocated so far */ |
---|
188 | UINT16 list_save; /* used internally */ |
---|
189 | } CONN_LIST; |
---|
190 | CONN_LIST *conn_list; /* an array of connections */ |
---|
191 | int conn_list_cnt; /* number allocated */ |
---|
192 | |
---|
193 | /* Operations over the PID map. Each indexes into long and then bit */ |
---|
194 | /* 5 is log2 of 32, the number of bits in an int */ |
---|
195 | #define PIDMAP_TEST(conn,idx) \ |
---|
196 | (conn_list [conn].pid_map [(idx) >> 5] & (1 << ((idx) & 31))) |
---|
197 | |
---|
198 | #define PIDMAP_SET(conn,idx) \ |
---|
199 | (conn_list [conn].pid_map [(idx) >> 5] |= 1 << ((idx) & 31)) |
---|
200 | |
---|
201 | #define PIDMAP_CLEAR(conn,idx) \ |
---|
202 | (conn_list [conn].pid_map [(idx) >> 5] &= ~(1 << ((idx) &31))) |
---|
203 | |
---|
204 | #define PROC_TERMINATED(plst) \ |
---|
205 | (!(plst)->running && !STS_SIGNALLED ((plst)->state)) |
---|
206 | |
---|
207 | |
---|
208 | /* first define the Connection routines exported from servcon.c */ |
---|
209 | |
---|
210 | int ConnCreate (struct svc_req *rqstp, open_in *in); |
---|
211 | void ConnDelete (int conn_idx, struct svc_req *rqstp, close_control control); |
---|
212 | |
---|
213 | void TspInit (int rpc_io_channel); |
---|
214 | Boolean TspTranslateRpcAddr (struct svc_req *rqstp, NET_OPAQUE *opaque); |
---|
215 | Boolean TspValidateAddr (NET_OPAQUE *opaque, NET_OPAQUE *sender); |
---|
216 | int TspConnGetIndex (struct svc_req *rqstp); |
---|
217 | |
---|
218 | void TspSendWaitChange (int conn_idx, BACK_MSG msg, UINT16 spec, PID pid, |
---|
219 | UINT32 context, Boolean force); |
---|
220 | void TspSendMessage (int conn_idx, Boolean resend); |
---|
221 | void TspMessageReceive (int conn_idx, PID pid); |
---|
222 | char* TspGetHostName (int conn_idx); |
---|
223 | void TgtCreateNew (PID pid, int conn_idx, INT32 child, |
---|
224 | char *name, Boolean spawn); |
---|
225 | Boolean TgtAttach (int conn_idx, PID pid); |
---|
226 | void TgtNotifyWaitChange(PID pid, int status, Boolean exclude); |
---|
227 | void TgtNotifyAll (int pid_idx, BACK_MSG msg, UINT16 spec, |
---|
228 | UINT32 context, int exclude_conn, Boolean force); |
---|
229 | void TgtDelete (PID_LIST*, int conn_idx, BACK_MSG notify); |
---|
230 | int TgtKillAndDelete (PID_LIST *plst, struct svc_req *rqstp, Boolean term); |
---|
231 | void TgtDetachCon (int conn_idx, int pid_idx, Boolean delete); |
---|
232 | int TgtThreadList (PID_LIST*, unsigned* buf, unsigned int size); |
---|
233 | int TgtGetThreadName (PID_LIST*, unsigned thLi, char* name); |
---|
234 | int TgtPtrace (int req, PID pid, char *addr, int data, void *addr2); |
---|
235 | int TgtRealPtrace (int req, PID pid, char *addr, int data, void *addr2); |
---|
236 | Boolean TgtHandleChildChange(PID pid, int* status, int* unexp, |
---|
237 | CPU_Exception_frame *ctx); |
---|
238 | #ifdef DDEBUG |
---|
239 | /* TgtDbgPtrace is a wrapper for RealPtrace() doing traces */ |
---|
240 | int TgtDbgPtrace (int req, PID pid, char *addr, int data, void *addr2); |
---|
241 | #endif |
---|
242 | |
---|
243 | |
---|
244 | /* Information stored in "handle" */ |
---|
245 | #define BKPT_INACTIVE 1 /* bkpt inactive for this execution */ |
---|
246 | #define BKPT_ACTIVE 0 /* bkpt active for this execution */ |
---|
247 | |
---|
248 | int BreakOverwrite (const PID_LIST* plst,const char* addr, |
---|
249 | unsigned int size); |
---|
250 | int BreakSet (PID_LIST*, int conn_idx, xdr_break*); |
---|
251 | int BreakSetAt (PID_LIST*, int conn_idx, unsigned long addr,break_type); |
---|
252 | int BreakClear (PID_LIST*, int conn_idx, int handle); |
---|
253 | int BreakGetIndex (PID_LIST*, void* addr); |
---|
254 | int BreakGet (const PID_LIST*, int data, xdr_break*); |
---|
255 | void BreakHide (const PID_LIST*, void*, int, void*); |
---|
256 | int BreakStepOff (const PID_LIST*, void** paddr2); |
---|
257 | void BreakSteppedOff (PID_LIST*); |
---|
258 | int BreakRespawn (PID_LIST*); |
---|
259 | int BreakIdentify (PID_LIST*, int adjust, int thread); |
---|
260 | void BreakPcChanged (PID_LIST*); |
---|
261 | int BreakStepRange (PID_LIST*, void* addr, int len); |
---|
262 | void BreaksDisable (int pid); |
---|
263 | void BreaksEnable (int pid); |
---|
264 | |
---|
265 | int TgtBreakRestoreOrig (int pid, void* addr, void* addr2); |
---|
266 | void TgtBreakCancelStep (PID_LIST* plst); |
---|
267 | |
---|
268 | Boolean ListAlloc (char *buff, CONN_LIST *clst); |
---|
269 | int FindPidEntry (int pid); |
---|
270 | |
---|
271 | open_out* RPCGENSRVNAME(open_connex_2_svc) (open_in *in, |
---|
272 | struct svc_req *rqstp); |
---|
273 | signal_out* RPCGENSRVNAME(send_signal_2_svc) (signal_in *in, |
---|
274 | struct svc_req *rqstp); |
---|
275 | ptrace_out* RPCGENSRVNAME(ptrace_2_svc) (ptrace_in *in, |
---|
276 | struct svc_req *rqstp); |
---|
277 | wait_out* RPCGENSRVNAME(wait_info_2_svc) (wait_in *in, |
---|
278 | struct svc_req *rqstp); |
---|
279 | #endif /* !SERVRPC_H */ |
---|
280 | |
---|