/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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; }