[981b99f] | 1 | /* |
---|
| 2 | * $Id$ |
---|
| 3 | */ |
---|
[4721cf1] | 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 | |
---|
[981b99f] | 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 | |
---|
[4721cf1] | 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 | |
---|