/* 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., 675 Mass Ave, Cambridge, MA 02139, 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 #include #include #include #include #include #include #include #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; }