1 /* Copyright 1993 Free Software Foundation, Inc.
3 This file is part of GDB.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 static char udip2soc_c
[]="@(#)udip2soc.c 2.11 Daniel Mann";
20 static char udip2soc_c_AMD
[]="@(#)udip2soc.c 2.8, AMD";
22 * This module converts UDI Procedural calls into
23 * UDI socket messages for UNIX.
24 * It is used by DFE client processes
25 ********************************************************************** HISTORY
27 /* This is all unneeded on DOS machines. */
33 /* Before sys/file.h for Unixware. */
34 #include <sys/types.h>
38 /* This used to say sys/fcntl.h, but the only systems I know of that
39 require that are old (pre-4.3, at least) BSD systems, which we
40 probably don't need to worry about. */
45 #include <sys/resource.h>
46 #include <sys/socket.h>
47 #include <netinet/in.h>
50 #include <sys/errno.h>
56 extern char* sys_errlist
[];
58 extern char* getenv();
60 /* local type decs. and macro defs. not in a .h file ************* MACRO/TYPE
62 #define version_c 0x121 /* DFE-IPC version id */
66 #define MAX_SESSIONS 5 /* maximum DFE-TIP connections */
67 #define SOC_BUF_SIZE 4* 1024 /* size of socket comms buffer */
68 #define SBUF_SIZE 500 /* size of string buffer */
69 #define ERRMSG_SIZE 500 /* size of error message buffer */
71 typedef struct connection_str
/* record of connect session */
74 char connect_id
[20]; /* connection identifier */
75 char domain_string
[20]; /* dommaing for conection */
76 char tip_string
[30]; /* TIP host name for AF_INET */
77 char tip_exe
[80]; /* TIP exe name */
78 int dfe_sd
; /* associated DFE socket */
79 int tip_pid
; /* pid of TIP process */
80 struct sockaddr_in dfe_sockaddr
;
81 struct sockaddr_in tip_sockaddr_in
;
82 struct sockaddr tip_sockaddr
;
85 typedef struct session_str
88 connection_t
* soc_con_p
; /* associated connection */
89 UDISessionId tip_id
; /* associated TIP session ID */
92 /* global dec/defs. which are not in a .h file ************* EXPORT DEC/DEFS
95 char dfe_errmsg
[ERRMSG_SIZE
];/* error string */
97 /* local dec/defs. which are not in a .h file *************** LOCAL DEC/DEFS
99 LOCAL connection_t soc_con
[MAX_SESSIONS
];
100 LOCAL session_t session
[MAX_SESSIONS
];
102 LOCAL UDR
* udrs
= &udr
; /* UDR for current session */
103 LOCAL
int current
; /* int-id for current session */
104 LOCAL
char sbuf
[SBUF_SIZE
]; /* String handler buffer */
105 LOCAL
char config_file
[80]; /* path/name for config file */
107 /***************************************************************** UDI_CONNECT
108 * Establish a new FDE to TIP conection. The file "./udi_soc" or
109 * "/etc/udi_soc" may be examined to obtain the conection information
110 * if the "Config" parameter is not a completd "line entry".
112 * NOTE: the Session string must not start whith white-space characters.
113 * Format of string is:
114 * <session> <domain> <soc_name|host_name> <tip_exe|port> <pass to UDIconnect>
115 * soc2cayman AF_INET cayman 7000 <not supported>
116 * soc2tip AF_UNIX astring tip.exe ...
119 UDIConnect(Config
, Session
)
120 char *Config
; /* in -- identification string */
121 UDISessionId
*Session
; /* out -- session ID */
123 UDIInt32 service_id
= UDIConnect_c
;
126 int rcnt
, pos
, params_pos
=0;
127 char *tip_main_string
;
129 struct hostent
*tip_info_p
;
137 #if 0 /* This is crap. It assumes that udi_soc is executable! */
138 sprintf(sbuf
, "which udi_soc");
139 f_p
= popen(sbuf
, "r");
141 { while( (sbuf
[cnt
++]=getc(f_p
)) != EOF
);
148 rcnt
< MAX_SESSIONS
&& session
[rcnt
].in_use
;
151 if (rcnt
>= MAX_SESSIONS
)
153 sprintf(dfe_errmsg
, "DFE-ipc ERROR: Too many sessions already open");
154 return UDIErrorIPCLimitation
;
157 /* One connection can be multiplexed between several sessions. */
160 cnt
< MAX_SESSIONS
&& soc_con
[cnt
].in_use
;
163 if (cnt
>= MAX_SESSIONS
)
166 "DFE-ipc ERROR: Too many connections already open");
167 return UDIErrorIPCLimitation
;
171 session
[rcnt
].soc_con_p
= &soc_con
[cnt
];
173 if (strchr(Config
, ' ')) /* test if file entry given */
175 soc_con
[cnt
].in_use
= TRUE
;
176 sscanf(Config
, "%s %s %s %s %n",
177 soc_con
[cnt
].connect_id
,
178 soc_con
[cnt
].domain_string
,
179 soc_con
[cnt
].tip_string
,
180 soc_con
[cnt
].tip_exe
,
182 tip_main_string
= Config
+ params_pos
;
184 else /* here if need to read udi_soc file */
186 strcpy(config_file
, "udi_soc");
187 env_p
= getenv("UDICONF");
189 strcpy(config_file
, env_p
);
191 fd
= fopen(config_file
, "r");
195 sprintf(dfe_errmsg
, "UDIConnect, can't open udi_soc file:\n%s ",
197 dfe_errno
= UDIErrorCantOpenConfigFile
;
203 if (fscanf(fd
, "%s %s %s %s %[^\n]\n",
204 soc_con
[cnt
].connect_id
,
205 soc_con
[cnt
].domain_string
,
206 soc_con
[cnt
].tip_string
,
207 soc_con
[cnt
].tip_exe
,
211 if (strcmp(Config
, soc_con
[cnt
].connect_id
) != 0)
214 soc_con
[cnt
].in_use
= TRUE
; /* here if entry found */
216 tip_main_string
= sbuf
;
221 if (!soc_con
[cnt
].in_use
)
224 "UDIConnect, can't find `%s' entry in udi_soc file",
226 dfe_errno
= UDIErrorNoSuchConfiguration
;
230 /*----------------------------------------------------------- SELECT DOMAIN */
231 if (strcmp(soc_con
[cnt
].domain_string
, "AF_UNIX") == 0)
233 else if (strcmp(soc_con
[cnt
].domain_string
, "AF_INET") == 0)
237 sprintf(dfe_errmsg
, "DFE-ipc ERROR: socket address family not known");
238 dfe_errno
= UDIErrorBadConfigFileEntry
;
242 /*---------------------------------------------------- MULTIPLEXED SOCKET ? */
243 /* If the requested session requires communication with
244 a TIP which already has a socket connection established,
245 then we do not create a new socket but multiplex the
246 existing one. A TIP is said to use the same socket if
247 socket-name/host-name and the domain are the same.
249 for (rcnt
=0; rcnt
< MAX_SESSIONS
; rcnt
++)
251 if (soc_con
[rcnt
].in_use
253 && strcmp(soc_con
[cnt
].domain_string
,
254 soc_con
[rcnt
].domain_string
) == 0
255 && strcmp(soc_con
[cnt
].tip_string
,
256 soc_con
[rcnt
].tip_string
) == 0)
258 session
[*Session
].soc_con_p
= &soc_con
[rcnt
];
259 soc_con
[cnt
].in_use
= FALSE
; /* don't need new connect */
263 /*------------------------------------------------------------------ SOCKET */
264 soc_con
[cnt
].dfe_sd
= socket(domain
, SOCK_STREAM
, 0);
265 if (soc_con
[cnt
].dfe_sd
== -1)
267 sprintf(dfe_errmsg
, "DFE-ipc ERROR, socket() call failed %s ",
269 dfe_errno
= UDIErrorUnknownError
;
273 /*--------------------------------------------------------- AF_UNIX CONNECT */
274 if (domain
== AF_UNIX
)
276 if (strcmp(soc_con
[cnt
].tip_string
, "*") == 0)
278 for (pos
= 0; pos
< 20; pos
++)
282 sprintf(soc_con
[cnt
].tip_string
,"/tmp/U%d", getpid() + pos
);
283 f
= open(soc_con
[cnt
].tip_string
, O_CREAT
);
288 unlink(soc_con
[cnt
].tip_string
);
295 "DFE-ipc ERROR, can't create random socket name");
296 dfe_errno
= UDIErrorCantConnect
;
301 soc_con
[cnt
].tip_sockaddr
.sa_family
= domain
;
302 memcpy(soc_con
[cnt
].tip_sockaddr
.sa_data
,
303 soc_con
[cnt
].tip_string
,
304 sizeof(soc_con
[cnt
].tip_sockaddr
.sa_data
));
305 if (connect(soc_con
[cnt
].dfe_sd
,
306 &soc_con
[cnt
].tip_sockaddr
,
307 sizeof(soc_con
[cnt
].tip_sockaddr
)))
308 { /* if connect() fails assume TIP not yet started */
309 /*------------------------------------------------------------ AF_UNIX EXEC */
314 arg0
= strrchr(soc_con
[cnt
].tip_exe
,'/');
319 arg0
= soc_con
[cnt
].tip_exe
;
323 if (pid
== 0) /* Child */
325 execlp(soc_con
[cnt
].tip_exe
,
327 soc_con
[cnt
].domain_string
,
328 soc_con
[cnt
].tip_string
,
333 if (waitpid(pid
, &statusp
, WNOHANG
))
335 sprintf(dfe_errmsg
, "DFE-ipc ERROR: can't exec the TIP");
336 dfe_errno
= UDIErrorCantStartTIP
;
341 for (pos
= 3; pos
> 0; pos
--)
343 if (!connect(soc_con
[cnt
].dfe_sd
,
344 &soc_con
[cnt
].tip_sockaddr
,
345 sizeof(soc_con
[cnt
].tip_sockaddr
)))
352 sprintf(dfe_errmsg
, "DFE-ipc ERROR, connect() call failed: %s",
354 dfe_errno
= UDIErrorCantConnect
;
359 /*--------------------------------------------------------- AF_INET CONNECT */
360 else if (domain
== AF_INET
)
363 "DFE-ipc WARNING, need to have first started remote TIP");
365 soc_con
[cnt
].tip_sockaddr_in
.sin_family
= domain
;
366 soc_con
[cnt
].tip_sockaddr_in
.sin_addr
.s_addr
=
367 inet_addr(soc_con
[cnt
].tip_string
);
368 if (soc_con
[cnt
].tip_sockaddr_in
.sin_addr
.s_addr
== -1)
370 tip_info_p
= gethostbyname(soc_con
[cnt
].tip_string
);
371 if (tip_info_p
== NULL
)
373 sprintf(dfe_errmsg
,"DFE-ipc ERROR, No such host %s",
374 soc_con
[cnt
].tip_string
);
375 dfe_errno
= UDIErrorNoSuchConnection
;
378 memcpy((char *)&soc_con
[cnt
].tip_sockaddr_in
.sin_addr
,
380 tip_info_p
->h_length
);
382 soc_con
[cnt
].tip_sockaddr_in
.sin_port
383 = htons(atoi(soc_con
[cnt
].tip_exe
));
385 if (connect(soc_con
[cnt
].dfe_sd
,
386 (struct sockaddr
*) &soc_con
[cnt
].tip_sockaddr_in
,
387 sizeof(soc_con
[cnt
].tip_sockaddr_in
)))
389 sprintf(dfe_errmsg
, "DFE-ipc ERROR, connect() call failed %s ",
391 dfe_errno
= UDIErrorCantConnect
;
395 /*------------------------------------------------------------- TIP CONNECT */
396 if (cnt
== 0) udr_create(udrs
, soc_con
[cnt
].dfe_sd
, SOC_BUF_SIZE
);
400 session
[*Session
].in_use
= TRUE
; /* session id is now in use */
403 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
404 udr_UDIInt32(udrs
, &service_id
);
406 DFEIPCId
= (company_c
<< 16) + (product_c
<< 12) + version_c
;
407 udr_UDIUInt32(udrs
, &DFEIPCId
);
409 udr_string(udrs
, tip_main_string
);
413 udrs
->udr_op
= UDR_DECODE
; /* recv all "out" parameters */
414 udr_UDIUInt32(udrs
, &TIPIPCId
);
415 if ((TIPIPCId
& 0xfff) < version_c
)
416 sprintf(dfe_errmsg
, "DFE-ipc: Obsolete TIP Specified");
418 udr_UDIInt32(udrs
, &soc_con
[cnt
].tip_pid
);
420 udr_UDISessionId(udrs
, &session
[*Session
].tip_id
);
422 udr_UDIError(udrs
, &dfe_errno
);
423 if (dfe_errno
> 0) UDIKill(*Session
, 0);
429 soc_con
[cnt
].in_use
= FALSE
;
430 session
[*Session
].in_use
= FALSE
;
431 /* XXX - Should also close dfe_sd, but not sure what to do if muxed */
435 /************************************************************** UDI_Disconnect
436 * UDIDisconnect() should be called before exiting the
437 * DFE to ensure proper shut down of the TIP.
439 UDIError
UDIDisconnect(Session
, Terminate
)
440 UDISessionId Session
;
444 UDIInt32 service_id
= UDIDisconnect_c
;
445 if(Session
< 0 || Session
> MAX_SESSIONS
)
447 sprintf(dfe_errmsg
," SessionId not valid (%d)", Session
);
448 return UDIErrorNoSuchConfiguration
;
451 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
452 udr_UDIInt32(udrs
, &service_id
);
453 udr_UDISessionId(udrs
, &session
[Session
].tip_id
);
454 udr_UDIBool(udrs
, &Terminate
);
457 session
[Session
].in_use
= FALSE
; /* session id is now free */
458 for (cnt
=0; cnt
< MAX_SESSIONS
; cnt
++)
459 if(session
[cnt
].in_use
460 && session
[cnt
].soc_con_p
== session
[Session
].soc_con_p
462 if(cnt
>= MAX_SESSIONS
) /* test if socket not multiplexed */
463 if(shutdown(session
[Session
].soc_con_p
->dfe_sd
, 2))
465 sprintf(dfe_errmsg
, "DFE-ipc WARNING: socket shutdown failed");
466 return UDIErrorIPCInternal
;
469 session
[Session
].soc_con_p
->in_use
= 0;
471 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
472 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
476 /******************************************************************** UDI_KILL
477 * UDIKill() is used to send a signal to the TIP.
478 * This is a private IPC call.
480 UDIError
UDIKill(Session
, Signal
)
481 UDISessionId Session
;
485 UDIInt32 service_id
= UDIKill_c
;
486 if(Session
< 0 || Session
> MAX_SESSIONS
)
488 sprintf(dfe_errmsg
," SessionId not valid (%d)", Session
);
489 return UDIErrorNoSuchConfiguration
;
492 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
493 udr_UDIInt32(udrs
, &service_id
);
494 udr_UDISessionId(udrs
, &session
[Session
].tip_id
);
495 udr_UDIInt32(udrs
, &Signal
);
498 session
[Session
].in_use
= FALSE
; /* session id is now free */
499 for (cnt
=0; cnt
< MAX_SESSIONS
; cnt
++)
500 if(session
[cnt
].in_use
501 && session
[cnt
].soc_con_p
== session
[Session
].soc_con_p
503 if(cnt
< MAX_SESSIONS
) /* test if socket not multiplexed */
504 if(shutdown(session
[Session
].soc_con_p
->dfe_sd
, 2))
506 sprintf(dfe_errmsg
, "DFE-ipc WARNING: socket shutdown failed");
507 return UDIErrorIPCInternal
;
510 session
[Session
].soc_con_p
->in_use
= 0;
512 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
513 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
517 /************************************************** UDI_Set_Current_Connection
518 * If you are connected to multiple TIPs, you can change
519 * TIPs using UDISetCurrentConnection().
521 UDIError
UDISetCurrentConnection(Session
)
522 UDISessionId Session
;
524 UDIInt32 service_id
= UDISetCurrentConnection_c
;
526 if(Session
< 0 || Session
> MAX_SESSIONS
)
527 return UDIErrorNoSuchConfiguration
;
528 if(!session
[Session
].in_use
) /* test if not in use yet */
529 return UDIErrorNoSuchConnection
;
532 /* change socket or multiplex the same socket */
533 udrs
->sd
= session
[Session
].soc_con_p
->dfe_sd
;
536 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
537 udr_UDIInt32(udrs
, &service_id
);
538 udr_UDISessionId(udrs
, &session
[Session
].tip_id
);
540 if(udr_errno
) return udr_errno
;
542 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
543 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
547 /************************************************************ UDI_Capabilities
548 * The DFE uses UDICapabilities() to both inform the TIP
549 * of what services the DFE offers and to inquire of the
550 * TIP what services the TIP offers.
552 UDIError
UDICapabilities(TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
,
554 UDIUInt32
*TIPId
; /* out */
555 UDIUInt32
*TargetId
; /* out */
556 UDIUInt32 DFEId
; /* in */
557 UDIUInt32 DFE
; /* in */
558 UDIUInt32
*TIP
; /* out */
559 UDIUInt32
*DFEIPCId
; /* out */
560 UDIUInt32
*TIPIPCId
; /* out */
561 char *TIPString
; /* out */
563 UDIInt32 service_id
= UDICapabilities_c
;
567 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
568 udr_UDIInt32(udrs
, &service_id
);
569 udr_UDIInt32(udrs
, &DFEId
);
570 udr_UDIInt32(udrs
, &DFE
);
572 if(udr_errno
) return udr_errno
;
574 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" paramters */
575 udr_UDIInt32(udrs
, TIPId
);
576 udr_UDIInt32(udrs
, TargetId
);
577 udr_UDIInt32(udrs
, TIP
);
578 udr_UDIInt32(udrs
, DFEIPCId
);
579 *DFEIPCId
= (company_c
<< 16) + (product_c
<< 12) + version_c
;
580 udr_UDIInt32(udrs
, TIPIPCId
);
581 udr_string(udrs
, sbuf
);
582 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
584 if(size
+1 > 80) return -1; /* test if sufficient space */
585 strcpy(TIPString
, sbuf
);
589 /********************************************************** UDI_Enumerate_TIPs
590 * Used by the DFE to enquire about available TIP
593 UDIError
UDIEnumerateTIPs(UDIETCallback
)
594 int (*UDIETCallback
)(); /* In -- function to callback */
598 fp
= fopen(config_file
, "r");
600 return UDIErrorCantOpenConfigFile
;
601 while(fgets( sbuf
, SBUF_SIZE
, fp
))
602 if(UDIETCallback( sbuf
) == UDITerminateEnumeration
)
605 return UDINoError
; /* return success */
608 /*********************************************************** UDI_GET_ERROR_MSG
609 * Some errors are target specific. They are indicated
610 * by a negative error return value. The DFE uses
611 * UDIGetErrorMsg() to get the descriptive text for
612 * the error message which can then be displayed to
615 UDIError
UDIGetErrorMsg(error_code
, msg_len
, msg
, CountDone
)
616 UDIError error_code
; /* In */
617 UDISizeT msg_len
; /* In -- allowed message space */
618 char* msg
; /* Out -- length of message*/
619 UDISizeT
*CountDone
; /* Out -- number of characters */
621 UDIInt32 service_id
= UDIGetErrorMsg_c
;
625 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
626 udr_UDIInt32(udrs
, &service_id
);
627 udr_UDIError(udrs
, &error_code
);
628 udr_UDISizeT(udrs
, &msg_len
);
630 if(udr_errno
) return udr_errno
;
632 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
633 udr_string(udrs
, sbuf
);
634 udr_UDISizeT(udrs
, CountDone
);
635 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
637 if(size
+1 > msg_len
) return -1; /* test if sufficient space */
642 /******************************************************* UDI_GET_TARGET_CONFIG
643 * UDIGetTargetConfig() gets information about the target.
645 UDIError
UDIGetTargetConfig(KnownMemory
, NumberOfRanges
, ChipVersions
,
647 UDIMemoryRange KnownMemory
[]; /* Out */
648 UDIInt
*NumberOfRanges
; /* In and Out */
649 UDIUInt32 ChipVersions
[]; /* Out */
650 UDIInt
*NumberOfChips
; /* In and Out */
652 UDIInt32 service_id
= UDIGetTargetConfig_c
;
654 int MaxOfRanges
= *NumberOfRanges
;
657 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
658 udr_UDIInt32(udrs
, &service_id
);
659 udr_UDIInt(udrs
, NumberOfRanges
);
660 udr_UDIInt(udrs
, NumberOfChips
);
662 if(udr_errno
) return udr_errno
;
664 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" paramters */
665 for(cnt
=1; cnt
<= MaxOfRanges
; cnt
++)
666 udr_UDIMemoryRange(udrs
, &KnownMemory
[cnt
-1]);
667 udr_UDIInt(udrs
, NumberOfRanges
);
668 udr_UDIInt(udrs
, NumberOfChips
);
669 for(cnt
=1; cnt
<= *NumberOfChips
; cnt
++)
670 udr_UDIUInt32(udrs
, &ChipVersions
[cnt
-1]);
671 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
675 /********************************************************** UDI_CREATE_PRCOESS
676 * UDICreateProcess() tells the target OS that a
677 * process is to be created and gets a PID back unless
678 * there is some error.
680 UDIError
UDICreateProcess(pid
)
681 UDIPId
*pid
; /* out */
683 UDIInt32 service_id
= UDICreateProcess_c
;
686 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
687 udr_UDIInt32(udrs
, &service_id
);
689 if(udr_errno
) return udr_errno
;
691 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
692 udr_UDIPId(udrs
, pid
);
693 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
697 /***************************************************** UDI_Set_Current_Process
698 * UDISetCurrentProcess uses a pid supplied by
699 * UDICreateProcess and sets it as the default for all
700 * udi calls until a new one is set. A user of a
702 UDIError
UDISetCurrentProcess (pid
)
705 UDIInt32 service_id
= UDISetCurrentProcess_c
;
708 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
709 udr_UDIInt32(udrs
, &service_id
);
710 udr_UDIPId(udrs
, &pid
);
712 if(udr_errno
) return udr_errno
;
714 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
715 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
719 /****************************************************** UDI_INITIALISE_PROCESS
720 * UDIInitializeProcess() prepare process for
721 * execution. (Reset processor if process os processor).
723 UDIError
UDIInitializeProcess( ProcessMemory
, NumberOfRanges
, EntryPoint
,
724 StackSizes
, NumberOfStacks
, ArgString
)
725 UDIMemoryRange ProcessMemory
[]; /* In */
726 UDIInt NumberOfRanges
; /* In */
727 UDIResource EntryPoint
; /* In */
728 CPUSizeT
*StackSizes
; /* In */
729 UDIInt NumberOfStacks
; /* In */
730 char *ArgString
; /* In */
732 UDIInt32 service_id
= UDIInitializeProcess_c
;
736 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
737 udr_UDIInt32(udrs
, &service_id
);
738 udr_UDIInt(udrs
, &NumberOfRanges
);
739 for(cnt
= 0; cnt
< NumberOfRanges
; cnt
++)
740 udr_UDIMemoryRange(udrs
, &ProcessMemory
[cnt
] );
741 udr_UDIResource(udrs
, &EntryPoint
);
742 udr_UDIInt(udrs
, &NumberOfStacks
);
743 for(cnt
= 0; cnt
< NumberOfStacks
; cnt
++)
744 udr_CPUSizeT(udrs
, &StackSizes
[cnt
]);
745 udr_string(udrs
, ArgString
);
747 if(udr_errno
) return udr_errno
;
749 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
750 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
754 /********************************************************* UDI_DESTROY_PROCESS
755 * UDIDestroyProcess() frees a process resource
756 * previously created by UDICreateProcess().
758 UDIError
UDIDestroyProcess(pid
)
761 UDIInt32 service_id
= UDIDestroyProcess_c
;
764 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
765 udr_UDIInt32(udrs
, &service_id
);
766 udr_UDIPId(udrs
, &pid
);
768 if(udr_errno
) return udr_errno
;
770 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
771 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
775 /****************************************************************** UDI_READ
776 * UDIRead() reads a block of objects from a target
777 * address space to host space.
780 UDIError
UDIRead (from
, to
, count
, size
, count_done
, host_endian
)
781 UDIResource from
; /* in - source address on target */
782 UDIHostMemPtr to
; /* out - destination address on host */
783 UDICount count
; /* in -- count of objects to be transferred */
784 UDISizeT size
; /* in -- size of each object */
785 UDICount
*count_done
; /* out - count actually transferred */
786 UDIBool host_endian
; /* in -- flag for endian information */
788 UDIInt32 service_id
= UDIRead_c
;
792 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
793 udr_UDIInt32(udrs
, &service_id
);
794 udr_UDIResource(udrs
, &from
);
795 udr_UDICount(udrs
, &count
);
796 udr_UDISizeT(udrs
, &size
);
797 udr_UDIBool(udrs
, &host_endian
);
799 if(udr_errno
) return udr_errno
;
801 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" paramters */
802 udr_UDICount(udrs
, count_done
);
803 byte_count
= (*count_done
) * size
;
804 if(*count_done
> 0 && *count_done
<= count
)
805 udr_bytes(udrs
, to
, byte_count
);
806 if(udr_errno
) return udr_errno
;
807 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
811 /****************************************************************** UDI_WRITE
812 * UDIWrite() writes a block of objects from host
813 * space to a target address+space.
815 UDIError
UDIWrite( from
, to
, count
, size
, count_done
, host_endian
)
816 UDIHostMemPtr from
; /* in -- source address on host */
817 UDIResource to
; /* in -- destination address on target */
818 UDICount count
; /* in -- count of objects to be transferred */
819 UDISizeT size
; /* in -- size of each object */
820 UDICount
*count_done
; /* out - count actually transferred */
821 UDIBool host_endian
; /* in -- flag for endian information */
823 UDIInt32 service_id
= UDIWrite_c
;
824 int byte_count
= count
* size
;
827 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
828 udr_UDIInt32(udrs
, &service_id
);
829 udr_UDIResource(udrs
, &to
);
830 udr_UDICount(udrs
, &count
);
831 udr_UDISizeT(udrs
, &size
);
832 udr_UDIBool(udrs
, &host_endian
);
833 udr_bytes(udrs
, from
, byte_count
);
835 if(udr_errno
) return udr_errno
;
837 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" paramters */
838 udr_UDICount(udrs
, count_done
);
839 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
843 /******************************************************************** UDI_COPY
844 * UDICopy() copies a block of objects from one target
845 * get address/space to another target address/space.
847 UDIError
UDICopy(from
, to
, count
, size
, count_done
, direction
)
848 UDIResource from
; /* in -- destination address on target */
849 UDIResource to
; /* in -- source address on target */
850 UDICount count
; /* in -- count of objects to be transferred */
851 UDISizeT size
; /* in -- size of each object */
852 UDICount
*count_done
; /* out - count actually transferred */
853 UDIBool direction
; /* in -- high-to-low or reverse */
855 UDIInt32 service_id
= UDICopy_c
;
858 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
859 udr_UDIInt32(udrs
, &service_id
);
860 udr_UDIResource(udrs
, &from
);
861 udr_UDIResource(udrs
, &to
);
862 udr_UDICount(udrs
, &count
);
863 udr_UDISizeT(udrs
, &size
);
864 udr_UDIBool(udrs
, &direction
);
866 if(udr_errno
) return udr_errno
;
868 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
869 udr_UDICount(udrs
, count_done
);
870 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
874 /***************************************************************** UDI_EXECUTE
875 * UDIExecute() continues execution of the default
876 * process from the current PC.
878 UDIError
UDIExecute()
880 UDIInt32 service_id
= UDIExecute_c
;
883 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
884 udr_UDIInt32(udrs
, &service_id
);
886 if(udr_errno
) return udr_errno
;
888 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
889 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
893 /******************************************************************** UDI_STEP
894 * UDIStep() specifies a number of "instruction"
897 UDIError
UDIStep(steps
, steptype
, range
)
898 UDIUInt32 steps
; /* in -- number of steps */
899 UDIStepType steptype
; /* in -- type of stepping to be done */
900 UDIRange range
; /* in -- range if StepInRange is TRUE */
902 UDIInt32 service_id
= UDIStep_c
;
905 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
906 udr_UDIInt32(udrs
, &service_id
);
907 udr_UDIInt32(udrs
, &steps
);
908 udr_UDIStepType(udrs
, &steptype
);
909 udr_UDIRange(udrs
, &range
);
911 if(udr_errno
) return udr_errno
;
913 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
914 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
918 /******************************************************************** UDI_STOP
919 * UDIStop() stops the default process
923 if (strcmp(session
[current
].soc_con_p
->domain_string
, "AF_UNIX") == 0)
924 kill(session
[current
].soc_con_p
->tip_pid
, SIGINT
);
928 /* XXX - should clean up session[] and soc_con[] structs here as well... */
933 /******************************************************************** UDI_WAIT
934 * UDIWait() returns the state of the target procesor.
936 UDIError
UDIWait(maxtime
, pid
, stop_reason
)
937 UDIInt32 maxtime
; /* in -- maximum time to wait for completion */
938 UDIPId
*pid
; /* out -- pid of process which stopped if any */
939 UDIUInt32
*stop_reason
; /* out -- PC where process stopped */
941 UDIInt32 service_id
= UDIWait_c
;
944 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
945 udr_UDIInt32(udrs
, &service_id
);
946 udr_UDIInt32(udrs
, &maxtime
);
948 if(udr_errno
) return udr_errno
;
950 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
951 udr_UDIPId(udrs
, pid
);
952 udr_UDIUInt32(udrs
, stop_reason
);
953 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
957 /********************************************************** UDI_SET_BREAKPOINT
958 * UDISetBreakpoint() sets a breakpoint at an adress
959 * and uses the passcount to state how many
960 * times that instruction should be hit before the
963 UDIError
UDISetBreakpoint (addr
, passcount
, type
, break_id
)
964 UDIResource addr
; /* in -- where breakpoint gets set */
965 UDIInt32 passcount
; /* in -- passcount for breakpoint */
966 UDIBreakType type
; /* in -- breakpoint type */
967 UDIBreakId
*break_id
; /* out - assigned break id */
969 UDIInt32 service_id
= UDISetBreakpoint_c
;
972 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
973 udr_UDIInt32(udrs
, &service_id
);
974 udr_UDIResource(udrs
, &addr
);
975 udr_UDIInt32(udrs
, &passcount
);
976 udr_UDIBreakType(udrs
, &type
);
978 if(udr_errno
) return udr_errno
;
980 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
981 udr_UDIBreakId(udrs
, break_id
);
982 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
986 /******************************************************** UDI_QUERY_BREAKPOINT
988 UDIError
UDIQueryBreakpoint (break_id
, addr
, passcount
, type
, current_count
)
989 UDIBreakId break_id
; /* in -- assigned break id */
990 UDIResource
*addr
; /* out - where breakpoint was set */
991 UDIInt32
*passcount
; /* out - trigger passcount for breakpoint */
992 UDIBreakType
*type
; /* out - breakpoint type */
993 UDIInt32
*current_count
; /* out - current count for breakpoint */
995 UDIInt32 service_id
= UDIQueryBreakpoint_c
;
998 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
999 udr_UDIInt32(udrs
, &service_id
);
1000 udr_UDIBreakId(udrs
, &break_id
);
1002 if(udr_errno
) return udr_errno
;
1004 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1005 udr_UDIResource(udrs
, addr
);
1006 udr_UDIInt32(udrs
, passcount
);
1007 udr_UDIBreakType(udrs
, type
);
1008 udr_UDIInt32(udrs
, current_count
);
1009 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
1013 /******************************************************** UDI_CLEAR_BREAKPOINT
1014 * UDIClearBreakpoint() is used to clear a breakpoint.
1016 UDIError
UDIClearBreakpoint (break_id
)
1017 UDIBreakId break_id
; /* in -- assigned break id */
1019 UDIInt32 service_id
= UDIClearBreakpoint_c
;
1022 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
1023 udr_UDIInt32(udrs
, &service_id
);
1024 udr_UDIBreakId(udrs
, &break_id
);
1026 if(udr_errno
) return udr_errno
;
1028 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1029 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
1033 /************************************************************** UDI_GET_STDOUT
1034 * UDIGetStdout() is called when a call to
1035 * UDIWait() indicates there is STD output data ready.
1037 UDIError
UDIGetStdout(buf
, bufsize
, count_done
)
1038 UDIHostMemPtr buf
; /* out -- buffer to be filled */
1039 UDISizeT bufsize
; /* in -- buffer size in bytes */
1040 UDISizeT
*count_done
; /* out -- number of bytes written to buf */
1042 UDIInt32 service_id
= UDIGetStdout_c
;
1045 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
1046 udr_UDIInt32(udrs
, &service_id
);
1047 udr_UDISizeT(udrs
, &bufsize
);
1049 if(udr_errno
) return udr_errno
;
1051 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1052 udr_UDISizeT(udrs
, count_done
);
1053 udr_bytes(udrs
, buf
, *count_done
);
1054 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
1058 /************************************************************** UDI_GET_STDERR
1059 * UDIGetStderr() is called when a call to
1060 * UDIWait() indicates there is STDERR output data ready
1062 UDIError
UDIGetStderr(buf
, bufsize
, count_done
)
1063 UDIHostMemPtr buf
; /* out -- buffer to be filled */
1064 UDISizeT bufsize
; /* in -- buffer size in bytes */
1065 UDISizeT
*count_done
; /* out -- number of bytes written to buf */
1067 UDIInt32 service_id
= UDIGetStderr_c
;
1070 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
1071 udr_UDIInt32(udrs
, &service_id
);
1072 udr_UDISizeT(udrs
, &bufsize
);
1074 if(udr_errno
) return udr_errno
;
1076 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1077 udr_UDISizeT(udrs
, count_done
);
1078 udr_bytes(udrs
, buf
, *count_done
);
1079 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
1083 /*************************************************************** UDI_PUT_STDIN
1084 * UDIPutStdin() is called whenever the DFE wants to
1085 * deliver an input character to the TIP.
1087 UDIError
UDIPutStdin (buf
, count
, count_done
)
1088 UDIHostMemPtr buf
; /* in -- buffer to be filled */
1089 UDISizeT count
; /* in -- buffer size in bytes */
1090 UDISizeT
*count_done
; /* out - number of bytes written to buf */
1092 UDIInt32 service_id
= UDIPutStdin_c
;
1095 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
1096 udr_UDIInt32(udrs
, &service_id
);
1097 udr_UDISizeT(udrs
, &count
);
1098 udr_bytes(udrs
, buf
, count
);
1100 if(udr_errno
) return udr_errno
;
1102 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1103 udr_UDISizeT(udrs
, count_done
);
1104 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
1108 /************************************************************** UDI_STDIN_MODE
1109 * UDIStdinMode() is used to change the mode that chazcters
1110 * are fetched from the user.
1112 UDIError
UDIStdinMode(mode
)
1113 UDIMode
*mode
; /* out - */
1115 UDIInt32 service_id
= UDIStdinMode_c
;
1118 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
1119 udr_UDIInt32(udrs
, &service_id
);
1121 if(udr_errno
) return udr_errno
;
1123 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1124 udr_UDIMode(udrs
, mode
);
1125 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
1129 /*************************************************************** UDI_PUT_TRANS
1130 * UDIPutTrans() is used to feed input to the passthru mode.
1132 UDIError
UDIPutTrans (buf
, count
, count_done
)
1133 UDIHostMemPtr buf
; /* in -- buffer address containing input data */
1134 UDISizeT count
; /* in -- number of bytes in buf */
1135 UDISizeT
*count_done
; /* out-- number of bytes transfered */
1137 UDIInt32 service_id
= UDIPutTrans_c
;
1140 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
1141 udr_UDIInt32(udrs
, &service_id
);
1142 udr_UDISizeT(udrs
, &count
);
1143 udr_bytes(udrs
, buf
, count
);
1145 if(udr_errno
) return udr_errno
;
1147 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1148 udr_UDISizeT(udrs
, count_done
);
1149 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
1153 /*************************************************************** UDI_GET_TRANS
1154 * UDIGetTrans() is used to get output lines from the
1157 UDIError
UDIGetTrans (buf
, bufsize
, count_done
)
1158 UDIHostMemPtr buf
; /* out -- buffer to be filled */
1159 UDISizeT bufsize
; /* in -- size of buf */
1160 UDISizeT
*count_done
; /* out -- number of bytes in buf */
1162 UDIInt32 service_id
= UDIGetTrans_c
;
1165 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
1166 udr_UDIInt32(udrs
, &service_id
);
1167 udr_UDISizeT(udrs
, &bufsize
);
1169 if(udr_errno
) return udr_errno
;
1171 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1172 udr_UDISizeT(udrs
, count_done
);
1173 udr_bytes(udrs
, buf
, *count_done
);
1174 udr_UDIError(udrs
, &dfe_errno
); /* get any TIP error */
1178 /************************************************************** UDI_Trans_Mode
1179 * UDITransMode() is used to change the mode that the
1180 * transparent routines operate in.
1182 UDIError
UDITransMode(mode
)
1183 UDIMode
*mode
; /* out -- selected mode */
1185 UDIInt32 service_id
= UDITransMode_c
;
1188 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
1189 udr_UDIInt32(udrs
, &service_id
);
1190 udr_UDIMode(udrs
, mode
);
1192 if(udr_errno
) return udr_errno
;
1194 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1195 udr_UDIError(udrs
, &dfe_errno
);
1199 /******************************************************************** UDI_TEST
1201 UDIError
UDITest( cnt
, str_p
, array
)
1203 UDIHostMemPtr str_p
;
1206 UDIInt32 service_id
= UDITest_c
;
1207 UDIInt16 scnt
= cnt
;
1212 udrs
->udr_op
= UDR_ENCODE
; /* send all "in" parameters */
1213 udr_UDIInt32(udrs
, &service_id
);
1215 printf("send cnt=%d scnt=%d\n", cnt
, scnt
);
1216 udr_UDISizeT(udrs
, &cnt
);
1217 udr_UDIInt16(udrs
, &scnt
);
1218 printf(" array[0]=0x%x array[1]=0x%x array[2]=0x%x array[3]=0x%x\n",
1219 array
[0], array
[1], array
[2], array
[3]);
1220 udr_bytes(udrs
, (char*)array
, 4*sizeof(UDIInt32
));
1221 printf(" string=%s\n", str_p
);
1222 udr_string(udrs
, str_p
);
1225 { fprintf(stderr
, " DFE-ipc Send ERROR\n");
1229 udrs
->udr_op
= UDR_DECODE
; /* receive all "out" parameters */
1231 udr_UDISizeT(udrs
, &r_cnt
);
1232 udr_UDIInt16(udrs
, &scnt
);
1233 printf(" rcnt=%d scnt=%d\n", r_cnt
, scnt
);
1234 udr_bytes(udrs
, (char*)array
, 4*sizeof(UDIInt32
));
1236 printf(" array[0]=0x%x array[1]=0x%x array[2]=0x%x array[3]=0x%x\n",
1237 array
[0], array
[1], array
[2], array
[3]);
1238 udr_string(udrs
, str_p
);
1239 printf(" string=%s\n", str_p
);
1241 udr_UDIError(udrs
, &dfe_errno
);
1247 UDIUInt32
UDIGetDFEIPCId()
1249 return ((company_c
<< 16) + (product_c
<< 12) + version_c
);
1251 #endif /* __GO32__ */