| /* main.c -- top level of ARMulator: ARM6 Instruction Emulator. |
| Copyright (C) 1994 Advanced RISC Machines Ltd. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ |
| |
| /**********************************************************************/ |
| /* Forks the ARMulator and hangs on a socket passing on RDP messages */ |
| /* down a pipe to the ARMulator which translates them into RDI calls. */ |
| /**********************************************************************/ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <sys/types.h> |
| #include <sys/socket.h> |
| #include <netinet/in.h> |
| #include <signal.h> |
| #include <netdb.h> |
| #include <unistd.h> |
| |
| #include "armdefs.h" |
| #include "dbg_rdi.h" |
| #include "dbg_conf.h" |
| |
| #define MAXHOSTNAMELENGTH 64 |
| |
| /* Read and write routines down sockets and pipes */ |
| |
| void MYread_chars (int sock, void *p, int n); |
| unsigned char MYread_char (int sock); |
| ARMword MYread_word (int sock); |
| void MYread_FPword (int sock, char *putinhere); |
| |
| void MYwrite_word (int sock, ARMword i); |
| void MYwrite_string (int sock, char *s); |
| void MYwrite_FPword (int sock, char *fromhere); |
| void MYwrite_char (int sock, unsigned char c); |
| |
| void passon (int source, int dest, int n); |
| |
| |
| /* Mother and child processes */ |
| void parent (void); |
| void kid (void); |
| |
| /* The child process id. */ |
| pid_t child; |
| |
| /* The socket to the debugger */ |
| int debugsock; |
| |
| /* The pipes between the two processes */ |
| int mumkid[2]; |
| int kidmum[2]; |
| |
| /* A pipe for handling SWI return values that goes straight from the */ |
| /* parent to the ARMulator host interface, bypassing the childs RDP */ |
| /* to RDI interpreter */ |
| int DebuggerARMul[2]; |
| |
| /* The maximum number of file descriptors */ |
| int nfds; |
| |
| /* The socket handle */ |
| int sockethandle; |
| |
| /* The machine name */ |
| char localhost[MAXHOSTNAMELENGTH + 1]; |
| |
| /* The socket number */ |
| unsigned int socketnumber; |
| |
| /**************************************************************/ |
| /* Takes one argument: the socket number. */ |
| /* Opens a socket to the debugger, and once opened spawns the */ |
| /* ARMulator and sets up a couple of pipes. */ |
| /**************************************************************/ |
| int |
| main (int argc, char *argv[]) |
| { |
| int i; |
| struct sockaddr_in devil, isa; |
| struct hostent *hp; |
| |
| |
| if (argc == 1) |
| { |
| fprintf (stderr, "No socket number\n"); |
| return 1; |
| } |
| |
| sscanf (argv[1], "%d", &socketnumber); |
| if (!socketnumber || socketnumber > 0xffff) |
| { |
| fprintf (stderr, "Invalid socket number: %d\n", socketnumber); |
| return 1; |
| } |
| |
| gethostname (localhost, MAXHOSTNAMELENGTH); |
| hp = gethostbyname (localhost); |
| if (!hp) |
| { |
| fprintf (stderr, "Cannot get local host info\n"); |
| return 1; |
| } |
| |
| /* Open a socket */ |
| sockethandle = socket (hp->h_addrtype, SOCK_STREAM, 0); |
| if (sockethandle < 0) |
| { |
| perror ("socket"); |
| return 1; |
| } |
| |
| devil.sin_family = hp->h_addrtype; |
| devil.sin_port = htons (socketnumber); |
| devil.sin_addr.s_addr = 0; |
| for (i = 0; i < sizeof (devil.sin_zero); i++) |
| devil.sin_zero[i] = '\000'; |
| memcpy (&devil.sin_addr, hp->h_addr_list[0], hp->h_length); |
| |
| if (bind (sockethandle, &devil, sizeof (devil)) < 0) |
| { |
| perror ("bind"); |
| return 1; |
| } |
| |
| /* May only accept one debugger at once */ |
| |
| if (listen (sockethandle, 0)) |
| { |
| perror ("listen"); |
| return 1; |
| } |
| |
| fprintf (stderr, "Waiting for connection from debugger..."); |
| |
| debugsock = accept (sockethandle, &isa, &i); |
| if (debugsock < 0) |
| { |
| perror ("accept"); |
| return 1; |
| } |
| |
| fprintf (stderr, " done.\nConnection Established.\n"); |
| |
| nfds = getdtablesize (); |
| |
| if (pipe (mumkid)) |
| { |
| perror ("pipe"); |
| return 1; |
| } |
| if (pipe (kidmum)) |
| { |
| perror ("pipe"); |
| return 1; |
| } |
| |
| if (pipe (DebuggerARMul)) |
| { |
| perror ("pipe"); |
| return 1; |
| } |
| |
| #ifdef DEBUG |
| fprintf (stderr, "Created pipes ok\n"); |
| #endif |
| |
| child = fork (); |
| |
| #ifdef DEBUG |
| fprintf (stderr, "fork() ok\n"); |
| #endif |
| |
| if (child == 0) |
| kid (); |
| if (child != -1) |
| parent (); |
| |
| perror ("fork"); |
| return 1; |
| } |